Merge branch 'rp/link-curl-before-ssl'
[gitweb.git] / http.c
diff --git a/http.c b/http.c
index 45348fb9bd7d2713bed668f6ef8ffb43783601ff..7da76edda16abea8a53299f2770ad2dce55c1b60 100644 (file)
--- a/http.c
+++ b/http.c
@@ -38,6 +38,20 @@ static int curl_ssl_verify = -1;
 static int curl_ssl_try;
 static const char *ssl_cert;
 static const char *ssl_cipherlist;
+static const char *ssl_version;
+static struct {
+       const char *name;
+       long ssl_version;
+} sslversions[] = {
+       { "sslv2", CURL_SSLVERSION_SSLv2 },
+       { "sslv3", CURL_SSLVERSION_SSLv3 },
+       { "tlsv1", CURL_SSLVERSION_TLSv1 },
+#if LIBCURL_VERSION_NUM >= 0x072200
+       { "tlsv1.0", CURL_SSLVERSION_TLSv1_0 },
+       { "tlsv1.1", CURL_SSLVERSION_TLSv1_1 },
+       { "tlsv1.2", CURL_SSLVERSION_TLSv1_2 },
+#endif
+};
 #if LIBCURL_VERSION_NUM >= 0x070903
 static const char *ssl_key;
 #endif
@@ -191,6 +205,8 @@ static int http_options(const char *var, const char *value, void *cb)
        }
        if (!strcmp("http.sslcipherlist", var))
                return git_config_string(&ssl_cipherlist, var, value);
+       if (!strcmp("http.sslversion", var))
+               return git_config_string(&ssl_version, var, value);
        if (!strcmp("http.sslcert", var))
                return git_config_string(&ssl_cert, var, value);
 #if LIBCURL_VERSION_NUM >= 0x070903
@@ -366,9 +382,24 @@ static CURL *get_curl_handle(void)
        if (http_proactive_auth)
                init_curl_http_auth(result);
 
+       if (getenv("GIT_SSL_VERSION"))
+               ssl_version = getenv("GIT_SSL_VERSION");
+       if (ssl_version && *ssl_version) {
+               int i;
+               for (i = 0; i < ARRAY_SIZE(sslversions); i++) {
+                       if (!strcmp(ssl_version, sslversions[i].name)) {
+                               curl_easy_setopt(result, CURLOPT_SSLVERSION,
+                                                sslversions[i].ssl_version);
+                               break;
+                       }
+               }
+               if (i == ARRAY_SIZE(sslversions))
+                       warning("unsupported ssl version %s: using default",
+                               ssl_version);
+       }
+
        if (getenv("GIT_SSL_CIPHER_LIST"))
                ssl_cipherlist = getenv("GIT_SSL_CIPHER_LIST");
-
        if (ssl_cipherlist != NULL && *ssl_cipherlist)
                curl_easy_setopt(result, CURLOPT_SSL_CIPHER_LIST,
                                ssl_cipherlist);
@@ -1091,7 +1122,7 @@ static void write_accept_language(struct strbuf *buf)
                     decimal_places++, max_q *= 10)
                        ;
 
-               sprintf(q_format, ";q=0.%%0%dd", decimal_places);
+               xsnprintf(q_format, sizeof(q_format), ";q=0.%%0%dd", decimal_places);
 
                strbuf_addstr(buf, "Accept-Language: ");
 
@@ -1336,7 +1367,7 @@ static int http_get_file(const char *url, const char *filename,
        ret = http_request_reauth(url, result, HTTP_REQUEST_FILE, options);
        fclose(result);
 
-       if (ret == HTTP_OK && move_temp_to_file(tmpfile.buf, filename))
+       if (ret == HTTP_OK && finalize_object_file(tmpfile.buf, filename))
                ret = HTTP_ERROR;
 cleanup:
        strbuf_release(&tmpfile);
@@ -1423,7 +1454,7 @@ static int fetch_and_setup_pack_index(struct packed_git **packs_head,
        ret = verify_pack_index(new_pack);
        if (!ret) {
                close_pack_index(new_pack);
-               ret = move_temp_to_file(tmp_idx, sha1_pack_index_name(sha1));
+               ret = finalize_object_file(tmp_idx, sha1_pack_index_name(sha1));
        }
        free(tmp_idx);
        if (ret)
@@ -1498,6 +1529,7 @@ int finish_http_pack_request(struct http_pack_request *preq)
        struct packed_git **lst;
        struct packed_git *p = preq->target;
        char *tmp_idx;
+       size_t len;
        struct child_process ip = CHILD_PROCESS_INIT;
        const char *ip_argv[8];
 
@@ -1511,9 +1543,9 @@ int finish_http_pack_request(struct http_pack_request *preq)
                lst = &((*lst)->next);
        *lst = (*lst)->next;
 
-       tmp_idx = xstrdup(preq->tmpfile);
-       strcpy(tmp_idx + strlen(tmp_idx) - strlen(".pack.temp"),
-              ".idx.temp");
+       if (!strip_suffix(preq->tmpfile, ".pack.temp", &len))
+               die("BUG: pack tmpfile does not end in .pack.temp?");
+       tmp_idx = xstrfmt("%.*s.idx.temp", (int)len, preq->tmpfile);
 
        ip_argv[0] = "index-pack";
        ip_argv[1] = "-o";
@@ -1535,8 +1567,8 @@ int finish_http_pack_request(struct http_pack_request *preq)
 
        unlink(sha1_pack_index_name(p->sha1));
 
-       if (move_temp_to_file(preq->tmpfile, sha1_pack_name(p->sha1))
-        || move_temp_to_file(tmp_idx, sha1_pack_index_name(p->sha1))) {
+       if (finalize_object_file(preq->tmpfile, sha1_pack_name(p->sha1))
+        || finalize_object_file(tmp_idx, sha1_pack_index_name(p->sha1))) {
                free(tmp_idx);
                return -1;
        }
@@ -1588,7 +1620,7 @@ struct http_pack_request *new_http_pack_request(
                        fprintf(stderr,
                                "Resuming fetch of pack %s at byte %ld\n",
                                sha1_to_hex(target->sha1), prev_posn);
-               sprintf(range, "Range: bytes=%ld-", prev_posn);
+               xsnprintf(range, sizeof(range), "Range: bytes=%ld-", prev_posn);
                preq->range_header = curl_slist_append(NULL, range);
                curl_easy_setopt(preq->slot->curl, CURLOPT_HTTPHEADER,
                        preq->range_header);
@@ -1748,7 +1780,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
                        fprintf(stderr,
                                "Resuming fetch of object %s at byte %ld\n",
                                hex, prev_posn);
-               sprintf(range, "Range: bytes=%ld-", prev_posn);
+               xsnprintf(range, sizeof(range), "Range: bytes=%ld-", prev_posn);
                range_header = curl_slist_append(range_header, range);
                curl_easy_setopt(freq->slot->curl,
                                 CURLOPT_HTTPHEADER, range_header);
@@ -1800,7 +1832,7 @@ int finish_http_object_request(struct http_object_request *freq)
                return -1;
        }
        freq->rename =
-               move_temp_to_file(freq->tmpfile, sha1_file_name(freq->sha1));
+               finalize_object_file(freq->tmpfile, sha1_file_name(freq->sha1));
 
        return freq->rename;
 }