aboutsummaryrefslogtreecommitdiffstats
path: root/http.c
diff options
context:
space:
mode:
Diffstat (limited to 'http.c')
-rw-r--r--http.c181
1 files changed, 116 insertions, 65 deletions
diff --git a/http.c b/http.c
index c8fc15aa11..17130823f0 100644
--- a/http.c
+++ b/http.c
@@ -3,6 +3,7 @@
#include "git-compat-util.h"
#include "git-curl-compat.h"
+#include "environment.h"
#include "hex.h"
#include "http.h"
#include "config.h"
@@ -19,7 +20,7 @@
#include "packfile.h"
#include "string-list.h"
#include "object-file.h"
-#include "object-store-ll.h"
+#include "odb.h"
#include "tempfile.h"
static struct trace_key trace_curl = TRACE_KEY_INIT(CURL);
@@ -104,6 +105,10 @@ static struct {
};
#endif
+static long curl_tcp_keepidle = -1;
+static long curl_tcp_keepintvl = -1;
+static long curl_tcp_keepcnt = -1;
+
enum proactive_auth {
PROACTIVE_AUTH_NONE = 0,
PROACTIVE_AUTH_IF_CREDENTIALS,
@@ -438,11 +443,11 @@ static int http_options(const char *var, const char *value,
return 0;
}
if (!strcmp("http.lowspeedlimit", var)) {
- curl_low_speed_limit = (long)git_config_int(var, value, ctx->kvi);
+ curl_low_speed_limit = git_config_int(var, value, ctx->kvi);
return 0;
}
if (!strcmp("http.lowspeedtime", var)) {
- curl_low_speed_time = (long)git_config_int(var, value, ctx->kvi);
+ curl_low_speed_time = git_config_int(var, value, ctx->kvi);
return 0;
}
@@ -557,6 +562,19 @@ static int http_options(const char *var, const char *value,
return 0;
}
+ if (!strcmp("http.keepaliveidle", var)) {
+ curl_tcp_keepidle = git_config_int(var, value, ctx->kvi);
+ return 0;
+ }
+ if (!strcmp("http.keepaliveinterval", var)) {
+ curl_tcp_keepintvl = git_config_int(var, value, ctx->kvi);
+ return 0;
+ }
+ if (!strcmp("http.keepalivecount", var)) {
+ curl_tcp_keepcnt = git_config_int(var, value, ctx->kvi);
+ return 0;
+ }
+
/* Fall back on the default ones */
return git_default_config(var, value, ctx, data);
}
@@ -598,8 +616,7 @@ static void init_curl_http_auth(CURL *result)
{
if ((!http_auth.username || !*http_auth.username) &&
(!http_auth.credential || !*http_auth.credential)) {
- int empty_auth = curl_empty_auth_enabled();
- if ((empty_auth != -1 && !always_auth_proactively()) || empty_auth == 1) {
+ if (!always_auth_proactively() && curl_empty_auth_enabled()) {
curl_easy_setopt(result, CURLOPT_USERPWD, ":");
return;
} else if (!always_auth_proactively()) {
@@ -609,7 +626,7 @@ static void init_curl_http_auth(CURL *result)
}
}
- credential_fill(&http_auth, 1);
+ credential_fill(the_repository, &http_auth, 1);
if (http_auth.password) {
if (always_auth_proactively()) {
@@ -652,7 +669,7 @@ static void init_curl_proxy_auth(CURL *result)
{
if (proxy_auth.username) {
if (!proxy_auth.password && !proxy_auth.credential)
- credential_fill(&proxy_auth, 1);
+ credential_fill(the_repository, &proxy_auth, 1);
set_proxyauth_name_password(result);
}
@@ -686,7 +703,7 @@ static int has_cert_password(void)
cert_auth.host = xstrdup("");
cert_auth.username = xstrdup("");
cert_auth.path = xstrdup(ssl_cert);
- credential_fill(&cert_auth, 0);
+ credential_fill(the_repository, &cert_auth, 0);
}
return 1;
}
@@ -700,16 +717,11 @@ static int has_proxy_cert_password(void)
proxy_cert_auth.host = xstrdup("");
proxy_cert_auth.username = xstrdup("");
proxy_cert_auth.path = xstrdup(http_proxy_ssl_cert);
- credential_fill(&proxy_cert_auth, 0);
+ credential_fill(the_repository, &proxy_cert_auth, 0);
}
return 1;
}
-static void set_curl_keepalive(CURL *c)
-{
- curl_easy_setopt(c, CURLOPT_TCP_KEEPALIVE, 1);
-}
-
/* Return 1 if redactions have been made, 0 otherwise. */
static int redact_sensitive_header(struct strbuf *header, size_t offset)
{
@@ -1008,13 +1020,13 @@ static CURL *get_curl_handle(void)
die("curl_easy_init failed");
if (!curl_ssl_verify) {
- curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 0);
- curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 0);
+ curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 0L);
} else {
/* Verify authenticity of the peer's certificate */
- curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 1);
+ curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 1L);
/* The name in the cert must match whom we tried to connect */
- curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2);
+ curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2L);
}
if (curl_http_version) {
@@ -1046,7 +1058,7 @@ static CURL *get_curl_handle(void)
if (http_ssl_backend && !strcmp("schannel", http_ssl_backend) &&
!http_schannel_check_revoke) {
- curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
+ curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, (long)CURLSSLOPT_NO_REVOKE);
}
if (http_proactive_auth != PROACTIVE_AUTH_NONE)
@@ -1106,8 +1118,8 @@ static CURL *get_curl_handle(void)
curl_low_speed_time);
}
- curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);
- curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
+ curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20L);
+ curl_easy_setopt(result, CURLOPT_POSTREDIR, (long)CURL_REDIR_POST_ALL);
#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR
{
@@ -1140,7 +1152,7 @@ static CURL *get_curl_handle(void)
user_agent ? user_agent : git_user_agent());
if (curl_ftp_no_epsv)
- curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0);
+ curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0L);
if (curl_ssl_try)
curl_easy_setopt(result, CURLOPT_USE_SSL, CURLUSESSL_TRY);
@@ -1182,18 +1194,18 @@ static CURL *get_curl_handle(void)
if (starts_with(curl_http_proxy, "socks5h"))
curl_easy_setopt(result,
- CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME);
+ CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5_HOSTNAME);
else if (starts_with(curl_http_proxy, "socks5"))
curl_easy_setopt(result,
- CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
+ CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5);
else if (starts_with(curl_http_proxy, "socks4a"))
curl_easy_setopt(result,
- CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4A);
+ CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4A);
else if (starts_with(curl_http_proxy, "socks"))
curl_easy_setopt(result,
- CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
+ CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4);
else if (starts_with(curl_http_proxy, "https")) {
- curl_easy_setopt(result, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS);
+ curl_easy_setopt(result, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTPS);
if (http_proxy_ssl_cert)
curl_easy_setopt(result, CURLOPT_PROXY_SSLCERT, http_proxy_ssl_cert);
@@ -1243,7 +1255,18 @@ static CURL *get_curl_handle(void)
}
init_curl_proxy_auth(result);
- set_curl_keepalive(result);
+ curl_easy_setopt(result, CURLOPT_TCP_KEEPALIVE, 1L);
+
+ if (curl_tcp_keepidle > -1)
+ curl_easy_setopt(result, CURLOPT_TCP_KEEPIDLE,
+ curl_tcp_keepidle);
+ if (curl_tcp_keepintvl > -1)
+ curl_easy_setopt(result, CURLOPT_TCP_KEEPINTVL,
+ curl_tcp_keepintvl);
+#ifdef GIT_CURL_HAVE_CURLOPT_TCP_KEEPCNT
+ if (curl_tcp_keepcnt > -1)
+ curl_easy_setopt(result, CURLOPT_TCP_KEEPCNT, curl_tcp_keepcnt);
+#endif
return result;
}
@@ -1257,10 +1280,30 @@ static void set_from_env(char **var, const char *envname)
}
}
+static void set_long_from_env(long *var, const char *envname)
+{
+ const char *val = getenv(envname);
+ if (val) {
+ long tmp;
+ char *endp;
+ int saved_errno = errno;
+
+ errno = 0;
+ tmp = strtol(val, &endp, 10);
+
+ if (errno)
+ warning_errno(_("failed to parse %s"), envname);
+ else if (*endp || endp == val)
+ warning(_("failed to parse %s"), envname);
+ else
+ *var = tmp;
+
+ errno = saved_errno;
+ }
+}
+
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 = URLMATCH_CONFIG_INIT;
@@ -1273,7 +1316,7 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
http_is_verbose = 0;
normalized_url = url_normalize(url, &config.url);
- git_config(urlmatch_config_entry, &config);
+ repo_config(the_repository, urlmatch_config_entry, &config);
free(normalized_url);
string_list_clear(&config.vars, 1);
@@ -1305,6 +1348,14 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
die("curl_global_init failed");
+#ifdef GIT_CURL_HAVE_GLOBAL_TRACE
+ {
+ const char *comp = getenv("GIT_TRACE_CURL_COMPONENTS");
+ if (comp)
+ curl_global_trace(comp);
+ }
+#endif
+
if (proactive_auth && http_proactive_auth == PROACTIVE_AUTH_NONE)
http_proactive_auth = PROACTIVE_AUTH_IF_CREDENTIALS;
@@ -1339,12 +1390,8 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
set_from_env(&user_agent, "GIT_HTTP_USER_AGENT");
- low_speed_limit = getenv("GIT_HTTP_LOW_SPEED_LIMIT");
- if (low_speed_limit)
- curl_low_speed_limit = strtol(low_speed_limit, NULL, 10);
- low_speed_time = getenv("GIT_HTTP_LOW_SPEED_TIME");
- if (low_speed_time)
- curl_low_speed_time = strtol(low_speed_time, NULL, 10);
+ set_long_from_env(&curl_low_speed_limit, "GIT_HTTP_LOW_SPEED_LIMIT");
+ set_long_from_env(&curl_low_speed_time, "GIT_HTTP_LOW_SPEED_TIME");
if (curl_ssl_verify == -1)
curl_ssl_verify = 1;
@@ -1371,6 +1418,10 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
ssl_cert_password_required = 1;
}
+ set_long_from_env(&curl_tcp_keepidle, "GIT_TCP_KEEPIDLE");
+ set_long_from_env(&curl_tcp_keepintvl, "GIT_TCP_KEEPINTVL");
+ set_long_from_env(&curl_tcp_keepcnt, "GIT_TCP_KEEPCNT");
+
curl_default = get_curl_handle();
}
@@ -1498,9 +1549,9 @@ struct active_request_slot *get_active_slot(void)
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, NULL);
curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, NULL);
curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, -1L);
- curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0);
- curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
- curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1L);
+ curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt(slot->curl, CURLOPT_RANGE, NULL);
/*
@@ -1509,9 +1560,9 @@ struct active_request_slot *get_active_slot(void)
* HTTP_FOLLOW_* cases themselves.
*/
if (http_follow_config == HTTP_FOLLOW_ALWAYS)
- curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 1);
+ curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 1L);
else
- curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 0);
+ curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 0L);
curl_easy_setopt(slot->curl, CURLOPT_IPRESOLVE, git_curl_ipresolve);
curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods);
@@ -1784,9 +1835,9 @@ static int handle_curl_result(struct slot_results *results)
curl_errorstr, sizeof(curl_errorstr));
if (results->curl_result == CURLE_OK) {
- credential_approve(&http_auth);
- credential_approve(&proxy_auth);
- credential_approve(&cert_auth);
+ credential_approve(the_repository, &http_auth);
+ credential_approve(the_repository, &proxy_auth);
+ credential_approve(the_repository, &cert_auth);
return HTTP_OK;
} else if (results->curl_result == CURLE_SSL_CERTPROBLEM) {
/*
@@ -1795,7 +1846,7 @@ static int handle_curl_result(struct slot_results *results)
* with the certificate. So we reject the credential to
* avoid caching or saving a bad password.
*/
- credential_reject(&cert_auth);
+ credential_reject(the_repository, &cert_auth);
return HTTP_NOAUTH;
} else if (results->curl_result == CURLE_SSL_PINNEDPUBKEYNOTMATCH) {
return HTTP_NOMATCHPUBLICKEY;
@@ -1808,7 +1859,7 @@ static int handle_curl_result(struct slot_results *results)
credential_clear_secrets(&http_auth);
return HTTP_REAUTH;
}
- credential_reject(&http_auth);
+ credential_reject(the_repository, &http_auth);
if (always_auth_proactively())
http_proactive_auth = PROACTIVE_AUTH_NONE;
return HTTP_NOAUTH;
@@ -1822,7 +1873,7 @@ static int handle_curl_result(struct slot_results *results)
}
} else {
if (results->http_connectcode == 407)
- credential_reject(&proxy_auth);
+ credential_reject(the_repository, &proxy_auth);
if (!curl_errorstr[0])
strlcpy(curl_errorstr,
curl_easy_strerror(results->curl_result),
@@ -2078,12 +2129,12 @@ static int http_request(const char *url,
int ret;
slot = get_active_slot();
- curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
+ curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1L);
if (!result) {
- curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
+ curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1L);
} else {
- curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
+ curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0L);
curl_easy_setopt(slot->curl, CURLOPT_WRITEDATA, result);
if (target == HTTP_REQUEST_FILE) {
@@ -2109,7 +2160,7 @@ static int http_request(const char *url,
strbuf_addstr(&buf, " no-cache");
if (options && options->initial_request &&
http_follow_config == HTTP_FOLLOW_INITIAL)
- curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 1);
+ curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 1L);
headers = curl_slist_append(headers, buf.buf);
@@ -2128,7 +2179,7 @@ static int http_request(const char *url,
curl_easy_setopt(slot->curl, CURLOPT_URL, url);
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
- curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 0);
+ curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 0L);
ret = run_one_slot(slot, &results);
@@ -2210,7 +2261,7 @@ static int http_request_reauth(const char *url,
int ret;
if (always_auth_proactively())
- credential_fill(&http_auth, 1);
+ credential_fill(the_repository, &http_auth, 1);
ret = http_request(url, result, target, options);
@@ -2251,7 +2302,7 @@ static int http_request_reauth(const char *url,
BUG("Unknown http_request target");
}
- credential_fill(&http_auth, 1);
+ credential_fill(the_repository, &http_auth, 1);
ret = http_request(url, result, target, options);
}
@@ -2289,7 +2340,7 @@ 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 && finalize_object_file(tmpfile.buf, filename))
+ if (ret == HTTP_OK && finalize_object_file(the_repository, tmpfile.buf, filename))
ret = HTTP_ERROR;
cleanup:
strbuf_release(&tmpfile);
@@ -2373,7 +2424,7 @@ static int fetch_and_setup_pack_index(struct packed_git **packs_head,
* 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) {
+ repo_for_each_pack(the_repository, p) {
if (hasheq(p->hash, sha1, the_repository->hash_algo))
return 0;
}
@@ -2498,7 +2549,7 @@ void http_install_packfile(struct packed_git *p,
lst = &((*lst)->next);
*lst = (*lst)->next;
- install_packed_git(the_repository, p);
+ packfile_store_add_pack(the_repository->objects->packfiles, p);
}
struct http_pack_request *new_http_pack_request(
@@ -2597,8 +2648,8 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb,
freq->stream.next_out = expn;
freq->stream.avail_out = sizeof(expn);
freq->zret = git_inflate(&freq->stream, Z_SYNC_FLUSH);
- the_hash_algo->update_fn(&freq->c, expn,
- sizeof(expn) - freq->stream.avail_out);
+ git_hash_update(&freq->c, expn,
+ sizeof(expn) - freq->stream.avail_out);
} while (freq->stream.avail_in && freq->zret == Z_OK);
return nmemb;
}
@@ -2620,7 +2671,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
oidcpy(&freq->oid, oid);
freq->localfile = -1;
- loose_object_path(the_repository, &filename, oid);
+ odb_loose_path(the_repository->objects->sources, &filename, oid);
strbuf_addf(&freq->tmpfile, "%s.temp", filename.buf);
strbuf_addf(&prevfile, "%s.prev", filename.buf);
@@ -2708,7 +2759,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
freq->headers = object_request_headers();
curl_easy_setopt(freq->slot->curl, CURLOPT_WRITEDATA, freq);
- curl_easy_setopt(freq->slot->curl, CURLOPT_FAILONERROR, 0);
+ curl_easy_setopt(freq->slot->curl, CURLOPT_FAILONERROR, 0L);
curl_easy_setopt(freq->slot->curl, CURLOPT_WRITEFUNCTION, fwrite_sha1_file);
curl_easy_setopt(freq->slot->curl, CURLOPT_ERRORBUFFER, freq->errorstr);
curl_easy_setopt(freq->slot->curl, CURLOPT_URL, freq->url);
@@ -2763,7 +2814,7 @@ int finish_http_object_request(struct http_object_request *freq)
return -1;
}
- the_hash_algo->final_oid_fn(&freq->real_oid, &freq->c);
+ git_hash_final_oid(&freq->real_oid, &freq->c);
if (freq->zret != Z_STREAM_END) {
unlink_or_warn(freq->tmpfile.buf);
return -1;
@@ -2772,8 +2823,8 @@ int finish_http_object_request(struct http_object_request *freq)
unlink_or_warn(freq->tmpfile.buf);
return -1;
}
- loose_object_path(the_repository, &filename, &freq->oid);
- freq->rename = finalize_object_file(freq->tmpfile.buf, filename.buf);
+ odb_loose_path(the_repository->objects->sources, &filename, &freq->oid);
+ freq->rename = finalize_object_file(the_repository, freq->tmpfile.buf, filename.buf);
strbuf_release(&filename);
return freq->rename;