aboutsummaryrefslogtreecommitdiff
path: root/http.c
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2016-04-27 14:20:37 +0200
committerJunio C Hamano <gitster@pobox.com>2016-04-27 14:02:33 -0700
commit8cb01e2fd3a50b6d0893dfb066183f16a3c7a355 (patch)
treef4c60954733e0eca23c2ef00c72169fc61932170 /http.c
parent90f7b16b3adc78d4bbabbd426fb69aa78c714f71 (diff)
downloadgit-8cb01e2fd3a50b6d0893dfb066183f16a3c7a355.tar.gz
git-8cb01e2fd3a50b6d0893dfb066183f16a3c7a355.tar.xz
http: support sending custom HTTP headers
We introduce a way to send custom HTTP headers with all requests. This allows us, for example, to send an extra token from build agents for temporary access to private repositories. (This is the use case that triggered this patch.) This feature can be used like this: git -c http.extraheader='Secret: sssh!' fetch $URL $REF Note that `curl_easy_setopt(..., CURLOPT_HTTPHEADER, ...)` takes only a single list, overriding any previous call. This means we have to collect _all_ of the headers we want to use into a single list, and feed it to cURL in one shot. Since we already unconditionally set a "pragma" header when initializing the curl handles, we can add our new headers to that list. For callers which override the default header list (like probe_rpc), we provide `http_copy_default_headers()` so they can do the same trick. Big thanks to Jeff King and Junio Hamano for their outstanding help and patient reviews. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Reviewed-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'http.c')
-rw-r--r--http.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/http.c b/http.c
index 69da4454d..aae9944cb 100644
--- a/http.c
+++ b/http.c
@@ -114,6 +114,7 @@ static unsigned long http_auth_methods = CURLAUTH_ANY;
static struct curl_slist *pragma_header;
static struct curl_slist *no_pragma_header;
+static struct curl_slist *extra_http_headers;
static struct active_request_slot *active_queue_head;
@@ -323,6 +324,19 @@ static int http_options(const char *var, const char *value, void *cb)
#endif
}
+ if (!strcmp("http.extraheader", var)) {
+ if (!value) {
+ return config_error_nonbool(var);
+ } else if (!*value) {
+ curl_slist_free_all(extra_http_headers);
+ extra_http_headers = NULL;
+ } else {
+ extra_http_headers =
+ curl_slist_append(extra_http_headers, value);
+ }
+ return 0;
+ }
+
/* Fall back on the default ones */
return git_default_config(var, value, cb);
}
@@ -675,8 +689,10 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
if (remote)
var_override(&http_proxy_authmethod, remote->http_proxy_authmethod);
- pragma_header = curl_slist_append(pragma_header, "Pragma: no-cache");
- no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:");
+ pragma_header = curl_slist_append(http_copy_default_headers(),
+ "Pragma: no-cache");
+ no_pragma_header = curl_slist_append(http_copy_default_headers(),
+ "Pragma:");
#ifdef USE_CURL_MULTI
{
@@ -762,6 +778,9 @@ void http_cleanup(void)
#endif
curl_global_cleanup();
+ curl_slist_free_all(extra_http_headers);
+ extra_http_headers = NULL;
+
curl_slist_free_all(pragma_header);
pragma_header = NULL;
@@ -1160,6 +1179,16 @@ int run_one_slot(struct active_request_slot *slot,
return handle_curl_result(results);
}
+struct curl_slist *http_copy_default_headers(void)
+{
+ struct curl_slist *headers = NULL, *h;
+
+ for (h = extra_http_headers; h; h = h->next)
+ headers = curl_slist_append(headers, h->data);
+
+ return headers;
+}
+
static CURLcode curlinfo_strbuf(CURL *curl, CURLINFO info, struct strbuf *buf)
{
char *ptr;
@@ -1377,7 +1406,7 @@ static int http_request(const char *url,
{
struct active_request_slot *slot;
struct slot_results results;
- struct curl_slist *headers = NULL;
+ struct curl_slist *headers = http_copy_default_headers();
struct strbuf buf = STRBUF_INIT;
const char *accept_language;
int ret;