#include #include #include #include #include #include "hscurl.h" static CURL *c = NULL; static int curl_init_done = 0; const size_t UASZ = 60; // get_curl returns an error code // cache_time is -1 for default cachability int get_curl(const char *darcs_version, const char *proxypass, const char *filename, const char *url, int cache_time) { char user_agent[UASZ]; CURLcode err; FILE *f; struct curl_slist *headers = NULL; if(!curl_init_done) { curl_global_init(CURL_GLOBAL_ALL); curl_init_done=1; } if (c == NULL) c = curl_easy_init(); if (c == NULL) return -2; f = fopen(filename,"wb"); if (f == NULL) return -1; err = curl_easy_setopt(c, CURLOPT_URL, url); /*curl_easy_setopt(c, CURLOPT_NOSIGNAL, NULL);*/ snprintf(user_agent,UASZ,"darcs/%s (libcurl/%s)", darcs_version, curl_version()); err += curl_easy_setopt(c, CURLOPT_USERAGENT, user_agent); #ifdef CURLOPT_WRITEDATA err += curl_easy_setopt(c, CURLOPT_WRITEDATA, f); #else err += curl_easy_setopt(c, CURLOPT_FILE, f); #endif err += curl_easy_setopt(c, CURLOPT_FOLLOWLOCATION, 1); err += curl_easy_setopt(c, CURLOPT_FAILONERROR, 1); err += curl_easy_setopt(c, CURLOPT_HTTPAUTH, CURLAUTH_ANY); /* libcurl currently always sends Pragma: no-cache, but never Cache-Control, which is contradictory. We override both, just to be sure. */ headers = curl_slist_append(headers, "Accept: */*"); if(cache_time == 0) { headers = curl_slist_append(headers, "Pragma: no-cache"); headers = curl_slist_append(headers, "Cache-Control: no-cache"); } else if(cache_time > 0) { /* This won't work well with HTTP/1.0 proxies. */ char buf[40]; snprintf(buf, 40, "Cache-Control: max-age=%d", cache_time); headers = curl_slist_append(headers, "Pragma:"); headers = curl_slist_append(headers, buf); } else { headers = curl_slist_append(headers, "Pragma:"); headers = curl_slist_append(headers, "Cache-Control:"); } err += curl_easy_setopt(c, CURLOPT_HTTPHEADER, headers); /* don't set the proxy user and password to an empty string */ if (proxypass && *proxypass) err += curl_easy_setopt(c, CURLOPT_PROXYUSERPWD, proxypass ); if(!err) err += curl_easy_perform(c); curl_slist_free_all(headers); fclose(f); return (int)err; }