mirror of
https://github.com/git-for-windows/git.git
synced 2026-04-10 08:22:54 -05:00
Merge branch 'nl/http-proxy-more' into next
The code to talk to http proxies learn to use the same credential API used to talk to the final http destinations. Will defer til 1.7.10. * nl/http-proxy-more: http: rename HTTP_REAUTH to HTTP_AUTH_RETRY http: Avoid limit of retrying request only twice http: handle proxy authentication failure (error 407) http: handle proxy proactive authentication http: try http_proxy env var when http.proxy config option is not set
This commit is contained in:
24
http-push.c
24
http-push.c
@@ -297,7 +297,7 @@ static void start_mkcol(struct transfer_request *request)
|
||||
|
||||
request->url = get_remote_object_url(repo->url, hex, 1);
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(request->url);
|
||||
slot->callback_func = process_response;
|
||||
slot->callback_data = request;
|
||||
curl_setup_http_get(slot->curl, request->url, DAV_MKCOL);
|
||||
@@ -417,7 +417,7 @@ static void start_put(struct transfer_request *request)
|
||||
strbuf_add(&buf, request->lock->tmpfile_suffix, 41);
|
||||
request->url = strbuf_detach(&buf, NULL);
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(request->url);
|
||||
slot->callback_func = process_response;
|
||||
slot->callback_data = request;
|
||||
curl_setup_http(slot->curl, request->url, DAV_PUT,
|
||||
@@ -438,7 +438,7 @@ static void start_move(struct transfer_request *request)
|
||||
struct active_request_slot *slot;
|
||||
struct curl_slist *dav_headers = NULL;
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(request->url);
|
||||
slot->callback_func = process_response;
|
||||
slot->callback_data = request;
|
||||
curl_setup_http_get(slot->curl, request->url, DAV_MOVE);
|
||||
@@ -467,7 +467,7 @@ static int refresh_lock(struct remote_lock *lock)
|
||||
|
||||
dav_headers = get_dav_token_headers(lock, DAV_HEADER_IF | DAV_HEADER_TIMEOUT);
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(lock->url);
|
||||
slot->results = &results;
|
||||
curl_setup_http_get(slot->curl, lock->url, DAV_LOCK);
|
||||
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
|
||||
@@ -882,7 +882,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)
|
||||
while (ep) {
|
||||
char saved_character = ep[1];
|
||||
ep[1] = '\0';
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(url);
|
||||
slot->results = &results;
|
||||
curl_setup_http_get(slot->curl, url, DAV_MKCOL);
|
||||
if (start_active_slot(slot)) {
|
||||
@@ -912,7 +912,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)
|
||||
dav_headers = curl_slist_append(dav_headers, timeout_header);
|
||||
dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(url);
|
||||
slot->results = &results;
|
||||
curl_setup_http(slot->curl, url, DAV_LOCK, &out_buffer, fwrite_buffer);
|
||||
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
|
||||
@@ -980,7 +980,7 @@ static int unlock_remote(struct remote_lock *lock)
|
||||
|
||||
dav_headers = get_dav_token_headers(lock, DAV_HEADER_LOCK);
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(lock->url);
|
||||
slot->results = &results;
|
||||
curl_setup_http_get(slot->curl, lock->url, DAV_UNLOCK);
|
||||
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
|
||||
@@ -1158,7 +1158,7 @@ static void remote_ls(const char *path, int flags,
|
||||
dav_headers = curl_slist_append(dav_headers, "Depth: 1");
|
||||
dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(url);
|
||||
slot->results = &results;
|
||||
curl_setup_http(slot->curl, url, DAV_PROPFIND,
|
||||
&out_buffer, fwrite_buffer);
|
||||
@@ -1232,7 +1232,7 @@ static int locking_available(void)
|
||||
dav_headers = curl_slist_append(dav_headers, "Depth: 0");
|
||||
dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(repo->url);
|
||||
slot->results = &results;
|
||||
curl_setup_http(slot->curl, repo->url, DAV_PROPFIND,
|
||||
&out_buffer, fwrite_buffer);
|
||||
@@ -1409,7 +1409,7 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)
|
||||
|
||||
strbuf_addf(&out_buffer.buf, "%s\n", sha1_to_hex(sha1));
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(lock->url);
|
||||
slot->results = &results;
|
||||
curl_setup_http(slot->curl, lock->url, DAV_PUT,
|
||||
&out_buffer, fwrite_null);
|
||||
@@ -1535,7 +1535,7 @@ static void update_remote_info_refs(struct remote_lock *lock)
|
||||
if (!aborted) {
|
||||
dav_headers = get_dav_token_headers(lock, DAV_HEADER_IF);
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(lock->url);
|
||||
slot->results = &results;
|
||||
curl_setup_http(slot->curl, lock->url, DAV_PUT,
|
||||
&buffer, fwrite_null);
|
||||
@@ -1695,7 +1695,7 @@ static int delete_remote_branch(const char *pattern, int force)
|
||||
return 0;
|
||||
url = xmalloc(strlen(repo->url) + strlen(remote_ref->name) + 1);
|
||||
sprintf(url, "%s%s", repo->url, remote_ref->name);
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(url);
|
||||
slot->results = &results;
|
||||
curl_setup_http_get(slot->curl, url, DAV_DELETE);
|
||||
if (start_active_slot(slot)) {
|
||||
|
||||
@@ -348,7 +348,7 @@ static void fetch_alternates(struct walker *walker, const char *base)
|
||||
* Use a callback to process the result, since another request
|
||||
* may fail and need to have alternates loaded before continuing
|
||||
*/
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(url);
|
||||
slot->callback_func = process_alternates_response;
|
||||
alt_req.walker = walker;
|
||||
slot->callback_data = &alt_req;
|
||||
|
||||
87
http.c
87
http.c
@@ -42,7 +42,9 @@ 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 struct credential cre_url = CREDENTIAL_INIT;
|
||||
static struct credential http_auth = CREDENTIAL_INIT;
|
||||
static struct credential proxy_auth = CREDENTIAL_INIT;
|
||||
static int http_proactive_auth;
|
||||
static const char *user_agent;
|
||||
|
||||
@@ -232,7 +234,21 @@ static int has_cert_password(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static CURL *get_curl_handle(void)
|
||||
static void set_proxy_auth(CURL *result)
|
||||
{
|
||||
if (proxy_auth.username && proxy_auth.password) {
|
||||
#if LIBCURL_VERSION_NUM >= 0x071901
|
||||
curl_easy_setopt(result, CURLOPT_PROXYUSERNAME, proxy_auth.username);
|
||||
curl_easy_setopt(result, CURLOPT_PROXYPASSWORD, proxy_auth.password);
|
||||
#else
|
||||
struct strbuf userpwd = STRBUF_INIT;
|
||||
strbuf_addf(&userpwd, "%s:%s", proxy_auth.username, proxy_auth.password);
|
||||
curl_easy_setopt(result, CURLOPT_PROXYUSERPWD, strbuf_detach(&userpwd, NULL));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static CURL *get_curl_handle(const char *url)
|
||||
{
|
||||
CURL *result = curl_easy_init();
|
||||
|
||||
@@ -295,9 +311,42 @@ static CURL *get_curl_handle(void)
|
||||
if (curl_ftp_no_epsv)
|
||||
curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0);
|
||||
|
||||
if (!curl_http_proxy) {
|
||||
const char *env_proxy, *no_proxy;
|
||||
char *env_proxy_var;
|
||||
int read_http_proxy;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
credential_from_url(&cre_url, url);
|
||||
strbuf_addf(&buf, "%s_proxy", cre_url.protocol);
|
||||
env_proxy_var = strbuf_detach(&buf, NULL);
|
||||
env_proxy = getenv(env_proxy_var);
|
||||
if (env_proxy) {
|
||||
read_http_proxy = 1;
|
||||
no_proxy = getenv("no_proxy");
|
||||
if (!no_proxy)
|
||||
no_proxy = getenv("NO_PROXY");
|
||||
if (no_proxy && (!strcmp("*", no_proxy) || strstr(no_proxy, cre_url.host)))
|
||||
read_http_proxy = 0;
|
||||
|
||||
if (read_http_proxy)
|
||||
curl_http_proxy = xstrdup(env_proxy);
|
||||
}
|
||||
free(env_proxy_var);
|
||||
}
|
||||
if (curl_http_proxy) {
|
||||
curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
|
||||
struct strbuf proxyhost = STRBUF_INIT;
|
||||
|
||||
if (!proxy_auth.host) /* check to parse only once */
|
||||
credential_from_url(&proxy_auth, curl_http_proxy);
|
||||
|
||||
if (http_proactive_auth && proxy_auth.username && !proxy_auth.password)
|
||||
/* proxy string has username but no password, ask for password */
|
||||
credential_fill(&proxy_auth);
|
||||
|
||||
strbuf_addf(&proxyhost, "%s://%s", proxy_auth.protocol, proxy_auth.host);
|
||||
curl_easy_setopt(result, CURLOPT_PROXY, strbuf_detach(&proxyhost, NULL));
|
||||
curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
|
||||
set_proxy_auth(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -385,7 +434,7 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
|
||||
}
|
||||
|
||||
#ifndef NO_CURL_EASY_DUPHANDLE
|
||||
curl_default = get_curl_handle();
|
||||
curl_default = get_curl_handle(url);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -434,7 +483,7 @@ void http_cleanup(void)
|
||||
ssl_cert_password_required = 0;
|
||||
}
|
||||
|
||||
struct active_request_slot *get_active_slot(void)
|
||||
struct active_request_slot *get_active_slot(const char *url)
|
||||
{
|
||||
struct active_request_slot *slot = active_queue_head;
|
||||
struct active_request_slot *newslot;
|
||||
@@ -472,7 +521,7 @@ struct active_request_slot *get_active_slot(void)
|
||||
|
||||
if (slot->curl == NULL) {
|
||||
#ifdef NO_CURL_EASY_DUPHANDLE
|
||||
slot->curl = get_curl_handle();
|
||||
slot->curl = get_curl_handle(url);
|
||||
#else
|
||||
slot->curl = curl_easy_duphandle(curl_default);
|
||||
#endif
|
||||
@@ -745,7 +794,7 @@ static int http_request(const char *url, void *result, int target, int options)
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
int ret;
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(url);
|
||||
slot->results = &results;
|
||||
curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
|
||||
|
||||
@@ -791,7 +840,16 @@ static int http_request(const char *url, void *result, int target, int options)
|
||||
} else {
|
||||
credential_fill(&http_auth);
|
||||
init_curl_http_auth(slot->curl);
|
||||
ret = HTTP_REAUTH;
|
||||
ret = HTTP_AUTH_RETRY;
|
||||
}
|
||||
} else if (results.http_code == 407) { /* Proxy authentication failure */
|
||||
if (proxy_auth.username && proxy_auth.password) {
|
||||
credential_reject(&proxy_auth);
|
||||
ret = HTTP_NOAUTH;
|
||||
} else {
|
||||
credential_fill(&proxy_auth);
|
||||
set_proxy_auth(slot->curl);
|
||||
ret = HTTP_AUTH_RETRY;
|
||||
}
|
||||
} else {
|
||||
if (!curl_errorstr[0])
|
||||
@@ -817,10 +875,13 @@ static int http_request(const char *url, void *result, int target, int options)
|
||||
static int http_request_reauth(const char *url, void *result, int target,
|
||||
int options)
|
||||
{
|
||||
int ret = http_request(url, result, target, options);
|
||||
if (ret != HTTP_REAUTH)
|
||||
return ret;
|
||||
return http_request(url, result, target, options);
|
||||
int ret;
|
||||
|
||||
do {
|
||||
ret = http_request(url, result, target, options);
|
||||
} while (ret == HTTP_AUTH_RETRY);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int http_get_strbuf(const char *url, struct strbuf *result, int options)
|
||||
@@ -1090,7 +1151,7 @@ struct http_pack_request *new_http_pack_request(
|
||||
goto abort;
|
||||
}
|
||||
|
||||
preq->slot = get_active_slot();
|
||||
preq->slot = get_active_slot(preq->url);
|
||||
curl_easy_setopt(preq->slot->curl, CURLOPT_FILE, preq->packfile);
|
||||
curl_easy_setopt(preq->slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
|
||||
curl_easy_setopt(preq->slot->curl, CURLOPT_URL, preq->url);
|
||||
@@ -1250,7 +1311,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
|
||||
}
|
||||
}
|
||||
|
||||
freq->slot = get_active_slot();
|
||||
freq->slot = get_active_slot(freq->url);
|
||||
|
||||
curl_easy_setopt(freq->slot->curl, CURLOPT_FILE, freq);
|
||||
curl_easy_setopt(freq->slot->curl, CURLOPT_WRITEFUNCTION, fwrite_sha1_file);
|
||||
|
||||
4
http.h
4
http.h
@@ -73,7 +73,7 @@ extern curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp);
|
||||
#endif
|
||||
|
||||
/* Slot lifecycle functions */
|
||||
extern struct active_request_slot *get_active_slot(void);
|
||||
extern struct active_request_slot *get_active_slot(const char *url);
|
||||
extern int start_active_slot(struct active_request_slot *slot);
|
||||
extern void run_active_slot(struct active_request_slot *slot);
|
||||
extern void finish_active_slot(struct active_request_slot *slot);
|
||||
@@ -123,7 +123,7 @@ extern char *get_remote_object_url(const char *url, const char *hex,
|
||||
#define HTTP_MISSING_TARGET 1
|
||||
#define HTTP_ERROR 2
|
||||
#define HTTP_START_FAILED 3
|
||||
#define HTTP_REAUTH 4
|
||||
#define HTTP_AUTH_RETRY 4
|
||||
#define HTTP_NOAUTH 5
|
||||
|
||||
/*
|
||||
|
||||
@@ -383,7 +383,7 @@ static int probe_rpc(struct rpc_state *rpc)
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
int err;
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(rpc->service_url);
|
||||
|
||||
headers = curl_slist_append(headers, rpc->hdr_content_type);
|
||||
headers = curl_slist_append(headers, rpc->hdr_accept);
|
||||
@@ -440,7 +440,7 @@ static int post_rpc(struct rpc_state *rpc)
|
||||
return err;
|
||||
}
|
||||
|
||||
slot = get_active_slot();
|
||||
slot = get_active_slot(rpc->service_url);
|
||||
|
||||
curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
|
||||
curl_easy_setopt(slot->curl, CURLOPT_POST, 1);
|
||||
|
||||
Reference in New Issue
Block a user