Merge branch 'mv/ssl-ftp-curl'
authorJunio C Hamano <gitster@pobox.com>
Fri, 19 Apr 2013 20:31:08 +0000 (13:31 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 19 Apr 2013 20:31:08 +0000 (13:31 -0700)
Does anybody really use commit walkers over (s)ftp?

* mv/ssl-ftp-curl:
Support FTP-over-SSL/TLS for regular FTP

1  2 
Documentation/config.txt
http.c
http.h
diff --combined Documentation/config.txt
index 42b0f3ba42d60d8f321808a0f3f02d7195ecc5c0,f2ef441f2d1d76094757ce36bda8a377567eaf16..21d4447cb4fe38037da6d0406edd7a56890c9745
@@@ -727,22 -727,9 +727,22 @@@ branch.autosetuprebase:
        This option defaults to never.
  
  branch.<name>.remote::
 -      When in branch <name>, it tells 'git fetch' and 'git push' which
 -      remote to fetch from/push to.  It defaults to `origin` if no remote is
 -      configured. `origin` is also used if you are not on any branch.
 +      When on branch <name>, it tells 'git fetch' and 'git push'
 +      which remote to fetch from/push to.  The remote to push to
 +      may be overridden with `remote.pushdefault` (for all branches).
 +      The remote to push to, for the current branch, may be further
 +      overridden by `branch.<name>.pushremote`.  If no remote is
 +      configured, or if you are not on any branch, it defaults to
 +      `origin` for fetching and `remote.pushdefault` for pushing.
 +
 +branch.<name>.pushremote::
 +      When on branch <name>, it overrides `branch.<name>.remote` for
 +      pushing.  It also overrides `remote.pushdefault` for pushing
 +      from branch <name>.  When you pull from one place (e.g. your
 +      upstream) and push to another place (e.g. your own publishing
 +      repository), you would want to set `remote.pushdefault` to
 +      specify the remote to push to for all branches, and use this
 +      option to override it for a specific branch.
  
  branch.<name>.merge::
        Defines, together with branch.<name>.remote, the upstream branch
@@@ -1109,11 -1096,6 +1109,11 @@@ format.signoff:
      the rights to submit this work under the same open source license.
      Please see the 'SubmittingPatches' document for further discussion.
  
 +format.coverLetter::
 +      A boolean that controls whether to generate a cover-letter when
 +      format-patch is invoked, but in addition can be set to "auto", to
 +      generate a cover-letter only when there's more than one patch.
 +
  filter.<driver>.clean::
        The command which is used to convert the content of a worktree
        file to a blob upon checkin.  See linkgit:gitattributes[5] for
@@@ -1465,6 -1447,14 +1465,14 @@@ http.sslCAPath:
        with when fetching or pushing over HTTPS. Can be overridden
        by the 'GIT_SSL_CAPATH' environment variable.
  
+ http.sslTry::
+       Attempt to use AUTH SSL/TLS and encrypted data transfers
+       when connecting via regular FTP protocol. This might be needed
+       if the FTP server requires it for security reasons or you wish
+       to connect securely whenever remote FTP server supports it.
+       Default is false since it might trigger certificate verification
+       errors on misconfigured servers.
  http.maxRequests::
        How many HTTP requests to launch in parallel. Can be overridden
        by the 'GIT_HTTP_MAX_REQUESTS' environment variable. Default is 5.
@@@ -1916,11 -1906,6 +1924,11 @@@ receive.updateserverinfo:
        If set to true, git-receive-pack will run git-update-server-info
        after receiving data from git-push and updating refs.
  
 +remote.pushdefault::
 +      The remote to push to by default.  Overrides
 +      `branch.<name>.remote` for all branches, and is overridden by
 +      `branch.<name>.pushremote` for specific branches.
 +
  remote.<name>.url::
        The URL of a remote repository.  See linkgit:git-fetch[1] or
        linkgit:git-push[1].
@@@ -2021,7 -2006,6 +2029,7 @@@ sendemail.<identity>.*:
  
  sendemail.aliasesfile::
  sendemail.aliasfiletype::
 +sendemail.annotate::
  sendemail.bcc::
  sendemail.cc::
  sendemail.cccmd::
@@@ -2147,13 -2131,7 +2155,13 @@@ uploadpack.hiderefs:
        are under the hierarchies listed on the value of this
        variable is excluded, and is hidden from `git ls-remote`,
        `git fetch`, etc.  An attempt to fetch a hidden ref by `git
 -      fetch` will fail.
 +      fetch` will fail.  See also `uploadpack.allowtipsha1inwant`.
 +
 +uploadpack.allowtipsha1inwant::
 +      When `uploadpack.hiderefs` is in effect, allow `upload-pack`
 +      to accept a fetch request that asks for an object at the tip
 +      of a hidden ref (by default, such a request is rejected).
 +      see also `uploadpack.hiderefs`.
  
  url.<base>.insteadOf::
        Any URL that starts with this value will be rewritten to
diff --combined http.c
index 48d4ff61c757f93d8385ca014ab14bb233acbb40,e3a274b5507af44d09b757c7b4b750b63e6bcf0e..92aba59082a4ed9aa0c92d8522793abcd332e279
--- 1/http.c
--- 2/http.c
+++ b/http.c
@@@ -5,7 -5,6 +5,7 @@@
  #include "url.h"
  #include "credential.h"
  #include "version.h"
 +#include "pkt-line.h"
  
  int active_requests;
  int http_is_verbose;
@@@ -31,6 -30,7 +31,7 @@@ static CURL *curl_default
  char curl_errorstr[CURL_ERROR_SIZE];
  
  static int curl_ssl_verify = -1;
+ static int curl_ssl_try;
  static const char *ssl_cert;
  #if LIBCURL_VERSION_NUM >= 0x070903
  static const char *ssl_key;
@@@ -163,6 -163,10 +164,10 @@@ static int http_options(const char *var
                        ssl_cert_password_required = 1;
                return 0;
        }
+       if (!strcmp("http.ssltry", var)) {
+               curl_ssl_try = git_config_bool(var, value);
+               return 0;
+       }
        if (!strcmp("http.minsessions", var)) {
                min_curl_sessions = git_config_int(var, value);
  #ifndef USE_CURL_MULTI
@@@ -282,6 -286,7 +287,6 @@@ static CURL *get_curl_handle(void
  #endif
        if (ssl_cainfo != NULL)
                curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo);
 -      curl_easy_setopt(result, CURLOPT_FAILONERROR, 1);
  
        if (curl_low_speed_limit > 0 && curl_low_speed_time > 0) {
                curl_easy_setopt(result, CURLOPT_LOW_SPEED_LIMIT,
        if (curl_ftp_no_epsv)
                curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0);
  
+ #ifdef CURLOPT_USE_SSL
+       if (curl_ssl_try)
+               curl_easy_setopt(result, CURLOPT_USE_SSL, CURLUSESSL_TRY);
+ #endif
        if (curl_http_proxy) {
                curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
                curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
@@@ -505,7 -515,6 +515,7 @@@ struct active_request_slot *get_active_
        curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, NULL);
        curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0);
        curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
 +      curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1);
        if (http_auth.password)
                init_curl_http_auth(slot->curl);
  
@@@ -761,25 -770,6 +771,25 @@@ char *get_remote_object_url(const char 
  
  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;
@@@ -844,8 -834,6 +854,8 @@@ static int http_request(const char *url
        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);
  
                run_active_slot(slot);
                ret = handle_curl_result(&results);
        } else {
 -              error("Unable to start HTTP request for %s", url);
 +              snprintf(curl_errorstr, sizeof(curl_errorstr),
 +                       "failed to start HTTP request");
                ret = HTTP_START_FAILED;
        }
  
@@@ -884,22 -871,6 +894,22 @@@ static int http_request_reauth(const ch
        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);
  }
  
@@@ -941,6 -912,15 +951,6 @@@ cleanup
        return ret;
  }
  
 -int http_error(const char *url, int ret)
 -{
 -      /* http_request has already handled HTTP_START_FAILED. */
 -      if (ret != HTTP_START_FAILED)
 -              error("%s while accessing %s", curl_errorstr, url);
 -
 -      return ret;
 -}
 -
  int http_fetch_ref(const char *base, struct ref *ref)
  {
        char *url;
diff --combined http.h
index 4dc53531ae07cb1fc223afad22255311bd3b9523,097514dd6fea374d02b2d4e1cc8d41d8f61bf1b5..d77c1b54f24d142461b9e1a0d11cf6de041bc59f
--- 1/http.h
--- 2/http.h
+++ b/http.h
  #define NO_CURL_IOCTL
  #endif
  
+ /*
+  * CURLOPT_USE_SSL was known as CURLOPT_FTP_SSL up to 7.16.4,
+  * and the constants were known as CURLFTPSSL_*
+ */
+ #if !defined(CURLOPT_USE_SSL) && defined(CURLOPT_FTP_SSL)
+ #define CURLOPT_USE_SSL CURLOPT_FTP_SSL
+ #define CURLUSESSL_TRY CURLFTPSSL_TRY
+ #endif
  struct slot_results {
        CURLcode curl_result;
        long http_code;
@@@ -118,7 -127,6 +127,7 @@@ extern char *get_remote_object_url(cons
  
  /* Options for http_request_*() */
  #define HTTP_NO_CACHE         1
 +#define HTTP_KEEP_ERROR               2
  
  /* Return values for http_request_*() */
  #define HTTP_OK                       0
   */
  int http_get_strbuf(const char *url, struct strbuf *content_type, struct strbuf *result, int options);
  
 -/*
 - * Prints an error message using error() containing url and curl_errorstr,
 - * and returns ret.
 - */
 -int http_error(const char *url, int ret);
 -
  extern int http_fetch_ref(const char *base, struct ref *ref);
  
  /* Helpers for fetching packs */