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 "content/common/net/url_fetcher.h" | 5 #include "content/common/net/url_fetcher.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
11 #include "base/file_path.h" | 11 #include "base/file_path.h" |
12 #include "base/file_util_proxy.h" | 12 #include "base/file_util_proxy.h" |
13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
15 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
16 #include "base/message_loop_proxy.h" | 16 #include "base/message_loop_proxy.h" |
17 #include "base/platform_file.h" | 17 #include "base/platform_file.h" |
18 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
19 #include "base/string_util.h" | 19 #include "base/string_util.h" |
20 #include "base/threading/thread.h" | 20 #include "base/threading/thread.h" |
| 21 #include "content/public/common/url_fetcher_delegate.h" |
21 #include "googleurl/src/gurl.h" | 22 #include "googleurl/src/gurl.h" |
22 #include "net/base/host_port_pair.h" | 23 #include "net/base/host_port_pair.h" |
23 #include "net/base/io_buffer.h" | 24 #include "net/base/io_buffer.h" |
24 #include "net/base/load_flags.h" | 25 #include "net/base/load_flags.h" |
25 #include "net/base/net_errors.h" | 26 #include "net/base/net_errors.h" |
26 #include "net/http/http_request_headers.h" | 27 #include "net/http/http_request_headers.h" |
27 #include "net/http/http_response_headers.h" | 28 #include "net/http/http_response_headers.h" |
28 #include "net/url_request/url_request.h" | 29 #include "net/url_request/url_request.h" |
29 #include "net/url_request/url_request_context.h" | 30 #include "net/url_request/url_request_context.h" |
30 #include "net/url_request/url_request_context_getter.h" | 31 #include "net/url_request/url_request_context_getter.h" |
31 #include "net/url_request/url_request_throttler_manager.h" | 32 #include "net/url_request/url_request_throttler_manager.h" |
32 | 33 |
33 static const int kBufferSize = 4096; | 34 static const int kBufferSize = 4096; |
34 const int URLFetcher::kInvalidHttpResponseCode = -1; | 35 const int URLFetcher::kInvalidHttpResponseCode = -1; |
35 | 36 |
36 class URLFetcher::Core | 37 class URLFetcher::Core |
37 : public base::RefCountedThreadSafe<URLFetcher::Core>, | 38 : public base::RefCountedThreadSafe<URLFetcher::Core>, |
38 public net::URLRequest::Delegate { | 39 public net::URLRequest::Delegate { |
39 public: | 40 public: |
40 // For POST requests, set |content_type| to the MIME type of the content | 41 // For POST requests, set |content_type| to the MIME type of the content |
41 // and set |content| to the data to upload. |flags| are flags to apply to | 42 // and set |content| to the data to upload. |flags| are flags to apply to |
42 // the load operation--these should be one or more of the LOAD_* flags | 43 // the load operation--these should be one or more of the LOAD_* flags |
43 // defined in net/base/load_flags.h. | 44 // defined in net/base/load_flags.h. |
44 Core(URLFetcher* fetcher, | 45 Core(URLFetcher* fetcher, |
45 const GURL& original_url, | 46 const GURL& original_url, |
46 RequestType request_type, | 47 RequestType request_type, |
47 URLFetcher::Delegate* d); | 48 content::URLFetcherDelegate* d); |
48 | 49 |
49 // Starts the load. It's important that this not happen in the constructor | 50 // Starts the load. It's important that this not happen in the constructor |
50 // because it causes the IO thread to begin AddRef()ing and Release()ing | 51 // because it causes the IO thread to begin AddRef()ing and Release()ing |
51 // us. If our caller hasn't had time to fully construct us and take a | 52 // us. If our caller hasn't had time to fully construct us and take a |
52 // reference, the IO thread could interrupt things, run a task, Release() | 53 // reference, the IO thread could interrupt things, run a task, Release() |
53 // us, and destroy us, leaving the caller with an already-destroyed object | 54 // us, and destroy us, leaving the caller with an already-destroyed object |
54 // when construction finishes. | 55 // when construction finishes. |
55 void Start(); | 56 void Start(); |
56 | 57 |
57 // Stops any in-progress load and ensures no callback will happen. It is | 58 // Stops any in-progress load and ensures no callback will happen. It is |
58 // safe to call this multiple times. | 59 // safe to call this multiple times. |
59 void Stop(); | 60 void Stop(); |
60 | 61 |
61 // Reports that the received content was malformed (i.e. failed parsing | 62 // Reports that the received content was malformed (i.e. failed parsing |
62 // or validation). This makes the throttling logic that does exponential | 63 // or validation). This makes the throttling logic that does exponential |
63 // back-off when servers are having problems treat the current request as | 64 // back-off when servers are having problems treat the current request as |
64 // a failure. Your call to this method will be ignored if your request is | 65 // a failure. Your call to this method will be ignored if your request is |
65 // already considered a failure based on the HTTP response code or response | 66 // already considered a failure based on the HTTP response code or response |
66 // headers. | 67 // headers. |
67 void ReceivedContentWasMalformed(); | 68 void ReceivedContentWasMalformed(); |
68 | 69 |
69 // Overridden from net::URLRequest::Delegate: | 70 // Overridden from net::URLRequest::Delegate: |
70 virtual void OnResponseStarted(net::URLRequest* request); | 71 virtual void OnResponseStarted(net::URLRequest* request); |
71 virtual void OnReadCompleted(net::URLRequest* request, int bytes_read); | 72 virtual void OnReadCompleted(net::URLRequest* request, int bytes_read); |
72 | 73 |
73 URLFetcher::Delegate* delegate() const { return delegate_; } | 74 content::URLFetcherDelegate* delegate() const { return delegate_; } |
74 static void CancelAll(); | 75 static void CancelAll(); |
75 | 76 |
76 private: | 77 private: |
77 friend class base::RefCountedThreadSafe<URLFetcher::Core>; | 78 friend class base::RefCountedThreadSafe<URLFetcher::Core>; |
78 | 79 |
79 class Registry { | 80 class Registry { |
80 public: | 81 public: |
81 Registry(); | 82 Registry(); |
82 ~Registry(); | 83 ~Registry(); |
83 | 84 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 void ReadResponse(); | 214 void ReadResponse(); |
214 | 215 |
215 // Drop ownership of any temp file managed by |temp_file_|. | 216 // Drop ownership of any temp file managed by |temp_file_|. |
216 void DisownTempFile(); | 217 void DisownTempFile(); |
217 | 218 |
218 URLFetcher* fetcher_; // Corresponding fetcher object | 219 URLFetcher* fetcher_; // Corresponding fetcher object |
219 GURL original_url_; // The URL we were asked to fetch | 220 GURL original_url_; // The URL we were asked to fetch |
220 GURL url_; // The URL we eventually wound up at | 221 GURL url_; // The URL we eventually wound up at |
221 RequestType request_type_; // What type of request is this? | 222 RequestType request_type_; // What type of request is this? |
222 net::URLRequestStatus status_; // Status of the request | 223 net::URLRequestStatus status_; // Status of the request |
223 URLFetcher::Delegate* delegate_; // Object to notify on completion | 224 content::URLFetcherDelegate* delegate_; // Object to notify on completion |
224 scoped_refptr<base::MessageLoopProxy> delegate_loop_proxy_; | 225 scoped_refptr<base::MessageLoopProxy> delegate_loop_proxy_; |
225 // Message loop proxy of the creating | 226 // Message loop proxy of the creating |
226 // thread. | 227 // thread. |
227 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | 228 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; |
228 // The message loop proxy for the thread | 229 // The message loop proxy for the thread |
229 // on which the request IO happens. | 230 // on which the request IO happens. |
230 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy_; | 231 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy_; |
231 // The message loop proxy for the thread | 232 // The message loop proxy for the thread |
232 // on which file access happens. | 233 // on which file access happens. |
233 scoped_ptr<net::URLRequest> request_; // The actual request this wraps | 234 scoped_ptr<net::URLRequest> request_; // The actual request this wraps |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 file_message_loop_proxy_, temp_file_, | 459 file_message_loop_proxy_, temp_file_, |
459 false, // No need to recurse, as the path is to a file. | 460 false, // No need to recurse, as the path is to a file. |
460 base::FileUtilProxy::StatusCallback()); // No callback: Ignore errors. | 461 base::FileUtilProxy::StatusCallback()); // No callback: Ignore errors. |
461 DisownTempFile(); | 462 DisownTempFile(); |
462 } | 463 } |
463 } | 464 } |
464 | 465 |
465 // static | 466 // static |
466 URLFetcher::Factory* URLFetcher::factory_ = NULL; | 467 URLFetcher::Factory* URLFetcher::factory_ = NULL; |
467 | 468 |
468 void URLFetcher::Delegate::OnURLFetchComplete( | |
469 const URLFetcher* source, | |
470 const GURL& url, | |
471 const net::URLRequestStatus& status, | |
472 int response_code, | |
473 const net::ResponseCookies& cookies, | |
474 const std::string& data) { | |
475 NOTREACHED() << "If you don't implement this, the no-params version " | |
476 << "should also be implemented, in which case this " | |
477 << "method won't be called..."; | |
478 } | |
479 | |
480 // TODO(skerner): This default implementation will be removed, and the | |
481 // method made pure virtual, once all users of URLFetcher are updated | |
482 // to not expect response data as a string argument. Once this is removed, | |
483 // the method URLFetcher::GetResponseStringRef() can be removed as well. | |
484 // crbug.com/83592 tracks this. | |
485 void URLFetcher::Delegate::OnURLFetchComplete(const URLFetcher* source) { | |
486 // A delegate that did not override this method is using the old | |
487 // parameter list to OnURLFetchComplete(). If a user asked to save | |
488 // the response to a file, they must use the new parameter list, | |
489 // in which case we can not get here. | |
490 // To avoid updating all callers, thunk to the old prototype for now. | |
491 OnURLFetchComplete(source, | |
492 source->url(), | |
493 source->status(), | |
494 source->response_code(), | |
495 source->cookies(), | |
496 source->GetResponseStringRef()); | |
497 } | |
498 | |
499 // static | 469 // static |
500 bool URLFetcher::g_interception_enabled = false; | 470 bool URLFetcher::g_interception_enabled = false; |
501 | 471 |
502 URLFetcher::URLFetcher(const GURL& url, | 472 URLFetcher::URLFetcher(const GURL& url, |
503 RequestType request_type, | 473 RequestType request_type, |
504 Delegate* d) | 474 content::URLFetcherDelegate* d) |
505 : ALLOW_THIS_IN_INITIALIZER_LIST( | 475 : ALLOW_THIS_IN_INITIALIZER_LIST( |
506 core_(new Core(this, url, request_type, d))) { | 476 core_(new Core(this, url, request_type, d))) { |
507 } | 477 } |
508 | 478 |
509 URLFetcher::~URLFetcher() { | 479 URLFetcher::~URLFetcher() { |
510 core_->Stop(); | 480 core_->Stop(); |
511 } | 481 } |
512 | 482 |
513 // static | 483 // static |
514 URLFetcher* URLFetcher::Create(int id, const GURL& url, | 484 URLFetcher* URLFetcher::Create(int id, const GURL& url, |
515 RequestType request_type, Delegate* d) { | 485 RequestType request_type, |
| 486 content::URLFetcherDelegate* d) { |
516 return factory_ ? factory_->CreateURLFetcher(id, url, request_type, d) : | 487 return factory_ ? factory_->CreateURLFetcher(id, url, request_type, d) : |
517 new URLFetcher(url, request_type, d); | 488 new URLFetcher(url, request_type, d); |
518 } | 489 } |
519 | 490 |
520 URLFetcher::Core::Core(URLFetcher* fetcher, | 491 URLFetcher::Core::Core(URLFetcher* fetcher, |
521 const GURL& original_url, | 492 const GURL& original_url, |
522 RequestType request_type, | 493 RequestType request_type, |
523 URLFetcher::Delegate* d) | 494 content::URLFetcherDelegate* d) |
524 : fetcher_(fetcher), | 495 : fetcher_(fetcher), |
525 original_url_(original_url), | 496 original_url_(original_url), |
526 request_type_(request_type), | 497 request_type_(request_type), |
527 delegate_(d), | 498 delegate_(d), |
528 delegate_loop_proxy_( | 499 delegate_loop_proxy_( |
529 base::MessageLoopProxy::current()), | 500 base::MessageLoopProxy::current()), |
530 request_(NULL), | 501 request_(NULL), |
531 load_flags_(net::LOAD_NORMAL), | 502 load_flags_(net::LOAD_NORMAL), |
532 response_code_(URLFetcher::kInvalidHttpResponseCode), | 503 response_code_(URLFetcher::kInvalidHttpResponseCode), |
533 buffer_(new net::IOBuffer(kBufferSize)), | 504 buffer_(new net::IOBuffer(kBufferSize)), |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 // Core::StartURLRequestWhenAppropriate() will be called. | 551 // Core::StartURLRequestWhenAppropriate() will be called. |
581 temp_file_writer_->CreateTempFile(); | 552 temp_file_writer_->CreateTempFile(); |
582 break; | 553 break; |
583 | 554 |
584 default: | 555 default: |
585 NOTREACHED(); | 556 NOTREACHED(); |
586 } | 557 } |
587 } | 558 } |
588 | 559 |
589 void URLFetcher::Core::Stop() { | 560 void URLFetcher::Core::Stop() { |
590 DCHECK(delegate_loop_proxy_->BelongsToCurrentThread()); | 561 if (delegate_loop_proxy_) { // May be NULL in tests. |
| 562 DCHECK(delegate_loop_proxy_->BelongsToCurrentThread()); |
| 563 } |
591 delegate_ = NULL; | 564 delegate_ = NULL; |
592 fetcher_ = NULL; | 565 fetcher_ = NULL; |
593 if (io_message_loop_proxy_.get()) { | 566 if (io_message_loop_proxy_.get()) { |
594 io_message_loop_proxy_->PostTask( | 567 io_message_loop_proxy_->PostTask( |
595 FROM_HERE, base::Bind(&Core::CancelURLRequest, this)); | 568 FROM_HERE, base::Bind(&Core::CancelURLRequest, this)); |
596 } | 569 } |
597 } | 570 } |
598 | 571 |
599 void URLFetcher::Core::ReceivedContentWasMalformed() { | 572 void URLFetcher::Core::ReceivedContentWasMalformed() { |
600 DCHECK(delegate_loop_proxy_->BelongsToCurrentThread()); | 573 DCHECK(delegate_loop_proxy_->BelongsToCurrentThread()); |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 } | 1047 } |
1075 | 1048 |
1076 bool URLFetcher::GetResponseAsString(std::string* out_response_string) const { | 1049 bool URLFetcher::GetResponseAsString(std::string* out_response_string) const { |
1077 if (core_->response_destination_ != STRING) | 1050 if (core_->response_destination_ != STRING) |
1078 return false; | 1051 return false; |
1079 | 1052 |
1080 *out_response_string = core_->data_; | 1053 *out_response_string = core_->data_; |
1081 return true; | 1054 return true; |
1082 } | 1055 } |
1083 | 1056 |
1084 const std::string& URLFetcher::GetResponseStringRef() const { | |
1085 CHECK(core_->response_destination_ == STRING); | |
1086 return core_->data_; | |
1087 } | |
1088 | |
1089 void URLFetcher::SetResponseDestinationForTesting( | 1057 void URLFetcher::SetResponseDestinationForTesting( |
1090 ResponseDestinationType value) { | 1058 ResponseDestinationType value) { |
1091 core_->response_destination_ = value; | 1059 core_->response_destination_ = value; |
1092 } | 1060 } |
1093 | 1061 |
1094 URLFetcher::ResponseDestinationType | 1062 URLFetcher::ResponseDestinationType |
1095 URLFetcher::GetResponseDestinationForTesting() const { | 1063 URLFetcher::GetResponseDestinationForTesting() const { |
1096 return core_->response_destination_; | 1064 return core_->response_destination_; |
1097 } | 1065 } |
1098 | 1066 |
(...skipping 16 matching lines...) Expand all Loading... |
1115 // static | 1083 // static |
1116 void URLFetcher::CancelAll() { | 1084 void URLFetcher::CancelAll() { |
1117 Core::CancelAll(); | 1085 Core::CancelAll(); |
1118 } | 1086 } |
1119 | 1087 |
1120 // static | 1088 // static |
1121 int URLFetcher::GetNumFetcherCores() { | 1089 int URLFetcher::GetNumFetcherCores() { |
1122 return Core::g_registry.Get().size(); | 1090 return Core::g_registry.Get().size(); |
1123 } | 1091 } |
1124 | 1092 |
1125 URLFetcher::Delegate* URLFetcher::delegate() const { | 1093 content::URLFetcherDelegate* URLFetcher::delegate() const { |
1126 return core_->delegate(); | 1094 return core_->delegate(); |
1127 } | 1095 } |
OLD | NEW |