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

Unified Diff: net/url_request/url_fetcher_core.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/url_request/url_fetcher_core.h ('k') | net/url_request/url_fetcher_delegate.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/url_request/url_fetcher_core.cc
diff --git a/net/url_request/url_fetcher_core.cc b/net/url_request/url_fetcher_core.cc
deleted file mode 100644
index 23857ad057427b2f5efc2282090c14ba53ed14c8..0000000000000000000000000000000000000000
--- a/net/url_request/url_fetcher_core.cc
+++ /dev/null
@@ -1,998 +0,0 @@
-// Copyright (c) 2012 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 "net/url_request/url_fetcher_core.h"
-
-#include <stdint.h>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/metrics/histogram.h"
-#include "base/profiler/scoped_tracker.h"
-#include "base/sequenced_task_runner.h"
-#include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
-#include "base/thread_task_runner_handle.h"
-#include "base/tracked_objects.h"
-#include "net/base/elements_upload_data_stream.h"
-#include "net/base/io_buffer.h"
-#include "net/base/load_flags.h"
-#include "net/base/net_errors.h"
-#include "net/base/request_priority.h"
-#include "net/base/upload_bytes_element_reader.h"
-#include "net/base/upload_data_stream.h"
-#include "net/base/upload_file_element_reader.h"
-#include "net/http/http_response_headers.h"
-#include "net/url_request/redirect_info.h"
-#include "net/url_request/url_fetcher_delegate.h"
-#include "net/url_request/url_fetcher_response_writer.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "net/url_request/url_request_throttler_manager.h"
-
-namespace {
-
-const int kBufferSize = 4096;
-const int kUploadProgressTimerInterval = 100;
-bool g_ignore_certificate_requests = false;
-
-void EmptyCompletionCallback(int result) {}
-
-} // namespace
-
-namespace net {
-
-// URLFetcherCore::Registry ---------------------------------------------------
-
-URLFetcherCore::Registry::Registry() {}
-URLFetcherCore::Registry::~Registry() {}
-
-void URLFetcherCore::Registry::AddURLFetcherCore(URLFetcherCore* core) {
- DCHECK(!ContainsKey(fetchers_, core));
- fetchers_.insert(core);
-}
-
-void URLFetcherCore::Registry::RemoveURLFetcherCore(URLFetcherCore* core) {
- DCHECK(ContainsKey(fetchers_, core));
- fetchers_.erase(core);
-}
-
-void URLFetcherCore::Registry::CancelAll() {
- while (!fetchers_.empty())
- (*fetchers_.begin())->CancelURLRequest(ERR_ABORTED);
-}
-
-// URLFetcherCore -------------------------------------------------------------
-
-// static
-base::LazyInstance<URLFetcherCore::Registry>
- URLFetcherCore::g_registry = LAZY_INSTANCE_INITIALIZER;
-
-URLFetcherCore::URLFetcherCore(URLFetcher* fetcher,
- const GURL& original_url,
- URLFetcher::RequestType request_type,
- URLFetcherDelegate* d)
- : fetcher_(fetcher),
- original_url_(original_url),
- request_type_(request_type),
- delegate_(d),
- delegate_task_runner_(base::ThreadTaskRunnerHandle::Get()),
- load_flags_(LOAD_NORMAL),
- response_code_(URLFetcher::RESPONSE_CODE_INVALID),
- buffer_(new IOBuffer(kBufferSize)),
- url_request_data_key_(NULL),
- was_fetched_via_proxy_(false),
- upload_content_set_(false),
- upload_range_offset_(0),
- upload_range_length_(0),
- referrer_policy_(
- URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE),
- is_chunked_upload_(false),
- was_cancelled_(false),
- stop_on_redirect_(false),
- stopped_on_redirect_(false),
- automatically_retry_on_5xx_(true),
- num_retries_on_5xx_(0),
- max_retries_on_5xx_(0),
- num_retries_on_network_changes_(0),
- max_retries_on_network_changes_(0),
- current_upload_bytes_(-1),
- current_response_bytes_(0),
- total_response_bytes_(-1) {
- CHECK(original_url_.is_valid());
-}
-
-void URLFetcherCore::Start() {
- DCHECK(delegate_task_runner_.get());
- DCHECK(request_context_getter_.get()) << "We need an URLRequestContext!";
- if (network_task_runner_.get()) {
- DCHECK_EQ(network_task_runner_,
- request_context_getter_->GetNetworkTaskRunner());
- } else {
- network_task_runner_ = request_context_getter_->GetNetworkTaskRunner();
- }
- DCHECK(network_task_runner_.get()) << "We need an IO task runner";
-
- network_task_runner_->PostTask(
- FROM_HERE, base::Bind(&URLFetcherCore::StartOnIOThread, this));
-}
-
-void URLFetcherCore::Stop() {
- if (delegate_task_runner_.get()) // May be NULL in tests.
- DCHECK(delegate_task_runner_->BelongsToCurrentThread());
-
- delegate_ = NULL;
- fetcher_ = NULL;
- if (!network_task_runner_.get())
- return;
- if (network_task_runner_->RunsTasksOnCurrentThread()) {
- CancelURLRequest(ERR_ABORTED);
- } else {
- network_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&URLFetcherCore::CancelURLRequest, this, ERR_ABORTED));
- }
-}
-
-void URLFetcherCore::SetUploadData(const std::string& upload_content_type,
- const std::string& upload_content) {
- AssertHasNoUploadData();
- DCHECK(!is_chunked_upload_);
- DCHECK(upload_content_type_.empty());
-
- // Empty |upload_content_type| is allowed iff the |upload_content| is empty.
- DCHECK(upload_content.empty() || !upload_content_type.empty());
-
- upload_content_type_ = upload_content_type;
- upload_content_ = upload_content;
- upload_content_set_ = true;
-}
-
-void URLFetcherCore::SetUploadFilePath(
- const std::string& upload_content_type,
- const base::FilePath& file_path,
- uint64 range_offset,
- uint64 range_length,
- scoped_refptr<base::TaskRunner> file_task_runner) {
- AssertHasNoUploadData();
- DCHECK(!is_chunked_upload_);
- DCHECK_EQ(upload_range_offset_, 0ULL);
- DCHECK_EQ(upload_range_length_, 0ULL);
- DCHECK(upload_content_type_.empty());
- DCHECK(!upload_content_type.empty());
-
- upload_content_type_ = upload_content_type;
- upload_file_path_ = file_path;
- upload_range_offset_ = range_offset;
- upload_range_length_ = range_length;
- upload_file_task_runner_ = file_task_runner;
- upload_content_set_ = true;
-}
-
-void URLFetcherCore::SetUploadStreamFactory(
- const std::string& upload_content_type,
- const URLFetcher::CreateUploadStreamCallback& factory) {
- AssertHasNoUploadData();
- DCHECK(!is_chunked_upload_);
- DCHECK(upload_content_type_.empty());
-
- upload_content_type_ = upload_content_type;
- upload_stream_factory_ = factory;
- upload_content_set_ = true;
-}
-
-void URLFetcherCore::SetChunkedUpload(const std::string& content_type) {
- if (!is_chunked_upload_) {
- AssertHasNoUploadData();
- DCHECK(upload_content_type_.empty());
- }
-
- // Empty |content_type| is not allowed here, because it is impossible
- // to ensure non-empty upload content as it is not yet supplied.
- DCHECK(!content_type.empty());
-
- upload_content_type_ = content_type;
- upload_content_.clear();
- is_chunked_upload_ = true;
-}
-
-void URLFetcherCore::AppendChunkToUpload(const std::string& content,
- bool is_last_chunk) {
- DCHECK(delegate_task_runner_.get());
- DCHECK(network_task_runner_.get());
- network_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&URLFetcherCore::CompleteAddingUploadDataChunk, this, content,
- is_last_chunk));
-}
-
-void URLFetcherCore::SetLoadFlags(int load_flags) {
- load_flags_ = load_flags;
-}
-
-int URLFetcherCore::GetLoadFlags() const {
- return load_flags_;
-}
-
-void URLFetcherCore::SetReferrer(const std::string& referrer) {
- referrer_ = referrer;
-}
-
-void URLFetcherCore::SetReferrerPolicy(
- URLRequest::ReferrerPolicy referrer_policy) {
- referrer_policy_ = referrer_policy;
-}
-
-void URLFetcherCore::SetExtraRequestHeaders(
- const std::string& extra_request_headers) {
- extra_request_headers_.Clear();
- extra_request_headers_.AddHeadersFromString(extra_request_headers);
-}
-
-void URLFetcherCore::AddExtraRequestHeader(const std::string& header_line) {
- extra_request_headers_.AddHeaderFromString(header_line);
-}
-
-void URLFetcherCore::SetRequestContext(
- URLRequestContextGetter* request_context_getter) {
- DCHECK(!request_context_getter_.get());
- DCHECK(request_context_getter);
- request_context_getter_ = request_context_getter;
-}
-
-void URLFetcherCore::SetFirstPartyForCookies(
- const GURL& first_party_for_cookies) {
- DCHECK(first_party_for_cookies_.is_empty());
- first_party_for_cookies_ = first_party_for_cookies;
-}
-
-void URLFetcherCore::SetURLRequestUserData(
- const void* key,
- const URLFetcher::CreateDataCallback& create_data_callback) {
- DCHECK(key);
- DCHECK(!create_data_callback.is_null());
- url_request_data_key_ = key;
- url_request_create_data_callback_ = create_data_callback;
-}
-
-void URLFetcherCore::SetStopOnRedirect(bool stop_on_redirect) {
- stop_on_redirect_ = stop_on_redirect;
-}
-
-void URLFetcherCore::SetAutomaticallyRetryOn5xx(bool retry) {
- automatically_retry_on_5xx_ = retry;
-}
-
-void URLFetcherCore::SetMaxRetriesOn5xx(int max_retries) {
- max_retries_on_5xx_ = max_retries;
-}
-
-int URLFetcherCore::GetMaxRetriesOn5xx() const {
- return max_retries_on_5xx_;
-}
-
-base::TimeDelta URLFetcherCore::GetBackoffDelay() const {
- return backoff_delay_;
-}
-
-void URLFetcherCore::SetAutomaticallyRetryOnNetworkChanges(int max_retries) {
- max_retries_on_network_changes_ = max_retries;
-}
-
-void URLFetcherCore::SaveResponseToFileAtPath(
- const base::FilePath& file_path,
- scoped_refptr<base::SequencedTaskRunner> file_task_runner) {
- DCHECK(delegate_task_runner_->BelongsToCurrentThread());
- SaveResponseWithWriter(scoped_ptr<URLFetcherResponseWriter>(
- new URLFetcherFileWriter(file_task_runner, file_path)));
-}
-
-void URLFetcherCore::SaveResponseToTemporaryFile(
- scoped_refptr<base::SequencedTaskRunner> file_task_runner) {
- DCHECK(delegate_task_runner_->BelongsToCurrentThread());
- SaveResponseWithWriter(scoped_ptr<URLFetcherResponseWriter>(
- new URLFetcherFileWriter(file_task_runner, base::FilePath())));
-}
-
-void URLFetcherCore::SaveResponseWithWriter(
- scoped_ptr<URLFetcherResponseWriter> response_writer) {
- DCHECK(delegate_task_runner_->BelongsToCurrentThread());
- response_writer_ = response_writer.Pass();
-}
-
-HttpResponseHeaders* URLFetcherCore::GetResponseHeaders() const {
- return response_headers_.get();
-}
-
-// TODO(panayiotis): socket_address_ is written in the IO thread,
-// if this is accessed in the UI thread, this could result in a race.
-// Same for response_headers_ above and was_fetched_via_proxy_ below.
-HostPortPair URLFetcherCore::GetSocketAddress() const {
- return socket_address_;
-}
-
-bool URLFetcherCore::WasFetchedViaProxy() const {
- return was_fetched_via_proxy_;
-}
-
-const GURL& URLFetcherCore::GetOriginalURL() const {
- return original_url_;
-}
-
-const GURL& URLFetcherCore::GetURL() const {
- return url_;
-}
-
-const URLRequestStatus& URLFetcherCore::GetStatus() const {
- return status_;
-}
-
-int URLFetcherCore::GetResponseCode() const {
- return response_code_;
-}
-
-const ResponseCookies& URLFetcherCore::GetCookies() const {
- return cookies_;
-}
-
-void URLFetcherCore::ReceivedContentWasMalformed() {
- DCHECK(delegate_task_runner_->BelongsToCurrentThread());
- if (network_task_runner_.get()) {
- network_task_runner_->PostTask(
- FROM_HERE, base::Bind(&URLFetcherCore::NotifyMalformedContent, this));
- }
-}
-
-bool URLFetcherCore::GetResponseAsString(
- std::string* out_response_string) const {
- URLFetcherStringWriter* string_writer =
- response_writer_ ? response_writer_->AsStringWriter() : NULL;
- if (!string_writer)
- return false;
-
- *out_response_string = string_writer->data();
- UMA_HISTOGRAM_MEMORY_KB("UrlFetcher.StringResponseSize",
- (string_writer->data().length() / 1024));
- return true;
-}
-
-bool URLFetcherCore::GetResponseAsFilePath(bool take_ownership,
- base::FilePath* out_response_path) {
- DCHECK(delegate_task_runner_->BelongsToCurrentThread());
-
- URLFetcherFileWriter* file_writer =
- response_writer_ ? response_writer_->AsFileWriter() : NULL;
- if (!file_writer)
- return false;
-
- *out_response_path = file_writer->file_path();
-
- if (take_ownership) {
- // Intentionally calling a file_writer_ method directly without posting
- // the task to network_task_runner_.
- //
- // This is for correctly handling the case when file_writer_->DisownFile()
- // is soon followed by URLFetcherCore::Stop(). We have to make sure that
- // DisownFile takes effect before Stop deletes file_writer_.
- //
- // This direct call should be thread-safe, since DisownFile itself does no
- // file operation. It just flips the state to be referred in destruction.
- file_writer->DisownFile();
- }
- return true;
-}
-
-void URLFetcherCore::OnReceivedRedirect(URLRequest* request,
- const RedirectInfo& redirect_info,
- bool* defer_redirect) {
- DCHECK_EQ(request, request_.get());
- DCHECK(network_task_runner_->BelongsToCurrentThread());
- if (stop_on_redirect_) {
- stopped_on_redirect_ = true;
- url_ = redirect_info.new_url;
- response_code_ = request_->GetResponseCode();
- was_fetched_via_proxy_ = request_->was_fetched_via_proxy();
- request->Cancel();
- OnReadCompleted(request, 0);
- }
-}
-
-void URLFetcherCore::OnResponseStarted(URLRequest* request) {
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "423948 URLFetcherCore::OnResponseStarted"));
-
- DCHECK_EQ(request, request_.get());
- DCHECK(network_task_runner_->BelongsToCurrentThread());
- if (request_->status().is_success()) {
- response_code_ = request_->GetResponseCode();
- response_headers_ = request_->response_headers();
- socket_address_ = request_->GetSocketAddress();
- was_fetched_via_proxy_ = request_->was_fetched_via_proxy();
- total_response_bytes_ = request_->GetExpectedContentSize();
- }
-
- ReadResponse();
-}
-
-void URLFetcherCore::OnCertificateRequested(
- URLRequest* request,
- SSLCertRequestInfo* cert_request_info) {
- DCHECK_EQ(request, request_.get());
- DCHECK(network_task_runner_->BelongsToCurrentThread());
-
- if (g_ignore_certificate_requests) {
- request->ContinueWithCertificate(NULL);
- } else {
- request->Cancel();
- }
-}
-
-void URLFetcherCore::OnReadCompleted(URLRequest* request,
- int bytes_read) {
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "423948 URLFetcherCore::OnReadCompleted"));
-
- DCHECK(request == request_);
- DCHECK(network_task_runner_->BelongsToCurrentThread());
-
- if (!stopped_on_redirect_)
- url_ = request->url();
- URLRequestThrottlerManager* throttler_manager =
- request->context()->throttler_manager();
- if (throttler_manager) {
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
- tracked_objects::ScopedTracker tracking_profile1(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "423948 URLFetcherCore::OnReadCompleted1"));
-
- url_throttler_entry_ = throttler_manager->RegisterRequestUrl(url_);
- }
-
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
- tracked_objects::ScopedTracker tracking_profile2(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "423948 URLFetcherCore::OnReadCompleted2"));
-
- do {
- if (!request_->status().is_success() || bytes_read <= 0)
- break;
-
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
- tracked_objects::ScopedTracker tracking_profile3(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "423948 URLFetcherCore::OnReadCompleted3"));
-
- current_response_bytes_ += bytes_read;
- InformDelegateDownloadProgress();
-
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
- tracked_objects::ScopedTracker tracking_profile4(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "423948 URLFetcherCore::OnReadCompleted4"));
-
- const int result =
- WriteBuffer(new DrainableIOBuffer(buffer_.get(), bytes_read));
- if (result < 0) {
- // Write failed or waiting for write completion.
- return;
- }
- } while (request_->Read(buffer_.get(), kBufferSize, &bytes_read));
-
- const URLRequestStatus status = request_->status();
-
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
- tracked_objects::ScopedTracker tracking_profile5(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "423948 URLFetcherCore::OnReadCompleted5"));
-
- if (status.is_success())
- request_->GetResponseCookies(&cookies_);
-
- // See comments re: HEAD requests in ReadResponse().
- if (!status.is_io_pending() || request_type_ == URLFetcher::HEAD) {
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
- tracked_objects::ScopedTracker tracking_profile6(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "423948 URLFetcherCore::OnReadCompleted6"));
-
- status_ = status;
- ReleaseRequest();
-
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
- tracked_objects::ScopedTracker tracking_profile7(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "423948 URLFetcherCore::OnReadCompleted7"));
-
- // No more data to write.
- const int result = response_writer_->Finish(
- base::Bind(&URLFetcherCore::DidFinishWriting, this));
-
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
- tracked_objects::ScopedTracker tracking_profile8(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "423948 URLFetcherCore::OnReadCompleted8"));
-
- if (result != ERR_IO_PENDING)
- DidFinishWriting(result);
- }
-}
-
-void URLFetcherCore::CancelAll() {
- g_registry.Get().CancelAll();
-}
-
-int URLFetcherCore::GetNumFetcherCores() {
- return g_registry.Get().size();
-}
-
-void URLFetcherCore::SetIgnoreCertificateRequests(bool ignored) {
- g_ignore_certificate_requests = ignored;
-}
-
-URLFetcherCore::~URLFetcherCore() {
- // |request_| should be NULL. If not, it's unsafe to delete it here since we
- // may not be on the IO thread.
- DCHECK(!request_.get());
-}
-
-void URLFetcherCore::StartOnIOThread() {
- // TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "456327 URLFetcherCore::StartOnIOThread"));
- DCHECK(network_task_runner_->BelongsToCurrentThread());
-
- if (!response_writer_)
- response_writer_.reset(new URLFetcherStringWriter);
-
- const int result = response_writer_->Initialize(
- base::Bind(&URLFetcherCore::DidInitializeWriter, this));
- if (result != ERR_IO_PENDING)
- DidInitializeWriter(result);
-}
-
-void URLFetcherCore::StartURLRequest() {
- // TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "456327 URLFetcherCore::StartURLRequest"));
- DCHECK(network_task_runner_->BelongsToCurrentThread());
-
- if (was_cancelled_) {
- // Since StartURLRequest() is posted as a *delayed* task, it may
- // run after the URLFetcher was already stopped.
- return;
- }
-
- DCHECK(request_context_getter_.get());
- DCHECK(!request_.get());
-
- g_registry.Get().AddURLFetcherCore(this);
- current_response_bytes_ = 0;
- request_ = request_context_getter_->GetURLRequestContext()->CreateRequest(
- original_url_, DEFAULT_PRIORITY, this, NULL);
- request_->set_stack_trace(stack_trace_);
- int flags = request_->load_flags() | load_flags_;
-
- if (is_chunked_upload_)
- request_->EnableChunkedUpload();
- request_->SetLoadFlags(flags);
- request_->SetReferrer(referrer_);
- request_->set_referrer_policy(referrer_policy_);
- request_->set_first_party_for_cookies(first_party_for_cookies_.is_empty() ?
- original_url_ : first_party_for_cookies_);
- if (url_request_data_key_ && !url_request_create_data_callback_.is_null()) {
- request_->SetUserData(url_request_data_key_,
- url_request_create_data_callback_.Run());
- }
-
- switch (request_type_) {
- case URLFetcher::GET:
- break;
-
- case URLFetcher::POST:
- case URLFetcher::PUT:
- case URLFetcher::PATCH:
- // Upload content must be set.
- DCHECK(is_chunked_upload_ || upload_content_set_);
-
- request_->set_method(
- request_type_ == URLFetcher::POST ? "POST" :
- request_type_ == URLFetcher::PUT ? "PUT" : "PATCH");
- if (!upload_content_type_.empty()) {
- extra_request_headers_.SetHeader(HttpRequestHeaders::kContentType,
- upload_content_type_);
- }
- if (!upload_content_.empty()) {
- scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader(
- upload_content_.data(), upload_content_.size()));
- request_->set_upload(
- ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0));
- } else if (!upload_file_path_.empty()) {
- scoped_ptr<UploadElementReader> reader(
- new UploadFileElementReader(upload_file_task_runner_.get(),
- upload_file_path_,
- upload_range_offset_,
- upload_range_length_,
- base::Time()));
- request_->set_upload(
- ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0));
- } else if (!upload_stream_factory_.is_null()) {
- scoped_ptr<UploadDataStream> stream = upload_stream_factory_.Run();
- DCHECK(stream);
- request_->set_upload(stream.Pass());
- }
-
- current_upload_bytes_ = -1;
- // TODO(kinaba): http://crbug.com/118103. Implement upload callback in the
- // layer and avoid using timer here.
- upload_progress_checker_timer_.reset(
- new base::RepeatingTimer<URLFetcherCore>());
- upload_progress_checker_timer_->Start(
- FROM_HERE,
- base::TimeDelta::FromMilliseconds(kUploadProgressTimerInterval),
- this,
- &URLFetcherCore::InformDelegateUploadProgress);
- break;
-
- case URLFetcher::HEAD:
- request_->set_method("HEAD");
- break;
-
- case URLFetcher::DELETE_REQUEST:
- request_->set_method("DELETE");
- break;
-
- default:
- NOTREACHED();
- }
-
- if (!extra_request_headers_.IsEmpty())
- request_->SetExtraRequestHeaders(extra_request_headers_);
-
- request_->Start();
-}
-
-void URLFetcherCore::DidInitializeWriter(int result) {
- if (result != OK) {
- CancelURLRequest(result);
- delegate_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&URLFetcherCore::InformDelegateFetchIsComplete, this));
- return;
- }
- StartURLRequestWhenAppropriate();
-}
-
-void URLFetcherCore::StartURLRequestWhenAppropriate() {
- DCHECK(network_task_runner_->BelongsToCurrentThread());
-
- if (was_cancelled_)
- return;
-
- DCHECK(request_context_getter_.get());
-
- int64 delay = 0;
- if (!original_url_throttler_entry_.get()) {
- // TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is
- // fixed.
- tracked_objects::ScopedTracker tracking_profile1(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "456327 URLFetcherCore::StartURLRequestWhenAppropriate1"));
- URLRequestThrottlerManager* manager =
- request_context_getter_->GetURLRequestContext()->throttler_manager();
- if (manager) {
- original_url_throttler_entry_ =
- manager->RegisterRequestUrl(original_url_);
- }
- }
- if (original_url_throttler_entry_.get()) {
- // TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is
- // fixed.
- tracked_objects::ScopedTracker tracking_profile2(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "456327 URLFetcherCore::StartURLRequestWhenAppropriate2"));
- delay = original_url_throttler_entry_->ReserveSendingTimeForNextRequest(
- GetBackoffReleaseTime());
- }
-
- if (delay == 0) {
- StartURLRequest();
- } else {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::Bind(&URLFetcherCore::StartURLRequest, this),
- base::TimeDelta::FromMilliseconds(delay));
- }
-}
-
-void URLFetcherCore::CancelURLRequest(int error) {
- DCHECK(network_task_runner_->BelongsToCurrentThread());
-
- if (request_.get()) {
- request_->CancelWithError(error);
- ReleaseRequest();
- }
-
- // Set the error manually.
- // Normally, calling URLRequest::CancelWithError() results in calling
- // OnReadCompleted() with bytes_read = -1 via an asynchronous task posted by
- // URLRequestJob::NotifyDone(). But, because the request was released
- // immediately after being canceled, the request could not call
- // OnReadCompleted() which overwrites |status_| with the error status.
- status_.set_status(URLRequestStatus::CANCELED);
- status_.set_error(error);
-
- // 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;
- first_party_for_cookies_ = GURL();
- url_request_data_key_ = NULL;
- url_request_create_data_callback_.Reset();
- was_cancelled_ = true;
-}
-
-void URLFetcherCore::OnCompletedURLRequest(
- base::TimeDelta backoff_delay) {
- DCHECK(delegate_task_runner_->BelongsToCurrentThread());
-
- // Save the status and backoff_delay so that delegates can read it.
- if (delegate_) {
- backoff_delay_ = backoff_delay;
- InformDelegateFetchIsComplete();
- }
-}
-
-void URLFetcherCore::InformDelegateFetchIsComplete() {
- DCHECK(delegate_task_runner_->BelongsToCurrentThread());
- if (delegate_)
- delegate_->OnURLFetchComplete(fetcher_);
-}
-
-void URLFetcherCore::NotifyMalformedContent() {
- DCHECK(network_task_runner_->BelongsToCurrentThread());
- if (url_throttler_entry_.get()) {
- int status_code = response_code_;
- if (status_code == URLFetcher::RESPONSE_CODE_INVALID) {
- // The status code will generally be known by the time clients
- // call the |ReceivedContentWasMalformed()| function (which ends up
- // calling the current function) but if it's not, we need to assume
- // the response was successful so that the total failure count
- // used to calculate exponential back-off goes up.
- status_code = 200;
- }
- url_throttler_entry_->ReceivedContentWasMalformed(status_code);
- }
-}
-
-void URLFetcherCore::DidFinishWriting(int result) {
- if (result != OK) {
- CancelURLRequest(result);
- delegate_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&URLFetcherCore::InformDelegateFetchIsComplete, this));
- return;
- }
- // If the file was successfully closed, then the URL request is complete.
- RetryOrCompleteUrlFetch();
-}
-
-void URLFetcherCore::RetryOrCompleteUrlFetch() {
- DCHECK(network_task_runner_->BelongsToCurrentThread());
- base::TimeDelta backoff_delay;
-
- // Checks the response from server.
- if (response_code_ >= 500 ||
- status_.error() == ERR_TEMPORARILY_THROTTLED) {
- // When encountering a server error, we will send the request again
- // after backoff time.
- ++num_retries_on_5xx_;
-
- // Note that backoff_delay may be 0 because (a) the
- // URLRequestThrottlerManager and related code does not
- // necessarily back off on the first error, (b) it only backs off
- // on some of the 5xx status codes, (c) not all URLRequestContexts
- // have a throttler manager.
- base::TimeTicks backoff_release_time = GetBackoffReleaseTime();
- backoff_delay = backoff_release_time - base::TimeTicks::Now();
- if (backoff_delay < base::TimeDelta())
- backoff_delay = base::TimeDelta();
-
- if (automatically_retry_on_5xx_ &&
- num_retries_on_5xx_ <= max_retries_on_5xx_) {
- StartOnIOThread();
- return;
- }
- } else {
- backoff_delay = base::TimeDelta();
- }
-
- // Retry if the request failed due to network changes.
- if (status_.error() == ERR_NETWORK_CHANGED &&
- num_retries_on_network_changes_ < max_retries_on_network_changes_) {
- ++num_retries_on_network_changes_;
-
- // Retry soon, after flushing all the current tasks which may include
- // further network change observers.
- network_task_runner_->PostTask(
- FROM_HERE, base::Bind(&URLFetcherCore::StartOnIOThread, this));
- return;
- }
-
- request_context_getter_ = NULL;
- first_party_for_cookies_ = GURL();
- url_request_data_key_ = NULL;
- url_request_create_data_callback_.Reset();
- bool posted = delegate_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&URLFetcherCore::OnCompletedURLRequest, this, backoff_delay));
-
- // If the delegate message loop does not exist any more, then the delegate
- // should be gone too.
- DCHECK(posted || !delegate_);
-}
-
-void URLFetcherCore::ReleaseRequest() {
- upload_progress_checker_timer_.reset();
- request_.reset();
- g_registry.Get().RemoveURLFetcherCore(this);
-}
-
-base::TimeTicks URLFetcherCore::GetBackoffReleaseTime() {
- DCHECK(network_task_runner_->BelongsToCurrentThread());
-
- if (!original_url_throttler_entry_.get())
- return base::TimeTicks();
-
- base::TimeTicks original_url_backoff =
- original_url_throttler_entry_->GetExponentialBackoffReleaseTime();
- base::TimeTicks destination_url_backoff;
- if (url_throttler_entry_.get() &&
- original_url_throttler_entry_.get() != url_throttler_entry_.get()) {
- destination_url_backoff =
- url_throttler_entry_->GetExponentialBackoffReleaseTime();
- }
-
- return original_url_backoff > destination_url_backoff ?
- original_url_backoff : destination_url_backoff;
-}
-
-void URLFetcherCore::CompleteAddingUploadDataChunk(
- const std::string& content, bool is_last_chunk) {
- if (was_cancelled_) {
- // Since CompleteAddingUploadDataChunk() is posted as a *delayed* task, it
- // may run after the URLFetcher was already stopped.
- return;
- }
- DCHECK(is_chunked_upload_);
- DCHECK(request_.get());
- DCHECK(!content.empty());
- request_->AppendChunkToUpload(content.data(),
- static_cast<int>(content.length()),
- is_last_chunk);
-}
-
-int URLFetcherCore::WriteBuffer(scoped_refptr<DrainableIOBuffer> data) {
- while (data->BytesRemaining() > 0) {
- const int result = response_writer_->Write(
- data.get(),
- data->BytesRemaining(),
- base::Bind(&URLFetcherCore::DidWriteBuffer, this, data));
- if (result < 0) {
- if (result != ERR_IO_PENDING)
- DidWriteBuffer(data, result);
- return result;
- }
- data->DidConsume(result);
- }
- return OK;
-}
-
-void URLFetcherCore::DidWriteBuffer(scoped_refptr<DrainableIOBuffer> data,
- int result) {
- if (result < 0) { // Handle errors.
- CancelURLRequest(result);
- response_writer_->Finish(base::Bind(&EmptyCompletionCallback));
- delegate_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&URLFetcherCore::InformDelegateFetchIsComplete, this));
- return;
- }
-
- // Continue writing.
- data->DidConsume(result);
- if (WriteBuffer(data) < 0)
- return;
-
- // Finished writing buffer_. Read some more, unless the request has been
- // cancelled and deleted.
- DCHECK_EQ(0, data->BytesRemaining());
- if (request_.get())
- ReadResponse();
-}
-
-void URLFetcherCore::ReadResponse() {
- // 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).
- int bytes_read = 0;
- if (request_->status().is_success() &&
- (request_type_ != URLFetcher::HEAD)) {
- if (!request_->Read(buffer_.get(), kBufferSize, &bytes_read))
- bytes_read = -1; // Match OnReadCompleted() interface contract.
- }
- OnReadCompleted(request_.get(), bytes_read);
-}
-
-void URLFetcherCore::InformDelegateUploadProgress() {
- DCHECK(network_task_runner_->BelongsToCurrentThread());
- if (request_.get()) {
- int64 current = request_->GetUploadProgress().position();
- if (current_upload_bytes_ != current) {
- current_upload_bytes_ = current;
- int64 total = -1;
- if (!is_chunked_upload_) {
- total = static_cast<int64>(request_->GetUploadProgress().size());
- // Total may be zero if the UploadDataStream::Init has not been called
- // yet. Don't send the upload progress until the size is initialized.
- if (!total)
- return;
- }
- delegate_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &URLFetcherCore::InformDelegateUploadProgressInDelegateThread,
- this, current, total));
- }
- }
-}
-
-void URLFetcherCore::InformDelegateUploadProgressInDelegateThread(
- int64 current, int64 total) {
- DCHECK(delegate_task_runner_->BelongsToCurrentThread());
- if (delegate_)
- delegate_->OnURLFetchUploadProgress(fetcher_, current, total);
-}
-
-void URLFetcherCore::InformDelegateDownloadProgress() {
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
- tracked_objects::ScopedTracker tracking_profile1(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "423948 URLFetcherCore::InformDelegateDownloadProgress1"));
-
- DCHECK(network_task_runner_->BelongsToCurrentThread());
-
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
- tracked_objects::ScopedTracker tracking_profile2(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "423948 URLFetcherCore::InformDelegateDownloadProgress2"));
-
- delegate_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &URLFetcherCore::InformDelegateDownloadProgressInDelegateThread,
- this, current_response_bytes_, total_response_bytes_));
-}
-
-void URLFetcherCore::InformDelegateDownloadProgressInDelegateThread(
- int64 current, int64 total) {
- DCHECK(delegate_task_runner_->BelongsToCurrentThread());
- if (delegate_)
- delegate_->OnURLFetchDownloadProgress(fetcher_, current, total);
-}
-
-void URLFetcherCore::AssertHasNoUploadData() const {
- DCHECK(!upload_content_set_);
- DCHECK(upload_content_.empty());
- DCHECK(upload_file_path_.empty());
- DCHECK(upload_stream_factory_.is_null());
-}
-
-} // namespace net
« no previous file with comments | « net/url_request/url_fetcher_core.h ('k') | net/url_request/url_fetcher_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698