From dfe8638511b637f1d57591be7443f51b453908e9 Mon Sep 17 00:00:00 2001 From: Friel Date: Tue, 8 Sep 2026 08:21:23 +0000 Subject: [PATCH 1/3] http: factor out pack request setup Separate curl request setup from opening the temporary pack. An HTTP authentication retry will need a fresh request without reopening or truncating the pack, which another downloader may be using. Keep the file and index-pack ownership unchanged. Free the previous header list when preparing another request. Signed-off-by: Friel --- http.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/http.c b/http.c index c8fcfd7693e897..cafdc568decbf6 100644 --- a/http.c +++ b/http.c @@ -2735,6 +2735,20 @@ struct http_pack_request *new_http_pack_request( strbuf_detach(&buf, NULL)); } +static void prepare_http_pack_request(struct http_pack_request *preq, + off_t offset) +{ + preq->slot = get_active_slot(); + curl_slist_free_all(preq->headers); + preq->headers = object_request_headers(); + curl_easy_setopt(preq->slot->curl, CURLOPT_WRITEDATA, preq->packfile); + curl_easy_setopt(preq->slot->curl, CURLOPT_WRITEFUNCTION, fwrite); + curl_easy_setopt(preq->slot->curl, CURLOPT_URL, preq->url); + curl_easy_setopt(preq->slot->curl, CURLOPT_HTTPHEADER, preq->headers); + if (offset > 0) + http_opt_request_remainder(preq->slot->curl, offset); +} + struct http_pack_request *new_direct_http_pack_request( const unsigned char *packed_git_hash, char *url) { @@ -2778,12 +2792,7 @@ struct http_pack_request *new_direct_http_pack_request( } preq->packfile = xfdopen(fd, "w"); - preq->slot = get_active_slot(); - preq->headers = object_request_headers(); - curl_easy_setopt(preq->slot->curl, CURLOPT_WRITEDATA, preq->packfile); - curl_easy_setopt(preq->slot->curl, CURLOPT_WRITEFUNCTION, fwrite); - curl_easy_setopt(preq->slot->curl, CURLOPT_URL, preq->url); - curl_easy_setopt(preq->slot->curl, CURLOPT_HTTPHEADER, preq->headers); + prepare_http_pack_request(preq, prev_posn); if (prev_posn > 0) { if (http_is_verbose) @@ -2791,7 +2800,6 @@ struct http_pack_request *new_direct_http_pack_request( "Resuming fetch of pack %s at byte %"PRIuMAX"\n", hash_to_hex(packed_git_hash), (uintmax_t)prev_posn); - http_opt_request_remainder(preq->slot->curl, prev_posn); } return preq; From 38057873cd364807f40686b0572ad119905171a8 Mon Sep 17 00:00:00 2001 From: Friel Date: Tue, 8 Sep 2026 08:21:37 +0000 Subject: [PATCH 2/3] http: authenticate packfile-URI downloads http-fetch --packfile does not handle HTTP_REAUTH, so a protected pack fails with HTTP 401 even when a credential helper can authenticate it. Use run_one_slot() and http_reauth_prepare() to retry authentication, with the same three-attempt limit as http_request_recoverable(). Look up credentials for the pack URL, not the fetch negotiation URL. Collect WWW-Authenticate and append helper Authorization headers. Disable FAILONERROR so older curl versions deliver challenge headers, but discard error response bodies instead of writing them into the partial pack. Unlike HTTP_REQUEST_FILE retries, never truncate that shared file. For a redirected 401, update credentials before run_one_slot() handles the response. Do this in the completion callback, while the curl handle still exists even with http.minSessions=0. Preserve the challenge and reload http.extraHeader for the new URL, so a direct retry cannot resend headers configured for the redirect source. Test destination-scoped credentials and resumption through fetch-pack. Signed-off-by: Friel --- Documentation/technical/packfile-uri.adoc | 6 ++ http-fetch.c | 9 +-- http.c | 92 +++++++++++++++++++++++ http.h | 8 ++ t/t5702-protocol-v2.sh | 64 ++++++++++++++++ 5 files changed, 173 insertions(+), 6 deletions(-) diff --git a/Documentation/technical/packfile-uri.adoc b/Documentation/technical/packfile-uri.adoc index 9d453d47651a03..1475f5bd662381 100644 --- a/Documentation/technical/packfile-uri.adoc +++ b/Documentation/technical/packfile-uri.adoc @@ -50,6 +50,12 @@ Client design The client has a config variable `fetch.uriprotocols` that determines which protocols the end user is willing to use. By default, this is empty. +HTTP(S) packfile downloads use the HTTP authentication and redirect +configuration used for other Git HTTP requests. Credentials are looked up +for the pack URL, including its path when `credential.useHttpPath` is +enabled, rather than copied from the fetch negotiation. A pack served by +another host can use credentials configured for that host. + When the client downloads the given URIs, it should store them with "keep" files, just like it does with the packfile in the `packfile` section. These additional "keep" files can only be removed after the refs have been updated - diff --git a/http-fetch.c b/http-fetch.c index 05f68f306a5821..d2691aecc235d0 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -56,7 +56,6 @@ static void fetch_single_packfile(struct object_id *packfile_hash, const char *url, const char **index_pack_args) { struct http_pack_request *preq; - struct slot_results results; int ret; http_init(NULL, url, 0); @@ -64,14 +63,12 @@ static void fetch_single_packfile(struct object_id *packfile_hash, preq = new_direct_http_pack_request(packfile_hash->hash, xstrdup(url)); if (!preq) die("couldn't create http pack request"); - preq->slot->results = &results; preq->index_pack_args = index_pack_args; preq->preserve_index_pack_stdout = 1; - if (start_active_slot(preq->slot)) { - run_active_slot(preq->slot); - if (results.curl_result != CURLE_OK && - results.http_code != 416) { + ret = run_http_pack_request(preq); + if (ret != HTTP_START_FAILED) { + if (ret != HTTP_OK) { struct url_info url; char *nurl = url_normalize(preq->url, &url); if (!nurl || !git_env_bool("GIT_TRACE_REDACT", 1)) { diff --git a/http.c b/http.c index cafdc568decbf6..af556448c17831 100644 --- a/http.c +++ b/http.c @@ -2749,6 +2749,98 @@ static void prepare_http_pack_request(struct http_pack_request *preq, http_opt_request_remainder(preq->slot->curl, offset); } +static void update_http_pack_url(void *data) +{ + struct http_pack_request *preq = data; + struct urlmatch_config config = URLMATCH_CONFIG_INIT; + struct strvec wwwauth; + char *url; + + if (preq->slot->http_code != 401 || + curl_easy_getinfo(preq->slot->curl, CURLINFO_EFFECTIVE_URL, &url) != CURLE_OK || + !url || !strcmp(preq->url, url)) + return; + + /* Change credential context before run_one_slot() handles the 401. */ + wwwauth = http_auth.wwwauth_headers; + http_auth.wwwauth_headers = (struct strvec)STRVEC_INIT; + free(preq->url); + preq->url = xstrdup(url); + credential_from_url(&http_auth, preq->url); + http_auth.wwwauth_headers = wwwauth; + + /* A direct retry must not reuse headers scoped to the redirect source. */ + string_list_clear(&extra_http_headers, 0); + config.section = "http"; + config.key = "extraheader"; + config.collect_fn = http_options; + url_normalize(preq->url, &config.url); + repo_config(the_repository, urlmatch_config_entry, &config); + free(config.url.url); + urlmatch_config_release(&config); +} + +static size_t fwrite_http_pack(char *ptr, size_t size, size_t nmemb, void *data) +{ + struct http_pack_request *preq = data; + long code; + + if (curl_easy_getinfo(preq->slot->curl, CURLINFO_HTTP_CODE, &code) != CURLE_OK) + return 0; + /* Error bodies must not overwrite a partial pack shared with another fetch. */ + if (code >= 300) + return size * nmemb; + return fwrite(ptr, size, nmemb, preq->packfile); +} + +int run_http_pack_request(struct http_pack_request *preq) +{ + off_t offset = ftello(preq->packfile); + int attempts = 3; + int ret; + + if (offset < 0) + return HTTP_START_FAILED; + + for (;;) { + struct slot_results results = { .retry_after = -1 }; + + preq->headers = http_append_auth_header(&http_auth, preq->headers); + curl_easy_setopt(preq->slot->curl, CURLOPT_HTTPHEADER, preq->headers); + curl_easy_setopt(preq->slot->curl, CURLOPT_HEADERFUNCTION, fwrite_wwwauth); + curl_easy_setopt(preq->slot->curl, CURLOPT_WRITEHEADER, NULL); + curl_easy_setopt(preq->slot->curl, CURLOPT_WRITEDATA, preq); + curl_easy_setopt(preq->slot->curl, CURLOPT_WRITEFUNCTION, fwrite_http_pack); + /* Older curl versions omit challenge headers with FAILONERROR. */ + curl_easy_setopt(preq->slot->curl, CURLOPT_FAILONERROR, 0L); + if (http_follow_config == HTTP_FOLLOW_INITIAL) + curl_easy_setopt(preq->slot->curl, CURLOPT_FOLLOWLOCATION, 1L); + preq->slot->callback_func = update_http_pack_url; + preq->slot->callback_data = preq; + ret = run_one_slot(preq->slot, &results); + preq->slot->results = NULL; + preq->slot->callback_func = NULL; + preq->slot->callback_data = NULL; + + if (ret != HTTP_START_FAILED && results.http_code == 416) { + ret = HTTP_OK; + break; + } + + if (ret != HTTP_REAUTH || !--attempts) + break; + + /* Never truncate a partial pack to recover from an error response. */ + if (ftello(preq->packfile) != offset) { + ret = HTTP_ERROR; + break; + } + http_reauth_prepare(1); + prepare_http_pack_request(preq, offset); + } + return ret; +} + struct http_pack_request *new_direct_http_pack_request( const unsigned char *packed_git_hash, char *url) { diff --git a/http.h b/http.h index 729c51904d39ad..f3e51097a8bcbb 100644 --- a/http.h +++ b/http.h @@ -232,6 +232,14 @@ struct http_pack_request *new_http_pack_request( const unsigned char *packed_git_hash, const char *base_url); struct http_pack_request *new_direct_http_pack_request( const unsigned char *packed_git_hash, char *url); + +/* + * Run a direct pack request, retrying HTTP authentication challenges. + * Returns HTTP_OK (also for 416), or an HTTP error. + * The caller must initialize HTTP credentials from the pack URL, not the Git + * remote, before constructing the request. + */ +int run_http_pack_request(struct http_pack_request *preq); int finish_http_pack_request(struct http_pack_request *preq); void release_http_pack_request(struct http_pack_request *preq); diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 0f05286de8b4df..3302cf5db3e2cb 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -1221,6 +1221,70 @@ configure_exclusion () { cat objh } +test_expect_success 'setup authenticated packfile URI' ' + git init "$HTTPD_DOCUMENT_ROOT_PATH/uri-auth" && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/uri-auth" config uploadpack.allowsidebandall true && + test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/uri-auth" one && + configure_exclusion "$HTTPD_DOCUMENT_ROOT_PATH/uri-auth" one.t >uri-auth-oid && + uri_auth_hash=$(cat packh) && + mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb" && + cp "$HTTPD_DOCUMENT_ROOT_PATH/mypack-$uri_auth_hash.pack" \ + "$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/uri-auth.pack" && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/uri-auth" config \ + uploadpack.blobpackfileuri \ + "$(cat uri-auth-oid) $uri_auth_hash $HTTPD_URL/auth/dumb/uri-auth.pack" && + write_script uri-auth-helper <<-\EOF + echo "$1" >>"$HOME/uri-auth-operations" + cat >>"$HOME/uri-auth-input" + if test "$1" = get + then + echo username=user@host + echo password=pass@host + fi + EOF +' + +test_expect_success 'packfile URI does not use a helper scoped to the remote host' ' + test_config_global "credential.http://localhost:$LIB_HTTPD_PORT.helper" \ + "!\"$TRASH_DIRECTORY/uri-auth-helper\"" && + >uri-auth-operations && + test_must_fail env GIT_TEST_SIDEBAND_ALL=1 \ + git -c protocol.version=2 -c fetch.uriprotocols=http \ + clone "http://localhost:$LIB_HTTPD_PORT/smart/uri-auth" uri-auth-other 2>err && + test_must_be_empty uri-auth-operations +' + +test_expect_success 'packfile URI uses credentials scoped to its own host' ' + test_config_global "credential.$HTTPD_URL.helper" \ + "!\"$TRASH_DIRECTORY/uri-auth-helper\"" && + test_config_global credential.useHttpPath true && + >uri-auth-operations && + >uri-auth-input && + GIT_TEST_SIDEBAND_ALL=1 git -c protocol.version=2 -c fetch.uriprotocols=http \ + clone "http://localhost:$LIB_HTTPD_PORT/smart/uri-auth" uri-auth-own-host && + test_cmp "$HTTPD_DOCUMENT_ROOT_PATH/uri-auth/one.t" uri-auth-own-host/one.t && + printf "get\nstore\n" >expect && + test_cmp expect uri-auth-operations && + test_grep "^path=auth/dumb/uri-auth.pack$" uri-auth-input +' + +test_expect_success 'packfile URI resumes after a credential challenge' ' + test_config_global credential.helper "!\"$TRASH_DIRECTORY/uri-auth-helper\"" && + git init uri-auth-resume && + mkdir -p uri-auth-resume/.git/objects/pack && + dd if="$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/uri-auth.pack" \ + of="uri-auth-resume/.git/objects/pack/pack-$uri_auth_hash.pack.temp" \ + bs=1 count=12 && + >uri-auth-operations && + GIT_TEST_SIDEBAND_ALL=1 git -C uri-auth-resume \ + -c protocol.version=2 -c fetch.uriprotocols=http \ + fetch "$HTTPD_URL/smart/uri-auth" HEAD && + git -C uri-auth-resume cat-file blob FETCH_HEAD:one.t >actual && + test_cmp "$HTTPD_DOCUMENT_ROOT_PATH/uri-auth/one.t" actual && + printf "get\nstore\n" >expect && + test_cmp expect uri-auth-operations +' + test_expect_success 'part of packfile response provided as URI' ' P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && rm -rf "$P" http_child log && From 409df2c11ff1465d7f587026ec3a0d9375c105ef Mon Sep 17 00:00:00 2001 From: Friel Date: Tue, 8 Sep 2026 08:21:47 +0000 Subject: [PATCH 3/3] t5563: exercise pack downloads with HTTP authentication tests Run the existing credential-helper assertions against both ls-remote and http-fetch --packfile. This covers Basic, Bearer, proactive and multistage authentication without duplicating their fixtures. Add pack-specific checks for the retry limit, anonymous URLs, redirect configuration, and source-scoped headers. Combine the redirected request with credential.useHttpPath and http.minSessions=0 to check credential selection and curl handle lifetime. Signed-off-by: Friel --- t/t5563-simple-http-auth.sh | 170 ++++++++++++++++++++++++++++++------ 1 file changed, 142 insertions(+), 28 deletions(-) diff --git a/t/t5563-simple-http-auth.sh b/t/t5563-simple-http-auth.sh index a7d475dd68dbd7..99a73b54a24a4f 100755 --- a/t/t5563-simple-http-auth.sh +++ b/t/t5563-simple-http-auth.sh @@ -63,7 +63,116 @@ test_expect_success 'setup repository' ' git push --mirror "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" ' -test_expect_success 'access using basic auth' ' +test_expect_success 'setup pack for authenticated downloads' ' + git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" repack -ad && + pack=$(echo "$HTTPD_DOCUMENT_ROOT_PATH/repo.git/objects/pack/"*.pack) && + pack_hash=${pack##*/pack-} && + pack_hash=${pack_hash%.pack} && + pack_url="$HTTPD_URL/custom_auth/repo.git/objects/pack/pack-$pack_hash.pack" +' + +test_expect_success 'packfile download bounds multistage authentication retries' ' + test_when_finished per_test_cleanup && + set_credential_reply get <<-EOF && + capability[]=authtype + capability[]=state + authtype=Multistage + credential=first + state[]=helper:second + continue=1 + EOF + set_credential_reply get second <<-EOF && + capability[]=authtype + capability[]=state + authtype=Multistage + credential=second + state[]=helper:third + continue=1 + EOF + cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF && + id=default response=WWW-Authenticate: Multistage challenge="retry" + EOF + test_config_global credential.helper test-helper && + test_must_fail git http-fetch --packfile="$pack_hash" \ + --index-pack-arg=index-pack --index-pack-arg=--stdin "$pack_url" && + test_path_is_file get-query.cred && + test_path_is_file get-query-second.cred && + test_path_is_missing get-query-third.cred && + test_path_is_missing store-query.cred +' + +test_expect_success 'packfile redirect does not reuse source-scoped headers' ' + test_when_finished per_test_cleanup && + set_credential_reply get <<-EOF && + capability[]=authtype + authtype=Bearer + credential=destination-token + EOF + cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF && + id=1 creds=Bearer source-token + id=2 creds=Bearer destination-token + EOF + cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF && + id=1 status=302 response=Location: http://localhost:$LIB_HTTPD_PORT/custom_auth/repo.git/objects/pack/pack-$pack_hash.pack + id=2 status=200 + id=default response=WWW-Authenticate: Bearer realm="destination" + EOF + test_config_global "http.$HTTPD_URL.extraHeader" "Authorization: Bearer source-token" && + test_config_global credential.helper test-helper && + test_config_global credential.useHttpPath true && + git -c http.minSessions=0 http-fetch --packfile="$pack_hash" \ + --index-pack-arg=index-pack --index-pack-arg=--stdin "$pack_url" && + expect_credential_query get <<-EOF && + capability[]=authtype + capability[]=state + protocol=http + host=localhost:$LIB_HTTPD_PORT + path=custom_auth/repo.git/objects/pack/pack-$pack_hash.pack + wwwauth[]=Bearer realm="destination" + EOF + expect_credential_query store <<-EOF + capability[]=authtype + authtype=Bearer + credential=destination-token + protocol=http + host=localhost:$LIB_HTTPD_PORT + path=custom_auth/repo.git/objects/pack/pack-$pack_hash.pack + EOF +' + +test_expect_success 'packfile download honors http.followRedirects=false' ' + test_when_finished per_test_cleanup && + test_config_global credential.helper test-helper && + test_must_fail git -c http.followRedirects=false \ + http-fetch --packfile="$pack_hash" \ + --index-pack-arg=index-pack --index-pack-arg=--stdin \ + "$HTTPD_URL/redir-to/auth/dumb/repo.git/objects/pack/pack-$pack_hash.pack" && + test_path_is_missing get-query.cred +' + +test_expect_success 'public packfile download does not consult credential helpers' ' + test_when_finished per_test_cleanup && + test_config_global credential.helper test-helper && + git http-fetch --packfile="$pack_hash" \ + --index-pack-arg=index-pack --index-pack-arg=--stdin \ + "$HTTPD_URL/dumb/repo.git/objects/pack/pack-$pack_hash.pack?signature=opaque" && + test_path_is_missing get-query.cred +' + +for request in refs pack +do + case "$request" in + refs) + command=ls-remote + url="$HTTPD_URL/custom_auth/repo.git" + ;; + pack) + command="http-fetch --packfile=$pack_hash --index-pack-arg=index-pack --index-pack-arg=--stdin" + url=$pack_url + ;; + esac + +test_expect_success "$request: access using basic auth" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -82,7 +191,7 @@ test_expect_success 'access using basic auth' ' EOF test_config_global credential.helper test-helper && - git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -100,7 +209,7 @@ test_expect_success 'access using basic auth' ' EOF ' -test_expect_success 'access using basic auth via authtype' ' +test_expect_success "$request: access using basic auth via authtype" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -120,7 +229,7 @@ test_expect_success 'access using basic auth via authtype' ' EOF test_config_global credential.helper test-helper && - GIT_CURL_VERBOSE=1 git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + GIT_CURL_VERBOSE=1 git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -139,7 +248,7 @@ test_expect_success 'access using basic auth via authtype' ' EOF ' -test_expect_success 'access using basic auth invalid credentials' ' +test_expect_success "$request: access using basic auth invalid credentials" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -158,7 +267,7 @@ test_expect_success 'access using basic auth invalid credentials' ' EOF test_config_global credential.helper test-helper && - test_must_fail git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + test_must_fail git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -177,7 +286,7 @@ test_expect_success 'access using basic auth invalid credentials' ' EOF ' -test_expect_success 'access using basic proactive auth' ' +test_expect_success "$request: access using basic proactive auth" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -197,7 +306,7 @@ test_expect_success 'access using basic proactive auth' ' test_config_global credential.helper test-helper && test_config_global http.proactiveAuth basic && - git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -215,7 +324,7 @@ test_expect_success 'access using basic proactive auth' ' EOF ' -test_expect_success 'access using auto proactive auth with basic default' ' +test_expect_success "$request: access using auto proactive auth with basic default" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -235,7 +344,7 @@ test_expect_success 'access using auto proactive auth with basic default' ' test_config_global credential.helper test-helper && test_config_global http.proactiveAuth auto && - git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -252,7 +361,7 @@ test_expect_success 'access using auto proactive auth with basic default' ' EOF ' -test_expect_success 'access using auto proactive auth with authtype from credential helper' ' +test_expect_success "$request: access using auto proactive auth with authtype from credential helper" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -275,7 +384,7 @@ test_expect_success 'access using auto proactive auth with authtype from credent test_config_global credential.helper test-helper && test_config_global http.proactiveAuth auto && - git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -293,7 +402,7 @@ test_expect_success 'access using auto proactive auth with authtype from credent EOF ' -test_expect_success 'access using basic auth with extra challenges' ' +test_expect_success "$request: access using basic auth with extra challenges" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -314,7 +423,7 @@ test_expect_success 'access using basic auth with extra challenges' ' EOF test_config_global credential.helper test-helper && - git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -334,7 +443,7 @@ test_expect_success 'access using basic auth with extra challenges' ' EOF ' -test_expect_success 'access using basic auth mixed-case wwwauth header name' ' +test_expect_success "$request: access using basic auth mixed-case wwwauth header name" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -355,7 +464,7 @@ test_expect_success 'access using basic auth mixed-case wwwauth header name' ' EOF test_config_global credential.helper test-helper && - git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -375,7 +484,7 @@ test_expect_success 'access using basic auth mixed-case wwwauth header name' ' EOF ' -test_expect_success 'access using basic auth with wwwauth header continuations' ' +test_expect_success "$request: access using basic auth with wwwauth header continuations" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -401,7 +510,7 @@ test_expect_success 'access using basic auth with wwwauth header continuations' EOF test_config_global credential.helper test-helper && - git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -421,7 +530,7 @@ test_expect_success 'access using basic auth with wwwauth header continuations' EOF ' -test_expect_success 'access using basic auth with wwwauth header empty continuations' ' +test_expect_success "$request: access using basic auth with wwwauth header empty continuations" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -449,7 +558,7 @@ test_expect_success 'access using basic auth with wwwauth header empty continuat printf "id=default response=WWW-Authenticate: Basic realm=\"example.com\"\r\n" >>"$CHALLENGE" && test_config_global credential.helper test-helper && - git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -469,7 +578,7 @@ test_expect_success 'access using basic auth with wwwauth header empty continuat EOF ' -test_expect_success 'access using basic auth with wwwauth header mixed continuations' ' +test_expect_success "$request: access using basic auth with wwwauth header mixed continuations" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -493,7 +602,7 @@ test_expect_success 'access using basic auth with wwwauth header mixed continuat printf "id=default response=WWW-Authenticate: Basic realm=\"example.com\"\r\n" >>"$CHALLENGE" && test_config_global credential.helper test-helper && - git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -512,7 +621,7 @@ test_expect_success 'access using basic auth with wwwauth header mixed continuat EOF ' -test_expect_success 'access using bearer auth' ' +test_expect_success "$request: access using bearer auth" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -536,7 +645,7 @@ test_expect_success 'access using bearer auth' ' EOF test_config_global credential.helper test-helper && - git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -557,7 +666,7 @@ test_expect_success 'access using bearer auth' ' EOF ' -test_expect_success 'access using bearer auth with invalid credentials' ' +test_expect_success "$request: access using bearer auth with invalid credentials" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -581,7 +690,7 @@ test_expect_success 'access using bearer auth with invalid credentials' ' EOF test_config_global credential.helper test-helper && - test_must_fail git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + test_must_fail git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -605,6 +714,8 @@ test_expect_success 'access using bearer auth with invalid credentials' ' EOF ' +if test "$request" = refs +then test_expect_success 'clone with bearer auth and probe_rpc' ' test_when_finished "per_test_cleanup" && test_when_finished "rm -rf large.git" && @@ -649,8 +760,9 @@ test_expect_success 'clone with bearer auth and probe_rpc' ' test_config_global credential.helper test-helper && git clone "$HTTPD_URL/custom_auth/large.git" partial-auth-clone 2>clone-error ' +fi -test_expect_success 'access using three-legged auth' ' +test_expect_success "$request: access using three-legged auth" ' test_when_finished "per_test_cleanup" && set_credential_reply get <<-EOF && @@ -686,7 +798,7 @@ test_expect_success 'access using three-legged auth' ' EOF test_config_global credential.helper test-helper && - git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + git $command "$url" && expect_credential_query get <<-EOF && capability[]=authtype @@ -721,6 +833,8 @@ test_expect_success 'access using three-legged auth' ' test_lazy_prereq SPNEGO 'curl --version | grep -qi "SPNEGO\|GSS-API\|Kerberos\|negotiate"' +done + test_expect_success SPNEGO 'http.emptyAuth=auto attempts Negotiate before credential_fill' ' test_when_finished "per_test_cleanup" &&