]> git.ipfire.org Git - thirdparty/git.git/blobdiff - remote-curl.c
Sync with Git 2.45.1
[thirdparty/git.git] / remote-curl.c
index 7f81bf3fafc4e5de90fa1fbf19c3b2cde26df8aa..cae98384dae637ec6c235c15ea7236aec65de317 100644 (file)
@@ -1,4 +1,5 @@
 #include "git-compat-util.h"
+#include "git-curl-compat.h"
 #include "config.h"
 #include "environment.h"
 #include "gettext.h"
@@ -211,14 +212,9 @@ static int set_option(const char *name, const char *value)
                options.filter = xstrdup(value);
                return 0;
        } else if (!strcmp(name, "object-format")) {
-               int algo;
                options.object_format = 1;
-               if (strcmp(value, "true")) {
-                       algo = hash_algo_by_name(value);
-                       if (algo == GIT_HASH_UNKNOWN)
-                               die("unknown object format '%s'", value);
-                       options.hash_algo = &hash_algos[algo];
-               }
+               if (strcmp(value, "true"))
+                       die(_("unknown value for object-format: %s"), value);
                return 0;
        } else {
                return 1 /* unsupported */;
@@ -893,7 +889,7 @@ static curl_off_t xcurl_off_t(size_t len)
 static int post_rpc(struct rpc_state *rpc, int stateless_connect, int flush_received)
 {
        struct active_request_slot *slot;
-       struct curl_slist *headers = http_copy_default_headers();
+       struct curl_slist *headers = NULL;
        int use_gzip = rpc->gzip_request;
        char *gzip_body = NULL;
        size_t gzip_size = 0;
@@ -926,20 +922,24 @@ static int post_rpc(struct rpc_state *rpc, int stateless_connect, int flush_rece
                do {
                        err = probe_rpc(rpc, &results);
                        if (err == HTTP_REAUTH)
-                               credential_fill(&http_auth);
+                               credential_fill(&http_auth, 0);
                } while (err == HTTP_REAUTH);
                if (err != HTTP_OK)
                        return -1;
 
-               if (results.auth_avail & CURLAUTH_GSSNEGOTIATE)
+               if (results.auth_avail & CURLAUTH_GSSNEGOTIATE || http_auth.authtype)
                        needs_100_continue = 1;
        }
 
+retry:
+       headers = http_copy_default_headers();
        headers = curl_slist_append(headers, rpc->hdr_content_type);
        headers = curl_slist_append(headers, rpc->hdr_accept);
        headers = curl_slist_append(headers, needs_100_continue ?
                "Expect: 100-continue" : "Expect:");
 
+       headers = http_append_auth_header(&http_auth, headers);
+
        /* Add Accept-Language header */
        if (rpc->hdr_accept_language)
                headers = curl_slist_append(headers, rpc->hdr_accept_language);
@@ -948,7 +948,6 @@ static int post_rpc(struct rpc_state *rpc, int stateless_connect, int flush_rece
        if (rpc->protocol_header)
                headers = curl_slist_append(headers, rpc->protocol_header);
 
-retry:
        slot = get_active_slot();
 
        curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
@@ -960,7 +959,9 @@ retry:
                /* The request body is large and the size cannot be predicted.
                 * We must use chunked encoding to send it.
                 */
+#ifdef GIT_CURL_NEED_TRANSFER_ENCODING_HEADER
                headers = curl_slist_append(headers, "Transfer-Encoding: chunked");
+#endif
                rpc->initial_buffer = 1;
                curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out);
                curl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc);
@@ -1043,7 +1044,8 @@ retry:
        rpc->any_written = 0;
        err = run_slot(slot, NULL);
        if (err == HTTP_REAUTH && !large_request) {
-               credential_fill(&http_auth);
+               credential_fill(&http_auth, 0);
+               curl_slist_free_all(headers);
                goto retry;
        }
        if (err != HTTP_OK)
@@ -1446,8 +1448,14 @@ static int stateless_connect(const char *service_name)
         * establish a stateless connection, otherwise we need to tell the
         * client to fallback to using other transport helper functions to
         * complete their request.
+        *
+        * The "git-upload-archive" service is a read-only operation. Fallback
+        * to use "git-upload-pack" service to discover protocol version.
         */
-       discover = discover_refs(service_name, 0);
+       if (!strcmp(service_name, "git-upload-archive"))
+               discover = discover_refs("git-upload-pack", 0);
+       else
+               discover = discover_refs(service_name, 0);
        if (discover->version != protocol_v2) {
                printf("fallback\n");
                fflush(stdout);
@@ -1485,9 +1493,11 @@ static int stateless_connect(const char *service_name)
 
        /*
         * Dump the capability listing that we got from the server earlier
-        * during the info/refs request.
+        * during the info/refs request. This does not work with the
+        * "git-upload-archive" service.
         */
-       write_or_die(rpc.in, discover->buf, discover->len);
+       if (strcmp(service_name, "git-upload-archive"))
+               write_or_die(rpc.in, discover->buf, discover->len);
 
        /* Until we see EOF keep sending POSTs */
        while (1) {
@@ -1563,8 +1573,11 @@ int cmd_main(int argc, const char **argv)
                if (buf.len == 0)
                        break;
                if (starts_with(buf.buf, "fetch ")) {
-                       if (nongit)
-                               die(_("remote-curl: fetch attempted without a local repo"));
+                       if (nongit) {
+                               setup_git_directory_gently(&nongit);
+                               if (nongit)
+                                       die(_("remote-curl: fetch attempted without a local repo"));
+                       }
                        parse_fetch(&buf);
 
                } else if (!strcmp(buf.buf, "list") || starts_with(buf.buf, "list ")) {