Git fork

Merge branch 'jk/http-walker-status-fix'

dumb-http walker has been updated to share more error recovery
strategy with the normal codepath.

* jk/http-walker-status-fix:
http: use normalize_curl_result() instead of manual conversion
http: normalize curl results for dumb loose and alternates fetches
http: factor out curl result code normalization

+47 -17
+10 -11
http-walker.c
··· 98 98 process_http_object_request(obj_req->req); 99 99 obj_req->state = COMPLETE; 100 100 101 + normalize_curl_result(&obj_req->req->curl_result, 102 + obj_req->req->http_code, 103 + obj_req->req->errorstr, 104 + sizeof(obj_req->req->errorstr)); 105 + 101 106 /* Use alternates if necessary */ 102 107 if (missing_target(obj_req->req)) { 103 108 fetch_alternates(walker, alt->base); ··· 207 212 const char null_byte = '\0'; 208 213 char *data; 209 214 int i = 0; 215 + 216 + normalize_curl_result(&slot->curl_result, slot->http_code, 217 + curl_errorstr, sizeof(curl_errorstr)); 210 218 211 219 if (alt_req->http_specific) { 212 220 if (slot->curl_result != CURLE_OK || ··· 518 526 req->localfile = -1; 519 527 } 520 528 521 - /* 522 - * we turned off CURLOPT_FAILONERROR to avoid losing a 523 - * persistent connection and got CURLE_OK. 524 - */ 525 - if (req->http_code >= 300 && req->curl_result == CURLE_OK && 526 - (starts_with(req->url, "http://") || 527 - starts_with(req->url, "https://"))) { 528 - req->curl_result = CURLE_HTTP_RETURNED_ERROR; 529 - xsnprintf(req->errorstr, sizeof(req->errorstr), 530 - "HTTP request failed"); 531 - } 529 + normalize_curl_result(&req->curl_result, req->http_code, 530 + req->errorstr, sizeof(req->errorstr)); 532 531 533 532 if (obj_req->state == ABORTED) { 534 533 ret = error("Request for %s aborted", hex);
+12 -6
http.c
··· 1544 1544 return strbuf_detach(&buf, NULL); 1545 1545 } 1546 1546 1547 - static int handle_curl_result(struct slot_results *results) 1547 + void normalize_curl_result(CURLcode *result, long http_code, 1548 + char *errorstr, size_t errorlen) 1548 1549 { 1549 1550 /* 1550 1551 * If we see a failing http code with CURLE_OK, we have turned off ··· 1554 1555 * Likewise, if we see a redirect (30x code), that means we turned off 1555 1556 * redirect-following, and we should treat the result as an error. 1556 1557 */ 1557 - if (results->curl_result == CURLE_OK && 1558 - results->http_code >= 300) { 1559 - results->curl_result = CURLE_HTTP_RETURNED_ERROR; 1558 + if (*result == CURLE_OK && http_code >= 300) { 1559 + *result = CURLE_HTTP_RETURNED_ERROR; 1560 1560 /* 1561 1561 * Normally curl will already have put the "reason phrase" 1562 1562 * from the server into curl_errorstr; unfortunately without 1563 1563 * FAILONERROR it is lost, so we can give only the numeric 1564 1564 * status code. 1565 1565 */ 1566 - xsnprintf(curl_errorstr, sizeof(curl_errorstr), 1566 + xsnprintf(errorstr, errorlen, 1567 1567 "The requested URL returned error: %ld", 1568 - results->http_code); 1568 + http_code); 1569 1569 } 1570 + } 1571 + 1572 + static int handle_curl_result(struct slot_results *results) 1573 + { 1574 + normalize_curl_result(&results->curl_result, results->http_code, 1575 + curl_errorstr, sizeof(curl_errorstr)); 1570 1576 1571 1577 if (results->curl_result == CURLE_OK) { 1572 1578 credential_approve(&http_auth);
+9
http.h
··· 136 136 137 137 #define missing_target(a) missing__target((a)->http_code, (a)->curl_result) 138 138 139 + /* 140 + * Normalize curl results to handle CURL_FAILONERROR (or lack thereof). Failing 141 + * http codes have their "result" converted to CURLE_HTTP_RETURNED_ERROR, and 142 + * an appropriate string placed in the errorstr buffer (pass curl_errorstr if 143 + * you don't have a custom buffer). 144 + */ 145 + void normalize_curl_result(CURLcode *result, long http_code, char *errorstr, 146 + size_t errorlen); 147 + 139 148 /* Helpers for modifying and creating URLs */ 140 149 extern void append_remote_object_url(struct strbuf *buf, const char *url, 141 150 const char *hex,
+16
t/t5550-http-fetch-dumb.sh
··· 408 408 test_i18ngrep "unable to access.*/redir-to/502" stderr 409 409 ' 410 410 411 + test_expect_success 'fetching via http alternates works' ' 412 + parent=$HTTPD_DOCUMENT_ROOT_PATH/alt-parent.git && 413 + git init --bare "$parent" && 414 + git -C "$parent" --work-tree=. commit --allow-empty -m foo && 415 + git -C "$parent" update-server-info && 416 + commit=$(git -C "$parent" rev-parse HEAD) && 417 + 418 + child=$HTTPD_DOCUMENT_ROOT_PATH/alt-child.git && 419 + git init --bare "$child" && 420 + echo "../../alt-parent.git/objects" >"$child/objects/info/alternates" && 421 + git -C "$child" update-ref HEAD $commit && 422 + git -C "$child" update-server-info && 423 + 424 + git -c http.followredirects=true clone "$HTTPD_URL/dumb/alt-child.git" 425 + ' 426 + 411 427 stop_httpd 412 428 test_done