safe_create_leading_directories(): add explicit "slash" pointer
[gitweb.git] / http.c
diff --git a/http.c b/http.c
index 3447945ee4f4e0e4b273d979ea1805b4c0f63b4c..bcf54aa35f96e8f0b87b6e2fd23408991a684b66 100644 (file)
--- a/http.c
+++ b/http.c
@@ -3,6 +3,7 @@
 #include "sideband.h"
 #include "run-command.h"
 #include "url.h"
+#include "urlmatch.h"
 #include "credential.h"
 #include "version.h"
 #include "pkt-line.h"
@@ -45,6 +46,7 @@ static long curl_low_speed_time = -1;
 static int curl_ftp_no_epsv;
 static const char *curl_http_proxy;
 static const char *curl_cookie_file;
+static int curl_save_cookies;
 struct credential http_auth = CREDENTIAL_INIT;
 static int http_proactive_auth;
 static const char *user_agent;
@@ -160,8 +162,7 @@ static int http_options(const char *var, const char *value, void *cb)
        if (!strcmp("http.sslcainfo", var))
                return git_config_string(&ssl_cainfo, var, value);
        if (!strcmp("http.sslcertpasswordprotected", var)) {
-               if (git_config_bool(var, value))
-                       ssl_cert_password_required = 1;
+               ssl_cert_password_required = git_config_bool(var, value);
                return 0;
        }
        if (!strcmp("http.ssltry", var)) {
@@ -200,6 +201,10 @@ static int http_options(const char *var, const char *value, void *cb)
 
        if (!strcmp("http.cookiefile", var))
                return git_config_string(&curl_cookie_file, var, value);
+       if (!strcmp("http.savecookies", var)) {
+               curl_save_cookies = git_config_bool(var, value);
+               return 0;
+       }
 
        if (!strcmp("http.postbuffer", var)) {
                http_post_buffer = git_config_int(var, value);
@@ -255,6 +260,42 @@ static int has_cert_password(void)
        return 1;
 }
 
+#if LIBCURL_VERSION_NUM >= 0x071900
+static void set_curl_keepalive(CURL *c)
+{
+       curl_easy_setopt(c, CURLOPT_TCP_KEEPALIVE, 1);
+}
+
+#elif LIBCURL_VERSION_NUM >= 0x071000
+static int sockopt_callback(void *client, curl_socket_t fd, curlsocktype type)
+{
+       int ka = 1;
+       int rc;
+       socklen_t len = (socklen_t)sizeof(ka);
+
+       if (type != CURLSOCKTYPE_IPCXN)
+               return 0;
+
+       rc = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&ka, len);
+       if (rc < 0)
+               warning("unable to set SO_KEEPALIVE on socket %s",
+                       strerror(errno));
+
+       return 0; /* CURL_SOCKOPT_OK only exists since curl 7.21.5 */
+}
+
+static void set_curl_keepalive(CURL *c)
+{
+       curl_easy_setopt(c, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
+}
+
+#else
+static void set_curl_keepalive(CURL *c)
+{
+       /* not supported on older curl versions */
+}
+#endif
+
 static CURL *get_curl_handle(void)
 {
        CURL *result = curl_easy_init();
@@ -327,6 +368,8 @@ static CURL *get_curl_handle(void)
                curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
        }
 
+       set_curl_keepalive(result);
+
        return result;
 }
 
@@ -341,10 +384,20 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
 {
        char *low_speed_limit;
        char *low_speed_time;
+       char *normalized_url;
+       struct urlmatch_config config = { STRING_LIST_INIT_DUP };
+
+       config.section = "http";
+       config.key = NULL;
+       config.collect_fn = http_options;
+       config.cascade_fn = git_default_config;
+       config.cb = NULL;
 
        http_is_verbose = 0;
+       normalized_url = url_normalize(url, &config.url);
 
-       git_config(http_options, NULL);
+       git_config(urlmatch_config_entry, &config);
+       free(normalized_url);
 
        curl_global_init(CURL_GLOBAL_ALL);
 
@@ -513,6 +566,8 @@ struct active_request_slot *get_active_slot(void)
        slot->callback_data = NULL;
        slot->callback_func = NULL;
        curl_easy_setopt(slot->curl, CURLOPT_COOKIEFILE, curl_cookie_file);
+       if (curl_save_cookies)
+               curl_easy_setopt(slot->curl, CURLOPT_COOKIEJAR, curl_cookie_file);
        curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, pragma_header);
        curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, curl_errorstr);
        curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, NULL);