summaryrefslogtreecommitdiffstats
path: root/http.c
diff options
context:
space:
mode:
Diffstat (limited to 'http.c')
-rw-r--r--http.c114
1 files changed, 38 insertions, 76 deletions
diff --git a/http.c b/http.c
index d59e59f66b..c8fc15aa11 100644
--- a/http.c
+++ b/http.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
#include "git-compat-util.h"
#include "git-curl-compat.h"
@@ -19,6 +20,7 @@
#include "string-list.h"
#include "object-file.h"
#include "object-store-ll.h"
+#include "tempfile.h"
static struct trace_key trace_curl = TRACE_KEY_INIT(CURL);
static int trace_curl_data = 1;
@@ -52,22 +54,16 @@ static struct {
{ "sslv2", CURL_SSLVERSION_SSLv2 },
{ "sslv3", CURL_SSLVERSION_SSLv3 },
{ "tlsv1", CURL_SSLVERSION_TLSv1 },
-#ifdef GIT_CURL_HAVE_CURL_SSLVERSION_TLSv1_0
{ "tlsv1.0", CURL_SSLVERSION_TLSv1_0 },
{ "tlsv1.1", CURL_SSLVERSION_TLSv1_1 },
{ "tlsv1.2", CURL_SSLVERSION_TLSv1_2 },
-#endif
-#ifdef GIT_CURL_HAVE_CURL_SSLVERSION_TLSv1_3
{ "tlsv1.3", CURL_SSLVERSION_TLSv1_3 },
-#endif
};
static char *ssl_key;
static char *ssl_key_type;
static char *ssl_capath;
static char *curl_no_proxy;
-#ifdef GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY
static char *ssl_pinnedkey;
-#endif
static char *ssl_cainfo;
static long curl_low_speed_limit = -1;
static long curl_low_speed_time = -1;
@@ -511,12 +507,7 @@ static int http_options(const char *var, const char *value,
}
if (!strcmp("http.pinnedpubkey", var)) {
-#ifdef GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY
return git_config_pathname(&ssl_pinnedkey, var, value);
-#else
- warning(_("Public key pinning not supported with cURL < 7.39.0"));
- return 0;
-#endif
}
if (!strcmp("http.extraheader", var)) {
@@ -700,7 +691,6 @@ static int has_cert_password(void)
return 1;
}
-#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_KEYPASSWD
static int has_proxy_cert_password(void)
{
if (http_proxy_ssl_cert == NULL || proxy_ssl_cert_password_required != 1)
@@ -714,37 +704,12 @@ static int has_proxy_cert_password(void)
}
return 1;
}
-#endif
-#ifdef GITCURL_HAVE_CURLOPT_TCP_KEEPALIVE
static void set_curl_keepalive(CURL *c)
{
curl_easy_setopt(c, CURLOPT_TCP_KEEPALIVE, 1);
}
-#else
-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_errno("unable to set SO_KEEPALIVE on socket");
-
- return CURL_SOCKOPT_OK;
-}
-
-static void set_curl_keepalive(CURL *c)
-{
- curl_easy_setopt(c, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
-}
-#endif
-
/* Return 1 if redactions have been made, 0 otherwise. */
static int redact_sensitive_header(struct strbuf *header, size_t offset)
{
@@ -1013,7 +978,6 @@ static long get_curl_allowed_protocols(int from_user, struct strbuf *list)
return bits;
}
-#ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2
static int get_curl_http_version_opt(const char *version_string, long *opt)
{
int i;
@@ -1036,8 +1000,6 @@ static int get_curl_http_version_opt(const char *version_string, long *opt)
return -1; /* not found */
}
-#endif
-
static CURL *get_curl_handle(void)
{
CURL *result = curl_easy_init();
@@ -1055,7 +1017,6 @@ static CURL *get_curl_handle(void)
curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2);
}
-#ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2
if (curl_http_version) {
long opt;
if (!get_curl_http_version_opt(curl_http_version, &opt)) {
@@ -1063,7 +1024,6 @@ static CURL *get_curl_handle(void)
curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);
}
}
-#endif
curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
curl_easy_setopt(result, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
@@ -1086,11 +1046,7 @@ static CURL *get_curl_handle(void)
if (http_ssl_backend && !strcmp("schannel", http_ssl_backend) &&
!http_schannel_check_revoke) {
-#ifdef GIT_CURL_HAVE_CURLSSLOPT_NO_REVOKE
curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
-#else
- warning(_("CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"));
-#endif
}
if (http_proactive_auth != PROACTIVE_AUTH_NONE)
@@ -1130,23 +1086,17 @@ static CURL *get_curl_handle(void)
curl_easy_setopt(result, CURLOPT_SSLKEYTYPE, ssl_key_type);
if (ssl_capath)
curl_easy_setopt(result, CURLOPT_CAPATH, ssl_capath);
-#ifdef GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY
if (ssl_pinnedkey)
curl_easy_setopt(result, CURLOPT_PINNEDPUBLICKEY, ssl_pinnedkey);
-#endif
if (http_ssl_backend && !strcmp("schannel", http_ssl_backend) &&
!http_schannel_use_ssl_cainfo) {
curl_easy_setopt(result, CURLOPT_CAINFO, NULL);
-#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_CAINFO
curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, NULL);
-#endif
} else if (ssl_cainfo != NULL || http_proxy_ssl_ca_info != NULL) {
if (ssl_cainfo)
curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo);
-#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_CAINFO
if (http_proxy_ssl_ca_info)
curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, http_proxy_ssl_ca_info);
-#endif
}
if (curl_low_speed_limit > 0 && curl_low_speed_time > 0) {
@@ -1242,7 +1192,6 @@ static CURL *get_curl_handle(void)
else if (starts_with(curl_http_proxy, "socks"))
curl_easy_setopt(result,
CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
-#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_KEYPASSWD
else if (starts_with(curl_http_proxy, "https")) {
curl_easy_setopt(result, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS);
@@ -1255,7 +1204,6 @@ static CURL *get_curl_handle(void)
if (has_proxy_cert_password())
curl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD, proxy_cert_auth.password);
}
-#endif
if (strstr(curl_http_proxy, "://"))
credential_from_url(&proxy_auth, curl_http_proxy);
else {
@@ -1329,7 +1277,6 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
free(normalized_url);
string_list_clear(&config.vars, 1);
-#ifdef GIT_CURL_HAVE_CURLSSLSET_NO_BACKENDS
if (http_ssl_backend) {
const curl_ssl_backend **backends;
struct strbuf buf = STRBUF_INIT;
@@ -1354,7 +1301,6 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
break; /* Okay! */
}
}
-#endif
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
die("curl_global_init failed");
@@ -1851,10 +1797,8 @@ static int handle_curl_result(struct slot_results *results)
*/
credential_reject(&cert_auth);
return HTTP_NOAUTH;
-#ifdef GIT_CURL_HAVE_CURLE_SSL_PINNEDPUBKEYNOTMATCH
} else if (results->curl_result == CURLE_SSL_PINNEDPUBKEYNOTMATCH) {
return HTTP_NOMATCHPUBLICKEY;
-#endif
} else if (missing_target(results))
return HTTP_MISSING_TARGET;
else if (results->http_code == 401) {
@@ -2290,17 +2234,19 @@ static int http_request_reauth(const char *url,
case HTTP_REQUEST_STRBUF:
strbuf_reset(result);
break;
- case HTTP_REQUEST_FILE:
- if (fflush(result)) {
+ case HTTP_REQUEST_FILE: {
+ FILE *f = result;
+ if (fflush(f)) {
error_errno("unable to flush a file");
return HTTP_START_FAILED;
}
- rewind(result);
- if (ftruncate(fileno(result), 0) < 0) {
+ rewind(f);
+ if (ftruncate(fileno(f), 0) < 0) {
error_errno("unable to truncate a file");
return HTTP_START_FAILED;
}
break;
+ }
default:
BUG("Unknown http_request target");
}
@@ -2388,8 +2334,24 @@ static char *fetch_pack_index(unsigned char *hash, const char *base_url)
strbuf_addf(&buf, "objects/pack/pack-%s.idx", hash_to_hex(hash));
url = strbuf_detach(&buf, NULL);
- strbuf_addf(&buf, "%s.temp", sha1_pack_index_name(hash));
- tmp = strbuf_detach(&buf, NULL);
+ /*
+ * Don't put this into packs/, since it's just temporary and we don't
+ * want to confuse it with our local .idx files. We'll generate our
+ * own index if we choose to download the matching packfile.
+ *
+ * It's tempting to use xmks_tempfile() here, but it's important that
+ * the file not exist, otherwise http_get_file() complains. So we
+ * create a filename that should be unique, and then just register it
+ * as a tempfile so that it will get cleaned up on exit.
+ *
+ * In theory we could hold on to the tempfile and delete these as soon
+ * as we download the matching pack, but it would take a bit of
+ * refactoring. Leaving them until the process ends is probably OK.
+ */
+ tmp = xstrfmt("%s/tmp_pack_%s.idx",
+ repo_get_object_directory(the_repository),
+ hash_to_hex(hash));
+ register_tempfile(tmp);
if (http_get_file(url, tmp, NULL) != HTTP_OK) {
error("Unable to get pack index %s", url);
@@ -2403,22 +2365,24 @@ static char *fetch_pack_index(unsigned char *hash, const char *base_url)
static int fetch_and_setup_pack_index(struct packed_git **packs_head,
unsigned char *sha1, const char *base_url)
{
- struct packed_git *new_pack;
+ struct packed_git *new_pack, *p;
char *tmp_idx = NULL;
int ret;
- if (has_pack_index(sha1)) {
- new_pack = parse_pack_index(sha1, sha1_pack_index_name(sha1));
- if (!new_pack)
- return -1; /* parse_pack_index() already issued error message */
- goto add_pack;
+ /*
+ * If we already have the pack locally, no need to fetch its index or
+ * even add it to list; we already have all of its objects.
+ */
+ for (p = get_all_packs(the_repository); p; p = p->next) {
+ if (hasheq(p->hash, sha1, the_repository->hash_algo))
+ return 0;
}
tmp_idx = fetch_pack_index(sha1, base_url);
if (!tmp_idx)
return -1;
- new_pack = parse_pack_index(sha1, tmp_idx);
+ new_pack = parse_pack_index(the_repository, sha1, tmp_idx);
if (!new_pack) {
unlink(tmp_idx);
free(tmp_idx);
@@ -2427,15 +2391,12 @@ static int fetch_and_setup_pack_index(struct packed_git **packs_head,
}
ret = verify_pack_index(new_pack);
- if (!ret) {
+ if (!ret)
close_pack_index(new_pack);
- ret = finalize_object_file(tmp_idx, sha1_pack_index_name(sha1));
- }
free(tmp_idx);
if (ret)
return -1;
-add_pack:
new_pack->next = *packs_head;
*packs_head = new_pack;
return 0;
@@ -2563,7 +2524,8 @@ struct http_pack_request *new_direct_http_pack_request(
preq->url = url;
- strbuf_addf(&preq->tmpfile, "%s.temp", sha1_pack_name(packed_git_hash));
+ odb_pack_name(the_repository, &preq->tmpfile, packed_git_hash, "pack");
+ strbuf_addstr(&preq->tmpfile, ".temp");
preq->packfile = fopen(preq->tmpfile.buf, "a");
if (!preq->packfile) {
error("Unable to open local file %s for pack",