diff options
Diffstat (limited to 'http-walker.c')
| -rw-r--r-- | http-walker.c | 85 |
1 files changed, 37 insertions, 48 deletions
diff --git a/http-walker.c b/http-walker.c index 7cdfb2f24c..c3e902c40e 100644 --- a/http-walker.c +++ b/http-walker.c @@ -1,6 +1,7 @@ #include "cache.h" #include "repository.h" #include "commit.h" +#include "hex.h" #include "walker.h" #include "http.h" #include "list.h" @@ -58,8 +59,8 @@ static void start_object_request(struct walker *walker, struct active_request_slot *slot; struct http_object_request *req; - req = new_http_object_request(obj_req->repo->base, obj_req->oid.hash); - if (req == NULL) { + req = new_http_object_request(obj_req->repo->base, &obj_req->oid); + if (!req) { obj_req->state = ABORTED; return; } @@ -98,10 +99,15 @@ static void process_object_response(void *callback_data) process_http_object_request(obj_req->req); obj_req->state = COMPLETE; + normalize_curl_result(&obj_req->req->curl_result, + obj_req->req->http_code, + obj_req->req->errorstr, + sizeof(obj_req->req->errorstr)); + /* Use alternates if necessary */ if (missing_target(obj_req->req)) { fetch_alternates(walker, alt->base); - if (obj_req->repo->next != NULL) { + if (obj_req->repo->next) { obj_req->repo = obj_req->repo->next; release_http_object_request(obj_req->req); @@ -122,7 +128,6 @@ static void release_object_request(struct object_request *obj_req) free(obj_req); } -#ifdef USE_CURL_MULTI static int fill_active_slot(struct walker *walker) { struct object_request *obj_req; @@ -131,7 +136,7 @@ static int fill_active_slot(struct walker *walker) list_for_each_safe(pos, tmp, head) { obj_req = list_entry(pos, struct object_request, node); if (obj_req->state == WAITING) { - if (has_sha1_file(obj_req->oid.hash)) + if (has_object_file(&obj_req->oid)) obj_req->state = COMPLETE; else { start_object_request(walker, obj_req); @@ -141,7 +146,6 @@ static int fill_active_slot(struct walker *walker) } return 0; } -#endif static void prefetch(struct walker *walker, unsigned char *sha1) { @@ -150,7 +154,7 @@ static void prefetch(struct walker *walker, unsigned char *sha1) newreq = xmalloc(sizeof(*newreq)); newreq->walker = walker; - hashcpy(newreq->oid.hash, sha1); + oidread(&newreq->oid, sha1); newreq->repo = data->alt; newreq->state = WAITING; newreq->req = NULL; @@ -158,10 +162,8 @@ static void prefetch(struct walker *walker, unsigned char *sha1) http_is_verbose = walker->get_verbosely; list_add_tail(&newreq->node, &object_queue_head); -#ifdef USE_CURL_MULTI fill_active_slots(); step_active_slots(); -#endif } static int is_alternate_allowed(const char *url) @@ -208,6 +210,9 @@ static void process_alternates_response(void *callback_data) char *data; int i = 0; + normalize_curl_result(&slot->curl_result, slot->http_code, + curl_errorstr, sizeof(curl_errorstr)); + if (alt_req->http_specific) { if (slot->curl_result != CURLE_OK || !alt_req->buffer->len) { @@ -221,12 +226,12 @@ static void process_alternates_response(void *callback_data) alt_req->url->buf); active_requests++; slot->in_use = 1; - if (slot->finished != NULL) + if (slot->finished) (*slot->finished) = 0; if (!start_active_slot(slot)) { cdata->got_alternates = -1; slot->in_use = 0; - if (slot->finished != NULL) + if (slot->finished) (*slot->finished) = 1; } return; @@ -349,11 +354,9 @@ static void fetch_alternates(struct walker *walker, const char *base) * wait for them to arrive and return to processing this request's * curl message */ -#ifdef USE_CURL_MULTI while (cdata->got_alternates == 0) { step_active_slots(); } -#endif /* Nothing to do if they've already been fetched */ if (cdata->got_alternates == 1) @@ -376,7 +379,7 @@ static void fetch_alternates(struct walker *walker, const char *base) alt_req.walker = walker; slot->callback_data = &alt_req; - curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer); + curl_easy_setopt(slot->curl, CURLOPT_WRITEDATA, &buffer); curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer); curl_easy_setopt(slot->curl, CURLOPT_URL, url.buf); @@ -431,18 +434,18 @@ static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigne target = find_sha1_pack(sha1, repo->packs); if (!target) return -1; + close_pack_index(target); if (walker->get_verbosely) { fprintf(stderr, "Getting pack %s\n", - sha1_to_hex(target->sha1)); + hash_to_hex(target->hash)); fprintf(stderr, " which contains %s\n", - sha1_to_hex(sha1)); + hash_to_hex(sha1)); } - preq = new_http_pack_request(target, repo->base); - if (preq == NULL) + preq = new_http_pack_request(target->hash, repo->base); + if (!preq) goto abort; - preq->lst = &repo->packs; preq->slot->results = &results; if (start_active_slot(preq->slot)) { @@ -461,6 +464,7 @@ static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigne release_http_pack_request(preq); if (ret) return ret; + http_install_packfile(target, &repo->packs); return 0; @@ -473,9 +477,9 @@ static void abort_object_request(struct object_request *obj_req) release_object_request(obj_req); } -static int fetch_object(struct walker *walker, unsigned char *sha1) +static int fetch_object(struct walker *walker, unsigned char *hash) { - char *hex = sha1_to_hex(sha1); + char *hex = hash_to_hex(hash); int ret = 0; struct object_request *obj_req = NULL; struct http_object_request *req; @@ -483,25 +487,21 @@ static int fetch_object(struct walker *walker, unsigned char *sha1) list_for_each(pos, head) { obj_req = list_entry(pos, struct object_request, node); - if (!hashcmp(obj_req->oid.hash, sha1)) + if (hasheq(obj_req->oid.hash, hash)) break; } - if (obj_req == NULL) + if (!obj_req) return error("Couldn't find request for %s in the queue", hex); - if (has_sha1_file(obj_req->oid.hash)) { - if (obj_req->req != NULL) + if (has_object_file(&obj_req->oid)) { + if (obj_req->req) abort_http_object_request(obj_req->req); abort_object_request(obj_req); return 0; } -#ifdef USE_CURL_MULTI while (obj_req->state == WAITING) step_active_slots(); -#else - start_object_request(walker, obj_req); -#endif /* * obj_req->req might change when fetching alternates in the callback @@ -518,17 +518,8 @@ static int fetch_object(struct walker *walker, unsigned char *sha1) req->localfile = -1; } - /* - * we turned off CURLOPT_FAILONERROR to avoid losing a - * persistent connection and got CURLE_OK. - */ - if (req->http_code >= 300 && req->curl_result == CURLE_OK && - (starts_with(req->url, "http://") || - starts_with(req->url, "https://"))) { - req->curl_result = CURLE_HTTP_RETURNED_ERROR; - xsnprintf(req->errorstr, sizeof(req->errorstr), - "HTTP request failed"); - } + normalize_curl_result(&req->curl_result, req->http_code, + req->errorstr, sizeof(req->errorstr)); if (obj_req->state == ABORTED) { ret = error("Request for %s aborted", hex); @@ -543,11 +534,11 @@ static int fetch_object(struct walker *walker, unsigned char *sha1) } else if (req->zret != Z_STREAM_END) { walker->corrupt_object_found++; ret = error("File %s (%s) corrupt", hex, req->url); - } else if (hashcmp(obj_req->oid.hash, req->real_sha1)) { + } else if (!oideq(&obj_req->oid, &req->real_oid)) { ret = error("File %s has bad hash", hex); } else if (req->rename < 0) { struct strbuf buf = STRBUF_INIT; - sha1_file_name(the_repository, &buf, req->sha1); + loose_object_path(the_repository, &buf, &req->oid); ret = error("unable to write sha1 filename %s", buf.buf); strbuf_release(&buf); } @@ -557,20 +548,20 @@ static int fetch_object(struct walker *walker, unsigned char *sha1) return ret; } -static int fetch(struct walker *walker, unsigned char *sha1) +static int fetch(struct walker *walker, unsigned char *hash) { struct walker_data *data = walker->data; struct alt_base *altbase = data->alt; - if (!fetch_object(walker, sha1)) + if (!fetch_object(walker, hash)) return 0; while (altbase) { - if (!http_fetch_pack(walker, altbase, sha1)) + if (!http_fetch_pack(walker, altbase, hash)) return 0; fetch_alternates(walker, data->alt->base); altbase = altbase->next; } - return error("Unable to find %s under %s", sha1_to_hex(sha1), + return error("Unable to find %s under %s", hash_to_hex(hash), data->alt->base); } @@ -623,9 +614,7 @@ struct walker *get_http_walker(const char *url) walker->cleanup = cleanup; walker->data = data; -#ifdef USE_CURL_MULTI add_fill_function(walker, (int (*)(void *)) fill_active_slot); -#endif return walker; } |
