Skip to content

Commit

Permalink
bundle-uri: add support for http(s):// and file://
Browse files Browse the repository at this point in the history
The previous change created the 'git fetch --bundle-uri=<uri>' option.
Currently, <uri> must be a filename.

Update copy_uri_to_file() to first inspect the URI for an HTTP(S) prefix
and use git-remote-https as the way to download the data at that URI.
Otherwise, check to see if file:// is present and modify the prefix
accordingly.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
  • Loading branch information
derrickstolee committed Jul 25, 2022
1 parent b6fed1d commit dac37c4
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 2 deletions.
68 changes: 66 additions & 2 deletions bundle-uri.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,75 @@ static int find_temp_filename(struct strbuf *name)
return fd;
}

static int download_https_uri_to_file(const char *file, const char *uri)
{
int result = 0;
struct child_process cp = CHILD_PROCESS_INIT;
FILE *child_in = NULL, *child_out = NULL;
struct strbuf line = STRBUF_INIT;
int found_get = 0;

strvec_pushl(&cp.args, "git-remote-https", "origin", uri, NULL);
cp.in = -1;
cp.out = -1;

if (start_command(&cp))
return 1;

child_in = fdopen(cp.in, "w");
if (!child_in) {
result = 1;
goto cleanup;
}

child_out = fdopen(cp.out, "r");
if (!child_out) {
result = 1;
goto cleanup;
}

fprintf(child_in, "capabilities\n");
fflush(child_in);

while (!strbuf_getline(&line, child_out)) {
if (!line.len)
break;
if (!strcmp(line.buf, "get"))
found_get = 1;
}
strbuf_release(&line);

if (!found_get) {
result = error(_("insufficient capabilities"));
goto cleanup;
}

fprintf(child_in, "get %s %s\n\n", uri, file);

cleanup:
if (child_in)
fclose(child_in);
if (finish_command(&cp))
return 1;
if (child_out)
fclose(child_out);
return result;
}

static int copy_uri_to_file(const char *filename, int fd, const char *uri)
{
int res, uri_fd;
const char *out;

if (skip_prefix(uri, "https:", &out) ||
skip_prefix(uri, "http:", &out))
return download_https_uri_to_file(filename, uri);

if (!skip_prefix(uri, "file://", &out))
out = uri;

/* Copy as a file */
int res;
int uri_fd = open(uri, 0);
uri_fd = open(uri, 0);

if (uri_fd < 0)
return -1;
Expand Down
37 changes: 37 additions & 0 deletions t/t5558-fetch-bundle-uri.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,41 @@ test_expect_success 'fetch file bundle' '
test_cmp expect actual
'

test_expect_success 'fetch file:// bundle' '
git init fetch-file &&
git -C fetch-file fetch --bundle-uri="file://$(pwd)/fetch-from/B.bundle" &&
git -C fetch-file rev-parse refs/bundles/topic >actual &&
git -C fetch-from rev-parse topic >expect &&
test_cmp expect actual
'

#########################################################################
# HTTP tests begin here

. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd

test_expect_success 'fail to fetch from non-existent HTTP URL' '
test_must_fail git fetch --bundle-uri="$HTTPD_URL/does-not-exist" 2>err &&
grep "failed to download bundle from URI" err
'

test_expect_success 'fail to fetch from non-bundle HTTP URL' '
echo bogus >"$HTTPD_DOCUMENT_ROOT_PATH/bogus" &&
test_must_fail git fetch --bundle-uri="$HTTPD_URL/bogus" 2>err &&
grep "is not a bundle" err
'

test_expect_success 'fetch HTTP bundle' '
cp fetch-from/B.bundle "$HTTPD_DOCUMENT_ROOT_PATH/B.bundle" &&
git init fetch-http &&
git -C fetch-http fetch --bundle-uri="$HTTPD_URL/B.bundle" &&
git -C fetch-http rev-parse refs/bundles/topic >actual &&
git -C fetch-from rev-parse topic >expect &&
test_cmp expect actual
'

# Do not add tests here unless they use the HTTP server, as they will
# not run unless the HTTP dependencies exist.

test_done

0 comments on commit dac37c4

Please sign in to comment.