|
37 | 37 | #include "mergesort.h" |
38 | 38 | #include "prio-queue.h" |
39 | 39 | #include "promisor-remote.h" |
| 40 | +#include "urlmatch.h" |
40 | 41 |
|
41 | 42 | static int transfer_unpack_limit = -1; |
42 | 43 | static int fetch_unpack_limit = -1; |
@@ -1375,6 +1376,29 @@ static int add_haves(struct fetch_negotiator *negotiator, |
1375 | 1376 | return haves_added; |
1376 | 1377 | } |
1377 | 1378 |
|
| 1379 | +static char *get_packfile_uri_base(const char *url) |
| 1380 | +{ |
| 1381 | + struct url_info info; |
| 1382 | + char *base; |
| 1383 | + |
| 1384 | + if (!url || !uri_protocols.nr) |
| 1385 | + return NULL; |
| 1386 | + base = url_normalize(url, &info); |
| 1387 | + if (!base) |
| 1388 | + return NULL; |
| 1389 | + |
| 1390 | + /* An absolute path must not bypass the configured URI protocols. */ |
| 1391 | + if ((starts_with(base, "http:") && |
| 1392 | + unsorted_string_list_has_string(&uri_protocols, "http")) || |
| 1393 | + (starts_with(base, "https:") && |
| 1394 | + unsorted_string_list_has_string(&uri_protocols, "https"))) { |
| 1395 | + base[info.path_off] = '\0'; |
| 1396 | + return base; |
| 1397 | + } |
| 1398 | + free(base); |
| 1399 | + return NULL; |
| 1400 | +} |
| 1401 | + |
1378 | 1402 | static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out, |
1379 | 1403 | struct fetch_pack_args *args, |
1380 | 1404 | const struct ref *wants, struct oidset *common, |
@@ -1423,6 +1447,11 @@ static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out, |
1423 | 1447 | } |
1424 | 1448 | } |
1425 | 1449 | if (to_send.len) { |
| 1450 | + char *uri_base = get_packfile_uri_base(args->url); |
| 1451 | + |
| 1452 | + if (uri_base) |
| 1453 | + strbuf_addstr(&to_send, ",absolute-path"); |
| 1454 | + free(uri_base); |
1426 | 1455 | packet_buf_write(&req_buf, "packfile-uris %s", |
1427 | 1456 | to_send.buf); |
1428 | 1457 | strbuf_release(&to_send); |
@@ -1639,18 +1668,32 @@ static void receive_wanted_refs(struct packet_reader *reader, |
1639 | 1668 | } |
1640 | 1669 |
|
1641 | 1670 | static void receive_packfile_uris(struct packet_reader *reader, |
1642 | | - struct string_list *uris) |
| 1671 | + struct string_list *uris, |
| 1672 | + const char *url) |
1643 | 1673 | { |
| 1674 | + char *uri_base = get_packfile_uri_base(url); |
| 1675 | + |
1644 | 1676 | process_section_header(reader, "packfile-uris", 0); |
1645 | 1677 | while (packet_reader_read(reader) == PACKET_READ_NORMAL) { |
1646 | | - if (reader->pktlen < the_hash_algo->hexsz || |
1647 | | - reader->line[the_hash_algo->hexsz] != ' ') |
| 1678 | + struct object_id oid; |
| 1679 | + const char *end; |
| 1680 | + |
| 1681 | + if (parse_oid_hex(reader->line, &oid, &end) || *end != ' ') |
1648 | 1682 | die("expected '<hash> <uri>', got: %s", reader->line); |
1649 | 1683 |
|
1650 | | - string_list_append(uris, reader->line); |
| 1684 | + if (end[1] == '/') { |
| 1685 | + if (end[2] == '/' || !uri_base) |
| 1686 | + die("unexpected relative packfile URI"); |
| 1687 | + string_list_append_nodup(uris, |
| 1688 | + xstrfmt("%s %s%s", oid_to_hex(&oid), |
| 1689 | + uri_base, end + 1)); |
| 1690 | + } else { |
| 1691 | + string_list_append(uris, reader->line); |
| 1692 | + } |
1651 | 1693 | } |
1652 | 1694 | if (reader->status != PACKET_READ_DELIM) |
1653 | 1695 | die("expected DELIM"); |
| 1696 | + free(uri_base); |
1654 | 1697 | } |
1655 | 1698 |
|
1656 | 1699 | enum fetch_state { |
@@ -1826,7 +1869,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args, |
1826 | 1869 | if (git_env_bool("GIT_TRACE_REDACT", 1)) |
1827 | 1870 | reader.options |= PACKET_READ_REDACT_URI_PATH; |
1828 | 1871 | if (process_section_header(&reader, "packfile-uris", 1)) |
1829 | | - receive_packfile_uris(&reader, &packfile_uris); |
| 1872 | + receive_packfile_uris(&reader, &packfile_uris, |
| 1873 | + args->url); |
1830 | 1874 | /* We don't expect more URIs. Reset to avoid expensive URI check. */ |
1831 | 1875 | reader.options &= ~PACKET_READ_REDACT_URI_PATH; |
1832 | 1876 |
|
|
0 commit comments