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