Merge branch 'jk/maint-http-init-not-in-result-handler'
authorJeff King <peff@peff.net>
Mon, 29 Oct 2012 08:13:09 +0000 (04:13 -0400)
committerJeff King <peff@peff.net>
Mon, 29 Oct 2012 08:13:09 +0000 (04:13 -0400)
Further clean-up to the http codepath that picks up results after
cURL library is done with one request slot.

* jk/maint-http-init-not-in-result-handler:
  http: do not set up curl auth after a 401
  remote-curl: do not call run_slot repeatedly

1  2 
http.c
remote-curl.c

diff --combined http.c
--- 1/http.c
--- 2/http.c
+++ b/http.c
@@@ -4,7 -4,6 +4,7 @@@
  #include "run-command.h"
  #include "url.h"
  #include "credential.h"
 +#include "version.h"
  
  int active_requests;
  int http_is_verbose;
@@@ -300,7 -299,7 +300,7 @@@ static CURL *get_curl_handle(void
                curl_easy_setopt(result, CURLOPT_VERBOSE, 1);
  
        curl_easy_setopt(result, CURLOPT_USERAGENT,
 -              user_agent ? user_agent : GIT_HTTP_USER_AGENT);
 +              user_agent ? user_agent : git_user_agent());
  
        if (curl_ftp_no_epsv)
                curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0);
@@@ -745,8 -744,7 +745,7 @@@ char *get_remote_object_url(const char 
        return strbuf_detach(&buf, NULL);
  }
  
- int handle_curl_result(struct active_request_slot *slot,
-                      struct slot_results *results)
+ int handle_curl_result(struct slot_results *results)
  {
        if (results->curl_result == CURLE_OK) {
                credential_approve(&http_auth);
                        return HTTP_NOAUTH;
                } else {
                        credential_fill(&http_auth);
-                       init_curl_http_auth(slot->curl);
                        return HTTP_REAUTH;
                }
        } else {
 +#if LIBCURL_VERSION_NUM >= 0x070c00
                if (!curl_errorstr[0])
                        strlcpy(curl_errorstr,
                                curl_easy_strerror(results->curl_result),
                                sizeof(curl_errorstr));
 +#endif
                return HTTP_ERROR;
        }
  }
@@@ -817,11 -812,10 +815,11 @@@ static int http_request(const char *url
  
        curl_easy_setopt(slot->curl, CURLOPT_URL, url);
        curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
 +      curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
  
        if (start_active_slot(slot)) {
                run_active_slot(slot);
-               ret = handle_curl_result(slot, &results);
+               ret = handle_curl_result(&results);
        } else {
                error("Unable to start HTTP request for %s", url);
                ret = HTTP_START_FAILED;
@@@ -925,7 -919,7 +923,7 @@@ static char *fetch_pack_index(unsigned 
        tmp = strbuf_detach(&buf, NULL);
  
        if (http_get_file(url, tmp, 0) != HTTP_OK) {
 -              error("Unable to get pack index %s\n", url);
 +              error("Unable to get pack index %s", url);
                free(tmp);
                tmp = NULL;
        }
diff --combined remote-curl.c
@@@ -95,16 -95,15 +95,16 @@@ static struct discovery* discover_refs(
        struct strbuf buffer = STRBUF_INIT;
        struct discovery *last = last_discovery;
        char *refs_url;
 -      int http_ret, is_http = 0, proto_git_candidate = 1;
 +      int http_ret, maybe_smart = 0;
  
        if (last && !strcmp(service, last->service))
                return last;
        free_discovery(last);
  
        strbuf_addf(&buffer, "%sinfo/refs", url);
 -      if (!prefixcmp(url, "http://") || !prefixcmp(url, "https://")) {
 -              is_http = 1;
 +      if ((!prefixcmp(url, "http://") || !prefixcmp(url, "https://")) &&
 +           git_env_bool("GIT_SMART_HTTP", 1)) {
 +              maybe_smart = 1;
                if (!strchr(url, '?'))
                        strbuf_addch(&buffer, '?');
                else
        refs_url = strbuf_detach(&buffer, NULL);
  
        http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
 -
 -      /* try again with "plain" url (no ? or & appended) */
 -      if (http_ret != HTTP_OK && http_ret != HTTP_NOAUTH) {
 -              free(refs_url);
 -              strbuf_reset(&buffer);
 -
 -              proto_git_candidate = 0;
 -              strbuf_addf(&buffer, "%sinfo/refs", url);
 -              refs_url = strbuf_detach(&buffer, NULL);
 -
 -              http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
 -      }
 -
        switch (http_ret) {
        case HTTP_OK:
                break;
        last->buf_alloc = strbuf_detach(&buffer, &last->len);
        last->buf = last->buf_alloc;
  
 -      if (is_http && proto_git_candidate
 -              && 5 <= last->len && last->buf[4] == '#') {
 +      if (maybe_smart && 5 <= last->len && last->buf[4] == '#') {
                /* smart HTTP response; validate that the service
                 * pkt-line matches our request.
                 */
@@@ -356,7 -369,7 +356,7 @@@ static int run_slot(struct active_reque
        slot->curl_result = curl_easy_perform(slot->curl);
        finish_active_slot(slot);
  
-       err = handle_curl_result(slot, &results);
+       err = handle_curl_result(&results);
        if (err != HTTP_OK && err != HTTP_REAUTH) {
                error("RPC failed; result=%d, HTTP code = %ld",
                      results.curl_result, results.http_code);
@@@ -380,7 -393,7 +380,7 @@@ static int probe_rpc(struct rpc_state *
        curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
        curl_easy_setopt(slot->curl, CURLOPT_POST, 1);
        curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);
 -      curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
 +      curl_easy_setopt(slot->curl, CURLOPT_ENCODING, NULL);
        curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, "0000");
        curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, 4);
        curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
@@@ -431,17 -444,18 +431,18 @@@ static int post_rpc(struct rpc_state *r
                        return -1;
        }
  
+       headers = curl_slist_append(headers, rpc->hdr_content_type);
+       headers = curl_slist_append(headers, rpc->hdr_accept);
+       headers = curl_slist_append(headers, "Expect:");
+ retry:
        slot = get_active_slot();
  
        curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
        curl_easy_setopt(slot->curl, CURLOPT_POST, 1);
        curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);
 -      curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
 +      curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
  
-       headers = curl_slist_append(headers, rpc->hdr_content_type);
-       headers = curl_slist_append(headers, rpc->hdr_accept);
-       headers = curl_slist_append(headers, "Expect:");
        if (large_request) {
                /* The request body is large and the size cannot be predicted.
                 * We must use chunked encoding to send it.
        curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, rpc_in);
        curl_easy_setopt(slot->curl, CURLOPT_FILE, rpc);
  
-       do {
-               err = run_slot(slot);
-       } while (err == HTTP_REAUTH && !large_request && !use_gzip);
+       err = run_slot(slot);
+       if (err == HTTP_REAUTH && !large_request && !use_gzip)
+               goto retry;
        if (err != HTTP_OK)
                err = -1;