X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fhttpfetch.cpp;h=c651055bca5364c969352f10ea139836c7f03c11;hb=86a0f5603b9e936b8527ae22c4aeaf5714c9d279;hp=60e4591a921444c57137dbc14f72bdebee124350;hpb=3aa28bc7a2014dcefd9f24517ff32223bec32a35;p=oweals%2Fminetest.git diff --git a/src/httpfetch.cpp b/src/httpfetch.cpp index 60e4591a9..c651055bc 100644 --- a/src/httpfetch.cpp +++ b/src/httpfetch.cpp @@ -18,7 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "socket.h" // for select() -#include "porting.h" // for sleep_ms() +#include "porting.h" // for sleep_ms(), get_sysinfo() #include "httpfetch.h" #include #include @@ -32,10 +32,26 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "util/container.h" #include "util/thread.h" +#include "version.h" +#include "main.h" +#include "settings.h" JMutex g_httpfetch_mutex; std::map > g_httpfetch_results; +HTTPFetchRequest::HTTPFetchRequest() +{ + url = ""; + caller = HTTPFETCH_DISCARD; + request_id = 0; + timeout = g_settings->getS32("curl_timeout"); + connect_timeout = timeout; + multipart = false; + + useragent = std::string("Minetest/") + minetest_version_hash + " (" + porting::get_sysinfo() + ")"; +} + + static void httpfetch_deliver_result(const HTTPFetchResult &fetchresult) { unsigned long caller = fetchresult.caller; @@ -169,6 +185,7 @@ struct HTTPFetchOngoing std::ostringstream oss; char *post_fields; struct curl_slist *httpheader; + curl_httppost *post; HTTPFetchOngoing(HTTPFetchRequest request_, CurlHandlePool *pool_): pool(pool_), @@ -177,7 +194,8 @@ struct HTTPFetchOngoing request(request_), result(request_), oss(std::ios::binary), - httpheader(NULL) + httpheader(NULL), + post(NULL) { curl = pool->alloc(); if (curl != NULL) { @@ -224,18 +242,52 @@ struct HTTPFetchOngoing httpfetch_writefunction); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &oss); } + // Set POST (or GET) data if (request.post_fields.empty()) { curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); - } - else { - curl_easy_setopt(curl, CURLOPT_POST, 1); - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, - request.post_fields.size()); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, - request.post_fields.c_str()); + } else if (request.multipart) { + curl_httppost *last = NULL; + for (std::map::iterator it = + request.post_fields.begin(); + it != request.post_fields.end(); + ++it) { + curl_formadd(&post, &last, + CURLFORM_NAMELENGTH, it->first.size(), + CURLFORM_PTRNAME, it->first.c_str(), + CURLFORM_CONTENTSLENGTH, it->second.size(), + CURLFORM_PTRCONTENTS, it->second.c_str(), + CURLFORM_END); + } + curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); // request.post_fields must now *never* be - // modified until CURLOPT_POSTFIELDS is cleared + // modified until CURLOPT_HTTPPOST is cleared + } else { + curl_easy_setopt(curl, CURLOPT_POST, 1); + if (request.post_data.empty()) { + std::string str; + for (std::map::iterator it = + request.post_fields.begin(); + it != request.post_fields.end(); + ++it) { + if (str != "") + str += "&"; + str += urlencode(it->first); + str += "="; + str += urlencode(it->second); + } + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, + str.size()); + curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, + str.c_str()); + } else { + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, + request.post_data.size()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, + request.post_data.c_str()); + // request.post_data must now *never* be + // modified until CURLOPT_POSTFIELDS is cleared + } } // Set additional HTTP headers for (size_t i = 0; i < request.extra_headers.size(); ++i) { @@ -244,6 +296,10 @@ struct HTTPFetchOngoing request.extra_headers[i].c_str()); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, httpheader); + + if (!g_settings->getBool("curl_verify_cert")) { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); + } } } @@ -287,7 +343,7 @@ struct HTTPFetchOngoing } if (res != CURLE_OK) { - infostream<free(curl); @@ -523,7 +583,7 @@ protected: if (select_timeout > 0) { // in Winsock it is forbidden to pass three empty // fd_sets to select(), so in that case use sleep_ms - if (max_fd == -1) { + if (max_fd != -1) { select_tv.tv_sec = select_timeout / 1000; select_tv.tv_usec = (select_timeout % 1000) * 1000; int retval = select(max_fd + 1, &read_fd_set, @@ -551,6 +611,8 @@ protected: log_register_thread("CurlFetchThread"); DSTACK(__FUNCTION_NAME); + porting::setThreadName("CurlFetchThread"); + CurlHandlePool pool; m_multi = curl_multi_init(); @@ -569,7 +631,7 @@ protected: */ while (!m_requests.empty()) { - Request req = m_requests.pop_front(); + Request req = m_requests.pop_frontNoEx(); processRequest(req); } processQueued(&pool);