1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/url_request/url_request_http_job.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/base_switches.h" 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/command_line.h" 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/compiler_specific.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_util.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_version_info.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/metrics/field_trial.h" 14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/metrics/histogram.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/rand_util.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/time.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/cert_status_flags.h" 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/cookie_policy.h" 203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/cookie_store.h" 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/filter.h" 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/base/host_port_pair.h" 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/load_flags.h" 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/mime_util.h" 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h" 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_util.h" 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/sdch_manager.h" 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/ssl_cert_request_info.h" 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/base/transport_security_state.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_request_headers.h" 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_response_headers.h" 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_response_info.h" 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_transaction.h" 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_transaction_factory.h" 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_util.h" 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/https_prober.h" 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/url_request/url_request.h" 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/url_request/url_request_context.h" 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/url_request/url_request_error_job.h" 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/url_request/url_request_redirect_job.h" 41201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "net/url_request/url_request_throttler_header_adapter.h" 42201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "net/url_request/url_request_throttler_manager.h" 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kAvailDictionaryHeader[] = "Avail-Dictionary"; 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// When histogramming results related to SDCH and/or an SDCH latency test, the 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// number of packets for which we need to record arrival times so as to 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// calculate interpacket latencies. We currently are only looking at the 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// first few packets, as we're monitoring the impact of the initial TCP 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// congestion window on stalling of transmissions. 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const size_t kSdchPacketHistogramCount = 5; 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace net { 5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace { 5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass HTTPSProberDelegateImpl : public HTTPSProberDelegate { 5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen public: 5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen HTTPSProberDelegateImpl(const std::string& host, int max_age, 6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool include_subdomains, 6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TransportSecurityState* sts) 6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen : host_(host), 6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen max_age_(max_age), 6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen include_subdomains_(include_subdomains), 6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen sts_(sts) { } 6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual void ProbeComplete(bool result) { 6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (result) { 6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::Time current_time(base::Time::Now()); 7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::TimeDelta max_age_delta = base::TimeDelta::FromSeconds(max_age_); 7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TransportSecurityState::DomainState domain_state; 7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen domain_state.expiry = current_time + max_age_delta; 7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen domain_state.mode = 7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TransportSecurityState::DomainState::MODE_OPPORTUNISTIC; 7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen domain_state.include_subdomains = include_subdomains_; 7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen sts_->EnableHost(host_, domain_state); 7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen delete this; 8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen private: 8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const std::string host_; 8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const int max_age_; 8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const bool include_subdomains_; 8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_refptr<TransportSecurityState> sts_; 8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}; 9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} // namespace 9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass URLRequestHttpJob::HttpFilterContext : public FilterContext { 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public: 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen explicit HttpFilterContext(URLRequestHttpJob* job); 96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual ~HttpFilterContext(); 97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // FilterContext implementation. 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual bool GetMimeType(std::string* mime_type) const; 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual bool GetURL(GURL* gurl) const; 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual base::Time GetRequestTime() const; 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual bool IsCachedContent() const; 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual bool IsDownload() const; 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual bool IsSdchResponse() const; 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual int64 GetByteReadCount() const; 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual int GetResponseCode() const; 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void RecordPacketStats(StatisticSelector statistic) const; 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private: 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen URLRequestHttpJob* job_; 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DISALLOW_COPY_AND_ASSIGN(HttpFilterContext); 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenURLRequestHttpJob::HttpFilterContext::HttpFilterContext(URLRequestHttpJob* job) 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : job_(job) { 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(job_); 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenURLRequestHttpJob::HttpFilterContext::~HttpFilterContext() { 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool URLRequestHttpJob::HttpFilterContext::GetMimeType( 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string* mime_type) const { 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return job_->GetMimeType(mime_type); 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool URLRequestHttpJob::HttpFilterContext::GetURL(GURL* gurl) const { 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!job_->request()) 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *gurl = job_->request()->url(); 132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbase::Time URLRequestHttpJob::HttpFilterContext::GetRequestTime() const { 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return job_->request() ? job_->request()->request_time() : base::Time(); 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool URLRequestHttpJob::HttpFilterContext::IsCachedContent() const { 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return job_->is_cached_content_; 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool URLRequestHttpJob::HttpFilterContext::IsDownload() const { 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return (job_->request_info_.load_flags & LOAD_IS_DOWNLOAD) != 0; 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool URLRequestHttpJob::HttpFilterContext::IsSdchResponse() const { 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return job_->sdch_dictionary_advertised_; 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint64 URLRequestHttpJob::HttpFilterContext::GetByteReadCount() const { 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return job_->filter_input_byte_count(); 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint URLRequestHttpJob::HttpFilterContext::GetResponseCode() const { 156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return job_->GetResponseCode(); 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid URLRequestHttpJob::HttpFilterContext::RecordPacketStats( 160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StatisticSelector statistic) const { 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen job_->RecordPacketStats(statistic); 162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// TODO(darin): make sure the port blocking code is not lost 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottURLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& scheme) { 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(scheme == "http" || scheme == "https"); 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int port = request->url().IntPort(); 17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!IsPortAllowedByDefault(port) && !IsPortAllowedByOverride(port)) 17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return new URLRequestErrorJob(request, ERR_UNSAFE_PORT); 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!request->context() || 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !request->context()->http_transaction_factory()) { 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED() << "requires a valid context"; 17721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return new URLRequestErrorJob(request, ERR_INVALID_ARGUMENT); 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TransportSecurityState::DomainState domain_state; 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (scheme == "http" && 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request->context()->transport_security_state() && 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request->context()->transport_security_state()->IsEnabledForHost( 184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &domain_state, 185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request->url().host(), 186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request->context()->IsSNIAvailable())) { 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (domain_state.mode == 18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TransportSecurityState::DomainState::MODE_STRICT) { 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK_EQ(request->url().scheme(), "http"); 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott url_canon::Replacements<char> replacements; 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const char kNewScheme[] = "https"; 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott replacements.SetScheme(kNewScheme, 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott url_parse::Component(0, strlen(kNewScheme))); 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GURL new_location = request->url().ReplaceComponents(replacements); 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new URLRequestRedirectJob(request, new_location); 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(agl): implement opportunistic HTTPS upgrade. 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new URLRequestHttpJob(request); 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottURLRequestHttpJob::URLRequestHttpJob(URLRequest* request) 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : URLRequestJob(request), 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_info_(NULL), 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_cookies_save_index_(0), 20921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen proxy_auth_state_(AUTH_STATE_DONT_NEED_AUTH), 21021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen server_auth_state_(AUTH_STATE_DONT_NEED_AUTH), 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ALLOW_THIS_IN_INITIALIZER_LIST(start_callback_( 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &URLRequestHttpJob::OnStartCompleted)), 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ALLOW_THIS_IN_INITIALIZER_LIST(read_callback_( 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &URLRequestHttpJob::OnReadCompleted)), 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_in_progress_(false), 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott transaction_(NULL), 21721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen throttling_entry_(URLRequestThrottlerManager::GetInstance()-> 218201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RegisterRequestUrl(request->url())), 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sdch_dictionary_advertised_(false), 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sdch_test_activated_(false), 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sdch_test_control_(false), 22221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen is_cached_content_(false), 223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen request_creation_time_(), 224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_timing_enabled_(false), 225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bytes_observed_in_packets_(0), 226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_(), 227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request_time_snapshot_(), 228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen final_packet_time_(), 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen observed_packet_count_(0), 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ALLOW_THIS_IN_INITIALIZER_LIST( 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen filter_context_(new HttpFilterContext(this))), 23221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { 233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ResetTimer(); 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::NotifyHeadersComplete() { 23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(!response_info_); 23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_info_ = transaction_->GetResponseInfo(); 24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Save boolean, as we'll need this info at destruction time, and filters may 24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // also need this info. 24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen is_cached_content_ = response_info_->was_cached; 24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!is_cached_content_) { 24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen URLRequestThrottlerHeaderAdapter response_adapter( 24772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_info_->headers); 248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen throttling_entry_->UpdateWithResponse(request_info_.url.host(), 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &response_adapter); 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ProcessStrictTransportSecurityHeader(); 25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (SdchManager::Global() && 25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SdchManager::Global()->IsInSupportedDomain(request_->url())) { 25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static const std::string name = "Get-Dictionary"; 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string url_text; 25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void* iter = NULL; 25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // TODO(jar): We need to not fetch dictionaries the first time they are 26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // seen, but rather wait until we can justify their usefulness. 26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // For now, we will only fetch the first dictionary, which will at least 26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // require multiple suggestions before we get additional ones for this site. 26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Eventually we should wait until a dictionary is requested several times 26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // before we even download it (so that we don't waste memory or bandwidth). 26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (response_info_->headers->EnumerateHeader(&iter, name, &url_text)) { 26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // request_->url() won't be valid in the destructor, so we use an 26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // alternate copy. 268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_EQ(request_->url(), request_info_.url); 26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Resolve suggested URL relative to request url. 27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sdch_dictionary_url_ = request_info_.url.Resolve(url_text); 27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The HTTP transaction may be restarted several times for the purposes 27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // of sending authorization information. Each time it restarts, we get 27672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // notified of the headers completion so that we can update the cookie store. 27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (transaction_->IsReadyToRestartForAuth()) { 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(!response_info_->auth_challenge.get()); 27972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen RestartTransactionWithAuth(string16(), string16()); 28072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 28172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 28372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen URLRequestJob::NotifyHeadersComplete(); 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid URLRequestHttpJob::NotifyDone(const URLRequestStatus& status) { 287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen RecordCompressionHistograms(); 288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen URLRequestJob::NotifyDone(status); 289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 29172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::DestroyTransaction() { 29272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(transaction_.get()); 29372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 29472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen transaction_.reset(); 29572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_info_ = NULL; 29672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen context_ = NULL; 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::StartTransaction() { 30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // NOTE: This method assumes that request_info_ is already setup properly. 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // If we already have a transaction, then we should restart the transaction 30372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // with auth provided by username_ and password_. 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 30572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int rv; 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 30772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (transaction_.get()) { 30872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = transaction_->RestartWithAuth(username_, password_, &start_callback_); 30972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen username_.clear(); 31072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen password_.clear(); 31172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 31272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(request_->context()); 31372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(request_->context()->http_transaction_factory()); 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 31572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv = request_->context()->http_transaction_factory()->CreateTransaction( 31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &transaction_); 31772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (rv == OK) { 318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!URLRequestThrottlerManager::GetInstance()->enforce_throttling() || 319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !throttling_entry_->IsDuringExponentialBackoff()) { 320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rv = transaction_->Start( 321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &request_info_, &start_callback_, request_->net_log()); 322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Special error code for the exponential back-off module. 324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rv = ERR_TEMPORARILY_THROTTLED; 325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 32672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Make sure the context is alive for the duration of the 32772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // transaction. 32872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen context_ = request_->context(); 32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (rv == ERR_IO_PENDING) 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The transaction started synchronously, but we need to notify the 33672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // URLRequest delegate via the message loop. 33772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen MessageLoop::current()->PostTask( 33872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen FROM_HERE, 33972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen method_factory_.NewRunnableMethod( 34072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &URLRequestHttpJob::OnStartCompleted, rv)); 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 34372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::AddExtraHeaders() { 34472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // TODO(jar): Consider optimizing away SDCH advertising bytes when the URL is 34572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // probably an img or such (and SDCH encoding is not likely). 34672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool advertise_sdch = SdchManager::Global() && 34772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SdchManager::Global()->IsInSupportedDomain(request_->url()); 34872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string avail_dictionaries; 34972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (advertise_sdch) { 35072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SdchManager::Global()->GetAvailDictionaryList(request_->url(), 35172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &avail_dictionaries); 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The AllowLatencyExperiment() is only true if we've successfully done a 35472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // full SDCH compression recently in this browser session for this host. 35572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Note that for this path, there might be no applicable dictionaries, and 35672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // hence we can't participate in the experiment. 35772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!avail_dictionaries.empty() && 35872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SdchManager::Global()->AllowLatencyExperiment(request_->url())) { 35972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We are participating in the test (or control), and hence we'll 36072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // eventually record statistics via either SDCH_EXPERIMENT_DECODE or 36172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // SDCH_EXPERIMENT_HOLDBACK, and we'll need some packet timing data. 362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_timing_enabled_ = true; 36372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (base::RandDouble() < .01) { 36472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sdch_test_control_ = true; // 1% probability. 36572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen advertise_sdch = false; 36672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 36772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sdch_test_activated_ = true; 36872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 36972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 37072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Supply Accept-Encoding headers first so that it is more likely that they 37372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // will be in the first transmitted packet. This can sometimes make it easier 37472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // to filter and analyze the streams to assure that a proxy has not damaged 37572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // these headers. Some proxies deliberately corrupt Accept-Encoding headers. 37672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!advertise_sdch) { 37772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Tell the server what compression formats we support (other than SDCH). 37872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info_.extra_headers.SetHeader( 37972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestHeaders::kAcceptEncoding, "gzip,deflate"); 38072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 38172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Include SDCH in acceptable list. 38272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info_.extra_headers.SetHeader( 38372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestHeaders::kAcceptEncoding, "gzip,deflate,sdch"); 38472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!avail_dictionaries.empty()) { 38572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info_.extra_headers.SetHeader( 38672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kAvailDictionaryHeader, 38772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen avail_dictionaries); 38872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sdch_dictionary_advertised_ = true; 38972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Since we're tagging this transaction as advertising a dictionary, we'll 39072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // definately employ an SDCH filter (or tentative sdch filter) when we get 39172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // a response. When done, we'll record histograms via SDCH_DECODE or 39272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // SDCH_PASSTHROUGH. Hence we need to record packet arrival times. 393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_timing_enabled_ = true; 39472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 39572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 39772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen URLRequestContext* context = request_->context(); 39872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (context) { 39972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Only add default Accept-Language and Accept-Charset if the request 40072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // didn't have them specified. 401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!context->accept_language().empty()) { 402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request_info_.extra_headers.SetHeaderIfMissing( 403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HttpRequestHeaders::kAcceptLanguage, 404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen context->accept_language()); 405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!context->accept_charset().empty()) { 407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request_info_.extra_headers.SetHeaderIfMissing( 408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HttpRequestHeaders::kAcceptCharset, 409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen context->accept_charset()); 410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 41172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 41472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::AddCookieHeaderAndStart() { 41572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // No matter what, we want to report our status as IO pending since we will 41672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // be notifying our consumer asynchronously via OnStartCompleted. 41772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 41972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int policy = OK; 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 42172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES) { 42272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen policy = ERR_FAILED; 42372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else if (request_->context()->cookie_policy()) { 42472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen policy = request_->context()->cookie_policy()->CanGetCookies( 42572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_->url(), 426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request_->first_party_for_cookies()); 42772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 42972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen OnCanGetCookiesCompleted(policy); 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 43272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete() { 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(transaction_.get()); 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 43572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const HttpResponseInfo* response_info = transaction_->GetResponseInfo(); 43672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(response_info); 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 43872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_cookies_.clear(); 43972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_cookies_save_index_ = 0; 440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 44172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen FetchResponseCookies(response_info, &response_cookies_); 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 44372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Now, loop over the response cookies, and attempt to persist each. 44472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SaveNextCookie(); 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 44772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::SaveNextCookie() { 44872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (response_cookies_save_index_ == response_cookies_.size()) { 44972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_cookies_.clear(); 45072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_cookies_save_index_ = 0; 45172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SetStatus(URLRequestStatus()); // Clear the IO_PENDING status 45272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotifyHeadersComplete(); 45372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 45672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // No matter what, we want to report our status as IO pending since we will 45772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // be notifying our consumer asynchronously via OnStartCompleted. 45872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 46072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int policy = OK; 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 46272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) { 46372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen policy = ERR_FAILED; 46472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else if (request_->context()->cookie_policy()) { 46572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen policy = request_->context()->cookie_policy()->CanSetCookie( 46672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_->url(), 46772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_->first_party_for_cookies(), 468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen response_cookies_[response_cookies_save_index_]); 469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen OnCanSetCookieCompleted(policy); 472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::FetchResponseCookies( 47572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const HttpResponseInfo* response_info, 47672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::vector<std::string>* cookies) { 47772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string name = "Set-Cookie"; 47872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string value; 479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void* iter = NULL; 48172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen while (response_info->headers->EnumerateHeader(&iter, name, &value)) { 48272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!value.empty()) 48372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cookies->push_back(value); 484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::ProcessStrictTransportSecurityHeader() { 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(response_info_); 489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen URLRequestContext* ctx = request_->context(); 49172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!ctx || !ctx->transport_security_state()) 49272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const bool https = response_info_->ssl_info.is_valid(); 49572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const bool valid_https = 49672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen https && !IsCertStatusError(response_info_->ssl_info.cert_status); 497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string name = "Strict-Transport-Security"; 49972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string value; 500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 50172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int max_age; 50272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool include_subdomains; 503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 50472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void* iter = NULL; 50572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen while (response_info_->headers->EnumerateHeader(&iter, name, &value)) { 50672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const bool ok = TransportSecurityState::ParseHeader( 50772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen value, &max_age, &include_subdomains); 50872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!ok) 50972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 51072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We will only accept strict mode if we saw the header from an HTTPS 51172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // connection with no certificate problems. 51272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!valid_https) 51372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 51472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::Time current_time(base::Time::Now()); 51572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::TimeDelta max_age_delta = base::TimeDelta::FromSeconds(max_age); 516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 51772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TransportSecurityState::DomainState domain_state; 51872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen domain_state.expiry = current_time + max_age_delta; 51972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen domain_state.mode = TransportSecurityState::DomainState::MODE_STRICT; 52072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen domain_state.include_subdomains = include_subdomains; 521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 52272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ctx->transport_security_state()->EnableHost(request_info_.url.host(), 52372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen domain_state); 524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 52672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // TODO(agl): change this over when we have fixed things at the server end. 52772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The string should be "Opportunistic-Transport-Security"; 52872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen name = "X-Bodge-Transport-Security"; 529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 53072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen while (response_info_->headers->EnumerateHeader(&iter, name, &value)) { 53172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const bool ok = TransportSecurityState::ParseHeader( 53272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen value, &max_age, &include_subdomains); 53372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!ok) 53472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 53572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // If we saw an opportunistic request over HTTPS, then clearly we can make 53672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // HTTPS connections to the host so we should remember this. 53772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (https) { 53872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::Time current_time(base::Time::Now()); 53972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::TimeDelta max_age_delta = base::TimeDelta::FromSeconds(max_age); 540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 54172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TransportSecurityState::DomainState domain_state; 54272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen domain_state.expiry = current_time + max_age_delta; 54372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen domain_state.mode = 54472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TransportSecurityState::DomainState::MODE_SPDY_ONLY; 54572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen domain_state.include_subdomains = include_subdomains; 546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 54772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ctx->transport_security_state()->EnableHost(request_info_.url.host(), 54872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen domain_state); 54972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 55072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 55272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!request()) 55372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 55572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // At this point, we have a request for opportunistic encryption over HTTP. 55672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // In this case we need to probe to check that we can make HTTPS 55772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // connections to that host. 55872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HTTPSProber* const prober = HTTPSProber::GetInstance(); 55972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (prober->HaveProbed(request_info_.url.host()) || 56072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen prober->InFlight(request_info_.url.host())) { 56172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 56272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 56472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HTTPSProberDelegateImpl* delegate = 56572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new HTTPSProberDelegateImpl(request_info_.url.host(), max_age, 56672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen include_subdomains, 56772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ctx->transport_security_state()); 56872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!prober->ProbeHost(request_info_.url.host(), request()->context(), 56972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen delegate)) { 57072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen delete delegate; 57172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::OnCanGetCookiesCompleted(int policy) { 576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the request was destroyed, then there is no more work to do. 577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (request_ && request_->delegate()) { 57821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (request_->context()->cookie_store()) { 57921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (policy == ERR_ACCESS_DENIED) { 58021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_->delegate()->OnGetCookies(request_, true); 58121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else if (policy == OK) { 58221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_->delegate()->OnGetCookies(request_, false); 58321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CookieOptions options; 58421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen options.set_include_httponly(); 58521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string cookies = 58621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_->context()->cookie_store()->GetCookiesWithOptions( 58721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_->url(), options); 58821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!cookies.empty()) { 58921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_info_.extra_headers.SetHeader( 59021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen HttpRequestHeaders::kCookie, cookies); 59121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We may have been canceled within OnGetCookies. 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GetStatus().is_success()) { 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StartTransaction(); 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyCanceled(); 599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::OnCanSetCookieCompleted(int policy) { 604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the request was destroyed, then there is no more work to do. 605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (request_ && request_->delegate()) { 60621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (request_->context()->cookie_store()) { 60721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (policy == ERR_ACCESS_DENIED) { 608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CookieOptions options; 609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen options.set_include_httponly(); 61021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_->delegate()->OnSetCookie( 61121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_, 61221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen response_cookies_[response_cookies_save_index_], 613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen options, 61421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen true); 61521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else if (policy == OK || policy == OK_FOR_SESSION_ONLY) { 61621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // OK to save the current response cookie now. 61721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CookieOptions options; 61821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen options.set_include_httponly(); 61921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (policy == OK_FOR_SESSION_ONLY) 62021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen options.set_force_session(); 62121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_->context()->cookie_store()->SetCookieWithOptions( 62221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_->url(), response_cookies_[response_cookies_save_index_], 62321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen options); 62421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_->delegate()->OnSetCookie( 62521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_, 62621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen response_cookies_[response_cookies_save_index_], 62721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen options, 62821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen false); 62921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_cookies_save_index_++; 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We may have been canceled within OnSetCookie. 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GetStatus().is_success()) { 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SaveNextCookie(); 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyCanceled(); 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::OnStartCompleted(int result) { 642dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen RecordTimer(); 643dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the request was destroyed, then there is no more work to do. 645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!request_ || !request_->delegate()) 646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the transaction was destroyed, then the job was cancelled, and 649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // we can just ignore this notification. 650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!transaction_.get()) 651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Clear the IO_PENDING status 654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetStatus(URLRequestStatus()); 655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Take care of any mandates for public key pinning. 657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(agl): we might have an issue here where a request for foo.example.com 658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // merges into a SPDY connection to www.example.com, and gets a different 659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // certificate. 660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const SSLInfo& ssl_info = transaction_->GetResponseInfo()->ssl_info; 661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (result == OK && 662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ssl_info.is_valid() && 663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen context_->transport_security_state()) { 664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TransportSecurityState::DomainState domain_state; 665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (context_->transport_security_state()->IsEnabledForHost( 666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &domain_state, 667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request_->url().host(), 668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen context_->IsSNIAvailable()) && 669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ssl_info.is_issued_by_known_root && 670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !domain_state.IsChainOfPublicKeysPermitted(ssl_info.public_key_hashes)){ 671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result = ERR_CERT_INVALID; 672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 67521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (result == OK) { 676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SaveCookiesAndNotifyHeadersComplete(); 677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (ShouldTreatAsCertificateError(result)) { 678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We encountered an SSL certificate error. Ask our delegate to decide 679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // what we should do. 680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(wtc): also pass ssl_info.cert_status, or just pass the whole 681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ssl_info. 682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->delegate()->OnSSLCertificateError( 683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_, result, transaction_->GetResponseInfo()->ssl_info.cert); 68421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->delegate()->OnCertificateRequested( 686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_, transaction_->GetResponseInfo()->cert_request_info); 687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); 689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::OnReadCompleted(int result) { 693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_in_progress_ = false; 694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 69572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (result == 0) { 69672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotifyDone(URLRequestStatus()); 69772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else if (result < 0) { 69872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); 69972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 70072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Clear the IO_PENDING status 70172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SetStatus(URLRequestStatus()); 70272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 70372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 70472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotifyReadComplete(result); 70572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 70672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 70772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool URLRequestHttpJob::ShouldTreatAsCertificateError(int result) { 70872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!IsCertificateError(result)) 70972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 71072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Revocation check failures are always certificate errors, even if the host 712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // is using Strict-Transport-Security. 713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (result == ERR_CERT_UNABLE_TO_CHECK_REVOCATION) 714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 71672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Check whether our context is using Strict-Transport-Security. 71772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!context_->transport_security_state()) 71872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 71972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 72072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TransportSecurityState::DomainState domain_state; 72172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // TODO(agl): don't ignore opportunistic mode. 72272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const bool r = context_->transport_security_state()->IsEnabledForHost( 723ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &domain_state, request_info_.url.host(), context_->IsSNIAvailable()); 72472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 72572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return !r || domain_state.mode == 72672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TransportSecurityState::DomainState::MODE_OPPORTUNISTIC; 72772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 72872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 72972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::RestartTransactionWithAuth( 73072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& username, 73172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& password) { 73272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen username_ = username; 73372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen password_ = password; 73472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 73572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // These will be reset in OnStartCompleted. 73672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_info_ = NULL; 73772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_cookies_.clear(); 73872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 739dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ResetTimer(); 740dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 74172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Update the cookies, since the cookie store may have been updated from the 74272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // headers in the 401/407. Since cookies were already appended to 74372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // extra_headers, we need to strip them out before adding them again. 74472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info_.extra_headers.RemoveHeader( 74572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestHeaders::kCookie); 74672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 74772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen AddCookieHeaderAndStart(); 74872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 74972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 75072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::SetUpload(UploadData* upload) { 75172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(!transaction_.get()) << "cannot change once started"; 75272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info_.upload_data = upload; 75372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 75472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 75572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::SetExtraRequestHeaders( 75672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const HttpRequestHeaders& headers) { 75772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(!transaction_.get()) << "cannot change once started"; 75872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info_.extra_headers.CopyFrom(headers); 75972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 76072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 76172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::Start() { 76272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(!transaction_.get()); 76372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 76472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Ensure that we do not send username and password fields in the referrer. 76572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen GURL referrer(request_->GetSanitizedReferrer()); 76672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 76772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info_.url = request_->url(); 76872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info_.referrer = referrer; 76972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info_.method = request_->method(); 77072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info_.load_flags = request_->load_flags(); 77172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info_.priority = request_->priority(); 772ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request_info_.request_id = request_->identifier(); 77372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 77472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (request_->context()) { 77572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info_.extra_headers.SetHeaderIfMissing( 77672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HttpRequestHeaders::kUserAgent, 77772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_->context()->GetUserAgent(request_->url())); 778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 78072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen AddExtraHeaders(); 781e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma 782e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma#ifdef ANDROID 783e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma // Attribute network traffic to the UID of the caller 784e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma request_info_.valid_uid = false; 785e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma request_info_.calling_uid = 0; 786e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma 787e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma if (request_->context()) { 788e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma uid_t uid; 789e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma if(request_->context()->getUID(&uid)) { 790e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma request_info_.valid_uid = true; 791e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma request_info_.calling_uid = uid; 792e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma } 793e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma } 794e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma#endif 795e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma 79672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen AddCookieHeaderAndStart(); 797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 79972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::Kill() { 80072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!transaction_.get()) 80172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 80372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DestroyTransaction(); 80472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen URLRequestJob::Kill(); 80572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 80772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLoadState URLRequestHttpJob::GetLoadState() const { 80872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return transaction_.get() ? 80972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen transaction_->GetLoadState() : LOAD_STATE_IDLE; 81072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 81272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenuint64 URLRequestHttpJob::GetUploadProgress() const { 81372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return transaction_.get() ? transaction_->GetUploadProgress() : 0; 814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 81672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool URLRequestHttpJob::GetMimeType(std::string* mime_type) const { 81772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(transaction_.get()); 818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 81972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!response_info_) 82072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 82272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return response_info_->headers->GetMimeType(mime_type); 82372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 82572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool URLRequestHttpJob::GetCharset(std::string* charset) { 82672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(transaction_.get()); 827201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 82872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!response_info_) 82972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 83172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return response_info_->headers->GetCharset(charset); 83272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 83472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::GetResponseInfo(HttpResponseInfo* info) { 83572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(request_); 83672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(transaction_.get()); 837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 83872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (response_info_) 83972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *info = *response_info_; 840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 84272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool URLRequestHttpJob::GetResponseCookies( 84372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::vector<std::string>* cookies) { 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(transaction_.get()); 845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 84672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!response_info_) 84772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 84872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 84972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // TODO(darin): Why are we extracting response cookies again? Perhaps we 85072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // should just leverage response_cookies_. 85172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 85272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cookies->clear(); 85372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen FetchResponseCookies(response_info_, cookies); 85472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 85772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint URLRequestHttpJob::GetResponseCode() const { 85872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(transaction_.get()); 859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 86072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!response_info_) 86172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return -1; 862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 86372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return response_info_->headers->response_code(); 86472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 865201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 866ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFilter* URLRequestHttpJob::SetupFilter() const { 86772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(transaction_.get()); 86872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!response_info_) 869ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NULL; 870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 871ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<Filter::FilterType> encoding_types; 87272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string encoding_type; 87372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void* iter = NULL; 87472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen while (response_info_->headers->EnumerateHeader(&iter, "Content-Encoding", 87572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &encoding_type)) { 876ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen encoding_types.push_back(Filter::ConvertEncodingToType(encoding_type)); 877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Even if encoding types are empty, there is a chance that we need to add 88072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // some decoding, as some proxies strip encoding completely. In such cases, 88172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // we may need to add (for example) SDCH filtering (when the context suggests 88272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // it is appropriate). 883ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Filter::FixupEncodingTypes(*filter_context_, &encoding_types); 884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 885ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return !encoding_types.empty() 886ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ? Filter::Factory(encoding_types, *filter_context_) : NULL; 88772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 88972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool URLRequestHttpJob::IsSafeRedirect(const GURL& location) { 89072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We only allow redirects to certain "safe" protocols. This does not 89172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // restrict redirects to externally handled protocols. Our consumer would 89272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // need to take care of those. 89372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 89472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!URLRequest::IsHandledURL(location)) 89572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 89672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 89772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static const char* kSafeSchemes[] = { 89872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "http", 89972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "https", 90072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "ftp" 90172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }; 90272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 90372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (size_t i = 0; i < arraysize(kSafeSchemes); ++i) { 90472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (location.SchemeIs(kSafeSchemes[i])) 90572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 90872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 90972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 91072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 91172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool URLRequestHttpJob::NeedsAuth() { 91272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int code = GetResponseCode(); 91372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (code == -1) 91472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 91572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 91672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Check if we need either Proxy or WWW Authentication. This could happen 91772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // because we either provided no auth info, or provided incorrect info. 91872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen switch (code) { 91972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case 407: 92072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (proxy_auth_state_ == AUTH_STATE_CANCELED) 92172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 92272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proxy_auth_state_ = AUTH_STATE_NEED_AUTH; 92372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 92472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case 401: 92572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (server_auth_state_ == AUTH_STATE_CANCELED) 92672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 92772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen server_auth_state_ = AUTH_STATE_NEED_AUTH; 92872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 93072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 93372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::GetAuthChallengeInfo( 93472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<AuthChallengeInfo>* result) { 93572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(transaction_.get()); 93672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(response_info_); 937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 93872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // sanity checks: 93972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(proxy_auth_state_ == AUTH_STATE_NEED_AUTH || 94072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen server_auth_state_ == AUTH_STATE_NEED_AUTH); 94172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(response_info_->headers->response_code() == 401 || 94272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_info_->headers->response_code() == 407); 943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 94472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *result = response_info_->auth_challenge; 94572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 94772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::SetAuth(const string16& username, 94872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& password) { 94972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(transaction_.get()); 95072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 95172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Proxy gets set first, then WWW. 95272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (proxy_auth_state_ == AUTH_STATE_NEED_AUTH) { 95372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proxy_auth_state_ = AUTH_STATE_HAVE_AUTH; 95472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 955ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_EQ(server_auth_state_, AUTH_STATE_NEED_AUTH); 95672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen server_auth_state_ = AUTH_STATE_HAVE_AUTH; 957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 95972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen RestartTransactionWithAuth(username, password); 960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 96272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::CancelAuth() { 96372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Proxy gets set first, then WWW. 96472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (proxy_auth_state_ == AUTH_STATE_NEED_AUTH) { 96572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proxy_auth_state_ = AUTH_STATE_CANCELED; 96672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 967ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_EQ(server_auth_state_, AUTH_STATE_NEED_AUTH); 96872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen server_auth_state_ = AUTH_STATE_CANCELED; 96972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 97172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // These will be reset in OnStartCompleted. 97272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_info_ = NULL; 973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_cookies_.clear(); 974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 975dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ResetTimer(); 976dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 97772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // OK, let the consumer read the error page... 97872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // 97972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Because we set the AUTH_STATE_CANCELED flag, NeedsAuth will return false, 98072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // which will cause the consumer to receive OnResponseStarted instead of 98172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // OnAuthRequired. 98272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // 98372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We have to do this via InvokeLater to avoid "recursing" the consumer. 98472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // 98572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen MessageLoop::current()->PostTask( 98672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen FROM_HERE, 98772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen method_factory_.NewRunnableMethod( 98872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &URLRequestHttpJob::OnStartCompleted, OK)); 989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 99172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::ContinueWithCertificate( 99272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen X509Certificate* client_cert) { 99372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(transaction_.get()); 99472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 99572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(!response_info_) << "should not have a response yet"; 996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 997dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ResetTimer(); 998dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // No matter what, we want to report our status as IO pending since we will 1000c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be notifying our consumer asynchronously via OnStartCompleted. 1001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 1002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 100372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int rv = transaction_->RestartWithCertificate(client_cert, &start_callback_); 100472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (rv == ERR_IO_PENDING) 100572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 1006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 100772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The transaction started synchronously, but we need to notify the 100872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // URLRequest delegate via the message loop. 100972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen MessageLoop::current()->PostTask( 101072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen FROM_HERE, 101172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen method_factory_.NewRunnableMethod( 101272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &URLRequestHttpJob::OnStartCompleted, rv)); 1013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 101572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::ContinueDespiteLastError() { 101672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // If the transaction was destroyed, then the job was cancelled. 101772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!transaction_.get()) 1018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 102072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(!response_info_) << "should not have a response yet"; 1021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1022dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ResetTimer(); 1023dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 102472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // No matter what, we want to report our status as IO pending since we will 102572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // be notifying our consumer asynchronously via OnStartCompleted. 102672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 1027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 102872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int rv = transaction_->RestartIgnoringLastError(&start_callback_); 102972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (rv == ERR_IO_PENDING) 103072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 1031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 103272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The transaction started synchronously, but we need to notify the 103372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // URLRequest delegate via the message loop. 103472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen MessageLoop::current()->PostTask( 103572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen FROM_HERE, 103672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen method_factory_.NewRunnableMethod( 103772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &URLRequestHttpJob::OnStartCompleted, rv)); 103872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 1039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 104072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool URLRequestHttpJob::ReadRawData(IOBuffer* buf, int buf_size, 104172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int *bytes_read) { 104272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK_NE(buf_size, 0); 104372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(bytes_read); 104472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(!read_in_progress_); 1045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 104672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int rv = transaction_->Read(buf, buf_size, &read_callback_); 104772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (rv >= 0) { 104872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *bytes_read = rv; 104972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 1050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1051c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (rv == ERR_IO_PENDING) { 105372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen read_in_progress_ = true; 105472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 105572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 105672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); 105772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 1058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 106072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 1061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 106272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid URLRequestHttpJob::StopCaching() { 106372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (transaction_.get()) 106472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen transaction_->StopCaching(); 106572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 1066c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1067dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenHostPortPair URLRequestHttpJob::GetSocketAddress() const { 1068dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return response_info_ ? response_info_->socket_address : HostPortPair(); 1069dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 1070dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 107172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenURLRequestHttpJob::~URLRequestHttpJob() { 107272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(!sdch_test_control_ || !sdch_test_activated_); 1073ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!is_cached_content_) { 107472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (sdch_test_control_) 1075ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen RecordPacketStats(FilterContext::SDCH_EXPERIMENT_HOLDBACK); 107672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (sdch_test_activated_) 1077ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen RecordPacketStats(FilterContext::SDCH_EXPERIMENT_DECODE); 107872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 1079ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Make sure SDCH filters are told to emit histogram data while 1080ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // filter_context_ is still alive. 108172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DestroyFilters(); 1082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 108372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (sdch_dictionary_url_.is_valid()) { 108472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Prior to reaching the destructor, request_ has been set to a NULL 108572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // pointer, so request_->url() is no longer valid in the destructor, and we 108672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // use an alternate copy |request_info_.url|. 108772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SdchManager* manager = SdchManager::Global(); 108872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // To be extra safe, since this is a "different time" from when we decided 108972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // to get the dictionary, we'll validate that an SdchManager is available. 109072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // At shutdown time, care is taken to be sure that we don't delete this 109172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // globally useful instance "too soon," so this check is just defensive 109272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // coding to assure that IF the system is shutting down, we don't have any 109372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // problem if the manager was deleted ahead of time. 109472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (manager) // Defensive programming. 109572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager->FetchDictionary(request_info_.url, sdch_dictionary_url_); 1096c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1097c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 109821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1099dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid URLRequestHttpJob::RecordTimer() { 1100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (request_creation_time_.is_null()) { 1101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NOTREACHED() 1102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << "The same transaction shouldn't start twice without new timing."; 1103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 1104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 1105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::TimeDelta to_start = base::Time::Now() - request_creation_time_; 1107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen request_creation_time_ = base::Time(); 1108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static const bool use_prefetch_histogram = 1110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::FieldTrialList::Find("Prefetch") && 1111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !base::FieldTrialList::Find("Prefetch")->group_name().empty(); 1112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpTimeToFirstByte", to_start); 1114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (use_prefetch_histogram) { 1115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_MEDIUM_TIMES( 1116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::FieldTrial::MakeName("Net.HttpTimeToFirstByte", 1117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "Prefetch"), 1118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen to_start); 1119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const bool is_prerender = !!(request_info_.load_flags & LOAD_PRERENDER); 1122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (is_prerender) { 1123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpTimeToFirstByte_Prerender", 1124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen to_start); 1125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (use_prefetch_histogram) { 1126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_MEDIUM_TIMES( 1127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::FieldTrial::MakeName("Net.HttpTimeToFirstByte_Prerender", 1128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "Prefetch"), 1129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen to_start); 1130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 1132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpTimeToFirstByte_NonPrerender", 1133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen to_start); 1134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (use_prefetch_histogram) { 1135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_MEDIUM_TIMES( 1136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::FieldTrial::MakeName("Net.HttpTimeToFirstByte_NonPrerender", 1137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "Prefetch"), 1138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen to_start); 1139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 1142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid URLRequestHttpJob::ResetTimer() { 1144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!request_creation_time_.is_null()) { 1145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NOTREACHED() 1146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << "The timer was reset before it was recorded."; 1147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 1148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 1149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen request_creation_time_ = base::Time::Now(); 1150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 1151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid URLRequestHttpJob::UpdatePacketReadTimes() { 1153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!packet_timing_enabled_) 1154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (filter_input_byte_count() <= bytes_observed_in_packets_) { 1157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_EQ(filter_input_byte_count(), bytes_observed_in_packets_); 1158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; // No new bytes have arrived. 1159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!bytes_observed_in_packets_) 1162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request_time_snapshot_ = request_ ? request_->request_time() : base::Time(); 1163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen final_packet_time_ = base::Time::Now(); 1165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const size_t kTypicalPacketSize = 1430; 1166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen while (filter_input_byte_count() > bytes_observed_in_packets_) { 1167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++observed_packet_count_; 1168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (packet_times_.size() < kSdchPacketHistogramCount) { 1169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_.push_back(final_packet_time_); 1170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_EQ(static_cast<size_t>(observed_packet_count_), 1171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_.size()); 1172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bytes_observed_in_packets_ += kTypicalPacketSize; 1174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Since packets may not be full, we'll remember the number of bytes we've 1176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // accounted for in packets thus far. 1177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bytes_observed_in_packets_ = filter_input_byte_count(); 1178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid URLRequestHttpJob::RecordPacketStats( 1181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilterContext::StatisticSelector statistic) const { 1182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!packet_timing_enabled_ || (final_packet_time_ == base::Time())) 1183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta duration = final_packet_time_ - request_time_snapshot_; 1186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen switch (statistic) { 1187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case FilterContext::SDCH_DECODE: { 1188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Network_Decode_Latency_F_a", duration, 1189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(20), 1190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMinutes(10), 100); 1191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_COUNTS_100("Sdch3.Network_Decode_Packets_b", 1192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static_cast<int>(observed_packet_count_)); 1193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CUSTOM_COUNTS("Sdch3.Network_Decode_Bytes_Processed_b", 1194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static_cast<int>(bytes_observed_in_packets_), 500, 100000, 100); 1195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (packet_times_.empty()) 1196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Network_Decode_1st_To_Last_a", 1198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen final_packet_time_ - packet_times_[0], 1199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(20), 1200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMinutes(10), 100); 1201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_GT(kSdchPacketHistogramCount, 4u); 1203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (packet_times_.size() <= 4) 1204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Network_Decode_1st_To_2nd_c", 1206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_[1] - packet_times_[0], 1207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(1), 1208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromSeconds(10), 100); 1209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Network_Decode_2nd_To_3rd_c", 1210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_[2] - packet_times_[1], 1211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(1), 1212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromSeconds(10), 100); 1213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Network_Decode_3rd_To_4th_c", 1214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_[3] - packet_times_[2], 1215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(1), 1216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromSeconds(10), 100); 1217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Network_Decode_4th_To_5th_c", 1218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_[4] - packet_times_[3], 1219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(1), 1220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromSeconds(10), 100); 1221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case FilterContext::SDCH_PASSTHROUGH: { 1224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Despite advertising a dictionary, we handled non-sdch compressed 1225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // content. 1226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Network_Pass-through_Latency_F_a", 1227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen duration, 1228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(20), 1229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMinutes(10), 100); 1230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_COUNTS_100("Sdch3.Network_Pass-through_Packets_b", 1231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen observed_packet_count_); 1232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (packet_times_.empty()) 1233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Network_Pass-through_1st_To_Last_a", 1235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen final_packet_time_ - packet_times_[0], 1236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(20), 1237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMinutes(10), 100); 1238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_GT(kSdchPacketHistogramCount, 4u); 1239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (packet_times_.size() <= 4) 1240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Network_Pass-through_1st_To_2nd_c", 1242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_[1] - packet_times_[0], 1243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(1), 1244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromSeconds(10), 100); 1245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Network_Pass-through_2nd_To_3rd_c", 1246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_[2] - packet_times_[1], 1247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(1), 1248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromSeconds(10), 100); 1249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Network_Pass-through_3rd_To_4th_c", 1250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_[3] - packet_times_[2], 1251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(1), 1252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromSeconds(10), 100); 1253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Network_Pass-through_4th_To_5th_c", 1254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_[4] - packet_times_[3], 1255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(1), 1256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromSeconds(10), 100); 1257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case FilterContext::SDCH_EXPERIMENT_DECODE: { 1261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Experiment_Decode", 1262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen duration, 1263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(20), 1264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMinutes(10), 100); 1265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We already provided interpacket histograms above in the SDCH_DECODE 1266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // case, so we don't need them here. 1267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case FilterContext::SDCH_EXPERIMENT_HOLDBACK: { 1270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Experiment_Holdback", 1271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen duration, 1272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(20), 1273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMinutes(10), 100); 1274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Experiment_Holdback_1st_To_Last_a", 1275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen final_packet_time_ - packet_times_[0], 1276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(20), 1277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMinutes(10), 100); 1278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_GT(kSdchPacketHistogramCount, 4u); 1280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (packet_times_.size() <= 4) 1281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Experiment_Holdback_1st_To_2nd_c", 1283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_[1] - packet_times_[0], 1284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(1), 1285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromSeconds(10), 100); 1286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Experiment_Holdback_2nd_To_3rd_c", 1287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_[2] - packet_times_[1], 1288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(1), 1289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromSeconds(10), 100); 1290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Experiment_Holdback_3rd_To_4th_c", 1291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_[3] - packet_times_[2], 1292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(1), 1293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromSeconds(10), 100); 1294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CLIPPED_TIMES("Sdch3.Experiment_Holdback_4th_To_5th_c", 1295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen packet_times_[4] - packet_times_[3], 1296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds(1), 1297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromSeconds(10), 100); 1298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen default: 1301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 1302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// The common type of histogram we use for all compression-tracking histograms. 1307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define COMPRESSION_HISTOGRAM(name, sample) \ 1308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen do { \ 1309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UMA_HISTOGRAM_CUSTOM_COUNTS("Net.Compress." name, sample, \ 1310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 500, 1000000, 100); \ 1311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } while(0) 1312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid URLRequestHttpJob::RecordCompressionHistograms() { 1314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(request_); 1315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!request_) 1316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (is_cached_content_ || // Don't record cached content 1319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !GetStatus().is_success() || // Don't record failed content 1320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !IsCompressibleContent() || // Only record compressible content 1321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !prefilter_bytes_read()) // Zero-byte responses aren't useful. 1322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Miniature requests aren't really compressible. Don't count them. 1325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const int kMinSize = 16; 1326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (prefilter_bytes_read() < kMinSize) 1327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Only record for http or https urls. 1330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool is_http = request_->url().SchemeIs("http"); 1331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool is_https = request_->url().SchemeIs("https"); 1332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!is_http && !is_https) 1333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int compressed_B = prefilter_bytes_read(); 1336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int decompressed_B = postfilter_bytes_read(); 1337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool was_filtered = HasFilter(); 1338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We want to record how often downloaded resources are compressed. 1340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // But, we recognize that different protocols may have different 1341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // properties. So, for each request, we'll put it into one of 3 1342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // groups: 1343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // a) SSL resources 1344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Proxies cannot tamper with compression headers with SSL. 1345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // b) Non-SSL, loaded-via-proxy resources 1346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // In this case, we know a proxy might have interfered. 1347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // c) Non-SSL, loaded-without-proxy resources 1348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // In this case, we know there was no explicit proxy. However, 1349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // it is possible that a transparent proxy was still interfering. 1350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 1351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // For each group, we record the same 3 histograms. 1352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (is_https) { 1354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (was_filtered) { 1355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen COMPRESSION_HISTOGRAM("SSL.BytesBeforeCompression", compressed_B); 1356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen COMPRESSION_HISTOGRAM("SSL.BytesAfterCompression", decompressed_B); 1357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 1358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen COMPRESSION_HISTOGRAM("SSL.ShouldHaveBeenCompressed", decompressed_B); 1359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (request_->was_fetched_via_proxy()) { 1364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (was_filtered) { 1365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen COMPRESSION_HISTOGRAM("Proxy.BytesBeforeCompression", compressed_B); 1366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen COMPRESSION_HISTOGRAM("Proxy.BytesAfterCompression", decompressed_B); 1367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 1368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen COMPRESSION_HISTOGRAM("Proxy.ShouldHaveBeenCompressed", decompressed_B); 1369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 1371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (was_filtered) { 1374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen COMPRESSION_HISTOGRAM("NoProxy.BytesBeforeCompression", compressed_B); 1375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen COMPRESSION_HISTOGRAM("NoProxy.BytesAfterCompression", decompressed_B); 1376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 1377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen COMPRESSION_HISTOGRAM("NoProxy.ShouldHaveBeenCompressed", decompressed_B); 1378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool URLRequestHttpJob::IsCompressibleContent() const { 1382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string mime_type; 1383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return GetMimeType(&mime_type) && 1384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (IsSupportedJavascriptMimeType(mime_type.c_str()) || 1385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IsSupportedNonImageMimeType(mime_type.c_str())); 1386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 138821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} // namespace net 1389