# - Media fetch if server uses remote_media setting
# - Serverlist download and server announcement
# - Downloads performed by main menu (e.g. mod manager)
-# - Downloads performed by mods (minetest.httpfetch)
# Only has an effect if compiled with cURL
#curl_parallel_limit = 8
#include "main.h" // for g_settings
#include "settings.h"
#include "version.h"
-
-#if USE_CURL
-#include <curl/curl.h>
-
-static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
-{
- ((std::string*)userp)->append((char*)contents, size * nmemb);
- return size * nmemb;
-}
-
-#endif
+#include "httpfetch.h"
Json::Value fetchJsonValue(const std::string url,
struct curl_slist *chunk) {
#if USE_CURL
- std::string liststring;
- CURL *curl;
- curl = curl_easy_init();
- if (curl)
- {
- CURLcode res;
-
- curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &liststring);
- curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, g_settings->getS32("curl_timeout"));
- curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, g_settings->getS32("curl_timeout"));
- curl_easy_setopt(curl, CURLOPT_USERAGENT, (std::string("Minetest ")+minetest_version_hash).c_str());
-
- if (chunk != 0)
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
-
- res = curl_easy_perform(curl);
- if (res != CURLE_OK)
- errorstream<<"Jsonreader: "<< url <<" not found (" << curl_easy_strerror(res) << ")" <<std::endl;
- curl_easy_cleanup(curl);
+ HTTPFetchRequest fetchrequest;
+ HTTPFetchResult fetchresult;
+ fetchrequest.url = url;
+ fetchrequest.useragent = std::string("Minetest ")+minetest_version_hash;
+ fetchrequest.timeout = g_settings->getS32("curl_timeout");
+ fetchrequest.caller = HTTPFETCH_SYNC;
+
+ struct curl_slist* runptr = chunk;
+ while(runptr) {
+ fetchrequest.extra_headers.push_back(runptr->data);
+ runptr = runptr->next;
}
+ httpfetch_sync(fetchrequest,fetchresult);
- Json::Value root;
- Json::Reader reader;
- std::istringstream stream(liststring);
- if (!liststring.size()) {
+ if (!fetchresult.succeeded) {
return Json::Value();
}
+ Json::Value root;
+ Json::Reader reader;
+ std::istringstream stream(fetchresult.data);
if (!reader.parse( stream, root ) )
{
errorstream << "URL: " << url << std::endl;
errorstream << "Failed to parse json data " << reader.getFormattedErrorMessages();
- errorstream << "data: \"" << liststring << "\"" << std::endl;
+ errorstream << "data: \"" << fetchresult.data << "\"" << std::endl;
return Json::Value();
}
#include "sound.h"
#include "sound_openal.h"
#include "clouds.h"
+#include "httpfetch.h"
#include <IGUIStaticText.h>
#include <ICameraSceneNode.h>
}
/******************************************************************************/
-#if USE_CURL
-static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
-{
- FILE* targetfile = (FILE*) userp;
- fwrite(contents,size,nmemb,targetfile);
- return size * nmemb;
-}
-#endif
bool GUIEngine::downloadFile(std::string url,std::string target) {
#if USE_CURL
- //download file via curl
- CURL *curl;
+ bool retval = true;
- curl = curl_easy_init();
+ FILE* targetfile = fopen(target.c_str(),"wb");
- if (curl)
- {
- CURLcode res;
- bool retval = true;
-
- FILE* targetfile = fopen(target.c_str(),"wb");
-
- if (targetfile) {
- curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, targetfile);
- curl_easy_setopt(curl, CURLOPT_USERAGENT, (std::string("Minetest ")+minetest_version_hash).c_str());
- res = curl_easy_perform(curl);
- if (res != CURLE_OK) {
- errorstream << "File at url \"" << url
- <<"\" not found (" << curl_easy_strerror(res) << ")" <<std::endl;
+ if (targetfile) {
+ HTTPFetchRequest fetchrequest;
+ HTTPFetchResult fetchresult;
+ fetchrequest.url = url;
+ fetchrequest.useragent = std::string("Minetest ")+minetest_version_hash;
+ fetchrequest.timeout = g_settings->getS32("curl_timeout");
+ fetchrequest.caller = HTTPFETCH_SYNC;
+ httpfetch_sync(fetchrequest,fetchresult);
+
+ if (fetchresult.succeeded) {
+ if (fwrite(fetchresult.data.c_str(),1,fetchresult.data.size(),targetfile) != fetchresult.data.size()) {
retval = false;
}
- fclose(targetfile);
}
else {
retval = false;
}
-
- curl_easy_cleanup(curl);
- return retval;
+ fclose(targetfile);
}
-#endif
+ else {
+ retval = false;
+ }
+
+ return retval;
+#else
return false;
+#endif
}
/******************************************************************************/
#include "log.h"
#include "tile.h" // ITextureSource
#include "hud.h" // drawItemStack
+#include "hex.h"
#include "util/string.h"
#include "util/numeric.h"
#include "filesys.h"
return Parent ? Parent->OnEvent(event) : false;
}
-static inline bool hex_digit_decode(char hexdigit, unsigned char &value)
-{
- if(hexdigit >= '0' && hexdigit <= '9')
- value = hexdigit - '0';
- else if(hexdigit >= 'A' && hexdigit <= 'F')
- value = hexdigit - 'A' + 10;
- else if(hexdigit >= 'a' && hexdigit <= 'f')
- value = hexdigit - 'a' + 10;
- else
- return false;
- return true;
-}
-
bool GUIFormSpecMenu::parseColor(std::string &value, video::SColor &color, bool quiet)
{
const char *hexpattern = NULL;
if (curl != NULL) {
if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE,
&result.response_code) != CURLE_OK) {
+ //we failed to get a return code make sure it is still 0
result.response_code = 0;
}
}
// Can be used in place of "caller" in asynchronous transfers to discard result
// (used as default value of "caller")
#define HTTPFETCH_DISCARD 0
+#define HTTPFETCH_SYNC 1
struct HTTPFetchRequest
{
caller = fetchrequest.caller;
request_id = fetchrequest.request_id;
}
+
};
// Initializes the httpfetch module