if (!strcmp("http.sslcert", var)) {
if (ssl_cert == NULL) {
- ssl_cert = xmalloc(strlen(value)+1);
- strcpy(ssl_cert, value);
+ if (!value)
+ return config_error_nonbool(var);
+ ssl_cert = xstrdup(value);
}
return 0;
}
#if LIBCURL_VERSION_NUM >= 0x070902
if (!strcmp("http.sslkey", var)) {
if (ssl_key == NULL) {
- ssl_key = xmalloc(strlen(value)+1);
- strcpy(ssl_key, value);
+ if (!value)
+ return config_error_nonbool(var);
+ ssl_key = xstrdup(value);
}
return 0;
}
#if LIBCURL_VERSION_NUM >= 0x070908
if (!strcmp("http.sslcapath", var)) {
if (ssl_capath == NULL) {
- ssl_capath = xmalloc(strlen(value)+1);
- strcpy(ssl_capath, value);
+ if (!value)
+ return config_error_nonbool(var);
+ ssl_capath = xstrdup(value);
}
return 0;
}
#endif
if (!strcmp("http.sslcainfo", var)) {
if (ssl_cainfo == NULL) {
- ssl_cainfo = xmalloc(strlen(value)+1);
- strcpy(ssl_cainfo, value);
+ if (!value)
+ return config_error_nonbool(var);
+ ssl_cainfo = xstrdup(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);
+ if (!value)
+ return config_error_nonbool(var);
+ curl_http_proxy = xstrdup(value);
}
return 0;
}
return result;
}
-void http_init(void)
+void http_init(struct remote *remote)
{
char *low_speed_limit;
char *low_speed_time;
curl_global_init(CURL_GLOBAL_ALL);
+ if (remote && remote->http_proxy)
+ curl_http_proxy = xstrdup(remote->http_proxy);
+
pragma_header = curl_slist_append(pragma_header, "Pragma: no-cache");
#ifdef USE_CURL_MULTI
void http_cleanup(void)
{
struct active_request_slot *slot = active_queue_head;
-#ifdef USE_CURL_MULTI
- char *wait_url;
-#endif
while (slot != NULL) {
struct active_request_slot *next = slot->next;
+ if (slot->curl != NULL) {
#ifdef USE_CURL_MULTI
- if (slot->in_use) {
- curl_easy_getinfo(slot->curl,
- CURLINFO_EFFECTIVE_URL,
- &wait_url);
- fprintf(stderr, "Waiting for %s\n", wait_url);
- run_active_slot(slot);
- }
+ curl_multi_remove_handle(curlm, slot->curl);
#endif
- if (slot->curl != NULL)
curl_easy_cleanup(slot->curl);
+ }
free(slot);
slot = next;
}
curl_slist_free_all(pragma_header);
pragma_header = NULL;
+
+ if (curl_http_proxy) {
+ free(curl_http_proxy);
+ curl_http_proxy = NULL;
+ }
}
struct active_request_slot *get_active_slot(void)
slot = slot->next;
}
}
+
+static inline int needs_quote(int ch)
+{
+ if (((ch >= 'A') && (ch <= 'Z'))
+ || ((ch >= 'a') && (ch <= 'z'))
+ || ((ch >= '0') && (ch <= '9'))
+ || (ch == '/')
+ || (ch == '-')
+ || (ch == '.'))
+ return 0;
+ return 1;
+}
+
+static inline int hex(int v)
+{
+ if (v < 10) return '0' + v;
+ else return 'A' + v - 10;
+}
+
+static char *quote_ref_url(const char *base, const char *ref)
+{
+ const char *cp;
+ char *dp, *qref;
+ int len, baselen, ch;
+
+ baselen = strlen(base);
+ len = baselen + 7; /* "/refs/" + NUL */
+ for (cp = ref; (ch = *cp) != 0; cp++, len++)
+ if (needs_quote(ch))
+ len += 2; /* extra two hex plus replacement % */
+ qref = xmalloc(len);
+ memcpy(qref, base, baselen);
+ dp = qref + baselen;
+ *(dp++) = '/';
+ for (cp = ref; (ch = *cp) != 0; cp++) {
+ if (needs_quote(ch)) {
+ *dp++ = '%';
+ *dp++ = hex((ch >> 4) & 0xF);
+ *dp++ = hex(ch & 0xF);
+ }
+ else
+ *dp++ = ch;
+ }
+ *dp = 0;
+
+ return qref;
+}
+
+int http_fetch_ref(const char *base, struct ref *ref)
+{
+ char *url;
+ struct strbuf buffer = STRBUF_INIT;
+ struct active_request_slot *slot;
+ struct slot_results results;
+ int ret;
+
+ url = quote_ref_url(base, ref->name);
+ slot = get_active_slot();
+ slot->results = &results;
+ curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
+ curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
+ curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
+ curl_easy_setopt(slot->curl, CURLOPT_URL, url);
+ if (start_active_slot(slot)) {
+ run_active_slot(slot);
+ if (results.curl_result == CURLE_OK) {
+ strbuf_rtrim(&buffer);
+ if (buffer.len == 40)
+ ret = get_sha1_hex(buffer.buf, ref->old_sha1);
+ else if (!prefixcmp(buffer.buf, "ref: ")) {
+ ref->symref = xstrdup(buffer.buf + 5);
+ ret = 0;
+ } else
+ ret = 1;
+ } else {
+ ret = error("Couldn't get %s for %s\n%s",
+ url, ref->name, curl_errorstr);
+ }
+ } else {
+ ret = error("Unable to start request");
+ }
+
+ strbuf_release(&buffer);
+ free(url);
+ return ret;
+}