]> asedeno.scripts.mit.edu Git - git.git/blobdiff - http.c
Merge branch 'master' into cc/help
[git.git] / http.c
diff --git a/http.c b/http.c
index ae27e0c9409b93558e50318f2dd0a4fe758293b5..146f62609dbf75cf8b6d873f040e1386d73b57d1 100644 (file)
--- a/http.c
+++ b/http.c
@@ -4,30 +4,31 @@ int data_received;
 int active_requests = 0;
 
 #ifdef USE_CURL_MULTI
-int max_requests = -1;
-CURLM *curlm;
+static int max_requests = -1;
+static CURLM *curlm;
 #endif
 #ifndef NO_CURL_EASY_DUPHANDLE
-CURL *curl_default;
+static CURL *curl_default;
 #endif
 char curl_errorstr[CURL_ERROR_SIZE];
 
-int curl_ssl_verify = -1;
-char *ssl_cert = NULL;
+static int curl_ssl_verify = -1;
+static char *ssl_cert = NULL;
 #if LIBCURL_VERSION_NUM >= 0x070902
-char *ssl_key = NULL;
+static char *ssl_key = NULL;
 #endif
 #if LIBCURL_VERSION_NUM >= 0x070908
-char *ssl_capath = NULL;
+static char *ssl_capath = NULL;
 #endif
-char *ssl_cainfo = NULL;
-long curl_low_speed_limit = -1;
-long curl_low_speed_time = -1;
-int curl_ftp_no_epsv = 0;
+static char *ssl_cainfo = NULL;
+static long curl_low_speed_limit = -1;
+static long curl_low_speed_time = -1;
+static int curl_ftp_no_epsv = 0;
+static char *curl_http_proxy = NULL;
 
-struct curl_slist *pragma_header;
+static struct curl_slist *pragma_header;
 
-struct active_request_slot *active_queue_head = NULL;
+static struct active_request_slot *active_queue_head = NULL;
 
 size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb,
                           struct buffer *buffer)
@@ -137,7 +138,7 @@ static int http_options(const char *var, const char *value)
                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);
@@ -160,6 +161,13 @@ static int http_options(const char *var, const char *value)
                curl_ftp_no_epsv = git_config_bool(var, value);
                return 0;
        }
+       if (!strcmp("http.proxy", var)) {
+               if (curl_http_proxy == NULL) {
+                       curl_http_proxy = xmalloc(strlen(value)+1);
+                       strcpy(curl_http_proxy, value);
+               }
+               return 0;
+       }
 
        /* Fall back on the default ones */
        return git_default_config(var, value);
@@ -205,6 +213,9 @@ static CURL* get_curl_handle(void)
        if (curl_ftp_no_epsv)
                curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0);
 
+       if (curl_http_proxy)
+               curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
+
        return result;
 }
 
@@ -276,6 +287,7 @@ void http_cleanup(void)
 #endif
 
        while (slot != NULL) {
+               struct active_request_slot *next = slot->next;
 #ifdef USE_CURL_MULTI
                if (slot->in_use) {
                        curl_easy_getinfo(slot->curl,
@@ -287,8 +299,10 @@ void http_cleanup(void)
 #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);
@@ -300,7 +314,7 @@ void http_cleanup(void)
        curl_global_cleanup();
 
        curl_slist_free_all(pragma_header);
-        pragma_header = NULL;
+       pragma_header = NULL;
 }
 
 struct active_request_slot *get_active_slot(void)
@@ -372,6 +386,7 @@ int start_active_slot(struct active_request_slot *slot)
 {
 #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) {
@@ -379,11 +394,60 @@ int start_active_slot(struct active_request_slot *slot)
                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
+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;