Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: net/proxy/proxy_script_fetcher.cc

Issue 2817043: Reduce the copying of string data between C++ and javascript in proxy_resolver_v8.cc. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: fix comment typo 'converts' Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/proxy/proxy_script_fetcher.h ('k') | net/proxy/proxy_script_fetcher_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // source code is governed by a BSD-style license that can be found in the 2 // Use of this source code is governed by a BSD-style license that can be
3 // LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/proxy/proxy_script_fetcher.h" 5 #include "net/proxy/proxy_script_fetcher.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/i18n/icu_string_conversions.h" 8 #include "base/i18n/icu_string_conversions.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/ref_counted.h" 11 #include "base/ref_counted.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
(...skipping 24 matching lines...) Expand all
38 "application/x-ns-proxy-autoconfig", 38 "application/x-ns-proxy-autoconfig",
39 "application/x-javascript-config", 39 "application/x-javascript-config",
40 }; 40 };
41 for (size_t i = 0; i < arraysize(kSupportedPacMimeTypes); ++i) { 41 for (size_t i = 0; i < arraysize(kSupportedPacMimeTypes); ++i) {
42 if (LowerCaseEqualsASCII(mime_type, kSupportedPacMimeTypes[i])) 42 if (LowerCaseEqualsASCII(mime_type, kSupportedPacMimeTypes[i]))
43 return true; 43 return true;
44 } 44 }
45 return false; 45 return false;
46 } 46 }
47 47
48 // Convert |bytes| (which is encoded by |charset|) in place to UTF8. 48 // Converts |bytes| (which is encoded by |charset|) to UTF16, saving the resul
49 // to |*utf16|.
49 // If |charset| is empty, then we don't know what it was and guess. 50 // If |charset| is empty, then we don't know what it was and guess.
50 void ConvertResponseToUTF8(const std::string& charset, std::string* bytes) { 51 void ConvertResponseToUTF16(const std::string& charset,
52 const std::string& bytes,
53 string16* utf16) {
51 const char* codepage; 54 const char* codepage;
52 55
53 if (charset.empty()) { 56 if (charset.empty()) {
54 // Assume ISO-8859-1 if no charset was specified. 57 // Assume ISO-8859-1 if no charset was specified.
55 codepage = base::kCodepageLatin1; 58 codepage = base::kCodepageLatin1;
56 } else { 59 } else {
57 // Otherwise trust the charset that was provided. 60 // Otherwise trust the charset that was provided.
58 codepage = charset.c_str(); 61 codepage = charset.c_str();
59 } 62 }
60 63
61 // We will be generous in the conversion -- if any characters lie 64 // We will be generous in the conversion -- if any characters lie
62 // outside of |charset| (i.e. invalid), then substitute them with 65 // outside of |charset| (i.e. invalid), then substitute them with
63 // U+FFFD rather than failing. 66 // U+FFFD rather than failing.
64 std::wstring tmp_wide; 67 base::CodepageToUTF16(bytes, codepage,
65 base::CodepageToWide(*bytes, codepage, 68 base::OnStringConversionError::SUBSTITUTE,
66 base::OnStringConversionError::SUBSTITUTE, 69 utf16);
67 &tmp_wide);
68 // TODO(eroman): would be nice to have a CodepageToUTF8() function.
69 *bytes = WideToUTF8(tmp_wide);
70 } 70 }
71 71
72 } // namespace 72 } // namespace
73 73
74 class ProxyScriptFetcherImpl : public ProxyScriptFetcher, 74 class ProxyScriptFetcherImpl : public ProxyScriptFetcher,
75 public URLRequest::Delegate { 75 public URLRequest::Delegate {
76 public: 76 public:
77 // Creates a ProxyScriptFetcher that issues requests through 77 // Creates a ProxyScriptFetcher that issues requests through
78 // |url_request_context|. |url_request_context| must remain valid for the 78 // |url_request_context|. |url_request_context| must remain valid for the
79 // lifetime of ProxyScriptFetcherImpl. 79 // lifetime of ProxyScriptFetcherImpl.
80 explicit ProxyScriptFetcherImpl(URLRequestContext* url_request_context); 80 explicit ProxyScriptFetcherImpl(URLRequestContext* url_request_context);
81 81
82 virtual ~ProxyScriptFetcherImpl(); 82 virtual ~ProxyScriptFetcherImpl();
83 83
84 // ProxyScriptFetcher methods: 84 // ProxyScriptFetcher methods:
85 85
86 virtual int Fetch(const GURL& url, std::string* bytes, 86 virtual int Fetch(const GURL& url, string16* text,
87 CompletionCallback* callback); 87 CompletionCallback* callback);
88 virtual void Cancel(); 88 virtual void Cancel();
89 virtual URLRequestContext* GetRequestContext(); 89 virtual URLRequestContext* GetRequestContext();
90 90
91 // URLRequest::Delegate methods: 91 // URLRequest::Delegate methods:
92 92
93 virtual void OnAuthRequired(URLRequest* request, 93 virtual void OnAuthRequired(URLRequest* request,
94 AuthChallengeInfo* auth_info); 94 AuthChallengeInfo* auth_info);
95 virtual void OnSSLCertificateError(URLRequest* request, int cert_error, 95 virtual void OnSSLCertificateError(URLRequest* request, int cert_error,
96 X509Certificate* cert); 96 X509Certificate* cert);
97 virtual void OnResponseStarted(URLRequest* request); 97 virtual void OnResponseStarted(URLRequest* request);
98 virtual void OnReadCompleted(URLRequest* request, int num_bytes); 98 virtual void OnReadCompleted(URLRequest* request, int num_bytes);
99 virtual void OnResponseCompleted(URLRequest* request); 99 virtual void OnResponseCompleted(URLRequest* request);
100 100
101 private: 101 private:
102 // Read more bytes from the response. 102 // Read more bytes from the response.
103 void ReadBody(URLRequest* request); 103 void ReadBody(URLRequest* request);
104 104
105 // Called once the request has completed to notify the caller of 105 // Called once the request has completed to notify the caller of
106 // |response_code_| and |response_bytes_|. 106 // |response_code_| and |response_text_|.
107 void FetchCompleted(); 107 void FetchCompleted();
108 108
109 // Clear out the state for the current request. 109 // Clear out the state for the current request.
110 void ResetCurRequestState(); 110 void ResetCurRequestState();
111 111
112 // Callback for time-out task of request with id |id|. 112 // Callback for time-out task of request with id |id|.
113 void OnTimeout(int id); 113 void OnTimeout(int id);
114 114
115 // Factory for creating the time-out task. This takes care of revoking 115 // Factory for creating the time-out task. This takes care of revoking
116 // outstanding tasks when |this| is deleted. 116 // outstanding tasks when |this| is deleted.
(...skipping 16 matching lines...) Expand all
133 133
134 // Unique ID for the current request. 134 // Unique ID for the current request.
135 int cur_request_id_; 135 int cur_request_id_;
136 136
137 // Callback to invoke on completion of the fetch. 137 // Callback to invoke on completion of the fetch.
138 CompletionCallback* callback_; 138 CompletionCallback* callback_;
139 139
140 // Holds the error condition that was hit on the current request, or OK. 140 // Holds the error condition that was hit on the current request, or OK.
141 int result_code_; 141 int result_code_;
142 142
143 // Holds the bytes read so far. Will not exceed |max_response_bytes|. This 143 // Holds the bytes read so far. Will not exceed |max_response_bytes|.
144 // buffer is owned by the owner of |callback|. 144 std::string bytes_read_so_far_;
145 std::string* result_bytes_; 145
146 // This buffer is owned by the owner of |callback|, and will be filled with
147 // UTF16 response on completion.
148 string16* result_text_;
146 }; 149 };
147 150
148 ProxyScriptFetcherImpl::ProxyScriptFetcherImpl( 151 ProxyScriptFetcherImpl::ProxyScriptFetcherImpl(
149 URLRequestContext* url_request_context) 152 URLRequestContext* url_request_context)
150 : ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), 153 : ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
151 url_request_context_(url_request_context), 154 url_request_context_(url_request_context),
152 buf_(new net::IOBuffer(kBufSize)), 155 buf_(new net::IOBuffer(kBufSize)),
153 next_id_(0), 156 next_id_(0),
154 cur_request_(NULL), 157 cur_request_(NULL),
155 cur_request_id_(0), 158 cur_request_id_(0),
156 callback_(NULL), 159 callback_(NULL),
157 result_code_(OK), 160 result_code_(OK),
158 result_bytes_(NULL) { 161 result_text_(NULL) {
159 DCHECK(url_request_context); 162 DCHECK(url_request_context);
160 } 163 }
161 164
162 ProxyScriptFetcherImpl::~ProxyScriptFetcherImpl() { 165 ProxyScriptFetcherImpl::~ProxyScriptFetcherImpl() {
163 // The URLRequest's destructor will cancel the outstanding request, and 166 // The URLRequest's destructor will cancel the outstanding request, and
164 // ensure that the delegate (this) is not called again. 167 // ensure that the delegate (this) is not called again.
165 } 168 }
166 169
167 int ProxyScriptFetcherImpl::Fetch(const GURL& url, 170 int ProxyScriptFetcherImpl::Fetch(const GURL& url,
168 std::string* bytes, 171 string16* text,
169 CompletionCallback* callback) { 172 CompletionCallback* callback) {
170 // It is invalid to call Fetch() while a request is already in progress. 173 // It is invalid to call Fetch() while a request is already in progress.
171 DCHECK(!cur_request_.get()); 174 DCHECK(!cur_request_.get());
172 175
173 DCHECK(callback); 176 DCHECK(callback);
174 DCHECK(bytes); 177 DCHECK(text);
175 178
176 cur_request_.reset(new URLRequest(url, this)); 179 cur_request_.reset(new URLRequest(url, this));
177 cur_request_->set_context(url_request_context_); 180 cur_request_->set_context(url_request_context_);
178 cur_request_->set_method("GET"); 181 cur_request_->set_method("GET");
179 182
180 // Make sure that the PAC script is downloaded using a direct connection, 183 // Make sure that the PAC script is downloaded using a direct connection,
181 // to avoid circular dependencies (fetching is a part of proxy resolution). 184 // to avoid circular dependencies (fetching is a part of proxy resolution).
182 // Also disable the use of the disk cache. The cache is disabled so that if 185 // Also disable the use of the disk cache. The cache is disabled so that if
183 // the user switches networks we don't potentially use the cached response 186 // the user switches networks we don't potentially use the cached response
184 // from old network when we should in fact be re-fetching on the new network. 187 // from old network when we should in fact be re-fetching on the new network.
185 cur_request_->set_load_flags(LOAD_BYPASS_PROXY | LOAD_DISABLE_CACHE); 188 cur_request_->set_load_flags(LOAD_BYPASS_PROXY | LOAD_DISABLE_CACHE);
186 189
187 // Save the caller's info for notification on completion. 190 // Save the caller's info for notification on completion.
188 callback_ = callback; 191 callback_ = callback;
189 result_bytes_ = bytes; 192 result_text_ = text;
190 result_bytes_->clear(); 193
194 bytes_read_so_far_.clear();
191 195
192 // Post a task to timeout this request if it takes too long. 196 // Post a task to timeout this request if it takes too long.
193 cur_request_id_ = ++next_id_; 197 cur_request_id_ = ++next_id_;
194 MessageLoop::current()->PostDelayedTask(FROM_HERE, 198 MessageLoop::current()->PostDelayedTask(FROM_HERE,
195 task_factory_.NewRunnableMethod(&ProxyScriptFetcherImpl::OnTimeout, 199 task_factory_.NewRunnableMethod(&ProxyScriptFetcherImpl::OnTimeout,
196 cur_request_id_), 200 cur_request_id_),
197 static_cast<int>(max_duration_ms)); 201 static_cast<int>(max_duration_ms));
198 202
199 // Start the request. 203 // Start the request.
200 cur_request_->Start(); 204 cur_request_->Start();
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 } 266 }
263 267
264 ReadBody(request); 268 ReadBody(request);
265 } 269 }
266 270
267 void ProxyScriptFetcherImpl::OnReadCompleted(URLRequest* request, 271 void ProxyScriptFetcherImpl::OnReadCompleted(URLRequest* request,
268 int num_bytes) { 272 int num_bytes) {
269 DCHECK(request == cur_request_.get()); 273 DCHECK(request == cur_request_.get());
270 if (num_bytes > 0) { 274 if (num_bytes > 0) {
271 // Enforce maximum size bound. 275 // Enforce maximum size bound.
272 if (num_bytes + result_bytes_->size() > 276 if (num_bytes + bytes_read_so_far_.size() >
273 static_cast<size_t>(max_response_bytes)) { 277 static_cast<size_t>(max_response_bytes)) {
274 result_code_ = ERR_FILE_TOO_BIG; 278 result_code_ = ERR_FILE_TOO_BIG;
275 request->Cancel(); 279 request->Cancel();
276 return; 280 return;
277 } 281 }
278 result_bytes_->append(buf_->data(), num_bytes); 282 bytes_read_so_far_.append(buf_->data(), num_bytes);
279 ReadBody(request); 283 ReadBody(request);
280 } else { // Error while reading, or EOF 284 } else { // Error while reading, or EOF
281 OnResponseCompleted(request); 285 OnResponseCompleted(request);
282 } 286 }
283 } 287 }
284 288
285 void ProxyScriptFetcherImpl::OnResponseCompleted(URLRequest* request) { 289 void ProxyScriptFetcherImpl::OnResponseCompleted(URLRequest* request) {
286 DCHECK(request == cur_request_.get()); 290 DCHECK(request == cur_request_.get());
287 291
288 // Use |result_code_| as the request's error if we have already set it to 292 // Use |result_code_| as the request's error if we have already set it to
289 // something specific. 293 // something specific.
290 if (result_code_ == OK && !request->status().is_success()) 294 if (result_code_ == OK && !request->status().is_success())
291 result_code_ = request->status().os_error(); 295 result_code_ = request->status().os_error();
292 296
293 FetchCompleted(); 297 FetchCompleted();
294 } 298 }
295 299
296 void ProxyScriptFetcherImpl::ReadBody(URLRequest* request) { 300 void ProxyScriptFetcherImpl::ReadBody(URLRequest* request) {
297 int num_bytes; 301 int num_bytes;
298 if (request->Read(buf_, kBufSize, &num_bytes)) { 302 if (request->Read(buf_, kBufSize, &num_bytes)) {
299 OnReadCompleted(request, num_bytes); 303 OnReadCompleted(request, num_bytes);
300 } else if (!request->status().is_io_pending()) { 304 } else if (!request->status().is_io_pending()) {
301 // Read failed synchronously. 305 // Read failed synchronously.
302 OnResponseCompleted(request); 306 OnResponseCompleted(request);
303 } 307 }
304 } 308 }
305 309
306 void ProxyScriptFetcherImpl::FetchCompleted() { 310 void ProxyScriptFetcherImpl::FetchCompleted() {
307 if (result_code_ == OK) { 311 if (result_code_ == OK) {
308 // The caller expects the response to be encoded as UTF8. 312 // The caller expects the response to be encoded as UTF16.
309 std::string charset; 313 std::string charset;
310 cur_request_->GetCharset(&charset); 314 cur_request_->GetCharset(&charset);
311 ConvertResponseToUTF8(charset, result_bytes_); 315 ConvertResponseToUTF16(charset, bytes_read_so_far_, result_text_);
312 } else { 316 } else {
313 // On error, the caller expects empty string for bytes. 317 // On error, the caller expects empty string for bytes.
314 result_bytes_->clear(); 318 result_text_->clear();
315 } 319 }
316 320
317 int result_code = result_code_; 321 int result_code = result_code_;
318 CompletionCallback* callback = callback_; 322 CompletionCallback* callback = callback_;
319 323
320 ResetCurRequestState(); 324 ResetCurRequestState();
321 325
322 callback->Run(result_code); 326 callback->Run(result_code);
323 } 327 }
324 328
325 void ProxyScriptFetcherImpl::ResetCurRequestState() { 329 void ProxyScriptFetcherImpl::ResetCurRequestState() {
326 cur_request_.reset(); 330 cur_request_.reset();
327 cur_request_id_ = 0; 331 cur_request_id_ = 0;
328 callback_ = NULL; 332 callback_ = NULL;
329 result_code_ = OK; 333 result_code_ = OK;
330 result_bytes_ = NULL; 334 result_text_ = NULL;
331 } 335 }
332 336
333 void ProxyScriptFetcherImpl::OnTimeout(int id) { 337 void ProxyScriptFetcherImpl::OnTimeout(int id) {
334 // Timeout tasks may outlive the URLRequest they reference. Make sure it 338 // Timeout tasks may outlive the URLRequest they reference. Make sure it
335 // is still applicable. 339 // is still applicable.
336 if (cur_request_id_ != id) 340 if (cur_request_id_ != id)
337 return; 341 return;
338 342
339 DCHECK(cur_request_.get()); 343 DCHECK(cur_request_.get());
340 result_code_ = ERR_TIMED_OUT; 344 result_code_ = ERR_TIMED_OUT;
(...skipping 15 matching lines...) Expand all
356 } 360 }
357 361
358 // static 362 // static
359 size_t ProxyScriptFetcher::SetSizeConstraintForUnittest(size_t size_bytes) { 363 size_t ProxyScriptFetcher::SetSizeConstraintForUnittest(size_t size_bytes) {
360 size_t prev = max_response_bytes; 364 size_t prev = max_response_bytes;
361 max_response_bytes = size_bytes; 365 max_response_bytes = size_bytes;
362 return prev; 366 return prev;
363 } 367 }
364 368
365 } // namespace net 369 } // namespace net
OLDNEW
« no previous file with comments | « net/proxy/proxy_script_fetcher.h ('k') | net/proxy/proxy_script_fetcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698