test-wildmatch: add "perf" command to compare wildmatch and fnmatch
[gitweb.git] / remote-curl.c
index e5e9490be7b246e06a849b3d35485fc3a9903abe..3ec474fc631eb3b433b3cadbd74aed4b83cba724 100644 (file)
@@ -290,6 +290,7 @@ static void output_refs(struct ref *refs)
 struct rpc_state {
        const char *service_name;
        const char **argv;
+       struct strbuf *stdin_preamble;
        char *service_url;
        char *hdr_content_type;
        char *hdr_accept;
@@ -361,16 +362,17 @@ static size_t rpc_in(char *ptr, size_t eltsize,
 
 static int run_slot(struct active_request_slot *slot)
 {
-       int err = 0;
+       int err;
        struct slot_results results;
 
        slot->results = &results;
        slot->curl_result = curl_easy_perform(slot->curl);
        finish_active_slot(slot);
 
-       if (results.curl_result != CURLE_OK) {
-               err |= error("RPC failed; result=%d, HTTP code = %ld",
-                       results.curl_result, results.http_code);
+       err = handle_curl_result(slot);
+       if (err != HTTP_OK && err != HTTP_REAUTH) {
+               error("RPC failed; result=%d, HTTP code = %ld",
+                     results.curl_result, results.http_code);
        }
 
        return err;
@@ -435,9 +437,11 @@ static int post_rpc(struct rpc_state *rpc)
        }
 
        if (large_request) {
-               err = probe_rpc(rpc);
-               if (err)
-                       return err;
+               do {
+                       err = probe_rpc(rpc);
+               } while (err == HTTP_REAUTH);
+               if (err != HTTP_OK)
+                       return -1;
        }
 
        slot = get_active_slot();
@@ -524,7 +528,11 @@ static int post_rpc(struct rpc_state *rpc)
        curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, rpc_in);
        curl_easy_setopt(slot->curl, CURLOPT_FILE, rpc);
 
-       err = run_slot(slot);
+       do {
+               err = run_slot(slot);
+       } while (err == HTTP_REAUTH && !large_request && !use_gzip);
+       if (err != HTTP_OK)
+               err = -1;
 
        curl_slist_free_all(headers);
        free(gzip_body);
@@ -535,6 +543,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
 {
        const char *svc = rpc->service_name;
        struct strbuf buf = STRBUF_INIT;
+       struct strbuf *preamble = rpc->stdin_preamble;
        struct child_process client;
        int err = 0;
 
@@ -545,6 +554,8 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
        client.argv = rpc->argv;
        if (start_command(&client))
                exit(1);
+       if (preamble)
+               write_or_die(client.in, preamble->buf, preamble->len);
        if (heads)
                write_or_die(client.in, heads->buf, heads->len);
 
@@ -626,13 +637,14 @@ static int fetch_git(struct discovery *heads,
        int nr_heads, struct ref **to_fetch)
 {
        struct rpc_state rpc;
+       struct strbuf preamble = STRBUF_INIT;
        char *depth_arg = NULL;
-       const char **argv;
        int argc = 0, i, err;
+       const char *argv[15];
 
-       argv = xmalloc((15 + nr_heads) * sizeof(char*));
        argv[argc++] = "fetch-pack";
        argv[argc++] = "--stateless-rpc";
+       argv[argc++] = "--stdin";
        argv[argc++] = "--lock-pack";
        if (options.followtags)
                argv[argc++] = "--include-tag";
@@ -651,24 +663,27 @@ static int fetch_git(struct discovery *heads,
                argv[argc++] = depth_arg;
        }
        argv[argc++] = url;
+       argv[argc++] = NULL;
+
        for (i = 0; i < nr_heads; i++) {
                struct ref *ref = to_fetch[i];
                if (!ref->name || !*ref->name)
                        die("cannot fetch by sha1 over smart http");
-               argv[argc++] = ref->name;
+               packet_buf_write(&preamble, "%s\n", ref->name);
        }
-       argv[argc++] = NULL;
+       packet_buf_flush(&preamble);
 
        memset(&rpc, 0, sizeof(rpc));
        rpc.service_name = "git-upload-pack",
        rpc.argv = argv;
+       rpc.stdin_preamble = &preamble;
        rpc.gzip_request = 1;
 
        err = rpc_service(&rpc, heads);
        if (rpc.result.len)
                safe_write(1, rpc.result.buf, rpc.result.len);
        strbuf_release(&rpc.result);
-       free(argv);
+       strbuf_release(&preamble);
        free(depth_arg);
        return err;
 }