From cfe201f429d891f5f7281b21656d77198dbd318b Mon Sep 17 00:00:00 2001 From: Otmane Lahlou <otmane.lahlou@c-s.fr> Date: Tue, 22 Jun 2010 18:42:08 +0200 Subject: [PATCH] ENH : curlHelper to avoid windows crash when passing a pointer on a file descriptor in libcurl --- Code/IO/otbCurlHelper.cxx | 33 ++++++++++++++++++--------------- Code/IO/otbCurlHelper.h | 21 ++++++++++++++++++++- 2 files changed, 38 insertions(+), 16 deletions(-) mode change 100644 => 100755 Code/IO/otbCurlHelper.cxx diff --git a/Code/IO/otbCurlHelper.cxx b/Code/IO/otbCurlHelper.cxx old mode 100644 new mode 100755 index 10b11490d4..7ee36bb306 --- a/Code/IO/otbCurlHelper.cxx +++ b/Code/IO/otbCurlHelper.cxx @@ -35,13 +35,9 @@ int CurlHelper::TestUrlAvailability(const std::string& url) const CURLcode res = CURL_LAST; curl = curl_easy_init(); - // Set up the browser - std::string browser = - "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11"; - if (curl) { - curl_easy_setopt(curl, CURLOPT_USERAGENT, browser.data()); + curl_easy_setopt(curl, CURLOPT_USERAGENT, m_Browser.data()); curl_easy_setopt(curl, CURLOPT_URL, url.data()); // Set the dummy write function curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Self::curlDummyWriteFunction); @@ -69,26 +65,32 @@ int CurlHelper::RetrieveFile(const std::string& urlString, std::string filename) CURLcode res = CURL_LAST; FILE* output_file = fopen(filename.c_str(), "w"); + curl = curl_easy_init(); - + char url[256]; - strcpy(url, urlString.data()); + strcpy(url, urlString.c_str()); -// std::cout << url << std::endl; if (curl) { - std::vector<char> chunk; curl_easy_setopt(curl, CURLOPT_URL, url); // Set 5s timeout curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5); - - curl_easy_setopt(curl, CURLOPT_WRITEDATA, output_file); + + // Use our writing static function to avoid file descriptor + // pointer crash on windows + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Self::write_data); + + // Say the file where to write the received data + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)output_file); + res = curl_easy_perform(curl); - fclose(output_file); /* always cleanup */ curl_easy_cleanup(curl); + + fclose(output_file); } return res; #else @@ -105,7 +107,7 @@ int CurlHelper::RetrieveFileMulti(const std::vector<std::string>& listURLs, #ifdef OTB_USE_CURL #ifdef OTB_CURL_MULTI_AVAILABLE otbMsgDevMacro(<< "Using curl multi"); - std::string m_Browser = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11"; + //std::string m_Browser = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11"; CURLM * multiHandle; std::vector<CURL *> listCurlHandles; @@ -155,7 +157,8 @@ int CurlHelper::RetrieveFileMulti(const std::vector<std::string>& listURLs, // Param easy handle curl_easy_setopt(lEasyHandle, CURLOPT_USERAGENT, m_Browser.data()); curl_easy_setopt(lEasyHandle, CURLOPT_URL, (*url).data()); - curl_easy_setopt(lEasyHandle, CURLOPT_WRITEDATA, *file); + curl_easy_setopt(lEasyHandle, CURLOPT_WRITEFUNCTION, &Self::write_data); + curl_easy_setopt(lEasyHandle, CURLOPT_WRITEDATA, (void*)(*file)); // Add easy handle to multi handle curl_multi_add_handle(multiHandle, lEasyHandle); @@ -166,7 +169,7 @@ int CurlHelper::RetrieveFileMulti(const std::vector<std::string>& listURLs, ++file; } -//fetch tiles + //fetch tiles // Configure multi handle - set the maximum connections curl_multi_setopt(multiHandle, CURLMOPT_MAXCONNECTS, maxConnect); curl_multi_setopt(multiHandle, CURLMOPT_PIPELINING, 0); diff --git a/Code/IO/otbCurlHelper.h b/Code/IO/otbCurlHelper.h index e0ffa8d10e..1918566b98 100644 --- a/Code/IO/otbCurlHelper.h +++ b/Code/IO/otbCurlHelper.h @@ -49,7 +49,10 @@ public: const std::vector<std::string>& listFiles, int maxConnect) const; protected: - CurlHelper() {} + CurlHelper() + { + m_Browser = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11"; + } ~CurlHelper() {} @@ -61,7 +64,23 @@ private: { return nmemb; } + + // Need to use our writing function to handle windows segfaults + // Need to be static cause the CURL_OPT is excpecting a pure C + // function or a static c++ method. + static size_t write_data(void* ptr, size_t size, size_t nmemb, void* data) + { + size_t written; + + FILE * fDescriptor = (FILE *)(data); + + written = fwrite(ptr,size,nmemb,fDescriptor); + + return written; + } + // Browser Agent used + std::string m_Browser; }; } #endif -- GitLab