index 6c1937b676ecd584cededed1c82df30448046ebe..87ebf7b86548d229afbfd9263d2470296a7b2ac7 100644 (file)
--- a/http.c
+++ b/http.c
char *ssl_cainfo = NULL;
long curl_low_speed_limit = -1;
long curl_low_speed_time = -1;
char *ssl_cainfo = NULL;
long curl_low_speed_limit = -1;
long curl_low_speed_time = -1;
+int curl_ftp_no_epsv = 0;
struct curl_slist *pragma_header;
struct curl_slist *pragma_header;
return 0;
}
return 0;
}
-#ifdef USE_CURL_MULTI
+#ifdef USE_CURL_MULTI
if (!strcmp("http.maxrequests", var)) {
if (max_requests == -1)
max_requests = git_config_int(var, value);
if (!strcmp("http.maxrequests", var)) {
if (max_requests == -1)
max_requests = git_config_int(var, value);
return 0;
}
return 0;
}
+ if (!strcmp("http.noepsv", var)) {
+ curl_ftp_no_epsv = git_config_bool(var, value);
+ return 0;
+ }
+
/* Fall back on the default ones */
return git_default_config(var, value);
}
/* Fall back on the default ones */
return git_default_config(var, value);
}
curl_easy_setopt(result, CURLOPT_USERAGENT, GIT_USER_AGENT);
curl_easy_setopt(result, CURLOPT_USERAGENT, GIT_USER_AGENT);
+ if (curl_ftp_no_epsv)
+ curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0);
+
return result;
}
return result;
}
max_requests = DEFAULT_MAX_REQUESTS;
#endif
max_requests = DEFAULT_MAX_REQUESTS;
#endif
+ if (getenv("GIT_CURL_FTP_NO_EPSV"))
+ curl_ftp_no_epsv = 1;
+
#ifndef NO_CURL_EASY_DUPHANDLE
curl_default = get_curl_handle();
#endif
#ifndef NO_CURL_EASY_DUPHANDLE
curl_default = get_curl_handle();
#endif
#endif
while (slot != NULL) {
#endif
while (slot != NULL) {
+ struct active_request_slot *next = slot->next;
#ifdef USE_CURL_MULTI
if (slot->in_use) {
curl_easy_getinfo(slot->curl,
#ifdef USE_CURL_MULTI
if (slot->in_use) {
curl_easy_getinfo(slot->curl,
#endif
if (slot->curl != NULL)
curl_easy_cleanup(slot->curl);
#endif
if (slot->curl != NULL)
curl_easy_cleanup(slot->curl);
- slot = slot->next;
+ free(slot);
+ slot = next;
}
}
+ active_queue_head = NULL;
#ifndef NO_CURL_EASY_DUPHANDLE
curl_easy_cleanup(curl_default);
#ifndef NO_CURL_EASY_DUPHANDLE
curl_easy_cleanup(curl_default);
curl_global_cleanup();
curl_slist_free_all(pragma_header);
curl_global_cleanup();
curl_slist_free_all(pragma_header);
+ pragma_header = NULL;
}
struct active_request_slot *get_active_slot(void)
}
struct active_request_slot *get_active_slot(void)
{
#ifdef USE_CURL_MULTI
CURLMcode curlm_result = curl_multi_add_handle(curlm, slot->curl);
{
#ifdef USE_CURL_MULTI
CURLMcode curlm_result = curl_multi_add_handle(curlm, slot->curl);
+ int num_transfers;
if (curlm_result != CURLM_OK &&
curlm_result != CURLM_CALL_MULTI_PERFORM) {
if (curlm_result != CURLM_OK &&
curlm_result != CURLM_CALL_MULTI_PERFORM) {
slot->in_use = 0;
return 0;
}
slot->in_use = 0;
return 0;
}
+
+ /*
+ * We know there must be something to do, since we just added
+ * something.
+ */
+ curl_multi_perform(curlm, &num_transfers);
#endif
return 1;
}
#ifdef USE_CURL_MULTI
#endif
return 1;
}
#ifdef USE_CURL_MULTI
+struct fill_chain {
+ void *data;
+ int (*fill)(void *);
+ struct fill_chain *next;
+};
+
+static struct fill_chain *fill_cfg = NULL;
+
+void add_fill_function(void *data, int (*fill)(void *))
+{
+ struct fill_chain *new = malloc(sizeof(*new));
+ struct fill_chain **linkp = &fill_cfg;
+ new->data = data;
+ new->fill = fill;
+ new->next = NULL;
+ while (*linkp)
+ linkp = &(*linkp)->next;
+ *linkp = new;
+}
+
+void fill_active_slots(void)
+{
+ struct active_request_slot *slot = active_queue_head;
+
+ while (active_requests < max_requests) {
+ struct fill_chain *fill;
+ for (fill = fill_cfg; fill; fill = fill->next)
+ if (fill->fill(fill->data))
+ break;
+
+ if (!fill)
+ break;
+ }
+
+ while (slot != NULL) {
+ if (!slot->in_use && slot->curl != NULL) {
+ curl_easy_cleanup(slot->curl);
+ slot->curl = NULL;
+ }
+ slot = slot->next;
+ }
+}
+
void step_active_slots(void)
{
int num_transfers;
void step_active_slots(void)
{
int num_transfers;