| 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 |