diff options
Diffstat (limited to 'http.c')
-rw-r--r-- | http.c | 127 |
1 files changed, 64 insertions, 63 deletions
@@ -150,7 +150,7 @@ static unsigned long empty_auth_useless = static struct curl_slist *pragma_header; static struct curl_slist *no_pragma_header; -static struct curl_slist *extra_http_headers; +static struct string_list extra_http_headers = STRING_LIST_INIT_DUP; static struct active_request_slot *active_queue_head; @@ -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) @@ -414,11 +414,9 @@ static int http_options(const char *var, const char *value, void *cb) if (!value) { return config_error_nonbool(var); } else if (!*value) { - curl_slist_free_all(extra_http_headers); - extra_http_headers = NULL; + string_list_clear(&extra_http_headers, 0); } else { - extra_http_headers = - curl_slist_append(extra_http_headers, value); + string_list_append(&extra_http_headers, value); } return 0; } @@ -513,9 +511,11 @@ static void set_proxyauth_name_password(CURL *result) #else struct strbuf s = STRBUF_INIT; - strbuf_addstr_urlencode(&s, proxy_auth.username, 1); + strbuf_addstr_urlencode(&s, proxy_auth.username, + is_rfc3986_unreserved); strbuf_addch(&s, ':'); - strbuf_addstr_urlencode(&s, proxy_auth.password, 1); + strbuf_addstr_urlencode(&s, proxy_auth.password, + is_rfc3986_unreserved); curl_proxyuserpwd = strbuf_detach(&s, NULL); curl_easy_setopt(result, CURLOPT_PROXYUSERPWD, curl_proxyuserpwd); #endif @@ -680,8 +680,8 @@ static void curl_dump_header(const char *text, unsigned char *ptr, size_t size, for (header = headers; *header; header++) { if (hide_sensitive_header) redact_sensitive_header(*header); - strbuf_insert((*header), 0, text, strlen(text)); - strbuf_insert((*header), strlen(text), ": ", 2); + strbuf_insertstr((*header), 0, text); + strbuf_insertstr((*header), strlen(text), ": "); strbuf_rtrim((*header)); strbuf_addch((*header), '\n'); trace_strbuf(&trace_curl, (*header)); @@ -1073,6 +1073,7 @@ void http_init(struct remote *remote, const char *url, int proactive_auth) git_config(urlmatch_config_entry, &config); free(normalized_url); + string_list_clear(&config.vars, 1); #if LIBCURL_VERSION_NUM >= 0x073800 if (http_ssl_backend) { @@ -1199,8 +1200,7 @@ void http_cleanup(void) #endif curl_global_cleanup(); - curl_slist_free_all(extra_http_headers); - extra_http_headers = NULL; + string_list_clear(&extra_http_headers, 0); curl_slist_free_all(pragma_header); pragma_header = NULL; @@ -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); @@ -1618,10 +1624,11 @@ int run_one_slot(struct active_request_slot *slot, struct curl_slist *http_copy_default_headers(void) { - struct curl_slist *headers = NULL, *h; + struct curl_slist *headers = NULL; + const struct string_list_item *item; - for (h = extra_http_headers; h; h = h->next) - headers = curl_slist_append(headers, h->data); + for_each_string_list_item(item, &extra_http_headers) + headers = curl_slist_append(headers, item->string); return headers; } @@ -2065,7 +2072,7 @@ int http_fetch_ref(const char *base, struct ref *ref) url = quote_ref_url(base, ref->name); if (http_get_strbuf(url, &buffer, &options) == HTTP_OK) { strbuf_rtrim(&buffer); - if (buffer.len == 40) + if (buffer.len == the_hash_algo->hexsz) ret = get_oid_hex(buffer.buf, &ref->old_oid); else if (starts_with(buffer.buf, "ref: ")) { ref->symref = xstrdup(buffer.buf + 5); @@ -2079,19 +2086,19 @@ int http_fetch_ref(const char *base, struct ref *ref) } /* Helpers for fetching packs */ -static char *fetch_pack_index(unsigned char *sha1, const char *base_url) +static char *fetch_pack_index(unsigned char *hash, const char *base_url) { char *url, *tmp; struct strbuf buf = STRBUF_INIT; if (http_is_verbose) - fprintf(stderr, "Getting index for pack %s\n", sha1_to_hex(sha1)); + fprintf(stderr, "Getting index for pack %s\n", hash_to_hex(hash)); end_url_with_slash(&buf, base_url); - strbuf_addf(&buf, "objects/pack/pack-%s.idx", sha1_to_hex(sha1)); + strbuf_addf(&buf, "objects/pack/pack-%s.idx", hash_to_hex(hash)); url = strbuf_detach(&buf, NULL); - strbuf_addf(&buf, "%s.temp", sha1_pack_index_name(sha1)); + strbuf_addf(&buf, "%s.temp", sha1_pack_index_name(hash)); tmp = strbuf_detach(&buf, NULL); if (http_get_file(url, tmp, NULL) != HTTP_OK) { @@ -2147,11 +2154,11 @@ add_pack: 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 +2170,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: @@ -2236,10 +2236,10 @@ int finish_http_pack_request(struct http_pack_request *preq) return -1; } - unlink(sha1_pack_index_name(p->sha1)); + unlink(sha1_pack_index_name(p->hash)); - if (finalize_object_file(preq->tmpfile.buf, sha1_pack_name(p->sha1)) - || finalize_object_file(tmp_idx, sha1_pack_index_name(p->sha1))) { + if (finalize_object_file(preq->tmpfile.buf, sha1_pack_name(p->hash)) + || finalize_object_file(tmp_idx, sha1_pack_index_name(p->hash))) { free(tmp_idx); return -1; } @@ -2262,10 +2262,10 @@ struct http_pack_request *new_http_pack_request( end_url_with_slash(&buf, base_url); strbuf_addf(&buf, "objects/pack/pack-%s.pack", - sha1_to_hex(target->sha1)); + hash_to_hex(target->hash)); preq->url = strbuf_detach(&buf, NULL); - strbuf_addf(&preq->tmpfile, "%s.temp", sha1_pack_name(target->sha1)); + strbuf_addf(&preq->tmpfile, "%s.temp", sha1_pack_name(target->hash)); preq->packfile = fopen(preq->tmpfile.buf, "a"); if (!preq->packfile) { error("Unable to open local file %s for pack", @@ -2289,7 +2289,8 @@ struct http_pack_request *new_http_pack_request( if (http_is_verbose) fprintf(stderr, "Resuming fetch of pack %s at byte %"PRIuMAX"\n", - sha1_to_hex(target->sha1), (uintmax_t)prev_posn); + hash_to_hex(target->hash), + (uintmax_t)prev_posn); http_opt_request_remainder(preq->slot->curl, prev_posn); } @@ -2319,14 +2320,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); @@ -2336,10 +2337,10 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb, freq->stream.next_out = expn; freq->stream.avail_out = sizeof(expn); freq->zret = git_inflate(&freq->stream, Z_SYNC_FLUSH); - git_SHA1_Update(&freq->c, expn, - sizeof(expn) - freq->stream.avail_out); + 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, @@ -2395,7 +2396,7 @@ struct http_object_request *new_http_object_request(const char *base_url, git_inflate_init(&freq->stream); - git_SHA1_Init(&freq->c); + the_hash_algo->init_fn(&freq->c); freq->url = get_remote_object_url(base_url, hex, 0); @@ -2430,7 +2431,7 @@ struct http_object_request *new_http_object_request(const char *base_url, if (prev_read == -1) { memset(&freq->stream, 0, sizeof(freq->stream)); git_inflate_init(&freq->stream); - git_SHA1_Init(&freq->c); + the_hash_algo->init_fn(&freq->c); if (prev_posn>0) { prev_posn = 0; lseek(freq->localfile, 0, SEEK_SET); @@ -2501,7 +2502,7 @@ int finish_http_object_request(struct http_object_request *freq) } git_inflate_end(&freq->stream); - git_SHA1_Final(freq->real_oid.hash, &freq->c); + the_hash_algo->final_fn(freq->real_oid.hash, &freq->c); if (freq->zret != Z_STREAM_END) { unlink_or_warn(freq->tmpfile.buf); return -1; |