diff --git a/src/httpfetch.cpp b/src/httpfetch.cpp index 78c0281f9..8a3b34f2c 100644 --- a/src/httpfetch.cpp +++ b/src/httpfetch.cpp @@ -215,26 +215,26 @@ public: private: CurlHandlePool *pool; - CURL *curl; - CURLM *multi; + CURL *curl = nullptr; + CURLM *multi = nullptr; HTTPFetchRequest request; HTTPFetchResult result; std::ostringstream oss; - struct curl_slist *http_header; - curl_httppost *post; + struct curl_slist *http_header = nullptr; +#if LIBCURL_VERSION_NUM >= 0x075500 + curl_mime *multipart_mime = nullptr; +#elif LIBCURL_VERSION_NUM >= 0x071304 + curl_httppost *post = nullptr; +#endif }; HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_, CurlHandlePool *pool_): pool(pool_), - curl(NULL), - multi(NULL), request(request_), result(request_), - oss(std::ios::binary), - http_header(NULL), - post(NULL) + oss(std::ios::binary) { curl = pool->alloc(); if (curl == NULL) { @@ -257,15 +257,16 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_, curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); } -#if LIBCURL_VERSION_NUM >= 0x071304 // Restrict protocols so that curl vulnerabilities in // other protocols don't affect us. - // These settings were introduced in curl 7.19.4. - long protocols = - CURLPROTO_HTTP | - CURLPROTO_HTTPS | - CURLPROTO_FTP | - CURLPROTO_FTPS; +#if LIBCURL_VERSION_NUM >= 0x075500 + // These settings were introduced in curl 7.85.0. + const char *protocols = "HTTP,HTTPS,FTP,FTPS"; + curl_easy_setopt(curl, CURLOPT_PROTOCOLS_STR, protocols); + curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, protocols); +#elif LIBCURL_VERSION_NUM >= 0x071304 + // These settings were introduced in curl 7.19.4, and later deprecated. + long protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | CURLPROTO_FTPS; curl_easy_setopt(curl, CURLOPT_PROTOCOLS, protocols); curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, protocols); #endif @@ -296,6 +297,15 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_, // Set data from fields or raw_data if (request.multipart) { +#if LIBCURL_VERSION_NUM >= 0x075500 + multipart_mime = curl_mime_init(curl); + for (auto &it : request.fields) { + curl_mimepart *part = curl_mime_addpart(multipart_mime); + curl_mime_name(part, it.first.c_str()); + curl_mime_data(part, it.second.c_str(), it.second.size()); + } + curl_easy_setopt(curl, CURLOPT_MIMEPOST, multipart_mime); +#elif LIBCURL_VERSION_NUM >= 0x071304 curl_httppost *last = NULL; for (StringMap::iterator it = request.fields.begin(); it != request.fields.end(); ++it) { @@ -307,8 +317,8 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_, CURLFORM_END); } curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); - // request.post_fields must now *never* be - // modified until CURLOPT_HTTPPOST is cleared + // request.post_fields must now *never* be modified until CURLOPT_HTTPPOST is cleared +#endif } else { switch (request.method) { case HTTP_GET: @@ -423,11 +433,17 @@ HTTPFetchOngoing::~HTTPFetchOngoing() curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL); curl_slist_free_all(http_header); } +#if LIBCURL_VERSION_NUM >= 0x075500 + if (multipart_mime) { + curl_easy_setopt(curl, CURLOPT_MIMEPOST, nullptr); + curl_mime_free(multipart_mime); + } +#elif LIBCURL_VERSION_NUM >= 0x071304 if (post) { curl_easy_setopt(curl, CURLOPT_HTTPPOST, NULL); curl_formfree(post); } - +#endif // Store the cURL handle for reuse pool->free(curl); }