http: add HTTP_KEEP_ERROR option

We currently set curl's FAILONERROR option, which means that
any http failures are reported as curl errors, and the
http body content from the server is thrown away.

This patch introduces a new option to http_get_strbuf which
specifies that the body content from a failed http response
should be placed in the destination strbuf, where it can be
accessed by the caller.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2013-04-05 18:14:06 -04:00 committed by Junio C Hamano
parent 21ccebec0d
commit 6d052d78d7
2 changed files with 38 additions and 0 deletions

37
http.c
View File

@ -761,6 +761,25 @@ char *get_remote_object_url(const char *url, const char *hex,
int handle_curl_result(struct slot_results *results)
{
/*
* If we see a failing http code with CURLE_OK, we have turned off
* FAILONERROR (to keep the server's custom error response), and should
* translate the code into failure here.
*/
if (results->curl_result == CURLE_OK &&
results->http_code >= 400) {
results->curl_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.
*/
snprintf(curl_errorstr, sizeof(curl_errorstr),
"The requested URL returned error: %ld",
results->http_code);
}
if (results->curl_result == CURLE_OK) {
credential_approve(&http_auth);
return HTTP_OK;
@ -825,6 +844,8 @@ static int http_request(const char *url, struct strbuf *type,
strbuf_addstr(&buf, "Pragma:");
if (options & HTTP_NO_CACHE)
strbuf_addstr(&buf, " no-cache");
if (options & HTTP_KEEP_ERROR)
curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 0);
headers = curl_slist_append(headers, buf.buf);
@ -862,6 +883,22 @@ static int http_request_reauth(const char *url,
int ret = http_request(url, type, result, target, options);
if (ret != HTTP_REAUTH)
return ret;
/*
* If we are using KEEP_ERROR, the previous request may have
* put cruft into our output stream; we should clear it out before
* making our next request. We only know how to do this for
* the strbuf case, but that is enough to satisfy current callers.
*/
if (options & HTTP_KEEP_ERROR) {
switch (target) {
case HTTP_REQUEST_STRBUF:
strbuf_reset(result);
break;
default:
die("BUG: HTTP_KEEP_ERROR is only supported with strbufs");
}
}
return http_request(url, type, result, target, options);
}

1
http.h
View File

@ -118,6 +118,7 @@ extern char *get_remote_object_url(const char *url, const char *hex,
/* Options for http_request_*() */
#define HTTP_NO_CACHE 1
#define HTTP_KEEP_ERROR 2
/* Return values for http_request_*() */
#define HTTP_OK 0