Merge branch 'js/http-custom-headers'
authorJunio C Hamano <gitster@pobox.com>
Fri, 6 May 2016 21:45:43 +0000 (14:45 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 6 May 2016 21:45:43 +0000 (14:45 -0700)
HTTP transport clients learned to throw extra HTTP headers at the
server, specified via http.extraHeader configuration variable.

* js/http-custom-headers:
http: support sending custom HTTP headers

1  2 
Documentation/config.txt
http.c
t/lib-httpd/apache.conf
diff --combined Documentation/config.txt
index 42d2b50477b2863c2d0d93b1e80d70cf85bc5451,091d3411c12c6ac186570d59b4f0749c3b512b9b..c7bbe98ebae256de6163f97eeded0965bf1f5f80
@@@ -1113,9 -1113,8 +1113,9 @@@ commit.template:
  credential.helper::
        Specify an external helper to be called when a username or
        password credential is needed; the helper may consult external
 -      storage to avoid prompting the user for the credentials. See
 -      linkgit:gitcredentials[7] for details.
 +      storage to avoid prompting the user for the credentials. Note
 +      that multiple helpers may be defined. See linkgit:gitcredentials[7]
 +      for details.
  
  credential.useHttpPath::
        When acquiring credentials, consider the "path" component of an http
@@@ -1655,6 -1654,12 +1655,12 @@@ http.emptyAuth:
        a username in the URL, as libcurl normally requires a username for
        authentication.
  
+ http.extraHeader::
+       Pass an additional HTTP header when communicating with a server.  If
+       more than one such entry exists, all of them are added as extra
+       headers.  To allow overriding the settings inherited from the system
+       config, an empty value will reset the extra headers to the empty list.
  http.cookieFile::
        File containing previously stored cookie lines which should be used
        in the Git http session, if they match the server. The file format
@@@ -1887,14 -1892,6 +1893,14 @@@ interactive.singleKey:
        setting is silently ignored if portable keystroke input
        is not available; requires the Perl module Term::ReadKey.
  
 +interactive.diffFilter::
 +      When an interactive command (such as `git add --patch`) shows
 +      a colorized diff, git will pipe the diff through the shell
 +      command defined by this configuration variable. The command may
 +      mark up the diff further for human consumption, provided that it
 +      retains a one-to-one correspondence with the lines in the
 +      original diff. Defaults to disabled (no filtering).
 +
  log.abbrevCommit::
        If true, makes linkgit:git-log[1], linkgit:git-show[1], and
        linkgit:git-whatchanged[1] assume `--abbrev-commit`. You may
@@@ -2738,17 -2735,6 +2744,17 @@@ submodule.<name>.ignore:
        "--ignore-submodules" option. The 'git submodule' commands are not
        affected by this setting.
  
 +submodule.fetchJobs::
 +      Specifies how many submodules are fetched/cloned at the same time.
 +      A positive integer allows up to that number of submodules fetched
 +      in parallel. A value of 0 will give some reasonable default.
 +      If unset, it defaults to 1.
 +
 +tag.forceSignAnnotated::
 +      A boolean to specify whether annotated tags created should be GPG signed.
 +      If `--annotate` is specified on the command line, it takes
 +      precedence over this option.
 +
  tag.sort::
        This variable controls the sort ordering of tags when displayed by
        linkgit:git-tag[1]. Without the "--sort=<value>" option provided, the
diff --combined http.c
index 4304b80ad3ac9d8ae249bc0bc007074bc5aa6181,aae9944cb9187bd0821c2bfbd55025a4235b9aff..985b995c1d05b9a1ae461d6056e14e66b39d563c
--- 1/http.c
--- 2/http.c
+++ b/http.c
@@@ -114,6 -114,7 +114,7 @@@ static unsigned long http_auth_methods 
  
  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 +324,19 @@@ static int http_options(const char *var
  #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);
  }
@@@ -605,10 -619,7 +619,10 @@@ static CURL *get_curl_handle(void
        if (curl_http_proxy) {
                curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
  #if LIBCURL_VERSION_NUM >= 0x071800
 -              if (starts_with(curl_http_proxy, "socks5"))
 +              if (starts_with(curl_http_proxy, "socks5h"))
 +                      curl_easy_setopt(result,
 +                              CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME);
 +              else if (starts_with(curl_http_proxy, "socks5"))
                        curl_easy_setopt(result,
                                CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
                else if (starts_with(curl_http_proxy, "socks4a"))
@@@ -678,8 -689,10 +692,10 @@@ void http_init(struct remote *remote, c
        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
        {
@@@ -765,6 -778,9 +781,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;
  
@@@ -1163,6 -1179,16 +1182,16 @@@ int run_one_slot(struct active_request_
        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;
@@@ -1380,7 -1406,7 +1409,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;
diff --combined t/lib-httpd/apache.conf
index 9317ba08582d2a5d06ef5a2a8d8e63c72a146b3b,838770c027017c4d0c88822c231fbef29d5c4ed4..b8ed96fac6e2e8a371b7caf8716b671585022382
@@@ -74,7 -74,6 +74,7 @@@ PassEnv GIT_VALGRIND_OPTION
  PassEnv GNUPGHOME
  PassEnv ASAN_OPTIONS
  PassEnv GIT_TRACE
 +PassEnv GIT_CONFIG_NOSYSTEM
  
  Alias /dumb/ www/
  Alias /auth/dumb/ www/auth/dumb/
        SetEnv GIT_HTTP_EXPORT_ALL
        Header set Set-Cookie name=value
  </LocationMatch>
+ <LocationMatch /smart_headers/>
+       <RequireAll>
+               Require expr %{HTTP:x-magic-one} == 'abra'
+               Require expr %{HTTP:x-magic-two} == 'cadabra'
+       </RequireAll>
+       SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
+       SetEnv GIT_HTTP_EXPORT_ALL
+ </LocationMatch>
  ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
  ScriptAlias /broken_smart/ broken-smart-http.sh/
  ScriptAlias /error/ error.sh/