summaryrefslogtreecommitdiffstats
path: root/chrome/browser/net/url_fetcher.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/net/url_fetcher.cc')
-rw-r--r--chrome/browser/net/url_fetcher.cc361
1 files changed, 0 insertions, 361 deletions
diff --git a/chrome/browser/net/url_fetcher.cc b/chrome/browser/net/url_fetcher.cc
deleted file mode 100644
index 9b4923d..0000000
--- a/chrome/browser/net/url_fetcher.cc
+++ /dev/null
@@ -1,361 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/net/url_fetcher.h"
-
-#include "base/compiler_specific.h"
-#include "base/message_loop_proxy.h"
-#include "base/string_util.h"
-#include "base/thread.h"
-#include "chrome/browser/net/url_fetcher_protect.h"
-#include "chrome/browser/net/url_request_context_getter.h"
-#include "googleurl/src/gurl.h"
-#include "net/base/load_flags.h"
-#include "net/base/io_buffer.h"
-#include "net/http/http_response_headers.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_context.h"
-
-static const int kBufferSize = 4096;
-
-bool URLFetcher::g_interception_enabled = false;
-
-class URLFetcher::Core
- : public base::RefCountedThreadSafe<URLFetcher::Core>,
- public URLRequest::Delegate {
- public:
- // For POST requests, set |content_type| to the MIME type of the content
- // and set |content| to the data to upload. |flags| are flags to apply to
- // the load operation--these should be one or more of the LOAD_* flags
- // defined in url_request.h.
- Core(URLFetcher* fetcher,
- const GURL& original_url,
- RequestType request_type,
- URLFetcher::Delegate* d);
-
- // Starts the load. It's important that this not happen in the constructor
- // because it causes the IO thread to begin AddRef()ing and Release()ing
- // us. If our caller hasn't had time to fully construct us and take a
- // reference, the IO thread could interrupt things, run a task, Release()
- // us, and destroy us, leaving the caller with an already-destroyed object
- // when construction finishes.
- void Start();
-
- // Stops any in-progress load and ensures no callback will happen. It is
- // safe to call this multiple times.
- void Stop();
-
- // URLRequest::Delegate implementations
- virtual void OnResponseStarted(URLRequest* request);
- virtual void OnReadCompleted(URLRequest* request, int bytes_read);
-
- URLFetcher::Delegate* delegate() const { return delegate_; }
-
- private:
- friend class base::RefCountedThreadSafe<URLFetcher::Core>;
-
- ~Core() {}
-
- // Wrapper functions that allow us to ensure actions happen on the right
- // thread.
- void StartURLRequest();
- void CancelURLRequest();
- void OnCompletedURLRequest(const URLRequestStatus& status);
-
- URLFetcher* fetcher_; // Corresponding fetcher object
- GURL original_url_; // The URL we were asked to fetch
- GURL url_; // The URL we eventually wound up at
- RequestType request_type_; // What type of request is this?
- URLFetcher::Delegate* delegate_; // Object to notify on completion
- MessageLoop* delegate_loop_; // Message loop of the creating thread
- scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
- // The message loop proxy for the thread
- // on which the request IO happens.
- URLRequest* request_; // The actual request this wraps
- int load_flags_; // Flags for the load operation
- int response_code_; // HTTP status code for the request
- std::string data_; // Results of the request
- scoped_refptr<net::IOBuffer> buffer_;
- // Read buffer
- scoped_refptr<URLRequestContextGetter> request_context_getter_;
- // Cookie/cache info for the request
- ResponseCookies cookies_; // Response cookies
- std::string extra_request_headers_;// Extra headers for the request, if any
- scoped_refptr<net::HttpResponseHeaders> response_headers_;
-
- std::string upload_content_; // HTTP POST payload
- std::string upload_content_type_; // MIME type of POST payload
-
- // The overload protection entry for this URL. This is used to
- // incrementally back off how rapidly we'll send requests to a particular
- // URL, to avoid placing too much demand on the remote resource. We update
- // this with the status of all requests as they return, and in turn use it
- // to determine how long to wait before making another request.
- URLFetcherProtectEntry* protect_entry_;
- // |num_retries_| indicates how many times we've failed to successfully
- // fetch this URL. Once this value exceeds the maximum number of retries
- // specified by the protection manager, we'll give up.
- int num_retries_;
-
- // True if the URLFetcher has been cancelled.
- bool was_cancelled_;
-
- friend class URLFetcher;
- DISALLOW_COPY_AND_ASSIGN(Core);
-};
-
-// static
-URLFetcher::Factory* URLFetcher::factory_ = NULL;
-
-URLFetcher::URLFetcher(const GURL& url,
- RequestType request_type,
- Delegate* d)
- : ALLOW_THIS_IN_INITIALIZER_LIST(
- core_(new Core(this, url, request_type, d))),
- automatically_retry_on_5xx_(true) {
-}
-
-URLFetcher::~URLFetcher() {
- core_->Stop();
-}
-
-// static
-URLFetcher* URLFetcher::Create(int id, const GURL& url,
- RequestType request_type, Delegate* d) {
- return factory_ ? factory_->CreateURLFetcher(id, url, request_type, d) :
- new URLFetcher(url, request_type, d);
-}
-
-URLFetcher::Core::Core(URLFetcher* fetcher,
- const GURL& original_url,
- RequestType request_type,
- URLFetcher::Delegate* d)
- : fetcher_(fetcher),
- original_url_(original_url),
- request_type_(request_type),
- delegate_(d),
- delegate_loop_(MessageLoop::current()),
- request_(NULL),
- load_flags_(net::LOAD_NORMAL),
- response_code_(-1),
- buffer_(new net::IOBuffer(kBufferSize)),
- protect_entry_(URLFetcherProtectManager::GetInstance()->Register(
- original_url_.host())),
- num_retries_(0),
- was_cancelled_(false) {
-}
-
-void URLFetcher::Core::Start() {
- DCHECK(delegate_loop_);
- CHECK(request_context_getter_) << "We need an URLRequestContext!";
- io_message_loop_proxy_ = request_context_getter_->GetIOMessageLoopProxy();
- CHECK(io_message_loop_proxy_.get()) << "We need an IO message loop proxy";
- io_message_loop_proxy_->PostDelayedTask(
- FROM_HERE,
- NewRunnableMethod(this, &Core::StartURLRequest),
- protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SEND));
-}
-
-void URLFetcher::Core::Stop() {
- DCHECK_EQ(MessageLoop::current(), delegate_loop_);
- delegate_ = NULL;
- fetcher_ = NULL;
- if (io_message_loop_proxy_.get()) {
- io_message_loop_proxy_->PostTask(
- FROM_HERE, NewRunnableMethod(this, &Core::CancelURLRequest));
- }
-}
-
-void URLFetcher::Core::OnResponseStarted(URLRequest* request) {
- DCHECK(request == request_);
- DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
- if (request_->status().is_success()) {
- response_code_ = request_->GetResponseCode();
- response_headers_ = request_->response_headers();
- }
-
- int bytes_read = 0;
- // Some servers may treat HEAD requests as GET requests. To free up the
- // network connection as soon as possible, signal that the request has
- // completed immediately, without trying to read any data back (all we care
- // about is the response code and headers, which we already have).
- if (request_->status().is_success() && (request_type_ != HEAD))
- request_->Read(buffer_, kBufferSize, &bytes_read);
- OnReadCompleted(request_, bytes_read);
-}
-
-void URLFetcher::Core::OnReadCompleted(URLRequest* request, int bytes_read) {
- DCHECK(request == request_);
- DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
-
- url_ = request->url();
-
- do {
- if (!request_->status().is_success() || bytes_read <= 0)
- break;
- data_.append(buffer_->data(), bytes_read);
- } while (request_->Read(buffer_, kBufferSize, &bytes_read));
-
- if (request_->status().is_success())
- request_->GetResponseCookies(&cookies_);
-
- // See comments re: HEAD requests in OnResponseStarted().
- if (!request_->status().is_io_pending() || (request_type_ == HEAD)) {
- delegate_loop_->PostTask(FROM_HERE, NewRunnableMethod(
- this, &Core::OnCompletedURLRequest, request_->status()));
- delete request_;
- request_ = NULL;
- }
-}
-
-void URLFetcher::Core::StartURLRequest() {
- DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
-
- if (was_cancelled_) {
- // Since StartURLRequest() is posted as a *delayed* task, it may
- // run after the URLFetcher was already stopped.
- return;
- }
-
- CHECK(request_context_getter_);
- DCHECK(!request_);
-
- request_ = new URLRequest(original_url_, this);
- int flags = request_->load_flags() | load_flags_;
- if (!g_interception_enabled) {
- flags = flags | net::LOAD_DISABLE_INTERCEPT;
- }
- request_->set_load_flags(flags);
- request_->set_context(request_context_getter_->GetURLRequestContext());
-
- switch (request_type_) {
- case GET:
- break;
-
- case POST:
- DCHECK(!upload_content_.empty());
- DCHECK(!upload_content_type_.empty());
-
- request_->set_method("POST");
- if (!extra_request_headers_.empty())
- extra_request_headers_ += "\r\n";
- StringAppendF(&extra_request_headers_,
- "Content-Type: %s", upload_content_type_.c_str());
- request_->AppendBytesToUpload(upload_content_.data(),
- static_cast<int>(upload_content_.size()));
- break;
-
- case HEAD:
- request_->set_method("HEAD");
- break;
-
- default:
- NOTREACHED();
- }
-
- if (!extra_request_headers_.empty())
- request_->SetExtraRequestHeaders(extra_request_headers_);
-
- request_->Start();
-}
-
-void URLFetcher::Core::CancelURLRequest() {
- DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
-
- if (request_) {
- request_->Cancel();
- delete request_;
- request_ = NULL;
- }
- // Release the reference to the request context. There could be multiple
- // references to URLFetcher::Core at this point so it may take a while to
- // delete the object, but we cannot delay the destruction of the request
- // context.
- request_context_getter_ = NULL;
- was_cancelled_ = true;
-}
-
-void URLFetcher::Core::OnCompletedURLRequest(const URLRequestStatus& status) {
- DCHECK(MessageLoop::current() == delegate_loop_);
-
- // Checks the response from server.
- if (response_code_ >= 500) {
- // When encountering a server error, we will send the request again
- // after backoff time.
- int64 back_off_time =
- protect_entry_->UpdateBackoff(URLFetcherProtectEntry::FAILURE);
- if (delegate_) {
- fetcher_->backoff_delay_ =
- base::TimeDelta::FromMilliseconds(back_off_time);
- }
- ++num_retries_;
- // Restarts the request if we still need to notify the delegate.
- if (delegate_) {
- if (fetcher_->automatically_retry_on_5xx_ &&
- num_retries_ <= protect_entry_->max_retries()) {
- io_message_loop_proxy_->PostDelayedTask(
- FROM_HERE,
- NewRunnableMethod(this, &Core::StartURLRequest), back_off_time);
- } else {
- delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_,
- cookies_, data_);
- }
- }
- } else {
- protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SUCCESS);
- if (delegate_) {
- fetcher_->backoff_delay_ = base::TimeDelta();
- delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_,
- cookies_, data_);
- }
- }
-}
-
-void URLFetcher::set_upload_data(const std::string& upload_content_type,
- const std::string& upload_content) {
- core_->upload_content_type_ = upload_content_type;
- core_->upload_content_ = upload_content;
-}
-
-const std::string& URLFetcher::upload_data() const {
- return core_->upload_content_;
-}
-
-void URLFetcher::set_load_flags(int load_flags) {
- core_->load_flags_ = load_flags;
-}
-
-int URLFetcher::load_flags() const {
- return core_->load_flags_;
-}
-
-void URLFetcher::set_extra_request_headers(
- const std::string& extra_request_headers) {
- core_->extra_request_headers_ = extra_request_headers;
-}
-
-void URLFetcher::set_request_context(
- URLRequestContextGetter* request_context_getter) {
- core_->request_context_getter_ = request_context_getter;
-}
-
-void URLFetcher::set_automatcally_retry_on_5xx(bool retry) {
- automatically_retry_on_5xx_ = retry;
-}
-
-net::HttpResponseHeaders* URLFetcher::response_headers() const {
- return core_->response_headers_;
-}
-
-void URLFetcher::Start() {
- core_->Start();
-}
-
-const GURL& URLFetcher::url() const {
- return core_->url_;
-}
-
-URLFetcher::Delegate* URLFetcher::delegate() const {
- return core_->delegate();
-}