promisor-remote: parse remote.*.partialclonefilter
[gitweb.git] / http.c
diff --git a/http.c b/http.c
index 8ab07458e4f5179c025a31b8801be9c86289c87c..27aa0a3192988cd0c272dab0e9f6cf52d538b6fa 100644 (file)
--- a/http.c
+++ b/http.c
@@ -176,7 +176,7 @@ size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)
        memcpy(ptr, buffer->buf.buf + buffer->posn, size);
        buffer->posn += size;
 
-       return size;
+       return size / eltsize;
 }
 
 #ifndef NO_CURL_IOCTL
@@ -204,12 +204,12 @@ size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)
        struct strbuf *buffer = buffer_;
 
        strbuf_add(buffer, ptr, size);
-       return size;
+       return nmemb;
 }
 
 size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf)
 {
-       return eltsize * nmemb;
+       return nmemb;
 }
 
 static void closedown_active_slot(struct active_request_slot *slot)
@@ -1544,7 +1544,8 @@ char *get_remote_object_url(const char *url, const char *hex,
        return strbuf_detach(&buf, NULL);
 }
 
-static int handle_curl_result(struct slot_results *results)
+void normalize_curl_result(CURLcode *result, long http_code,
+                          char *errorstr, size_t errorlen)
 {
        /*
         * If we see a failing http code with CURLE_OK, we have turned off
@@ -1554,19 +1555,24 @@ static int handle_curl_result(struct slot_results *results)
         * Likewise, if we see a redirect (30x code), that means we turned off
         * redirect-following, and we should treat the result as an error.
         */
-       if (results->curl_result == CURLE_OK &&
-           results->http_code >= 300) {
-               results->curl_result = CURLE_HTTP_RETURNED_ERROR;
+       if (*result == CURLE_OK && http_code >= 300) {
+               *result = CURLE_HTTP_RETURNED_ERROR;
                /*
                 * Normally curl will already have put the "reason phrase"
                 * from the server into curl_errorstr; unfortunately without
                 * FAILONERROR it is lost, so we can give only the numeric
                 * status code.
                 */
-               xsnprintf(curl_errorstr, sizeof(curl_errorstr),
+               xsnprintf(errorstr, errorlen,
                          "The requested URL returned error: %ld",
-                         results->http_code);
+                         http_code);
        }
+}
+
+static int handle_curl_result(struct slot_results *results)
+{
+       normalize_curl_result(&results->curl_result, results->http_code,
+                             curl_errorstr, sizeof(curl_errorstr));
 
        if (results->curl_result == CURLE_OK) {
                credential_approve(&http_auth);
@@ -2147,11 +2153,11 @@ static int fetch_and_setup_pack_index(struct packed_git **packs_head,
 int http_get_info_packs(const char *base_url, struct packed_git **packs_head)
 {
        struct http_get_options options = {0};
-       int ret = 0, i = 0;
-       char *url, *data;
+       int ret = 0;
+       char *url;
+       const char *data;
        struct strbuf buf = STRBUF_INIT;
-       unsigned char hash[GIT_MAX_RAWSZ];
-       const unsigned hexsz = the_hash_algo->hexsz;
+       struct object_id oid;
 
        end_url_with_slash(&buf, base_url);
        strbuf_addstr(&buf, "objects/info/packs");
@@ -2163,24 +2169,17 @@ int http_get_info_packs(const char *base_url, struct packed_git **packs_head)
                goto cleanup;
 
        data = buf.buf;
-       while (i < buf.len) {
-               switch (data[i]) {
-               case 'P':
-                       i++;
-                       if (i + hexsz + 12 <= buf.len &&
-                           starts_with(data + i, " pack-") &&
-                           starts_with(data + i + hexsz + 6, ".pack\n")) {
-                               get_sha1_hex(data + i + 6, hash);
-                               fetch_and_setup_pack_index(packs_head, hash,
-                                                     base_url);
-                               i += hexsz + 11;
-                               break;
-                       }
-               default:
-                       while (i < buf.len && data[i] != '\n')
-                               i++;
+       while (*data) {
+               if (skip_prefix(data, "P pack-", &data) &&
+                   !parse_oid_hex(data, &oid, &data) &&
+                   skip_prefix(data, ".pack", &data) &&
+                   (*data == '\n' || *data == '\0')) {
+                       fetch_and_setup_pack_index(packs_head, oid.hash, base_url);
+               } else {
+                       data = strchrnul(data, '\n');
                }
-               i++;
+               if (*data)
+                       data++; /* skip past newline */
        }
 
 cleanup:
@@ -2320,14 +2319,14 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb,
                        BUG("curl_easy_getinfo for HTTP code failed: %s",
                                curl_easy_strerror(c));
                if (slot->http_code >= 300)
-                       return size;
+                       return nmemb;
        }
 
        do {
                ssize_t retval = xwrite(freq->localfile,
                                        (char *) ptr + posn, size - posn);
                if (retval < 0)
-                       return posn;
+                       return posn / eltsize;
                posn += retval;
        } while (posn < size);
 
@@ -2340,7 +2339,7 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb,
                the_hash_algo->update_fn(&freq->c, expn,
                                         sizeof(expn) - freq->stream.avail_out);
        } while (freq->stream.avail_in && freq->zret == Z_OK);
-       return size;
+       return nmemb;
 }
 
 struct http_object_request *new_http_object_request(const char *base_url,