OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/common/net/url_fetcher.h" | 5 #include "chrome/common/net/url_fetcher.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/message_loop_proxy.h" | 12 #include "base/message_loop_proxy.h" |
13 #include "base/stl_util-inl.h" | 13 #include "base/stl_util-inl.h" |
14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
15 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
16 #include "googleurl/src/gurl.h" | 16 #include "googleurl/src/gurl.h" |
17 #include "net/base/load_flags.h" | 17 #include "net/base/load_flags.h" |
18 #include "net/base/io_buffer.h" | 18 #include "net/base/io_buffer.h" |
19 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
20 #include "net/http/http_request_headers.h" | 20 #include "net/http/http_request_headers.h" |
21 #include "net/http/http_response_headers.h" | 21 #include "net/http/http_response_headers.h" |
22 #include "net/url_request/url_request.h" | 22 #include "net/url_request/url_request.h" |
23 #include "net/url_request/url_request_context.h" | 23 #include "net/url_request/url_request_context.h" |
24 #include "net/url_request/url_request_context_getter.h" | 24 #include "net/url_request/url_request_context_getter.h" |
25 #include "net/url_request/url_request_throttler_manager.h" | 25 #include "net/url_request/url_request_throttler_manager.h" |
26 | 26 |
27 static const int kBufferSize = 4096; | 27 static const int kBufferSize = 4096; |
28 | 28 |
29 // Hold the body of a response to a URL fetch in a std::string. | |
30 class StringResponseBodyContainer | |
31 : public URLFetcher::ResponseBodyContainerInterface { | |
32 public: | |
33 StringResponseBodyContainer() {} | |
34 | |
35 virtual void Append(char* data, int data_length) { | |
darin (slow to review)
2011/04/28 03:25:17
if the goal is to have an alternative implementati
Sam Kerner (Chrome)
2011/04/28 04:24:58
My plan was to have each call to Append() send a m
| |
36 data_.append(data, data_length); | |
37 } | |
38 | |
39 virtual bool GetAsString(std::string* out_body) const { | |
40 *out_body = data_; | |
41 return true; | |
42 } | |
43 | |
44 private: | |
45 std::string data_; | |
46 }; | |
47 | |
48 // Default implementation of OnURLFetchCompleteNew() takes the response | |
49 // body, makes it into a string, and calls the old callback. | |
50 void URLFetcher::Delegate::OnURLFetchCompleteNew( | |
51 const URLFetcher* source, | |
52 const GURL& url, | |
53 const net::URLRequestStatus& status, | |
54 int response_code, | |
55 const ResponseCookies& cookies, | |
56 const ResponseBodyContainerInterface& response_body) { | |
57 | |
58 std::string response_data; | |
59 | |
60 // If the response container doesn't support getting the response as | |
61 // a string, then it is not the default string container. The delegate that | |
62 // passed in its wn container should have overriden this method and | |
63 // dealt with the container itself. | |
64 CHECK(response_body.GetAsString(&response_data)); | |
65 | |
66 // To avoid changing existing code, call the old callback with a string | |
67 // holding the response. | |
68 OnURLFetchComplete( | |
69 source, url, status, response_code, cookies, response_data); | |
70 } | |
71 | |
72 URLFetcher::ResponseBodyContainerInterface* | |
73 URLFetcher::Delegate::CreateResponseBodyContainer() { | |
74 // If subclass does not override, use a string. | |
75 return new StringResponseBodyContainer; | |
76 } | |
77 | |
29 class URLFetcher::Core | 78 class URLFetcher::Core |
30 : public base::RefCountedThreadSafe<URLFetcher::Core>, | 79 : public base::RefCountedThreadSafe<URLFetcher::Core>, |
31 public net::URLRequest::Delegate { | 80 public net::URLRequest::Delegate { |
32 public: | 81 public: |
33 // For POST requests, set |content_type| to the MIME type of the content | 82 // For POST requests, set |content_type| to the MIME type of the content |
34 // and set |content| to the data to upload. |flags| are flags to apply to | 83 // and set |content| to the data to upload. |flags| are flags to apply to |
35 // the load operation--these should be one or more of the LOAD_* flags | 84 // the load operation--these should be one or more of the LOAD_* flags |
36 // defined in net/base/load_flags.h. | 85 // defined in net/base/load_flags.h. |
37 Core(URLFetcher* fetcher, | 86 Core(URLFetcher* fetcher, |
38 const GURL& original_url, | 87 const GURL& original_url, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
117 URLFetcher::Delegate* delegate_; // Object to notify on completion | 166 URLFetcher::Delegate* delegate_; // Object to notify on completion |
118 scoped_refptr<base::MessageLoopProxy> delegate_loop_proxy_; | 167 scoped_refptr<base::MessageLoopProxy> delegate_loop_proxy_; |
119 // Message loop proxy of the creating | 168 // Message loop proxy of the creating |
120 // thread. | 169 // thread. |
121 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | 170 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; |
122 // The message loop proxy for the thread | 171 // The message loop proxy for the thread |
123 // on which the request IO happens. | 172 // on which the request IO happens. |
124 scoped_ptr<net::URLRequest> request_; // The actual request this wraps | 173 scoped_ptr<net::URLRequest> request_; // The actual request this wraps |
125 int load_flags_; // Flags for the load operation | 174 int load_flags_; // Flags for the load operation |
126 int response_code_; // HTTP status code for the request | 175 int response_code_; // HTTP status code for the request |
127 std::string data_; // Results of the request | 176 scoped_ptr<ResponseBodyContainerInterface> response_body_; |
177 // Results of the request | |
128 scoped_refptr<net::IOBuffer> buffer_; | 178 scoped_refptr<net::IOBuffer> buffer_; |
129 // Read buffer | 179 // Read buffer |
130 scoped_refptr<net::URLRequestContextGetter> request_context_getter_; | 180 scoped_refptr<net::URLRequestContextGetter> request_context_getter_; |
131 // Cookie/cache info for the request | 181 // Cookie/cache info for the request |
132 ResponseCookies cookies_; // Response cookies | 182 ResponseCookies cookies_; // Response cookies |
133 net::HttpRequestHeaders extra_request_headers_; | 183 net::HttpRequestHeaders extra_request_headers_; |
134 scoped_refptr<net::HttpResponseHeaders> response_headers_; | 184 scoped_refptr<net::HttpResponseHeaders> response_headers_; |
135 | 185 |
136 std::string upload_content_; // HTTP POST payload | 186 std::string upload_content_; // HTTP POST payload |
137 std::string upload_content_type_; // MIME type of POST payload | 187 std::string upload_content_type_; // MIME type of POST payload |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
317 DCHECK(request == request_); | 367 DCHECK(request == request_); |
318 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 368 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
319 | 369 |
320 url_ = request->url(); | 370 url_ = request->url(); |
321 url_throttler_entry_ = | 371 url_throttler_entry_ = |
322 net::URLRequestThrottlerManager::GetInstance()->RegisterRequestUrl(url_); | 372 net::URLRequestThrottlerManager::GetInstance()->RegisterRequestUrl(url_); |
323 | 373 |
324 do { | 374 do { |
325 if (!request_->status().is_success() || bytes_read <= 0) | 375 if (!request_->status().is_success() || bytes_read <= 0) |
326 break; | 376 break; |
327 data_.append(buffer_->data(), bytes_read); | 377 response_body_->Append(buffer_->data(), bytes_read); |
328 } while (request_->Read(buffer_, kBufferSize, &bytes_read)); | 378 } while (request_->Read(buffer_, kBufferSize, &bytes_read)); |
329 | 379 |
330 if (request_->status().is_success()) | 380 if (request_->status().is_success()) |
331 request_->GetResponseCookies(&cookies_); | 381 request_->GetResponseCookies(&cookies_); |
332 | 382 |
333 // See comments re: HEAD requests in OnResponseStarted(). | 383 // See comments re: HEAD requests in OnResponseStarted(). |
334 if (!request_->status().is_io_pending() || (request_type_ == HEAD)) { | 384 if (!request_->status().is_io_pending() || (request_type_ == HEAD)) { |
335 backoff_release_time_ = GetBackoffReleaseTime(); | 385 backoff_release_time_ = GetBackoffReleaseTime(); |
336 | 386 |
337 bool posted = delegate_loop_proxy_->PostTask( | 387 bool posted = delegate_loop_proxy_->PostTask( |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
392 break; | 442 break; |
393 | 443 |
394 default: | 444 default: |
395 NOTREACHED(); | 445 NOTREACHED(); |
396 } | 446 } |
397 | 447 |
398 if (!extra_request_headers_.IsEmpty()) | 448 if (!extra_request_headers_.IsEmpty()) |
399 request_->SetExtraRequestHeaders(extra_request_headers_); | 449 request_->SetExtraRequestHeaders(extra_request_headers_); |
400 | 450 |
401 // There might be data left over from a previous request attempt. | 451 // There might be data left over from a previous request attempt. |
402 data_.clear(); | 452 response_body_.reset(delegate_->CreateResponseBodyContainer()); |
403 | 453 |
404 request_->Start(); | 454 request_->Start(); |
405 } | 455 } |
406 | 456 |
407 void URLFetcher::Core::StartURLRequestWhenAppropriate() { | 457 void URLFetcher::Core::StartURLRequestWhenAppropriate() { |
408 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 458 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
409 | 459 |
410 if (was_cancelled_) | 460 if (was_cancelled_) |
411 return; | 461 return; |
412 | 462 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
458 fetcher_->backoff_delay_ = backoff_release_time_ - base::TimeTicks::Now(); | 508 fetcher_->backoff_delay_ = backoff_release_time_ - base::TimeTicks::Now(); |
459 if (fetcher_->backoff_delay_ < base::TimeDelta()) | 509 if (fetcher_->backoff_delay_ < base::TimeDelta()) |
460 fetcher_->backoff_delay_ = base::TimeDelta(); | 510 fetcher_->backoff_delay_ = base::TimeDelta(); |
461 | 511 |
462 if (fetcher_->automatically_retry_on_5xx_ && | 512 if (fetcher_->automatically_retry_on_5xx_ && |
463 num_retries_ <= fetcher_->max_retries()) { | 513 num_retries_ <= fetcher_->max_retries()) { |
464 io_message_loop_proxy_->PostTask( | 514 io_message_loop_proxy_->PostTask( |
465 FROM_HERE, | 515 FROM_HERE, |
466 NewRunnableMethod(this, &Core::StartURLRequestWhenAppropriate)); | 516 NewRunnableMethod(this, &Core::StartURLRequestWhenAppropriate)); |
467 } else { | 517 } else { |
468 delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_, | 518 delegate_->OnURLFetchCompleteNew(fetcher_, url_, status, response_code_, |
469 cookies_, data_); | 519 cookies_, *response_body_); |
470 } | 520 } |
471 } | 521 } |
472 } else { | 522 } else { |
473 if (delegate_) { | 523 if (delegate_) { |
474 fetcher_->backoff_delay_ = base::TimeDelta(); | 524 fetcher_->backoff_delay_ = base::TimeDelta(); |
475 delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_, | 525 delegate_->OnURLFetchCompleteNew(fetcher_, url_, status, response_code_, |
476 cookies_, data_); | 526 cookies_, *response_body_); |
477 } | 527 } |
478 } | 528 } |
479 } | 529 } |
480 | 530 |
481 void URLFetcher::Core::NotifyMalformedContent() { | 531 void URLFetcher::Core::NotifyMalformedContent() { |
482 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 532 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
483 if (url_throttler_entry_ != NULL) | 533 if (url_throttler_entry_ != NULL) |
484 url_throttler_entry_->ReceivedContentWasMalformed(); | 534 url_throttler_entry_->ReceivedContentWasMalformed(); |
485 } | 535 } |
486 | 536 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
581 } | 631 } |
582 | 632 |
583 // static | 633 // static |
584 int URLFetcher::GetNumFetcherCores() { | 634 int URLFetcher::GetNumFetcherCores() { |
585 return Core::g_registry.Get().size(); | 635 return Core::g_registry.Get().size(); |
586 } | 636 } |
587 | 637 |
588 URLFetcher::Delegate* URLFetcher::delegate() const { | 638 URLFetcher::Delegate* URLFetcher::delegate() const { |
589 return core_->delegate(); | 639 return core_->delegate(); |
590 } | 640 } |
OLD | NEW |