url_fetcher_core.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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/logging.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/single_thread_task_runner.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/thread_task_runner_handle.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_bytes_element_reader.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_data_stream.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_file_element_reader.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_fetcher_response_writer.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_throttler_manager.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBufferSize = 4096; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kUploadProgressTimerInterval = 100; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_interception_enabled = false; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool g_ignore_certificate_requests = false; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLFetcherCore::Registry --------------------------------------------------- 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLFetcherCore::Registry::Registry() {} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLFetcherCore::Registry::~Registry() {} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::Registry::AddURLFetcherCore(URLFetcherCore* core) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!ContainsKey(fetchers_, core)); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetchers_.insert(core); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::Registry::RemoveURLFetcherCore(URLFetcherCore* core) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ContainsKey(fetchers_, core)); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetchers_.erase(core); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::Registry::CancelAll() { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!fetchers_.empty()) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*fetchers_.begin())->CancelURLRequest(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLFetcherCore ------------------------------------------------------------- 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<URLFetcherCore::Registry> 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLFetcherCore::g_registry = LAZY_INSTANCE_INITIALIZER; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLFetcherCore::URLFetcherCore(URLFetcher* fetcher, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& original_url, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLFetcher::RequestType request_type, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLFetcherDelegate* d) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : fetcher_(fetcher), 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_url_(original_url), 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_type_(request_type), 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_(d), 727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) delegate_task_runner_(base::ThreadTaskRunnerHandle::Get()), 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) load_flags_(LOAD_NORMAL), 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_code_(URLFetcher::RESPONSE_CODE_INVALID), 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_(new IOBuffer(kBufferSize)), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_request_data_key_(NULL), 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_fetched_via_proxy_(false), 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_content_set_(false), 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) upload_range_offset_(0), 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) upload_range_length_(0), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_chunked_upload_(false), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_cancelled_(false), 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_writer_(NULL), 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_destination_(STRING), 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stop_on_redirect_(false), 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stopped_on_redirect_(false), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) automatically_retry_on_5xx_(true), 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_retries_on_5xx_(0), 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_retries_on_5xx_(0), 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_retries_on_network_changes_(0), 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_retries_on_network_changes_(0), 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_upload_bytes_(-1), 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_response_bytes_(0), 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_response_bytes_(-1) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(original_url_.is_valid()); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::Start() { 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(delegate_task_runner_.get()); 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(request_context_getter_.get()) << "We need an URLRequestContext!"; 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (network_task_runner_.get()) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(network_task_runner_, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_context_getter_->GetNetworkTaskRunner()); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) network_task_runner_ = request_context_getter_->GetNetworkTaskRunner(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_.get()) << "We need an IO task runner"; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) network_task_runner_->PostTask( 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&URLFetcherCore::StartOnIOThread, this)); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::Stop() { 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (delegate_task_runner_.get()) // May be NULL in tests. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_ = NULL; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher_ = NULL; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!network_task_runner_.get()) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (network_task_runner_->RunsTasksOnCurrentThread()) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelURLRequest(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) network_task_runner_->PostTask( 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&URLFetcherCore::CancelURLRequest, this)); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetUploadData(const std::string& upload_content_type, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& upload_content) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_chunked_upload_); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!upload_content_set_); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(upload_content_.empty()); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(upload_file_path_.empty()); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(upload_content_type_.empty()); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Empty |upload_content_type| is allowed iff the |upload_content| is empty. 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(upload_content.empty() || !upload_content_type.empty()); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) upload_content_type_ = upload_content_type; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) upload_content_ = upload_content; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_content_set_ = true; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLFetcherCore::SetUploadFilePath( 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& upload_content_type, 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& file_path, 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64 range_offset, 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64 range_length, 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::TaskRunner> file_task_runner) { 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!is_chunked_upload_); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!upload_content_set_); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(upload_content_.empty()); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(upload_file_path_.empty()); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(upload_range_offset_, 0ULL); 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(upload_range_length_, 0ULL); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(upload_content_type_.empty()); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!upload_content_type.empty()); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_content_type_ = upload_content_type; 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_file_path_ = file_path; 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) upload_range_offset_ = range_offset; 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) upload_range_length_ = range_length; 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_file_task_runner_ = file_task_runner; 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_content_set_ = true; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetChunkedUpload(const std::string& content_type) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_chunked_upload_ || 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (upload_content_type_.empty() && 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) upload_content_.empty())); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Empty |content_type| is not allowed here, because it is impossible 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to ensure non-empty upload content as it is not yet supplied. 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!content_type.empty()); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) upload_content_type_ = content_type; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) upload_content_.clear(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_chunked_upload_ = true; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::AppendChunkToUpload(const std::string& content, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_last_chunk) { 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(delegate_task_runner_.get()); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_.get()); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) network_task_runner_->PostTask( 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLFetcherCore::CompleteAddingUploadDataChunk, this, content, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_last_chunk)); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetLoadFlags(int load_flags) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) load_flags_ = load_flags; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLFetcherCore::GetLoadFlags() const { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return load_flags_; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetReferrer(const std::string& referrer) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) referrer_ = referrer; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetExtraRequestHeaders( 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extra_request_headers) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra_request_headers_.Clear(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra_request_headers_.AddHeadersFromString(extra_request_headers); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::AddExtraRequestHeader(const std::string& header_line) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra_request_headers_.AddHeaderFromString(header_line); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::GetExtraRequestHeaders( 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestHeaders* headers) const { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->CopyFrom(extra_request_headers_); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetRequestContext( 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestContextGetter* request_context_getter) { 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!request_context_getter_.get()); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_context_getter); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_context_getter_ = request_context_getter; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetFirstPartyForCookies( 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& first_party_for_cookies) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(first_party_for_cookies_.is_empty()); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_party_for_cookies_ = first_party_for_cookies; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetURLRequestUserData( 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* key, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const URLFetcher::CreateDataCallback& create_data_callback) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(key); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!create_data_callback.is_null()); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_request_data_key_ = key; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_request_create_data_callback_ = create_data_callback; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetStopOnRedirect(bool stop_on_redirect) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stop_on_redirect_ = stop_on_redirect; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetAutomaticallyRetryOn5xx(bool retry) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) automatically_retry_on_5xx_ = retry; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLFetcherCore::SetMaxRetriesOn5xx(int max_retries) { 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_retries_on_5xx_ = max_retries; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int URLFetcherCore::GetMaxRetriesOn5xx() const { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return max_retries_on_5xx_; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta URLFetcherCore::GetBackoffDelay() const { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return backoff_delay_; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLFetcherCore::SetAutomaticallyRetryOnNetworkChanges(int max_retries) { 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_retries_on_network_changes_ = max_retries; 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SaveResponseToFileAtPath( 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& file_path, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::TaskRunner> file_task_runner) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_task_runner_ = file_task_runner; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_destination_ = URLFetcherCore::PERMANENT_FILE; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_destination_file_path_ = file_path; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SaveResponseToTemporaryFile( 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::TaskRunner> file_task_runner) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_task_runner_ = file_task_runner; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_destination_ = URLFetcherCore::TEMP_FILE; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseHeaders* URLFetcherCore::GetResponseHeaders() const { 282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return response_headers_.get(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(panayiotis): socket_address_ is written in the IO thread, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if this is accessed in the UI thread, this could result in a race. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same for response_headers_ above and was_fetched_via_proxy_ below. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostPortPair URLFetcherCore::GetSocketAddress() const { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return socket_address_; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLFetcherCore::WasFetchedViaProxy() const { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return was_fetched_via_proxy_; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GURL& URLFetcherCore::GetOriginalURL() const { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return original_url_; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GURL& URLFetcherCore::GetURL() const { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url_; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const URLRequestStatus& URLFetcherCore::GetStatus() const { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return status_; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLFetcherCore::GetResponseCode() const { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return response_code_; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ResponseCookies& URLFetcherCore::GetCookies() const { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cookies_; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool URLFetcherCore::FileErrorOccurred(int* out_error_code) const { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Can't have a file error if no file is being created or written to. 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!file_writer_) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int error_code = file_writer_->error_code(); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (error_code == OK) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out_error_code = error_code; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::ReceivedContentWasMalformed() { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (network_task_runner_.get()) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) network_task_runner_->PostTask( 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&URLFetcherCore::NotifyMalformedContent, this)); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLFetcherCore::GetResponseAsString( 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* out_response_string) const { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_destination_ != URLFetcherCore::STRING) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out_response_string = data_; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_MEMORY_KB("UrlFetcher.StringResponseSize", 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (data_.length() / 1024)); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLFetcherCore::GetResponseAsFilePath(bool take_ownership, 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath* out_response_path) { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool destination_is_file = 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_destination_ == URLFetcherCore::TEMP_FILE || 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_destination_ == URLFetcherCore::PERMANENT_FILE; 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!destination_is_file || !file_writer_) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out_response_path = file_writer_->file_path(); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (take_ownership) { 3617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Intentionally calling a file_writer_ method directly without posting 3627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // the task to network_task_runner_. 363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // 3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // This is for correctly handling the case when file_writer_->DisownFile() 3657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // is soon followed by URLFetcherCore::Stop(). We have to make sure that 3667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // DisownFile takes effect before Stop deletes file_writer_. 3677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // 3687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // This direct call should be thread-safe, since DisownFile itself does no 3697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // file operation. It just flips the state to be referred in destruction. 370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch file_writer_->DisownFile(); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::OnReceivedRedirect(URLRequest* request, 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& new_url, 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* defer_redirect) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request, request_.get()); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stop_on_redirect_) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stopped_on_redirect_ = true; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_ = new_url; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_code_ = request_->GetResponseCode(); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_fetched_via_proxy_ = request_->was_fetched_via_proxy(); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->Cancel(); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnReadCompleted(request, 0); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::OnResponseStarted(URLRequest* request) { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request, request_.get()); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->status().is_success()) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_code_ = request_->GetResponseCode(); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_headers_ = request_->response_headers(); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_address_ = request_->GetSocketAddress(); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_fetched_via_proxy_ = request_->was_fetched_via_proxy(); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_response_bytes_ = request_->GetExpectedContentSize(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadResponse(); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLFetcherCore::OnCertificateRequested( 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLRequest* request, 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SSLCertRequestInfo* cert_request_info) { 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(request, request_.get()); 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (g_ignore_certificate_requests) { 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request->ContinueWithCertificate(NULL); 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request->Cancel(); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::OnReadCompleted(URLRequest* request, 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read) { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request == request_); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!stopped_on_redirect_) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_ = request->url(); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestThrottlerManager* throttler_manager = 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->context()->throttler_manager(); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (throttler_manager) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_throttler_entry_ = throttler_manager->RegisterRequestUrl(url_); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool waiting_on_write = false; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_->status().is_success() || bytes_read <= 0) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_response_bytes_ += bytes_read; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InformDelegateDownloadProgress(); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InformDelegateDownloadDataIfNecessary(bytes_read); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int result = 440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WriteBuffer(new DrainableIOBuffer(buffer_.get(), bytes_read)); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result < 0) { 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Write failed or waiting for write completion. 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result == ERR_IO_PENDING) 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_on_write = true; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } while (request_->Read(buffer_.get(), kBufferSize, &bytes_read)); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const URLRequestStatus status = request_->status(); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status.is_success()) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->GetResponseCookies(&cookies_); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See comments re: HEAD requests in ReadResponse(). 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((!status.is_io_pending() && !waiting_on_write) || 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (request_type_ == URLFetcher::HEAD)) { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status_ = status; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseRequest(); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No more data to write. 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int result = response_writer_->Finish( 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLFetcherCore::DidFinishWriting, this)); 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result != ERR_IO_PENDING) 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DidFinishWriting(result); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::CancelAll() { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_registry.Get().CancelAll(); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLFetcherCore::GetNumFetcherCores() { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_registry.Get().size(); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::SetEnableInterceptionForTests(bool enabled) { 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_interception_enabled = enabled; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLFetcherCore::SetIgnoreCertificateRequests(bool ignored) { 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_ignore_certificate_requests = ignored; 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLFetcherCore::~URLFetcherCore() { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |request_| should be NULL. If not, it's unsafe to delete it here since we 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // may not be on the IO thread. 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!request_.get()); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::StartOnIOThread() { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (response_destination_) { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STRING: 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response_writer_.reset(new URLFetcherStringWriter(&data_)); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PERMANENT_FILE: 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TEMP_FILE: 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(file_task_runner_.get()) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Need to set the file task runner."; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_writer_ = new URLFetcherFileWriter(file_task_runner_); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the file is successfully created, 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLFetcherCore::StartURLRequestWhenAppropriate() will be called. 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (response_destination_ == PERMANENT_FILE) { 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_writer_->set_destination_file_path( 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response_destination_file_path_); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response_writer_.reset(file_writer_); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(response_writer_); 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int result = response_writer_->Initialize( 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLFetcherCore::DidInitializeWriter, this)); 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result != ERR_IO_PENDING) 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DidInitializeWriter(result); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::StartURLRequest() { 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (was_cancelled_) { 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since StartURLRequest() is posted as a *delayed* task, it may 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // run after the URLFetcher was already stopped. 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(request_context_getter_.get()); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!request_.get()); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_registry.Get().AddURLFetcherCore(this); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_response_bytes_ = 0; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_.reset(request_context_getter_->GetURLRequestContext()->CreateRequest( 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_url_, this)); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->set_stack_trace(stack_trace_); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags = request_->load_flags() | load_flags_; 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_interception_enabled) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags = flags | LOAD_DISABLE_INTERCEPT; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_chunked_upload_) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->EnableChunkedUpload(); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->set_load_flags(flags); 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_->SetReferrer(referrer_); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->set_first_party_for_cookies(first_party_for_cookies_.is_empty() ? 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_url_ : first_party_for_cookies_); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_request_data_key_ && !url_request_create_data_callback_.is_null()) { 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->SetUserData(url_request_data_key_, 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_request_create_data_callback_.Run()); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (request_type_) { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case URLFetcher::GET: 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case URLFetcher::POST: 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case URLFetcher::PUT: 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case URLFetcher::PATCH: 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Upload content must be set. 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(is_chunked_upload_ || upload_content_set_); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->set_method( 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_type_ == URLFetcher::POST ? "POST" : 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_type_ == URLFetcher::PUT ? "PUT" : "PATCH"); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra_request_headers_.SetHeader(HttpRequestHeaders::kContentType, 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) upload_content_type_); 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!upload_content_type_.empty()) { 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extra_request_headers_.SetHeader(HttpRequestHeaders::kContentType, 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_content_type_); 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!upload_content_.empty()) { 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader( 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_content_.data(), upload_content_.size())); 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->set_upload(make_scoped_ptr( 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadDataStream::CreateWithReader(reader.Pass(), 0))); 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (!upload_file_path_.empty()) { 581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<UploadElementReader> reader( 582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new UploadFileElementReader(upload_file_task_runner_.get(), 583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) upload_file_path_, 584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) upload_range_offset_, 585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) upload_range_length_, 586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Time())); 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->set_upload(make_scoped_ptr( 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadDataStream::CreateWithReader(reader.Pass(), 0))); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_upload_bytes_ = -1; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kinaba): http://crbug.com/118103. Implement upload callback in the 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // layer and avoid using timer here. 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) upload_progress_checker_timer_.reset( 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new base::RepeatingTimer<URLFetcherCore>()); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) upload_progress_checker_timer_->Start( 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kUploadProgressTimerInterval), 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &URLFetcherCore::InformDelegateUploadProgress); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case URLFetcher::HEAD: 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->set_method("HEAD"); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case URLFetcher::DELETE_REQUEST: 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->set_method("DELETE"); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extra_request_headers_.IsEmpty()) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->SetExtraRequestHeaders(extra_request_headers_); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There might be data left over from a previous request attempt. 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_.clear(); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we are writing the response to a file, the only caller 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of this function should have created it and not written yet. 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!file_writer_ || file_writer_->total_bytes_written() == 0); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->Start(); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLFetcherCore::DidInitializeWriter(int result) { 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result != OK) { 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_task_runner_->PostTask( 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLFetcherCore::InformDelegateFetchIsComplete, this)); 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartURLRequestWhenAppropriate(); 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::StartURLRequestWhenAppropriate() { 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (was_cancelled_) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(request_context_getter_.get()); 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 delay = 0LL; 647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (original_url_throttler_entry_.get() == NULL) { 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestThrottlerManager* manager = 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_context_getter_->GetURLRequestContext()->throttler_manager(); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (manager) { 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_url_throttler_entry_ = 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->RegisterRequestUrl(original_url_); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (original_url_throttler_entry_.get() != NULL) { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay = original_url_throttler_entry_->ReserveSendingTimeForNextRequest( 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBackoffReleaseTime()); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delay == 0) { 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartURLRequest(); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&URLFetcherCore::StartURLRequest, this), 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(delay)); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::CancelURLRequest() { 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_.get()) { 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->Cancel(); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseRequest(); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Release the reference to the request context. There could be multiple 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // references to URLFetcher::Core at this point so it may take a while to 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // delete the object, but we cannot delay the destruction of the request 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // context. 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_context_getter_ = NULL; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_party_for_cookies_ = GURL(); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_request_data_key_ = NULL; 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_request_create_data_callback_.Reset(); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_cancelled_ = true; 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response_writer_.reset(); 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_writer_ = NULL; 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::OnCompletedURLRequest( 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta backoff_delay) { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save the status and backoff_delay so that delegates can read it. 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_) { 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backoff_delay_ = backoff_delay; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InformDelegateFetchIsComplete(); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateFetchIsComplete() { 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnURLFetchComplete(fetcher_); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::NotifyMalformedContent() { 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (url_throttler_entry_.get() != NULL) { 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int status_code = response_code_; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status_code == URLFetcher::RESPONSE_CODE_INVALID) { 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The status code will generally be known by the time clients 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call the |ReceivedContentWasMalformed()| function (which ends up 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // calling the current function) but if it's not, we need to assume 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the response was successful so that the total failure count 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // used to calculate exponential back-off goes up. 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status_code = 200; 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_throttler_entry_->ReceivedContentWasMalformed(status_code); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLFetcherCore::DidFinishWriting(int result) { 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result != OK) { 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_task_runner_->PostTask( 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLFetcherCore::InformDelegateFetchIsComplete, this)); 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the file was successfully closed, then the URL request is complete. 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RetryOrCompleteUrlFetch(); 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::RetryOrCompleteUrlFetch() { 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta backoff_delay; 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks the response from server. 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_code_ >= 500 || 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status_.error() == ERR_TEMPORARILY_THROTTLED) { 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When encountering a server error, we will send the request again 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // after backoff time. 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++num_retries_on_5xx_; 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that backoff_delay may be 0 because (a) the 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequestThrottlerManager and related code does not 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // necessarily back off on the first error, (b) it only backs off 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on some of the 5xx status codes, (c) not all URLRequestContexts 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have a throttler manager. 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks backoff_release_time = GetBackoffReleaseTime(); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backoff_delay = backoff_release_time - base::TimeTicks::Now(); 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (backoff_delay < base::TimeDelta()) 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backoff_delay = base::TimeDelta(); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (automatically_retry_on_5xx_ && 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_retries_on_5xx_ <= max_retries_on_5xx_) { 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartOnIOThread(); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backoff_delay = base::TimeDelta(); 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Retry if the request failed due to network changes. 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status_.error() == ERR_NETWORK_CHANGED && 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_retries_on_network_changes_ < max_retries_on_network_changes_) { 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++num_retries_on_network_changes_; 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Retry soon, after flushing all the current tasks which may include 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // further network change observers. 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) network_task_runner_->PostTask( 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(&URLFetcherCore::StartOnIOThread, this)); 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_context_getter_ = NULL; 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_party_for_cookies_ = GURL(); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_request_data_key_ = NULL; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_request_create_data_callback_.Reset(); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool posted = delegate_task_runner_->PostTask( 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLFetcherCore::OnCompletedURLRequest, this, backoff_delay)); 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the delegate message loop does not exist any more, then the delegate 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be gone too. 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(posted || !delegate_); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::ReleaseRequest() { 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) upload_progress_checker_timer_.reset(); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_.reset(); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_registry.Get().RemoveURLFetcherCore(this); 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeTicks URLFetcherCore::GetBackoffReleaseTime() { 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (original_url_throttler_entry_.get()) { 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks original_url_backoff = 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_url_throttler_entry_->GetExponentialBackoffReleaseTime(); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks destination_url_backoff; 801868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (url_throttler_entry_.get() != NULL && 802868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) original_url_throttler_entry_.get() != url_throttler_entry_.get()) { 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destination_url_backoff = 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_throttler_entry_->GetExponentialBackoffReleaseTime(); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return original_url_backoff > destination_url_backoff ? 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_url_backoff : destination_url_backoff; 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::TimeTicks(); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::CompleteAddingUploadDataChunk( 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& content, bool is_last_chunk) { 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (was_cancelled_) { 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since CompleteAddingUploadDataChunk() is posted as a *delayed* task, it 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // may run after the URLFetcher was already stopped. 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_chunked_upload_); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_.get()); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!content.empty()); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->AppendChunkToUpload(content.data(), 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(content.length()), 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_last_chunk); 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 82990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int URLFetcherCore::WriteBuffer(scoped_refptr<DrainableIOBuffer> data) { 83090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) while (data->BytesRemaining() > 0) { 83190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const int result = response_writer_->Write( 832868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) data.get(), 833868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) data->BytesRemaining(), 83490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&URLFetcherCore::DidWriteBuffer, this, data)); 83590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result < 0) 83690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return result; 83790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data->DidConsume(result); 83890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 83990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return OK; 84090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 84190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 84290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void URLFetcherCore::DidWriteBuffer(scoped_refptr<DrainableIOBuffer> data, 84390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int result) { 84490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result >= 0) { // Continue writing. 84590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data->DidConsume(result); 84690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) result = WriteBuffer(data); 84790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result == ERR_IO_PENDING) 84890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 84990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 85090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 85190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result < 0) { // Handle errors. 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_task_runner_->PostTask( 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLFetcherCore::InformDelegateFetchIsComplete, this)); 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Finished writing buffer_. Read some more. 85890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(0, data->BytesRemaining()); 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadResponse(); 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::ReadResponse() { 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some servers may treat HEAD requests as GET requests. To free up the 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // network connection as soon as possible, signal that the request has 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // completed immediately, without trying to read any data back (all we care 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // about is the response code and headers, which we already have). 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read = 0; 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->status().is_success() && 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (request_type_ != URLFetcher::HEAD)) 870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_->Read(buffer_.get(), kBufferSize, &bytes_read); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnReadCompleted(request_.get(), bytes_read); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateUploadProgress() { 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_.get()) { 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 current = request_->GetUploadProgress().position(); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_upload_bytes_ != current) { 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_upload_bytes_ = current; 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 total = -1; 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_chunked_upload_) { 8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) total = static_cast<int64>(request_->GetUploadProgress().size()); 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Total may be zero if the UploadDataStream::Init has not been called 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // yet. Don't send the upload progress until the size is initialized. 8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!total) 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_task_runner_->PostTask( 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &URLFetcherCore::InformDelegateUploadProgressInDelegateThread, 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, current, total)); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateUploadProgressInDelegateThread( 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 current, int64 total) { 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnURLFetchUploadProgress(fetcher_, current, total); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateDownloadProgress() { 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_task_runner_->PostTask( 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &URLFetcherCore::InformDelegateDownloadProgressInDelegateThread, 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, current_response_bytes_, total_response_bytes_)); 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateDownloadProgressInDelegateThread( 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 current, int64 total) { 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnURLFetchDownloadProgress(fetcher_, current, total); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateDownloadDataIfNecessary(int bytes_read) { 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(network_task_runner_->BelongsToCurrentThread()); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_ && delegate_->ShouldSendDownloadData()) { 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<std::string> download_data( 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new std::string(buffer_->data(), bytes_read)); 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_task_runner_->PostTask( 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &URLFetcherCore::InformDelegateDownloadDataInDelegateThread, 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, base::Passed(&download_data))); 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLFetcherCore::InformDelegateDownloadDataInDelegateThread( 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<std::string> download_data) { 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_) 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnURLFetchDownloadData(fetcher_, download_data.Pass()); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 941