Merge branch 'tr/http-updates'

* tr/http-updates:
  Remove http.authAny
  Allow curl to rewind the RPC read buffer
  Add an option for using any HTTP authentication scheme, not only basic
  http: maintain curl sessions
This commit is contained in:
Junio C Hamano 2010-01-10 08:53:04 -08:00
Родитель 0b4ae29f03 525ecd26c6
Коммит 637afcf4e0
3 изменённых файлов: 60 добавлений и 2 удалений

Просмотреть файл

@ -1136,6 +1136,12 @@ http.maxRequests::
How many HTTP requests to launch in parallel. Can be overridden How many HTTP requests to launch in parallel. Can be overridden
by the 'GIT_HTTP_MAX_REQUESTS' environment variable. Default is 5. by the 'GIT_HTTP_MAX_REQUESTS' environment variable. Default is 5.
http.minSessions::
The number of curl sessions (counted across slots) to be kept across
requests. They will not be ended with curl_easy_cleanup() until
http_cleanup() is invoked. If USE_CURL_MULTI is not defined, this
value will be capped at 1. Defaults to 1.
http.postBuffer:: http.postBuffer::
Maximum size in bytes of the buffer used by smart HTTP Maximum size in bytes of the buffer used by smart HTTP
transports when POSTing data to the remote system. transports when POSTing data to the remote system.

26
http.c
Просмотреть файл

