reachable.c: use error_errno()
[gitweb.git] / http.c
diff --git a/http.c b/http.c
index dfc53c1e2554e76126459d6cb1f098facac28593..fa39b879cecbe3402075600ce9edfbee08eee986 100644 (file)
--- a/http.c
+++ b/http.c
 #include "gettext.h"
 #include "transport.h"
 
+#if LIBCURL_VERSION_NUM >= 0x070a08
+long int git_curl_ipresolve = CURL_IPRESOLVE_WHATEVER;
+#else
+long int git_curl_ipresolve;
+#endif
 int active_requests;
 int http_is_verbose;
 size_t http_post_buffer = 16 * LARGE_PACKET_MAX;
@@ -57,11 +62,15 @@ static const char *ssl_key;
 #if LIBCURL_VERSION_NUM >= 0x070908
 static const char *ssl_capath;
 #endif
+#if LIBCURL_VERSION_NUM >= 0x072c00
+static const char *ssl_pinnedkey;
+#endif
 static const char *ssl_cainfo;
 static long curl_low_speed_limit = -1;
 static long curl_low_speed_time = -1;
 static int curl_ftp_no_epsv;
 static const char *curl_http_proxy;
+static const char *curl_no_proxy;
 static const char *http_proxy_authmethod;
 static struct {
        const char *name;
@@ -87,6 +96,7 @@ static int curl_save_cookies;
 struct credential http_auth = CREDENTIAL_INIT;
 static int http_proactive_auth;
 static const char *user_agent;
+static int curl_empty_auth;
 
 #if LIBCURL_VERSION_NUM >= 0x071700
 /* Use CURLOPT_KEYPASSWD as is */
@@ -299,14 +309,31 @@ static int http_options(const char *var, const char *value, void *cb)
        if (!strcmp("http.useragent", var))
                return git_config_string(&user_agent, var, value);
 
+       if (!strcmp("http.emptyauth", var)) {
+               curl_empty_auth = git_config_bool(var, value);
+               return 0;
+       }
+
+       if (!strcmp("http.pinnedpubkey", var)) {
+#if LIBCURL_VERSION_NUM >= 0x072c00
+               return git_config_pathname(&ssl_pinnedkey, var, value);
+#else
+               warning(_("Public key pinning not supported with cURL < 7.44.0"));
+               return 0;
+#endif
+       }
+
        /* Fall back on the default ones */
        return git_default_config(var, value, cb);
 }
 
 static void init_curl_http_auth(CURL *result)
 {
-       if (!http_auth.username)
+       if (!http_auth.username) {
+               if (curl_empty_auth)
+                       curl_easy_setopt(result, CURLOPT_USERPWD, ":");
                return;
+       }
 
        credential_fill(&http_auth);
 
@@ -419,8 +446,7 @@ static int sockopt_callback(void *client, curl_socket_t fd, curlsocktype type)
 
        rc = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&ka, len);
        if (rc < 0)
-               warning("unable to set SO_KEEPALIVE on socket %s",
-                       strerror(errno));
+               warning_errno("unable to set SO_KEEPALIVE on socket");
 
        return 0; /* CURL_SOCKOPT_OK only exists since curl 7.21.5 */
 }
@@ -498,6 +524,10 @@ static CURL *get_curl_handle(void)
 #if LIBCURL_VERSION_NUM >= 0x070908
        if (ssl_capath != NULL)
                curl_easy_setopt(result, CURLOPT_CAPATH, ssl_capath);
+#endif
+#if LIBCURL_VERSION_NUM >= 0x072c00
+       if (ssl_pinnedkey != NULL)
+               curl_easy_setopt(result, CURLOPT_PINNEDPUBLICKEY, ssl_pinnedkey);
 #endif
        if (ssl_cainfo != NULL)
                curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo);
@@ -594,6 +624,11 @@ static CURL *get_curl_handle(void)
                }
 
                curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);
+#if LIBCURL_VERSION_NUM >= 0x071304
+               var_override(&curl_no_proxy, getenv("NO_PROXY"));
+               var_override(&curl_no_proxy, getenv("no_proxy"));
+               curl_easy_setopt(result, CURLOPT_NOPROXY, curl_no_proxy);
+#endif
        }
        init_curl_proxy_auth(result);
 
@@ -824,10 +859,14 @@ struct active_request_slot *get_active_slot(void)
        curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
        curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1);
        curl_easy_setopt(slot->curl, CURLOPT_RANGE, NULL);
+
+#if LIBCURL_VERSION_NUM >= 0x070a08
+       curl_easy_setopt(slot->curl, CURLOPT_IPRESOLVE, git_curl_ipresolve);
+#endif
 #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
        curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods);
 #endif
-       if (http_auth.password)
+       if (http_auth.password || curl_empty_auth)
                init_curl_http_auth(slot->curl);
 
        return slot;
@@ -1851,8 +1890,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
        }
 
        if (freq->localfile < 0) {
-               error("Couldn't create temporary file %s: %s",
-                     freq->tmpfile, strerror(errno));
+               error_errno("Couldn't create temporary file %s", freq->tmpfile);
                goto abort;
        }
 
@@ -1897,8 +1935,8 @@ struct http_object_request *new_http_object_request(const char *base_url,
                        prev_posn = 0;
                        lseek(freq->localfile, 0, SEEK_SET);
                        if (ftruncate(freq->localfile, 0) < 0) {
-                               error("Couldn't truncate temporary file %s: %s",
-                                         freq->tmpfile, strerror(errno));
+                               error_errno("Couldn't truncate temporary file %s",
+                                           freq->tmpfile);
                                goto abort;
                        }
                }