diff --git a/src/common/linux/http_upload.cc b/src/common/linux/http_upload.cc index 4896edd0..ea68123e 100644 --- a/src/common/linux/http_upload.cc +++ b/src/common/linux/http_upload.cc @@ -28,6 +28,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include #include #include #include @@ -66,69 +67,102 @@ bool HTTPUpload::SendRequest(const string &url, if (!CheckParameters(parameters)) return false; - CURL *curl = curl_easy_init(); - CURLcode err_code = CURLE_OK; + void *curl_lib = dlopen("libcurl.so", RTLD_NOW); + if (!curl_lib) { + curl_lib = dlopen("libcurl.so.4", RTLD_NOW); + } + if (!curl_lib) { + curl_lib = dlopen("libcurl.so.3", RTLD_NOW); + } + if (!curl_lib) { + return false; + } + + CURL* (*curl_easy_init)(void); + *(void**) (&curl_easy_init) = dlsym(curl_lib, "curl_easy_init"); + CURL *curl = (*curl_easy_init)(); if (error_description != NULL) *error_description = "No Error"; - if (curl) { - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_USERAGENT, kUserAgent); - // Set proxy information if necessary. - if (!proxy.empty()) - curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str()); - if (!proxy_user_pwd.empty()) - curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, proxy_user_pwd.c_str()); + if (!curl) { + dlclose(curl_lib); + return false; + } - struct curl_httppost *formpost = NULL; - struct curl_httppost *lastptr = NULL; - // Add form data. - map::const_iterator iter = parameters.begin(); - for (; iter != parameters.end(); ++iter) - curl_formadd(&formpost, &lastptr, - CURLFORM_COPYNAME, iter->first.c_str(), - CURLFORM_COPYCONTENTS, iter->second.c_str(), - CURLFORM_END); + CURLcode err_code = CURLE_OK; + CURLcode (*curl_easy_setopt)(CURL *, CURLoption, ...); + *(void**) (&curl_easy_setopt) = dlsym(curl_lib, "curl_easy_setopt"); + (*curl_easy_setopt)(curl, CURLOPT_URL, url.c_str()); + (*curl_easy_setopt)(curl, CURLOPT_USERAGENT, kUserAgent); + // Set proxy information if necessary. + if (!proxy.empty()) + (*curl_easy_setopt)(curl, CURLOPT_PROXY, proxy.c_str()); + if (!proxy_user_pwd.empty()) + (*curl_easy_setopt)(curl, CURLOPT_PROXYUSERPWD, proxy_user_pwd.c_str()); - // Add form file. - curl_formadd(&formpost, &lastptr, - CURLFORM_COPYNAME, file_part_name.c_str(), - CURLFORM_FILE, upload_file.c_str(), + struct curl_httppost *formpost = NULL; + struct curl_httppost *lastptr = NULL; + // Add form data. + CURLFORMcode (*curl_formadd)(struct curl_httppost **, struct curl_httppost **, ...); + *(void**) (&curl_formadd) = dlsym(curl_lib, "curl_formadd"); + map::const_iterator iter = parameters.begin(); + for (; iter != parameters.end(); ++iter) + (*curl_formadd)(&formpost, &lastptr, + CURLFORM_COPYNAME, iter->first.c_str(), + CURLFORM_COPYCONTENTS, iter->second.c_str(), CURLFORM_END); - curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); + // Add form file. + (*curl_formadd)(&formpost, &lastptr, + CURLFORM_COPYNAME, file_part_name.c_str(), + CURLFORM_FILE, upload_file.c_str(), + CURLFORM_END); - // Disable 100-continue header. - struct curl_slist *headerlist = NULL; - char buf[] = "Expect:"; - headerlist = curl_slist_append(headerlist, buf); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); + (*curl_easy_setopt)(curl, CURLOPT_HTTPPOST, formpost); - if (response_body != NULL) { - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, - reinterpret_cast(response_body)); - } + // Disable 100-continue header. + struct curl_slist *headerlist = NULL; + char buf[] = "Expect:"; + struct curl_slist* (*curl_slist_append)(struct curl_slist *, const char *); + *(void**) (&curl_slist_append) = dlsym(curl_lib, "curl_slist_append"); + headerlist = (*curl_slist_append)(headerlist, buf); + (*curl_easy_setopt)(curl, CURLOPT_HTTPHEADER, headerlist); - err_code = curl_easy_perform(curl); -#ifndef NDEBUG - if (err_code != CURLE_OK) - fprintf(stderr, "Failed to send http request to %s, error: %s\n", - url.c_str(), - curl_easy_strerror(err_code)); -#endif - if (error_description != NULL) - *error_description = curl_easy_strerror(err_code); - - if (curl != NULL) - curl_easy_cleanup(curl); - if (formpost != NULL) - curl_formfree(formpost); - if (headerlist != NULL) - curl_slist_free_all(headerlist); - return err_code == CURLE_OK; + if (response_body != NULL) { + (*curl_easy_setopt)(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + (*curl_easy_setopt)(curl, CURLOPT_WRITEDATA, + reinterpret_cast(response_body)); } - return false; + + CURLcode (*curl_easy_perform)(CURL *); + *(void**) (&curl_easy_perform) = dlsym(curl_lib, "curl_easy_perform"); + err_code = (*curl_easy_perform)(curl); +#ifndef NDEBUG + const char* (*curl_easy_strerror)(CURLcode); + *(void**) (&curl_easy_strerror) = dlsym(curl_lib, "curl_easy_strerror"); + if (err_code != CURLE_OK) + fprintf(stderr, "Failed to send http request to %s, error: %s\n", + url.c_str(), + (*curl_easy_strerror)(err_code)); +#endif + if (error_description != NULL) + *error_description = (*curl_easy_strerror)(err_code); + + void (*curl_easy_cleanup)(CURL *); + *(void**) (&curl_easy_cleanup) = dlsym(curl_lib, "curl_easy_cleanup"); + (*curl_easy_cleanup)(curl); + if (formpost != NULL) { + void (*curl_formfree)(struct curl_httppost *); + *(void**) (&curl_formfree) = dlsym(curl_lib, "curl_formfree"); + (*curl_formfree)(formpost); + } + if (headerlist != NULL) { + void (*curl_slist_free_all)(struct curl_slist *); + *(void**) (&curl_slist_free_all) = dlsym(curl_lib, "curl_slist_free_all"); + (*curl_slist_free_all)(headerlist); + } + dlclose(curl_lib); + return err_code == CURLE_OK; } // static diff --git a/src/tools/linux/symupload/Makefile b/src/tools/linux/symupload/Makefile index 1fb843ee..c0c49eed 100644 --- a/src/tools/linux/symupload/Makefile +++ b/src/tools/linux/symupload/Makefile @@ -12,10 +12,10 @@ DUMP_UPLOAD_OBJ=minidump_upload.o http_upload.o SYM_UPLOAD_OBJ=sym_upload.o http_upload.o minidump_upload:$(DUMP_UPLOAD_OBJ) - $(CXX) $(CXXFLAGS) `curl-config --libs` -o $@ $^ + $(CXX) $(CXXFLAGS) -ldl -o $@ $^ sym_upload:$(SYM_UPLOAD_OBJ) - $(CXX) $(CXXFLAGS) `curl-config --libs` -o $@ $^ + $(CXX) $(CXXFLAGS) -ldl -o $@ $^ http_upload.o:../../../common/linux/http_upload.cc $(CXX) $(CXXFLAGS) `curl-config --cflags` -c $^