url_fetcher_core.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher_core.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util_proxy.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/thread_task_runner_handle.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_throttler_manager.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBufferSize = 4096;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kUploadProgressTimerInterval = 100;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_interception_enabled = false;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLFetcherCore::Registry ---------------------------------------------------
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLFetcherCore::Registry::Registry() {}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLFetcherCore::Registry::~Registry() {}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::Registry::AddURLFetcherCore(URLFetcherCore* core) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!ContainsKey(fetchers_, core));
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetchers_.insert(core);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::Registry::RemoveURLFetcherCore(URLFetcherCore* core) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(ContainsKey(fetchers_, core));
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetchers_.erase(core);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::Registry::CancelAll() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!fetchers_.empty())
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*fetchers_.begin())->CancelURLRequest();
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLFetcherCore::FileWriter -------------------------------------------------
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLFetcherCore::FileWriter::FileWriter(
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLFetcherCore* core,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::TaskRunner> file_task_runner)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : core_(core),
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_code_(base::PLATFORM_FILE_OK),
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_task_runner_(file_task_runner),
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_handle_(base::kInvalidPlatformFileValue) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLFetcherCore::FileWriter::~FileWriter() {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloseAndDeleteFile();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::FileWriter::CreateFileAtPath(
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FilePath& file_path) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(core_->network_task_runner_->BelongsToCurrentThread());
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(file_task_runner_.get());
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::FileUtilProxy::CreateOrOpen(
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_task_runner_,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_path,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&URLFetcherCore::FileWriter::DidCreateFile,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 file_path));
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::FileWriter::CreateTempFile() {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(core_->network_task_runner_->BelongsToCurrentThread());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(file_task_runner_.get());
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::FileUtilProxy::CreateTemporary(
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_task_runner_,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,  // No additional file flags.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&URLFetcherCore::FileWriter::DidCreateTempFile,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::FileWriter::WriteBuffer(int num_bytes) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(core_->network_task_runner_->BelongsToCurrentThread());
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start writing to the file by setting the initial state
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of |pending_bytes_| and |buffer_offset_| to indicate that the
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entire buffer has not yet been written.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_bytes_ = num_bytes;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_offset_ = 0;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContinueWrite(base::PLATFORM_FILE_OK, 0);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::FileWriter::ContinueWrite(
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError error_code,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int bytes_written) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(core_->network_task_runner_->BelongsToCurrentThread());
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file_handle_ == base::kInvalidPlatformFileValue) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // While a write was being done on the file thread, a request
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to close or disown the file occured on the IO thread.  At
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // this point a request to close the file is pending on the
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // file thread.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Every code path that resets |core_->request_| should reset
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |core->file_writer_| or cause the file writer to disown the file.  In the
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // former case, this callback can not be called, because the weak pointer to
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |this| will be NULL. In the latter case, the check of |file_handle_| at the
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // start of this method ensures that we can not reach this point.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(core_->request_.get());
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::PLATFORM_FILE_OK != error_code) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_code_ = error_code;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CloseAndDeleteFile();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    core_->delegate_task_runner_->PostTask(
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&URLFetcherCore::InformDelegateFetchIsComplete, core_));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  total_bytes_written_ += bytes_written;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_offset_ += bytes_written;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_bytes_ -= bytes_written;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pending_bytes_ > 0) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::FileUtilProxy::Write(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file_task_runner_, file_handle_,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        total_bytes_written_,  // Append to the end
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (core_->buffer_->data() + buffer_offset_), pending_bytes_,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&URLFetcherCore::FileWriter::ContinueWrite,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_factory_.GetWeakPtr()));
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Finished writing core_->buffer_ to the file. Read some more.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    core_->ReadResponse();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::FileWriter::DisownFile() {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(core_->network_task_runner_->BelongsToCurrentThread());
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disowning is done by the delegate's OnURLFetchComplete method.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The file should be closed by the time that method is called.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(file_handle_ == base::kInvalidPlatformFileValue);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Forget about any file by reseting the path.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_path_.clear();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::FileWriter::CloseFileAndCompleteRequest() {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(core_->network_task_runner_->BelongsToCurrentThread());
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file_handle_ != base::kInvalidPlatformFileValue) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::FileUtilProxy::Close(
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file_task_runner_, file_handle_,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&URLFetcherCore::FileWriter::DidCloseFile,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_factory_.GetWeakPtr()));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_handle_ = base::kInvalidPlatformFileValue;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::FileWriter::CloseAndDeleteFile() {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(core_->network_task_runner_->BelongsToCurrentThread());
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file_handle_ == base::kInvalidPlatformFileValue) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeleteFile(base::PLATFORM_FILE_OK);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Close the file if it is open.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::FileUtilProxy::Close(
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_task_runner_, file_handle_,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&URLFetcherCore::FileWriter::DeleteFile,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_handle_ = base::kInvalidPlatformFileValue;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::FileWriter::DeleteFile(
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError error_code) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(core_->network_task_runner_->BelongsToCurrentThread());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file_path_.empty())
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::FileUtilProxy::Delete(
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_task_runner_, file_path_,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,  // No need to recurse, as the path is to a file.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::FileUtilProxy::StatusCallback());
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisownFile();
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::FileWriter::DidCreateFile(
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FilePath& file_path,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError error_code,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PassPlatformFile file_handle,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool created) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DidCreateFileInternal(file_path, error_code, file_handle);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::FileWriter::DidCreateTempFile(
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError error_code,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PassPlatformFile file_handle,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FilePath& file_path) {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DidCreateFileInternal(file_path, error_code, file_handle);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::FileWriter::DidCreateFileInternal(
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FilePath& file_path,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError error_code,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PassPlatformFile file_handle) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(core_->network_task_runner_->BelongsToCurrentThread());
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::PLATFORM_FILE_OK != error_code) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_code_ = error_code;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CloseAndDeleteFile();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    core_->delegate_task_runner_->PostTask(
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&URLFetcherCore::InformDelegateFetchIsComplete, core_));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_path_ = file_path;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_handle_ = file_handle.ReleaseValue();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  total_bytes_written_ = 0;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  core_->network_task_runner_->PostTask(
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&URLFetcherCore::StartURLRequestWhenAppropriate, core_));
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::FileWriter::DidCloseFile(
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError error_code) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(core_->network_task_runner_->BelongsToCurrentThread());
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::PLATFORM_FILE_OK != error_code) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_code_ = error_code;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CloseAndDeleteFile();
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    core_->delegate_task_runner_->PostTask(
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&URLFetcherCore::InformDelegateFetchIsComplete, core_));
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the file was successfully closed, then the URL request is complete.
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  core_->RetryOrCompleteUrlFetch();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLFetcherCore -------------------------------------------------------------
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<URLFetcherCore::Registry>
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLFetcherCore::g_registry = LAZY_INSTANCE_INITIALIZER;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLFetcherCore::URLFetcherCore(URLFetcher* fetcher,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const GURL& original_url,
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               URLFetcher::RequestType request_type,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               URLFetcherDelegate* d)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : fetcher_(fetcher),
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      original_url_(original_url),
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_type_(request_type),
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(d),
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_task_runner_(
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::ThreadTaskRunnerHandle::Get()),
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_(NULL),
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      load_flags_(LOAD_NORMAL),
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_code_(URLFetcher::RESPONSE_CODE_INVALID),
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buffer_(new IOBuffer(kBufferSize)),
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url_request_data_key_(NULL),
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      was_fetched_via_proxy_(false),
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_chunked_upload_(false),
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_retries_(0),
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      was_cancelled_(false),
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_destination_(STRING),
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      stop_on_redirect_(false),
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      stopped_on_redirect_(false),
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      automatically_retry_on_5xx_(true),
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_retries_(0),
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_upload_bytes_(-1),
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_response_bytes_(0),
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      total_response_bytes_(-1) {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(original_url_.is_valid());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::Start() {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate_task_runner_);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(request_context_getter_) << "We need an URLRequestContext!";
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (network_task_runner_) {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_EQ(network_task_runner_,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              request_context_getter_->GetNetworkTaskRunner());
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    network_task_runner_ = request_context_getter_->GetNetworkTaskRunner();
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_.get()) << "We need an IO task runner";
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  network_task_runner_->PostTask(
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&URLFetcherCore::StartOnIOThread, this));
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::Stop() {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_task_runner_)  // May be NULL in tests.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(delegate_task_runner_->BelongsToCurrentThread());
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = NULL;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher_ = NULL;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!network_task_runner_.get())
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (network_task_runner_->RunsTasksOnCurrentThread()) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelURLRequest();
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    network_task_runner_->PostTask(
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE, base::Bind(&URLFetcherCore::CancelURLRequest, this));
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetUploadData(const std::string& upload_content_type,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const std::string& upload_content) {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_chunked_upload_);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  upload_content_type_ = upload_content_type;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  upload_content_ = upload_content;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetChunkedUpload(const std::string& content_type) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_chunked_upload_ ||
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         (upload_content_type_.empty() &&
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          upload_content_.empty()));
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  upload_content_type_ = content_type;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  upload_content_.clear();
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_chunked_upload_ = true;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::AppendChunkToUpload(const std::string& content,
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         bool is_last_chunk) {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate_task_runner_);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_.get());
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  network_task_runner_->PostTask(
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&URLFetcherCore::CompleteAddingUploadDataChunk, this, content,
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 is_last_chunk));
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetLoadFlags(int load_flags) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_flags_ = load_flags;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLFetcherCore::GetLoadFlags() const {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return load_flags_;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetReferrer(const std::string& referrer) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  referrer_ = referrer;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetExtraRequestHeaders(
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extra_request_headers) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extra_request_headers_.Clear();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extra_request_headers_.AddHeadersFromString(extra_request_headers);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::AddExtraRequestHeader(const std::string& header_line) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extra_request_headers_.AddHeaderFromString(header_line);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::GetExtraRequestHeaders(
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestHeaders* headers) const {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers->CopyFrom(extra_request_headers_);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetRequestContext(
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLRequestContextGetter* request_context_getter) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!request_context_getter_);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(request_context_getter);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_context_getter_ = request_context_getter;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetFirstPartyForCookies(
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& first_party_for_cookies) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(first_party_for_cookies_.is_empty());
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_party_for_cookies_ = first_party_for_cookies;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetURLRequestUserData(
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const void* key,
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const URLFetcher::CreateDataCallback& create_data_callback) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(key);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!create_data_callback.is_null());
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_request_data_key_ = key;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_request_create_data_callback_ = create_data_callback;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetStopOnRedirect(bool stop_on_redirect) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  stop_on_redirect_ = stop_on_redirect;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetAutomaticallyRetryOn5xx(bool retry) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automatically_retry_on_5xx_ = retry;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetMaxRetries(int max_retries) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  max_retries_ = max_retries;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLFetcherCore::GetMaxRetries() const {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return max_retries_;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta URLFetcherCore::GetBackoffDelay() const {
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backoff_delay_;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SaveResponseToFileAtPath(
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FilePath& file_path,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::TaskRunner> file_task_runner) {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate_task_runner_->BelongsToCurrentThread());
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_task_runner_ = file_task_runner;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_destination_ = URLFetcherCore::PERMANENT_FILE;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_destination_file_path_ = file_path;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SaveResponseToTemporaryFile(
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::TaskRunner> file_task_runner) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate_task_runner_->BelongsToCurrentThread());
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_task_runner_ = file_task_runner;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_destination_ = URLFetcherCore::TEMP_FILE;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseHeaders* URLFetcherCore::GetResponseHeaders() const {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return response_headers_;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(panayiotis): socket_address_ is written in the IO thread,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if this is accessed in the UI thread, this could result in a race.
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same for response_headers_ above and was_fetched_via_proxy_ below.
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostPortPair URLFetcherCore::GetSocketAddress() const {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return socket_address_;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLFetcherCore::WasFetchedViaProxy() const {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return was_fetched_via_proxy_;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GURL& URLFetcherCore::GetOriginalURL() const {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return original_url_;
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GURL& URLFetcherCore::GetURL() const {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return url_;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const URLRequestStatus& URLFetcherCore::GetStatus() const {
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return status_;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLFetcherCore::GetResponseCode() const {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return response_code_;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ResponseCookies& URLFetcherCore::GetCookies() const {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cookies_;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLFetcherCore::FileErrorOccurred(
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError* out_error_code) const {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Can't have a file error if no file is being created or written to.
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!file_writer_.get())
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError error_code = file_writer_->error_code();
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error_code == base::PLATFORM_FILE_OK)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *out_error_code = error_code;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::ReceivedContentWasMalformed() {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate_task_runner_->BelongsToCurrentThread());
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (network_task_runner_.get()) {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    network_task_runner_->PostTask(
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE, base::Bind(&URLFetcherCore::NotifyMalformedContent, this));
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLFetcherCore::GetResponseAsString(
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* out_response_string) const {
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_destination_ != URLFetcherCore::STRING)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *out_response_string = data_;
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_MEMORY_KB("UrlFetcher.StringResponseSize",
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          (data_.length() / 1024));
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLFetcherCore::GetResponseAsFilePath(bool take_ownership,
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           FilePath* out_response_path) {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate_task_runner_->BelongsToCurrentThread());
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool destination_is_file =
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_destination_ == URLFetcherCore::TEMP_FILE ||
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_destination_ == URLFetcherCore::PERMANENT_FILE;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!destination_is_file || !file_writer_.get())
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *out_response_path = file_writer_->file_path();
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (take_ownership) {
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    network_task_runner_->PostTask(
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&URLFetcherCore::DisownFile, this));
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::OnReceivedRedirect(URLRequest* request,
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const GURL& new_url,
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        bool* defer_redirect) {
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(request, request_.get());
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (stop_on_redirect_) {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stopped_on_redirect_ = true;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_ = new_url;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_code_ = request_->GetResponseCode();
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    was_fetched_via_proxy_ = request_->was_fetched_via_proxy();
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request->Cancel();
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnReadCompleted(request, 0);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::OnResponseStarted(URLRequest* request) {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(request, request_.get());
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_->status().is_success()) {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_code_ = request_->GetResponseCode();
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_headers_ = request_->response_headers();
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_address_ = request_->GetSocketAddress();
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    was_fetched_via_proxy_ = request_->was_fetched_via_proxy();
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    total_response_bytes_ = request_->GetExpectedContentSize();
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReadResponse();
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::OnReadCompleted(URLRequest* request,
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int bytes_read) {
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(request == request_);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!stopped_on_redirect_)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_ = request->url();
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestThrottlerManager* throttler_manager =
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request->context()->throttler_manager();
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (throttler_manager) {
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_throttler_entry_ = throttler_manager->RegisterRequestUrl(url_);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool waiting_on_write = false;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!request_->status().is_success() || bytes_read <= 0)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_response_bytes_ += bytes_read;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InformDelegateDownloadProgress();
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InformDelegateDownloadDataIfNecessary(bytes_read);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!WriteBuffer(bytes_read)) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If WriteBuffer() returns false, we have a pending write to
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // wait on before reading further.
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      waiting_on_write = true;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (request_->Read(buffer_, kBufferSize, &bytes_read));
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const URLRequestStatus status = request_->status();
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status.is_success())
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->GetResponseCookies(&cookies_);
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See comments re: HEAD requests in ReadResponse().
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((!status.is_io_pending() && !waiting_on_write) ||
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (request_type_ == URLFetcher::HEAD)) {
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = status;
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReleaseRequest();
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If a file is open, close it.
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (file_writer_.get()) {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If the file is open, close it.  After closing the file,
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // RetryOrCompleteUrlFetch() will be called.
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_writer_->CloseFileAndCompleteRequest();
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Otherwise, complete or retry the URL request directly.
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RetryOrCompleteUrlFetch();
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::CancelAll() {
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_registry.Get().CancelAll();
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLFetcherCore::GetNumFetcherCores() {
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_registry.Get().size();
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetEnableInterceptionForTests(bool enabled) {
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_interception_enabled = enabled;
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLFetcherCore::~URLFetcherCore() {
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |request_| should be NULL.  If not, it's unsafe to delete it here since we
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // may not be on the IO thread.
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!request_.get());
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::StartOnIOThread() {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (response_destination_) {
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STRING:
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StartURLRequestWhenAppropriate();
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PERMANENT_FILE:
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TEMP_FILE:
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(file_task_runner_.get())
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << "Need to set the file task runner.";
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_writer_.reset(new FileWriter(this, file_task_runner_));
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If the file is successfully created,
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // URLFetcherCore::StartURLRequestWhenAppropriate() will be called.
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switch (response_destination_) {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case PERMANENT_FILE:
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          file_writer_->CreateFileAtPath(response_destination_file_path_);
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case TEMP_FILE:
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          file_writer_->CreateTempFile();
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default:
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          NOTREACHED();
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::StartURLRequest() {
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (was_cancelled_) {
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Since StartURLRequest() is posted as a *delayed* task, it may
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // run after the URLFetcher was already stopped.
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(request_context_getter_);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!request_.get());
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_registry.Get().AddURLFetcherCore(this);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_response_bytes_ = 0;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_.reset(request_context_getter_->GetURLRequestContext()->CreateRequest(
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      original_url_, this));
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_->set_stack_trace(stack_trace_);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int flags = request_->load_flags() | load_flags_;
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_interception_enabled)
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags = flags | LOAD_DISABLE_INTERCEPT;
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_chunked_upload_)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->EnableChunkedUpload();
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_->set_load_flags(flags);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_->set_referrer(referrer_);
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_->set_first_party_for_cookies(first_party_for_cookies_.is_empty() ?
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      original_url_ : first_party_for_cookies_);
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (url_request_data_key_ && !url_request_create_data_callback_.is_null()) {
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->SetUserData(url_request_data_key_,
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          url_request_create_data_callback_.Run());
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (request_type_) {
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case URLFetcher::GET:
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case URLFetcher::POST:
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case URLFetcher::PUT:
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(!upload_content_type_.empty());
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_->set_method(
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          request_type_ == URLFetcher::POST ? "POST" : "PUT");
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extra_request_headers_.SetHeader(HttpRequestHeaders::kContentType,
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       upload_content_type_);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!upload_content_.empty()) {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_->AppendBytesToUpload(
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            upload_content_.data(), static_cast<int>(upload_content_.length()));
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_upload_bytes_ = -1;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(kinaba): http://crbug.com/118103. Implement upload callback in the
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      //  layer and avoid using timer here.
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      upload_progress_checker_timer_.reset(
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          new base::RepeatingTimer<URLFetcherCore>());
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      upload_progress_checker_timer_->Start(
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE,
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::TimeDelta::FromMilliseconds(kUploadProgressTimerInterval),
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          this,
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &URLFetcherCore::InformDelegateUploadProgress);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case URLFetcher::HEAD:
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_->set_method("HEAD");
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case URLFetcher::DELETE_REQUEST:
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_->set_method("DELETE");
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extra_request_headers_.IsEmpty())
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->SetExtraRequestHeaders(extra_request_headers_);
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There might be data left over from a previous request attempt.
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_.clear();
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we are writing the response to a file, the only caller
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of this function should have created it and not written yet.
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!file_writer_.get() || file_writer_->total_bytes_written() == 0);
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_->Start();
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::StartURLRequestWhenAppropriate() {
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (was_cancelled_)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(request_context_getter_);
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 delay = 0LL;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (original_url_throttler_entry_ == NULL) {
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLRequestThrottlerManager* manager =
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_context_getter_->GetURLRequestContext()->throttler_manager();
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (manager) {
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      original_url_throttler_entry_ =
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          manager->RegisterRequestUrl(original_url_);
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (original_url_throttler_entry_ != NULL) {
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delay = original_url_throttler_entry_->ReserveSendingTimeForNextRequest(
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetBackoffReleaseTime());
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delay == 0) {
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartURLRequest();
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE, base::Bind(&URLFetcherCore::StartURLRequest, this),
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(delay));
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::CancelURLRequest() {
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_.get()) {
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->Cancel();
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReleaseRequest();
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Release the reference to the request context. There could be multiple
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // references to URLFetcher::Core at this point so it may take a while to
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // delete the object, but we cannot delay the destruction of the request
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // context.
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_context_getter_ = NULL;
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_party_for_cookies_ = GURL();
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_request_data_key_ = NULL;
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_request_create_data_callback_.Reset();
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_cancelled_ = true;
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_writer_.reset();
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::OnCompletedURLRequest(
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta backoff_delay) {
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate_task_runner_->BelongsToCurrentThread());
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Save the status and backoff_delay so that delegates can read it.
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_) {
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backoff_delay_ = backoff_delay;
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InformDelegateFetchIsComplete();
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateFetchIsComplete() {
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate_task_runner_->BelongsToCurrentThread());
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnURLFetchComplete(fetcher_);
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::NotifyMalformedContent() {
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (url_throttler_entry_ != NULL) {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int status_code = response_code_;
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status_code == URLFetcher::RESPONSE_CODE_INVALID) {
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The status code will generally be known by the time clients
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // call the |ReceivedContentWasMalformed()| function (which ends up
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // calling the current function) but if it's not, we need to assume
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the response was successful so that the total failure count
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // used to calculate exponential back-off goes up.
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status_code = 200;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_throttler_entry_->ReceivedContentWasMalformed(status_code);
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::RetryOrCompleteUrlFetch() {
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta backoff_delay;
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks the response from server.
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_code_ >= 500 ||
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status_.error() == ERR_TEMPORARILY_THROTTLED) {
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When encountering a server error, we will send the request again
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // after backoff time.
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++num_retries_;
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that backoff_delay may be 0 because (a) the
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // URLRequestThrottlerManager and related code does not
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // necessarily back off on the first error, (b) it only backs off
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on some of the 5xx status codes, (c) not all URLRequestContexts
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // have a throttler manager.
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeTicks backoff_release_time = GetBackoffReleaseTime();
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backoff_delay = backoff_release_time - base::TimeTicks::Now();
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (backoff_delay < base::TimeDelta())
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backoff_delay = base::TimeDelta();
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (automatically_retry_on_5xx_ && num_retries_ <= max_retries_) {
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StartOnIOThread();
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backoff_delay = base::TimeDelta();
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_context_getter_ = NULL;
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_party_for_cookies_ = GURL();
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_request_data_key_ = NULL;
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_request_create_data_callback_.Reset();
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool posted = delegate_task_runner_->PostTask(
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&URLFetcherCore::OnCompletedURLRequest, this, backoff_delay));
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the delegate message loop does not exist any more, then the delegate
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be gone too.
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(posted || !delegate_);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::ReleaseRequest() {
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  upload_progress_checker_timer_.reset();
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_.reset();
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_registry.Get().RemoveURLFetcherCore(this);
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeTicks URLFetcherCore::GetBackoffReleaseTime() {
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (original_url_throttler_entry_) {
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeTicks original_url_backoff =
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        original_url_throttler_entry_->GetExponentialBackoffReleaseTime();
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeTicks destination_url_backoff;
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (url_throttler_entry_ != NULL &&
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        original_url_throttler_entry_ != url_throttler_entry_) {
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      destination_url_backoff =
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          url_throttler_entry_->GetExponentialBackoffReleaseTime();
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return original_url_backoff > destination_url_backoff ?
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        original_url_backoff : destination_url_backoff;
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::TimeTicks();
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::CompleteAddingUploadDataChunk(
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& content, bool is_last_chunk) {
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (was_cancelled_) {
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Since CompleteAddingUploadDataChunk() is posted as a *delayed* task, it
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // may run after the URLFetcher was already stopped.
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_chunked_upload_);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(request_.get());
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!content.empty());
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_->AppendChunkToUpload(content.data(),
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                static_cast<int>(content.length()),
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                is_last_chunk);
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return true if the write was done and reading may continue.
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return false if the write is pending, and the next read will
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be done later.
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLFetcherCore::WriteBuffer(int num_bytes) {
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool write_complete = false;
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (response_destination_) {
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STRING:
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_.append(buffer_->data(), num_bytes);
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      write_complete = true;
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PERMANENT_FILE:
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TEMP_FILE:
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_writer_->WriteBuffer(num_bytes);
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // WriteBuffer() sends a request the file thread.
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The write is not done yet.
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      write_complete = false;
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return write_complete;
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::ReadResponse() {
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Some servers may treat HEAD requests as GET requests.  To free up the
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // network connection as soon as possible, signal that the request has
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // completed immediately, without trying to read any data back (all we care
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // about is the response code and headers, which we already have).
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_read = 0;
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_->status().is_success() &&
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (request_type_ != URLFetcher::HEAD))
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->Read(buffer_, kBufferSize, &bytes_read);
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnReadCompleted(request_.get(), bytes_read);
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::DisownFile() {
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_writer_->DisownFile();
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateUploadProgress() {
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_.get()) {
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 current = request_->GetUploadProgress().position();
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (current_upload_bytes_ != current) {
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_upload_bytes_ = current;
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int64 total = -1;
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!is_chunked_upload_)
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        total = static_cast<int64>(upload_content_.size());
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_task_runner_->PostTask(
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE,
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &URLFetcherCore::InformDelegateUploadProgressInDelegateThread,
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              this, current, total));
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateUploadProgressInDelegateThread(
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 current, int64 total) {
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate_task_runner_->BelongsToCurrentThread());
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnURLFetchUploadProgress(fetcher_, current, total);
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateDownloadProgress() {
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_task_runner_->PostTask(
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &URLFetcherCore::InformDelegateDownloadProgressInDelegateThread,
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          this, current_response_bytes_, total_response_bytes_));
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateDownloadProgressInDelegateThread(
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 current, int64 total) {
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate_task_runner_->BelongsToCurrentThread());
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnURLFetchDownloadProgress(fetcher_, current, total);
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateDownloadDataIfNecessary(int bytes_read) {
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network_task_runner_->BelongsToCurrentThread());
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_ && delegate_->ShouldSendDownloadData()) {
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<std::string> download_data(
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new std::string(buffer_->data(), bytes_read));
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_task_runner_->PostTask(
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &URLFetcherCore::InformDelegateDownloadDataInDelegateThread,
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this, base::Passed(&download_data)));
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateDownloadDataInDelegateThread(
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<std::string> download_data) {
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate_task_runner_->BelongsToCurrentThread());
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnURLFetchDownloadData(fetcher_, download_data.Pass());
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
1014