diff options
author | Junio C Hamano <gitster@pobox.com> | 2013-10-30 12:09:53 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-10-30 12:09:53 -0700 |
commit | 177f0a400955f2345c73a5c8b0459d617429ffd9 (patch) | |
tree | befe6d8d3e767c1dc6bc06b3a8557d44a5faaefe /remote-curl.c | |
parent | 0d6cf2471f426dd2b742e2285aad78381738be96 (diff) | |
parent | 70900eda4a0ed473ab5a933940285ac3dda698c0 (diff) | |
download | git-177f0a400955f2345c73a5c8b0459d617429ffd9.tar.gz |
Merge branch 'jk/http-auth-redirects'
Handle the case where http transport gets redirected during the
authorization request better.
* jk/http-auth-redirects:
http.c: Spell the null pointer as NULL
remote-curl: rewrite base url from info/refs redirects
remote-curl: store url as a strbuf
remote-curl: make refs_url a strbuf
http: update base URLs when we see redirects
http: provide effective url to callers
http: hoist credential request out of handle_curl_result
http: refactor options to http_get_*
http_request: factor out curlinfo_strbuf
http_get_file: style fixes
Diffstat (limited to 'remote-curl.c')
-rw-r--r-- | remote-curl.c | 69 |
1 files changed, 41 insertions, 28 deletions
diff --git a/remote-curl.c b/remote-curl.c index b5ebe01800..c9b891adbf 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -9,9 +9,11 @@ #include "string-list.h" #include "sideband.h" #include "argv-array.h" +#include "credential.h" static struct remote *remote; -static const char *url; /* always ends with a trailing slash */ +/* always ends with a trailing slash */ +static struct strbuf url = STRBUF_INIT; struct options { int verbosity; @@ -130,7 +132,8 @@ static struct ref *parse_info_refs(struct discovery *heads) mid = &data[i]; if (data[i] == '\n') { if (mid - start != 40) - die("%sinfo/refs not valid: is this a git repository?", url); + die("%sinfo/refs not valid: is this a git repository?", + url.buf); data[i] = 0; ref_name = mid + 1; ref = xmalloc(sizeof(struct ref) + @@ -149,7 +152,7 @@ static struct ref *parse_info_refs(struct discovery *heads) } ref = alloc_ref("HEAD"); - if (!http_fetch_ref(url, ref) && + if (!http_fetch_ref(url.buf, ref) && !resolve_remote_symref(ref, refs)) { ref->next = refs; refs = ref; @@ -203,40 +206,47 @@ static struct discovery* discover_refs(const char *service, int for_push) struct strbuf exp = STRBUF_INIT; struct strbuf type = STRBUF_INIT; struct strbuf buffer = STRBUF_INIT; + struct strbuf refs_url = STRBUF_INIT; + struct strbuf effective_url = STRBUF_INIT; struct discovery *last = last_discovery; - char *refs_url; int http_ret, maybe_smart = 0; + struct http_get_options options; if (last && !strcmp(service, last->service)) return last; free_discovery(last); - strbuf_addf(&buffer, "%sinfo/refs", url); - if ((!prefixcmp(url, "http://") || !prefixcmp(url, "https://")) && + strbuf_addf(&refs_url, "%sinfo/refs", url.buf); + if ((!prefixcmp(url.buf, "http://") || !prefixcmp(url.buf, "https://")) && git_env_bool("GIT_SMART_HTTP", 1)) { maybe_smart = 1; - if (!strchr(url, '?')) - strbuf_addch(&buffer, '?'); + if (!strchr(url.buf, '?')) + strbuf_addch(&refs_url, '?'); else - strbuf_addch(&buffer, '&'); - strbuf_addf(&buffer, "service=%s", service); + strbuf_addch(&refs_url, '&'); + strbuf_addf(&refs_url, "service=%s", service); } - refs_url = strbuf_detach(&buffer, NULL); - http_ret = http_get_strbuf(refs_url, &type, &buffer, - HTTP_NO_CACHE | HTTP_KEEP_ERROR); + memset(&options, 0, sizeof(options)); + options.content_type = &type; + options.effective_url = &effective_url; + options.base_url = &url; + options.no_cache = 1; + options.keep_error = 1; + + http_ret = http_get_strbuf(refs_url.buf, &buffer, &options); switch (http_ret) { case HTTP_OK: break; case HTTP_MISSING_TARGET: show_http_message(&type, &buffer); - die("repository '%s' not found", url); + die("repository '%s' not found", url.buf); case HTTP_NOAUTH: show_http_message(&type, &buffer); - die("Authentication failed for '%s'", url); + die("Authentication failed for '%s'", url.buf); default: show_http_message(&type, &buffer); - die("unable to access '%s': %s", url, curl_errorstr); + die("unable to access '%s': %s", url.buf, curl_errorstr); } last= xcalloc(1, sizeof(*last_discovery)); @@ -277,9 +287,10 @@ static struct discovery* discover_refs(const char *service, int for_push) else last->refs = parse_info_refs(last); - free(refs_url); + strbuf_release(&refs_url); strbuf_release(&exp); strbuf_release(&type); + strbuf_release(&effective_url); strbuf_release(&buffer); last_discovery = last; return last; @@ -463,6 +474,8 @@ static int post_rpc(struct rpc_state *rpc) if (large_request) { do { err = probe_rpc(rpc); + if (err == HTTP_REAUTH) + credential_fill(&http_auth); } while (err == HTTP_REAUTH); if (err != HTTP_OK) return -1; @@ -562,8 +575,10 @@ retry: curl_easy_setopt(slot->curl, CURLOPT_FILE, rpc); err = run_slot(slot); - if (err == HTTP_REAUTH && !large_request) + if (err == HTTP_REAUTH && !large_request) { + credential_fill(&http_auth); goto retry; + } if (err != HTTP_OK) err = -1; @@ -598,7 +613,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads) rpc->out = client.out; strbuf_init(&rpc->result, 0); - strbuf_addf(&buf, "%s%s", url, svc); + strbuf_addf(&buf, "%s%s", url.buf, svc); rpc->service_url = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "Content-Type: application/x-%s-request", svc); @@ -650,7 +665,7 @@ static int fetch_dumb(int nr_heads, struct ref **to_fetch) for (i = 0; i < nr_heads; i++) targets[i] = xstrdup(sha1_to_hex(to_fetch[i]->old_sha1)); - walker = get_http_walker(url); + walker = get_http_walker(url.buf); walker->get_all = 1; walker->get_tree = 1; walker->get_history = 1; @@ -697,7 +712,7 @@ static int fetch_git(struct discovery *heads, depth_arg = strbuf_detach(&buf, NULL); argv[argc++] = depth_arg; } - argv[argc++] = url; + argv[argc++] = url.buf; argv[argc++] = NULL; for (i = 0; i < nr_heads; i++) { @@ -795,7 +810,7 @@ static int push_dav(int nr_spec, char **specs) argv[argc++] = "--dry-run"; if (options.verbosity > 1) argv[argc++] = "--verbose"; - argv[argc++] = url; + argv[argc++] = url.buf; for (i = 0; i < nr_spec; i++) argv[argc++] = specs[i]; argv[argc++] = NULL; @@ -828,7 +843,7 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs) argv_array_push(&args, options.progress ? "--progress" : "--no-progress"); for_each_string_list_item(cas_option, &cas_options) argv_array_push(&args, cas_option->string); - argv_array_push(&args, url); + argv_array_push(&args, url.buf); for (i = 0; i < nr_spec; i++) argv_array_push(&args, specs[i]); @@ -909,14 +924,12 @@ int main(int argc, const char **argv) remote = remote_get(argv[1]); if (argc > 2) { - end_url_with_slash(&buf, argv[2]); + end_url_with_slash(&url, argv[2]); } else { - end_url_with_slash(&buf, remote->url[0]); + end_url_with_slash(&url, remote->url[0]); } - url = strbuf_detach(&buf, NULL); - - http_init(remote, url, 0); + http_init(remote, url.buf, 0); do { if (strbuf_getline(&buf, stdin, '\n') == EOF) { |