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