toolkit/crashreporter/google-breakpad/src/common/linux/libcurl_wrapper.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Copyright (c) 2009, Google Inc.
michael@0 2 // All rights reserved.
michael@0 3 //
michael@0 4 // Redistribution and use in source and binary forms, with or without
michael@0 5 // modification, are permitted provided that the following conditions are
michael@0 6 // met:
michael@0 7 //
michael@0 8 // * Redistributions of source code must retain the above copyright
michael@0 9 // notice, this list of conditions and the following disclaimer.
michael@0 10 // * Redistributions in binary form must reproduce the above
michael@0 11 // copyright notice, this list of conditions and the following disclaimer
michael@0 12 // in the documentation and/or other materials provided with the
michael@0 13 // distribution.
michael@0 14 // * Neither the name of Google Inc. nor the names of its
michael@0 15 // contributors may be used to endorse or promote products derived from
michael@0 16 // this software without specific prior written permission.
michael@0 17 //
michael@0 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 29
michael@0 30 #include <dlfcn.h>
michael@0 31
michael@0 32 #include <iostream>
michael@0 33 #include <string>
michael@0 34
michael@0 35 #include "common/linux/libcurl_wrapper.h"
michael@0 36 #include "common/using_std_string.h"
michael@0 37
michael@0 38 namespace google_breakpad {
michael@0 39 LibcurlWrapper::LibcurlWrapper()
michael@0 40 : init_ok_(false),
michael@0 41 formpost_(NULL),
michael@0 42 lastptr_(NULL),
michael@0 43 headerlist_(NULL) {
michael@0 44 curl_lib_ = dlopen("libcurl.so", RTLD_NOW);
michael@0 45 if (!curl_lib_) {
michael@0 46 curl_lib_ = dlopen("libcurl.so.4", RTLD_NOW);
michael@0 47 }
michael@0 48 if (!curl_lib_) {
michael@0 49 curl_lib_ = dlopen("libcurl.so.3", RTLD_NOW);
michael@0 50 }
michael@0 51 if (!curl_lib_) {
michael@0 52 std::cout << "Could not find libcurl via dlopen";
michael@0 53 return;
michael@0 54 }
michael@0 55 std::cout << "LibcurlWrapper init succeeded";
michael@0 56 init_ok_ = true;
michael@0 57 return;
michael@0 58 }
michael@0 59
michael@0 60 bool LibcurlWrapper::SetProxy(const string& proxy_host,
michael@0 61 const string& proxy_userpwd) {
michael@0 62 if (!init_ok_) {
michael@0 63 return false;
michael@0 64 }
michael@0 65 // Set proxy information if necessary.
michael@0 66 if (!proxy_host.empty()) {
michael@0 67 (*easy_setopt_)(curl_, CURLOPT_PROXY, proxy_host.c_str());
michael@0 68 } else {
michael@0 69 std::cout << "SetProxy called with empty proxy host.";
michael@0 70 return false;
michael@0 71 }
michael@0 72 if (!proxy_userpwd.empty()) {
michael@0 73 (*easy_setopt_)(curl_, CURLOPT_PROXYUSERPWD, proxy_userpwd.c_str());
michael@0 74 } else {
michael@0 75 std::cout << "SetProxy called with empty proxy username/password.";
michael@0 76 return false;
michael@0 77 }
michael@0 78 std::cout << "Set proxy host to " << proxy_host;
michael@0 79 return true;
michael@0 80 }
michael@0 81
michael@0 82 bool LibcurlWrapper::AddFile(const string& upload_file_path,
michael@0 83 const string& basename) {
michael@0 84 if (!init_ok_) {
michael@0 85 return false;
michael@0 86 }
michael@0 87 std::cout << "Adding " << upload_file_path << " to form upload.";
michael@0 88 // Add form file.
michael@0 89 (*formadd_)(&formpost_, &lastptr_,
michael@0 90 CURLFORM_COPYNAME, basename.c_str(),
michael@0 91 CURLFORM_FILE, upload_file_path.c_str(),
michael@0 92 CURLFORM_END);
michael@0 93
michael@0 94 return true;
michael@0 95 }
michael@0 96
michael@0 97 // Callback to get the response data from server.
michael@0 98 static size_t WriteCallback(void *ptr, size_t size,
michael@0 99 size_t nmemb, void *userp) {
michael@0 100 if (!userp)
michael@0 101 return 0;
michael@0 102
michael@0 103 string *response = reinterpret_cast<string *>(userp);
michael@0 104 size_t real_size = size * nmemb;
michael@0 105 response->append(reinterpret_cast<char *>(ptr), real_size);
michael@0 106 return real_size;
michael@0 107 }
michael@0 108
michael@0 109 bool LibcurlWrapper::SendRequest(const string& url,
michael@0 110 const std::map<string, string>& parameters,
michael@0 111 string* server_response) {
michael@0 112 (*easy_setopt_)(curl_, CURLOPT_URL, url.c_str());
michael@0 113 std::map<string, string>::const_iterator iter = parameters.begin();
michael@0 114 for (; iter != parameters.end(); ++iter)
michael@0 115 (*formadd_)(&formpost_, &lastptr_,
michael@0 116 CURLFORM_COPYNAME, iter->first.c_str(),
michael@0 117 CURLFORM_COPYCONTENTS, iter->second.c_str(),
michael@0 118 CURLFORM_END);
michael@0 119
michael@0 120 (*easy_setopt_)(curl_, CURLOPT_HTTPPOST, formpost_);
michael@0 121 if (server_response != NULL) {
michael@0 122 (*easy_setopt_)(curl_, CURLOPT_WRITEFUNCTION, WriteCallback);
michael@0 123 (*easy_setopt_)(curl_, CURLOPT_WRITEDATA,
michael@0 124 reinterpret_cast<void *>(server_response));
michael@0 125 }
michael@0 126
michael@0 127 CURLcode err_code = CURLE_OK;
michael@0 128 err_code = (*easy_perform_)(curl_);
michael@0 129 easy_strerror_ = reinterpret_cast<const char* (*)(CURLcode)>
michael@0 130 (dlsym(curl_lib_, "curl_easy_strerror"));
michael@0 131
michael@0 132 #ifndef NDEBUG
michael@0 133 if (err_code != CURLE_OK)
michael@0 134 fprintf(stderr, "Failed to send http request to %s, error: %s\n",
michael@0 135 url.c_str(),
michael@0 136 (*easy_strerror_)(err_code));
michael@0 137 #endif
michael@0 138 if (headerlist_ != NULL) {
michael@0 139 (*slist_free_all_)(headerlist_);
michael@0 140 }
michael@0 141
michael@0 142 (*easy_cleanup_)(curl_);
michael@0 143 if (formpost_ != NULL) {
michael@0 144 (*formfree_)(formpost_);
michael@0 145 }
michael@0 146
michael@0 147 return err_code == CURLE_OK;
michael@0 148 }
michael@0 149
michael@0 150 bool LibcurlWrapper::Init() {
michael@0 151 if (!init_ok_) {
michael@0 152 std::cout << "Init_OK was not true in LibcurlWrapper::Init(), check earlier log messages";
michael@0 153 return false;
michael@0 154 }
michael@0 155
michael@0 156 if (!SetFunctionPointers()) {
michael@0 157 std::cout << "Could not find function pointers";
michael@0 158 init_ok_ = false;
michael@0 159 return false;
michael@0 160 }
michael@0 161
michael@0 162 curl_ = (*easy_init_)();
michael@0 163
michael@0 164 last_curl_error_ = "No Error";
michael@0 165
michael@0 166 if (!curl_) {
michael@0 167 dlclose(curl_lib_);
michael@0 168 std::cout << "Curl initialization failed";
michael@0 169 return false;
michael@0 170 }
michael@0 171
michael@0 172 // Disable 100-continue header.
michael@0 173 char buf[] = "Expect:";
michael@0 174
michael@0 175 headerlist_ = (*slist_append_)(headerlist_, buf);
michael@0 176 (*easy_setopt_)(curl_, CURLOPT_HTTPHEADER, headerlist_);
michael@0 177 return true;
michael@0 178 }
michael@0 179
michael@0 180 #define SET_AND_CHECK_FUNCTION_POINTER(var, function_name, type) \
michael@0 181 var = reinterpret_cast<type>(dlsym(curl_lib_, function_name)); \
michael@0 182 if (!var) { \
michael@0 183 std::cout << "Could not find libcurl function " << function_name; \
michael@0 184 init_ok_ = false; \
michael@0 185 return false; \
michael@0 186 }
michael@0 187
michael@0 188 bool LibcurlWrapper::SetFunctionPointers() {
michael@0 189
michael@0 190 SET_AND_CHECK_FUNCTION_POINTER(easy_init_,
michael@0 191 "curl_easy_init",
michael@0 192 CURL*(*)());
michael@0 193
michael@0 194 SET_AND_CHECK_FUNCTION_POINTER(easy_setopt_,
michael@0 195 "curl_easy_setopt",
michael@0 196 CURLcode(*)(CURL*, CURLoption, ...));
michael@0 197
michael@0 198 SET_AND_CHECK_FUNCTION_POINTER(formadd_, "curl_formadd",
michael@0 199 CURLFORMcode(*)(curl_httppost**, curl_httppost**, ...));
michael@0 200
michael@0 201 SET_AND_CHECK_FUNCTION_POINTER(slist_append_, "curl_slist_append",
michael@0 202 curl_slist*(*)(curl_slist*, const char*));
michael@0 203
michael@0 204 SET_AND_CHECK_FUNCTION_POINTER(easy_perform_,
michael@0 205 "curl_easy_perform",
michael@0 206 CURLcode(*)(CURL*));
michael@0 207
michael@0 208 SET_AND_CHECK_FUNCTION_POINTER(easy_cleanup_,
michael@0 209 "curl_easy_cleanup",
michael@0 210 void(*)(CURL*));
michael@0 211
michael@0 212 SET_AND_CHECK_FUNCTION_POINTER(slist_free_all_,
michael@0 213 "curl_slist_free_all",
michael@0 214 void(*)(curl_slist*));
michael@0 215
michael@0 216 SET_AND_CHECK_FUNCTION_POINTER(formfree_,
michael@0 217 "curl_formfree",
michael@0 218 void(*)(curl_httppost*));
michael@0 219 return true;
michael@0 220 }
michael@0 221
michael@0 222 }

mercurial