summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Jeff King <peff@peff.net>2013-04-05 18:14:06 -0400
committerLibravatar Junio C Hamano <gitster@pobox.com>2013-04-06 18:56:41 -0700
commit6d052d78d74e581dd93dd6328d3c214f469e34d7 (patch)
tree044f8168624ee4a51c79fb1a4432b9130f8d09e2
parentUpdate draft release notes to 1.8.3 (diff)
downloadtgif-6d052d78d74e581dd93dd6328d3c214f469e34d7.tar.xz
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>
-rw-r--r--http.c37
-rw-r--r--http.h1
2 files changed, 38 insertions, 0 deletions
diff --git a/http.c b/http.c
index 8803c70825..45cc7c7010 100644
--- a/http.c
+++ b/http.c
@@ -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);
}
diff --git a/http.h b/http.h
index 25d1931398..0fe54f4131 100644
--- a/http.h
+++ b/http.h
@@ -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