@ -7,6 +7,12 @@ int active_requests;
int http_is_verbose; int http_is_verbose;
size_t http_post_buffer = 16 * LARGE_PACKET_MAX; size_t http_post_buffer = 16 * LARGE_PACKET_MAX;
#if LIBCURL_VERSION_NUM >= 0x070a06
#define LIBCURL_CAN_HANDLE_AUTH_ANY
#endif
static int min_curl_sessions = 1;
static int curl_session_count;
#ifdef USE_CURL_MULTI #ifdef USE_CURL_MULTI
static int max_requests = -1; static int max_requests = -1;
static CURLM *curlm; static CURLM *curlm;
@ -152,6 +158,14 @@ static int http_options(const char *var, const char *value, void *cb)
ssl_cert_password_required = 1; ssl_cert_password_required = 1;
return 0; return 0;
} }
if (!strcmp("http.minsessions", var)) {
min_curl_sessions = git_config_int(var, value);
#ifndef USE_CURL_MULTI
if (min_curl_sessions > 1)
min_curl_sessions = 1;
#endif
return 0;
}
#ifdef USE_CURL_MULTI #ifdef USE_CURL_MULTI
if (!strcmp("http.maxrequests", var)) { if (!strcmp("http.maxrequests", var)) {
max_requests = git_config_int(var, value); max_requests = git_config_int(var, value);
@ -230,6 +244,9 @@ static CURL *get_curl_handle(void)
#if LIBCURL_VERSION_NUM >= 0x070907 #if LIBCURL_VERSION_NUM >= 0x070907
curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
#endif #endif
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
curl_easy_setopt(result, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
#endif
init_curl_http_auth(result); init_curl_http_auth(result);
@ -372,6 +389,7 @@ void http_init(struct remote *remote)
if (curl_ssl_verify == -1) if (curl_ssl_verify == -1)
curl_ssl_verify = 1; curl_ssl_verify = 1;
curl_session_count = 0;
#ifdef USE_CURL_MULTI #ifdef USE_CURL_MULTI
if (max_requests < 1) if (max_requests < 1)
max_requests = DEFAULT_MAX_REQUESTS; max_requests = DEFAULT_MAX_REQUESTS;
@ -480,6 +498,7 @@ struct active_request_slot *get_active_slot(void)
#else #else
slot->curl = curl_easy_duphandle(curl_default); slot->curl = curl_easy_duphandle(curl_default);
#endif #endif
curl_session_count++;
} }
active_requests++; active_requests++;
@ -558,9 +577,11 @@ void fill_active_slots(void)
} }
while (slot != NULL) { while (slot != NULL) {
if (!slot->in_use && slot->curl != NULL) { if (!slot->in_use && slot->curl != NULL
&& curl_session_count > min_curl_sessions) {
curl_easy_cleanup(slot->curl); curl_easy_cleanup(slot->curl);
slot->curl = NULL; slot->curl = NULL;
curl_session_count--;
} }
slot = slot->next; slot = slot->next;
} }
@ -633,12 +654,13 @@ static void closedown_active_slot(struct active_request_slot *slot)
void release_active_slot(struct active_request_slot *slot) void release_active_slot(struct active_request_slot *slot)
{ {
closedown_active_slot(slot); closedown_active_slot(slot);
if (slot->curl) { if (slot->curl && curl_session_count > min_curl_sessions) {
#ifdef USE_CURL_MULTI #ifdef USE_CURL_MULTI
curl_multi_remove_handle(curlm, slot->curl); curl_multi_remove_handle(curlm, slot->curl);
#endif #endif
curl_easy_cleanup(slot->curl); curl_easy_cleanup(slot->curl);
slot->curl = NULL; slot->curl = NULL;
curl_session_count--;
} }
#ifdef USE_CURL_MULTI #ifdef USE_CURL_MULTI
fill_active_slots(); fill_active_slots();

Просмотреть файл

@ -290,6 +290,7 @@ struct rpc_state {
int out; int out;
struct strbuf result; struct strbuf result;
unsigned gzip_request : 1; unsigned gzip_request : 1;
unsigned initial_buffer : 1;
}; };
static size_t rpc_out(void *ptr, size_t eltsize, static size_t rpc_out(void *ptr, size_t eltsize,
@ -300,6 +301,7 @@ static size_t rpc_out(void *ptr, size_t eltsize,
size_t avail = rpc->len - rpc->pos; size_t avail = rpc->len - rpc->pos;
if (!avail) { if (!avail) {
rpc->initial_buffer = 0;
avail = packet_read_line(rpc->out, rpc->buf, rpc->alloc); avail = packet_read_line(rpc->out, rpc->buf, rpc->alloc);
if (!avail) if (!avail)
return 0; return 0;
@ -314,6 +316,29 @@ static size_t rpc_out(void *ptr, size_t eltsize,
return avail; return avail;
} }
#ifndef NO_CURL_IOCTL
curlioerr rpc_ioctl(CURL *handle, int cmd, void *clientp)
{
struct rpc_state *rpc = clientp;
switch (cmd) {
case CURLIOCMD_NOP:
return CURLIOE_OK;
case CURLIOCMD_RESTARTREAD:
if (rpc->initial_buffer) {
rpc->pos = 0;
return CURLIOE_OK;
}
fprintf(stderr, "Unable to rewind rpc post data - try increasing http.postBuffer\n");
return CURLIOE_FAILRESTART;
default:
return CURLIOE_UNKNOWNCMD;
}
}
#endif
static size_t rpc_in(const void *ptr, size_t eltsize, static size_t rpc_in(const void *ptr, size_t eltsize,
size_t nmemb, void *buffer_) size_t nmemb, void *buffer_)
{ {
@ -370,8 +395,13 @@ static int post_rpc(struct rpc_state *rpc)
*/ */
headers = curl_slist_append(headers, "Expect: 100-continue"); headers = curl_slist_append(headers, "Expect: 100-continue");
headers = curl_slist_append(headers, "Transfer-Encoding: chunked"); headers = curl_slist_append(headers, "Transfer-Encoding: chunked");
rpc->initial_buffer = 1;
curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out); curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out);
curl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc); curl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc);
#ifndef NO_CURL_IOCTL
curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, rpc_ioctl);
curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, rpc);
#endif
if (options.verbosity > 1) { if (options.verbosity > 1) {
fprintf(stderr, "POST %s (chunked)\n", rpc->service_name); fprintf(stderr, "POST %s (chunked)\n", rpc->service_name);
fflush(stderr); fflush(stderr);