url_request_http_job.cc revision 010d83a9304c5a91596085d917d248abff47903a
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_http_job.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_switches.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_version_info.h" 139ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/field_trial.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/host_port_pair.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/mime_util.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/network_delegate.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/sdch_manager.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_status_flags.h" 27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "net/cookies/cookie_store.h" 28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "net/http/http_content_disposition.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_request_headers.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_info.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_status_code.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_transaction.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_transaction_factory.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_config_service.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/fraudulent_certificate_reporter.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/http_user_agent_settings.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_error_job.h" 44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/url_request/url_request_job_factory.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_redirect_job.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_throttler_header_adapter.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_throttler_manager.h" 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/websockets/websocket_handshake_stream_base.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kAvailDictionaryHeader[] = "Avail-Dictionary"; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestHttpJob::HttpFilterContext : public FilterContext { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit HttpFilterContext(URLRequestHttpJob* job); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~HttpFilterContext(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FilterContext implementation. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetMimeType(std::string* mime_type) const OVERRIDE; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetURL(GURL* gurl) const OVERRIDE; 62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual bool GetContentDisposition(std::string* disposition) const OVERRIDE; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual base::Time GetRequestTime() const OVERRIDE; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsCachedContent() const OVERRIDE; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsDownload() const OVERRIDE; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsSdchResponse() const OVERRIDE; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int64 GetByteReadCount() const OVERRIDE; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetResponseCode() const OVERRIDE; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RecordPacketStats(StatisticSelector statistic) const OVERRIDE; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Method to allow us to reset filter context for a response that should have 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // been SDCH encoded when there is an update due to an explicit HTTP header. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetSdchResponseToFalse(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestHttpJob* job_; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(HttpFilterContext); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestHttpJob::HttpFilterContext::HttpFilterContext(URLRequestHttpJob* job) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : job_(job) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(job_); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestHttpJob::HttpFilterContext::~HttpFilterContext() { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::HttpFilterContext::GetMimeType( 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* mime_type) const { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job_->GetMimeType(mime_type); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::HttpFilterContext::GetURL(GURL* gurl) const { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!job_->request()) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *gurl = job_->request()->url(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool URLRequestHttpJob::HttpFilterContext::GetContentDisposition( 102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::string* disposition) const { 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch HttpResponseHeaders* headers = job_->GetResponseHeaders(); 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void *iter = NULL; 105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return headers->EnumerateHeader(&iter, "Content-Disposition", disposition); 106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Time URLRequestHttpJob::HttpFilterContext::GetRequestTime() const { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job_->request() ? job_->request()->request_time() : base::Time(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::HttpFilterContext::IsCachedContent() const { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job_->is_cached_content_; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::HttpFilterContext::IsDownload() const { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (job_->request_info_.load_flags & LOAD_IS_DOWNLOAD) != 0; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::HttpFilterContext::ResetSdchResponseToFalse() { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(job_->sdch_dictionary_advertised_); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_->sdch_dictionary_advertised_ = false; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::HttpFilterContext::IsSdchResponse() const { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job_->sdch_dictionary_advertised_; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 URLRequestHttpJob::HttpFilterContext::GetByteReadCount() const { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job_->filter_input_byte_count(); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLRequestHttpJob::HttpFilterContext::GetResponseCode() const { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job_->GetResponseCode(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::HttpFilterContext::RecordPacketStats( 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StatisticSelector statistic) const { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_->RecordPacketStats(statistic); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(darin): make sure the port blocking code is not lost 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetworkDelegate* network_delegate, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme) { 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(scheme == "http" || scheme == "https" || scheme == "ws" || 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scheme == "wss"); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request->context()->http_transaction_factory()) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "requires a valid context"; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new URLRequestErrorJob( 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request, network_delegate, ERR_INVALID_ARGUMENT); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL redirect_url; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request->GetHSTSRedirect(&redirect_url)) { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new URLRequestRedirectJob( 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request, network_delegate, redirect_url, 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Use status code 307 to preserve the method, so POST requests work. 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, "HSTS"); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new URLRequestHttpJob(request, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) network_delegate, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->context()->http_user_agent_settings()); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestHttpJob::URLRequestHttpJob( 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequest* request, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetworkDelegate* network_delegate, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpUserAgentSettings* http_user_agent_settings) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : URLRequestJob(request, network_delegate), 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_(DEFAULT_PRIORITY), 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_(NULL), 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_save_index_(0), 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_auth_state_(AUTH_STATE_DONT_NEED_AUTH), 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_auth_state_(AUTH_STATE_DONT_NEED_AUTH), 1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) start_callback_(base::Bind(&URLRequestHttpJob::OnStartCompleted, 1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Unretained(this))), 1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) notify_before_headers_sent_callback_( 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&URLRequestHttpJob::NotifyBeforeSendHeadersCallback, 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Unretained(this))), 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_in_progress_(false), 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throttling_entry_(NULL), 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_dictionary_advertised_(false), 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_test_activated_(false), 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_test_control_(false), 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_cached_content_(false), 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_creation_time_(), 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet_timing_enabled_(false), 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_(false), 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_observed_in_packets_(0), 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_snapshot_(), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final_packet_time_(), 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) filter_context_(new HttpFilterContext(this)), 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this), 1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) on_headers_received_callback_( 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&URLRequestHttpJob::OnHeadersReceivedCallback, 1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Unretained(this))), 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) awaiting_callback_(false), 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_user_agent_settings_(http_user_agent_settings) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestThrottlerManager* manager = request->context()->throttler_manager(); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (manager) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throttling_entry_ = manager->RegisterRequestUrl(request->url()); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetTimer(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)URLRequestHttpJob::~URLRequestHttpJob() { 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(!awaiting_callback_); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!sdch_test_control_ || !sdch_test_activated_); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_cached_content_) { 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sdch_test_control_) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordPacketStats(FilterContext::SDCH_EXPERIMENT_HOLDBACK); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sdch_test_activated_) 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordPacketStats(FilterContext::SDCH_EXPERIMENT_DECODE); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure SDCH filters are told to emit histogram data while 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // filter_context_ is still alive. 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DestroyFilters(); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sdch_dictionary_url_.is_valid()) { 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Prior to reaching the destructor, request_ has been set to a NULL 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // pointer, so request_->url() is no longer valid in the destructor, and we 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // use an alternate copy |request_info_.url|. 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SdchManager* manager = SdchManager::Global(); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // To be extra safe, since this is a "different time" from when we decided 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to get the dictionary, we'll validate that an SdchManager is available. 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // At shutdown time, care is taken to be sure that we don't delete this 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // globally useful instance "too soon," so this check is just defensive 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // coding to assure that IF the system is shutting down, we don't have any 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // problem if the manager was deleted ahead of time. 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (manager) // Defensive programming. 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager->FetchDictionary(request_info_.url, sdch_dictionary_url_); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoneWithRequest(ABORTED); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestHttpJob::SetPriority(RequestPriority priority) { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_ = priority; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (transaction_) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transaction_->SetPriority(priority_); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestHttpJob::Start() { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!transaction_.get()); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // URLRequest::SetReferrer ensures that we do not send username and password 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // fields in the referrer. 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL referrer(request_->referrer()); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.url = request_->url(); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.method = request_->method(); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.load_flags = request_->load_flags(); 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Enable privacy mode if cookie settings or flags tell us not send or 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // save cookies. 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool enable_privacy_mode = 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES) || 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) || 26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CanEnablePrivacyMode(); 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Privacy mode could still be disabled in OnCookiesLoaded if we are going 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // to send previously saved cookies. 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request_info_.privacy_mode = enable_privacy_mode ? 265e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch PRIVACY_MODE_ENABLED : PRIVACY_MODE_DISABLED; 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Strip Referer from request_info_.extra_headers to prevent, e.g., plugins 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from overriding headers that are controlled using other means. Otherwise a 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // plugin could set a referrer although sending the referrer is inhibited. 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Our consumer should have made sure that this is a safe referrer. See for 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // instance WebCore::FrameLoader::HideReferrer. 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (referrer.is_valid()) { 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer, 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) referrer.spec()); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.extra_headers.SetHeaderIfMissing( 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HttpRequestHeaders::kUserAgent, 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_user_agent_settings_ ? 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) http_user_agent_settings_->GetUserAgent() : std::string()); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddExtraHeaders(); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddCookieHeaderAndStart(); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestHttpJob::Kill() { 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!transaction_.get()) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DestroyTransaction(); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLRequestJob::Kill(); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::NotifyHeadersComplete() { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!response_info_); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_ = transaction_->GetResponseInfo(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save boolean, as we'll need this info at destruction time, and filters may 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // also need this info. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_cached_content_ = response_info_->was_cached; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!is_cached_content_ && throttling_entry_.get()) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestThrottlerHeaderAdapter response_adapter(GetResponseHeaders()); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throttling_entry_->UpdateWithResponse(request_info_.url.host(), 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &response_adapter); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The ordering of these calls is not important. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessStrictTransportSecurityHeader(); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessPublicKeyPinsHeader(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SdchManager::Global() && 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SdchManager::Global()->IsInSupportedDomain(request_->url())) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string name = "Get-Dictionary"; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_text; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* iter = NULL; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jar): We need to not fetch dictionaries the first time they are 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // seen, but rather wait until we can justify their usefulness. 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For now, we will only fetch the first dictionary, which will at least 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // require multiple suggestions before we get additional ones for this site. 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Eventually we should wait until a dictionary is requested several times 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before we even download it (so that we don't waste memory or bandwidth). 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetResponseHeaders()->EnumerateHeader(&iter, name, &url_text)) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // request_->url() won't be valid in the destructor, so we use an 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // alternate copy. 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_->url(), request_info_.url); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resolve suggested URL relative to request url. 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_dictionary_url_ = request_info_.url.Resolve(url_text); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The HTTP transaction may be restarted several times for the purposes 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of sending authorization information. Each time it restarts, we get 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notified of the headers completion so that we can update the cookie store. 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transaction_->IsReadyToRestartForAuth()) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!response_info_->auth_challenge.get()); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(battre): This breaks the webrequest API for 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequestTestHTTP.BasicAuthWithCookies 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // where OnBeforeSendHeaders -> OnSendHeaders -> OnBeforeSendHeaders 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occurs. 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestartTransactionWithAuth(AuthCredentials()); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestJob::NotifyHeadersComplete(); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::NotifyDone(const URLRequestStatus& status) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneWithRequest(FINISHED); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestJob::NotifyDone(status); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::DestroyTransaction() { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneWithRequest(ABORTED); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction_.reset(); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_ = NULL; 36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) receive_headers_end_ = base::TimeTicks(); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::StartTransaction() { 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (network_delegate()) { 3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnCallToDelegate(); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rv = network_delegate()->NotifyBeforeSendHeaders( 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_, notify_before_headers_sent_callback_, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &request_info_.extra_headers); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If an extension blocks the request, we rely on the callback to 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MaybeStartTransactionInternal(). 3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (rv == ERR_IO_PENDING) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeStartTransactionInternal(rv); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTransactionInternal(); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::NotifyBeforeSendHeadersCallback(int result) { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that there are no callbacks to already canceled requests. 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(URLRequestStatus::CANCELED, GetStatus().status()); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeStartTransactionInternal(result); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::MaybeStartTransactionInternal(int result) { 3901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnCallToDelegateComplete(); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == OK) { 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTransactionInternal(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string source("delegate"); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->net_log().AddEvent(NetLog::TYPE_CANCELLED, 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::StringCallback("source", &source)); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyCanceled(); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::StartTransactionInternal() { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: This method assumes that request_info_ is already setup properly. 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we already have a transaction, then we should restart the transaction 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with auth provided by auth_credentials_. 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (network_delegate()) { 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) network_delegate()->NotifySendHeaders( 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_, request_info_.extra_headers); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transaction_.get()) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = transaction_->RestartWithAuth(auth_credentials_, start_callback_); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_credentials_ = AuthCredentials(); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_->context()->http_transaction_factory()); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = request_->context()->http_transaction_factory()->CreateTransaction( 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) priority_, &transaction_); 423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (rv == OK && request_info_.url.SchemeIsWSOrWSS()) { 425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // TODO(ricea): Implement WebSocket throttling semantics as defined in 426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // RFC6455 Section 4.1. 427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::SupportsUserData::Data* data = request_->GetUserData( 428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) WebSocketHandshakeStreamBase::CreateHelper::DataKey()); 429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (data) { 430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) transaction_->SetWebSocketHandshakeStreamCreateHelper( 431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static_cast<WebSocketHandshakeStreamBase::CreateHelper*>(data)); 432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) rv = ERR_DISALLOWED_URL_SCHEME; 434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == OK) { 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transaction_->SetBeforeNetworkStartCallback( 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&URLRequestHttpJob::NotifyBeforeNetworkStart, 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this))); 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!throttling_entry_.get() || 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !throttling_entry_->ShouldRejectRequest(*request_)) { 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = transaction_->Start( 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &request_info_, start_callback_, request_->net_log()); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_time_ = base::TimeTicks::Now(); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Special error code for the exponential back-off module. 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ERR_TEMPORARILY_THROTTLED; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The transaction started synchronously, but we need to notify the 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequest delegate via the message loop. 45990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestHttpJob::OnStartCompleted, 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), rv)); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::AddExtraHeaders() { 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Supply Accept-Encoding field only if it is not already provided. 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It should be provided IF the content is known to have restrictions on 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // potential encoding, such as streaming multi-media. 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For details see bug 47381. 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jar, enal): jpeg files etc. should set up a request header if 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // possible. Right now it is done only by buffered_resource_loader and 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // simple_data_source. 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_info_.extra_headers.HasHeader( 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestHeaders::kAcceptEncoding)) { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool advertise_sdch = SdchManager::Global() && 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SdchManager::Global()->IsInSupportedDomain(request_->url()); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string avail_dictionaries; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (advertise_sdch) { 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SdchManager::Global()->GetAvailDictionaryList(request_->url(), 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &avail_dictionaries); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The AllowLatencyExperiment() is only true if we've successfully done a 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // full SDCH compression recently in this browser session for this host. 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that for this path, there might be no applicable dictionaries, 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and hence we can't participate in the experiment. 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!avail_dictionaries.empty() && 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SdchManager::Global()->AllowLatencyExperiment(request_->url())) { 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We are participating in the test (or control), and hence we'll 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // eventually record statistics via either SDCH_EXPERIMENT_DECODE or 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SDCH_EXPERIMENT_HOLDBACK, and we'll need some packet timing data. 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet_timing_enabled_ = true; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::RandDouble() < .01) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_test_control_ = true; // 1% probability. 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) advertise_sdch = false; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_test_activated_ = true; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Supply Accept-Encoding headers first so that it is more likely that they 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be in the first transmitted packet. This can sometimes make it 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // easier to filter and analyze the streams to assure that a proxy has not 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // damaged these headers. Some proxies deliberately corrupt Accept-Encoding 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // headers. 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!advertise_sdch) { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the server what compression formats we support (other than SDCH). 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.SetHeader( 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestHeaders::kAcceptEncoding, "gzip,deflate"); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Include SDCH in acceptable list. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.SetHeader( 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestHeaders::kAcceptEncoding, "gzip,deflate,sdch"); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!avail_dictionaries.empty()) { 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.SetHeader( 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kAvailDictionaryHeader, 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) avail_dictionaries); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_dictionary_advertised_ = true; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we're tagging this transaction as advertising a dictionary, 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we'll definitely employ an SDCH filter (or tentative sdch filter) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when we get a response. When done, we'll record histograms via 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // arrival times. 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet_timing_enabled_ = true; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (http_user_agent_settings_) { 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only add default Accept-Language if the request didn't have it 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // specified. 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string accept_language = 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_user_agent_settings_->GetAcceptLanguage(); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!accept_language.empty()) { 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.SetHeaderIfMissing( 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestHeaders::kAcceptLanguage, 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_language); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::AddCookieHeaderAndStart() { 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No matter what, we want to report our status as IO pending since we will 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be notifying our consumer asynchronously via OnStartCompleted. 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the request was destroyed, then there is no more work to do. 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 551a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CookieStore* cookie_store = GetCookieStore(); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cookie_store && !(request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES)) { 553effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch cookie_store->GetAllCookiesForURLAsync( 554effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_->url(), 555effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&URLRequestHttpJob::CheckCookiePolicyAndLoad, 556effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_factory_.GetWeakPtr())); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoStartTransaction(); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::DoLoadCookies() { 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CookieOptions options; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.set_include_httponly(); 565a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetCookieStore()->GetCookiesWithOptionsAsync( 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->url(), options, 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestHttpJob::OnCookiesLoaded, 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::CheckCookiePolicyAndLoad( 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CookieList& cookie_list) { 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CanGetCookies(cookie_list)) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoLoadCookies(); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoStartTransaction(); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestHttpJob::OnCookiesLoaded(const std::string& cookie_line) { 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!cookie_line.empty()) { 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.SetHeader( 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestHeaders::kCookie, cookie_line); 58390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Disable privacy mode as we are sending cookies anyway. 584e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch request_info_.privacy_mode = PRIVACY_MODE_DISABLED; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoStartTransaction(); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::DoStartTransaction() { 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We may have been canceled while retrieving cookies. 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetStatus().is_success()) { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTransaction(); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyCanceled(); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete(int result) { 5991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // End of the call started in OnStartCompleted. 6001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnCallToDelegateComplete(); 6011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != net::OK) { 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string source("delegate"); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->net_log().AddEvent(NetLog::TYPE_CANCELLED, 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::StringCallback("source", &source)); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response_info = transaction_->GetResponseInfo(); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(response_info); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_.clear(); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_save_index_ = 0; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FetchResponseCookies(&response_cookies_); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetResponseHeaders()->GetDateValue(&response_date_)) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_date_ = base::Time(); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now, loop over the response cookies, and attempt to persist each. 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SaveNextCookie(); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the save occurs synchronously, SaveNextCookie will loop and save the next 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cookie. If the save is deferred, the callback is responsible for continuing 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to iterate through the cookies. 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(erikwright): Modify the CookieStore API to indicate via return value 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whether it completed synchronously or asynchronously. 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/131066. 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::SaveNextCookie() { 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No matter what, we want to report our status as IO pending since we will 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be notifying our consumer asynchronously via OnStartCompleted. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to communicate with the callback. See the implementation of 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnCookieSaved. 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SharedBoolean> callback_pending = new SharedBoolean(false); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SharedBoolean> save_next_cookie_running = 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SharedBoolean(true); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) && 645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetCookieStore() && response_cookies_.size() > 0) { 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CookieOptions options; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.set_include_httponly(); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.set_server_time(response_date_); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CookieStore::SetCookiesCallback callback( 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestHttpJob::OnCookieSaved, 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save_next_cookie_running, 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_pending)); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loop through the cookies as long as SetCookieWithOptionsAsync completes 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // synchronously. 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!callback_pending->data && 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_save_index_ < response_cookies_.size()) { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CanSetCookie( 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_[response_cookies_save_index_], &options)) { 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_pending->data = true; 663a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetCookieStore()->SetCookieWithOptionsAsync( 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->url(), response_cookies_[response_cookies_save_index_], 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options, callback); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++response_cookies_save_index_; 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save_next_cookie_running->data = false; 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!callback_pending->data) { 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_.clear(); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_save_index_ = 0; 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus()); // Clear the IO_PENDING status 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyHeadersComplete(); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |save_next_cookie_running| is true when the callback is bound and set to 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// false when SaveNextCookie exits, allowing the callback to determine if the 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// save occurred synchronously or asynchronously. 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |callback_pending| is false when the callback is invoked and will be set to 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true by the callback, allowing SaveNextCookie to detect whether the save 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// occurred synchronously. 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See SaveNextCookie() for more information. 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::OnCookieSaved( 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SharedBoolean> save_next_cookie_running, 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SharedBoolean> callback_pending, 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool cookie_status) { 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_pending->data = false; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we were called synchronously, return. 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (save_next_cookie_running->data) { 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We were called asynchronously, so trigger the next save. 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We may have been canceled within OnSetCookie. 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetStatus().is_success()) { 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SaveNextCookie(); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyCanceled(); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::FetchResponseCookies( 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>* cookies) { 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string name = "Set-Cookie"; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* iter = NULL; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponseHeaders* headers = GetResponseHeaders(); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (headers->EnumerateHeader(&iter, name, &value)) { 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value.empty()) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookies->push_back(value); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTE: |ProcessStrictTransportSecurityHeader| and 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |ProcessPublicKeyPinsHeader| have very similar structures, by design. 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::ProcessStrictTransportSecurityHeader() { 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(response_info_); 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransportSecurityState* security_state = 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->context()->transport_security_state(); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLInfo& ssl_info = response_info_->ssl_info; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only accept HSTS headers on HTTPS connections that have no 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // certificate errors. 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !security_state) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec: 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a UA receives more than one STS header field in a HTTP response 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message over secure transport, then the UA MUST process only the 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // first such header field. 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HttpResponseHeaders* headers = GetResponseHeaders(); 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string value; 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (headers->EnumerateHeader(NULL, "Strict-Transport-Security", &value)) 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) security_state->AddHSTSHeader(request_info_.url.host(), value); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::ProcessPublicKeyPinsHeader() { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(response_info_); 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransportSecurityState* security_state = 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->context()->transport_security_state(); 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLInfo& ssl_info = response_info_->ssl_info; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only accept HPKP headers on HTTPS connections that have no 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // certificate errors. 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !security_state) 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // http://tools.ietf.org/html/draft-ietf-websec-key-pinning: 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If a UA receives more than one PKP header field in an HTTP 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // response message over secure transport, then the UA MUST process 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // only the first such header field. 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponseHeaders* headers = GetResponseHeaders(); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (headers->EnumerateHeader(NULL, "Public-Key-Pins", &value)) 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) security_state->AddHPKPHeader(request_info_.url.host(), value, ssl_info); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::OnStartCompleted(int result) { 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordTimer(); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the request was destroyed, then there is no more work to do. 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 777a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If the job is done (due to cancellation), can just ignore this 778a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // notification. 779a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (done_) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) receive_headers_end_ = base::TimeTicks::Now(); 78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the IO_PENDING status 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus()); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const URLRequestContext* context = request_->context(); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction_->GetResponseInfo() != NULL) { 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FraudulentCertificateReporter* reporter = 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context->fraudulent_certificate_reporter(); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reporter != NULL) { 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLInfo& ssl_info = transaction_->GetResponseInfo()->ssl_info; 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool sni_available = SSLConfigService::IsSNIAvailable( 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context->ssl_config_service()); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& host = request_->url().host(); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reporter->SendReport(host, ssl_info, sni_available); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == OK) { 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (network_delegate()) { 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that |this| may not be deleted until 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |on_headers_received_callback_| or 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |NetworkDelegate::URLRequestDestroyed()| has been called. 8091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnCallToDelegate(); 810effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch allowed_unsafe_redirect_url_ = GURL(); 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int error = network_delegate()->NotifyHeadersReceived( 812868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_, 813868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) on_headers_received_callback_, 814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) headers.get(), 815effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &override_response_headers_, 816effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &allowed_unsafe_redirect_url_); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error != net::OK) { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error == net::ERR_IO_PENDING) { 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) awaiting_callback_ = true; 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string source("delegate"); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->net_log().AddEvent(NetLog::TYPE_CANCELLED, 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::StringCallback("source", 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &source)); 8251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnCallToDelegateComplete(); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, error)); 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SaveCookiesAndNotifyHeadersComplete(net::OK); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (IsCertificateError(result)) { 8348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // We encountered an SSL certificate error. 8358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (result == ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY || 8368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) result == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN) { 8378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // These are hard failures. They're handled separately and don't have 8388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // the correct cert status, so set it here. 8398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SSLInfo info(transaction_->GetResponseInfo()->ssl_info); 8408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) info.cert_status = MapNetErrorToCertStatus(result); 8418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NotifySSLCertificateError(info, true); 8428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 8438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Maybe overridable, maybe not. Ask the delegate to decide. 8448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const URLRequestContext* context = request_->context(); 845010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TransportSecurityState* state = context->transport_security_state(); 846010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const bool fatal = 847010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state && 848010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state->ShouldSSLErrorsBeFatal( 8498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) request_info_.url.host(), 850010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SSLConfigService::IsSNIAvailable(context->ssl_config_service())); 8518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NotifySSLCertificateError( 8528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) transaction_->GetResponseInfo()->ssl_info, fatal); 8538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyCertificateRequested( 856868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_->GetResponseInfo()->cert_request_info.get()); 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Even on an error, there may be useful information in the response 8595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // info (e.g. whether there's a cached copy). 8605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (transaction_.get()) 8615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) response_info_ = transaction_->GetResponseInfo(); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::OnHeadersReceivedCallback(int result) { 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) awaiting_callback_ = false; 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that there are no callbacks to already canceled requests. 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(URLRequestStatus::CANCELED, GetStatus().status()); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SaveCookiesAndNotifyHeadersComplete(result); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::OnReadCompleted(int result) { 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_in_progress_ = false; 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ShouldFixMismatchedContentLength(result)) 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = OK; 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == OK) { 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus()); 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (result < 0) { 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the IO_PENDING status 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus()); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyReadComplete(result); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::RestartTransactionWithAuth( 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AuthCredentials& credentials) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_credentials_ = credentials; 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These will be reset in OnStartCompleted. 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_ = NULL; 89990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) receive_headers_end_ = base::TimeTicks(); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_.clear(); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetTimer(); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the cookies, since the cookie store may have been updated from the 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // headers in the 401/407. Since cookies were already appended to 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extra_headers, we need to strip them out before adding them again. 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kCookie); 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddCookieHeaderAndStart(); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestHttpJob::SetUpload(UploadDataStream* upload) { 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!transaction_.get()) << "cannot change once started"; 9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.upload_data_stream = upload; 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::SetExtraRequestHeaders( 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestHeaders& headers) { 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!transaction_.get()) << "cannot change once started"; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.CopyFrom(headers); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadState URLRequestHttpJob::GetLoadState() const { 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transaction_.get() ? 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction_->GetLoadState() : LOAD_STATE_IDLE; 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UploadProgress URLRequestHttpJob::GetUploadProgress() const { 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transaction_.get() ? 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction_->GetUploadProgress() : UploadProgress(); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::GetMimeType(std::string* mime_type) const { 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_info_) 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetResponseHeaders()->GetMimeType(mime_type); 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::GetCharset(std::string* charset) { 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_info_) 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetResponseHeaders()->GetCharset(charset); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::GetResponseInfo(HttpResponseInfo* info) { 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_); 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_info_) { 9555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(transaction_.get()); 9565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *info = *response_info_; 958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (override_response_headers_.get()) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->headers = override_response_headers_; 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestHttpJob::GetLoadTimingInfo( 9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoadTimingInfo* load_timing_info) const { 96590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If haven't made it far enough to receive any headers, don't return 96690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // anything. This makes for more consistent behavior in the case of errors. 96790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!transaction_ || receive_headers_end_.is_null()) 96890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 96990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (transaction_->GetLoadTimingInfo(load_timing_info)) 97090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) load_timing_info->receive_headers_end = receive_headers_end_; 9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::GetResponseCookies(std::vector<std::string>* cookies) { 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_info_) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(darin): Why are we extracting response cookies again? Perhaps we 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should just leverage response_cookies_. 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookies->clear(); 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FetchResponseCookies(cookies); 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLRequestHttpJob::GetResponseCode() const { 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_info_) 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetResponseHeaders()->response_code(); 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Filter* URLRequestHttpJob::SetupFilter() const { 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_info_) 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Filter::FilterType> encoding_types; 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string encoding_type; 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponseHeaders* headers = GetResponseHeaders(); 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* iter = NULL; 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (headers->EnumerateHeader(&iter, "Content-Encoding", &encoding_type)) { 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encoding_types.push_back(Filter::ConvertEncodingToType(encoding_type)); 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (filter_context_->IsSdchResponse()) { 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We are wary of proxies that discard or damage SDCH encoding. If a server 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // explicitly states that this is not SDCH content, then we can correct our 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // assumption that this is an SDCH response, and avoid the need to recover 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as though the content is corrupted (when we discover it is not SDCH 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // encoded). 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sdch_response_status; 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter = NULL; 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (headers->EnumerateHeader(&iter, "X-Sdch-Encode", 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &sdch_response_status)) { 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sdch_response_status == "0") { 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_context_->ResetSdchResponseToFalse(); 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Even if encoding types are empty, there is a chance that we need to add 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // some decoding, as some proxies strip encoding completely. In such cases, 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we may need to add (for example) SDCH filtering (when the context suggests 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it is appropriate). 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Filter::FixupEncodingTypes(*filter_context_, &encoding_types); 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !encoding_types.empty() 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? Filter::Factory(encoding_types, *filter_context_) : NULL; 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1036c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool URLRequestHttpJob::CopyFragmentOnRedirect(const GURL& location) const { 1037c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Allow modification of reference fragments by default, unless 1038c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // |allowed_unsafe_redirect_url_| is set and equal to the redirect URL. 1039c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // When this is the case, we assume that the network delegate has set the 1040c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // desired redirect URL (with or without fragment), so it must not be changed 1041c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // any more. 1042c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return !allowed_unsafe_redirect_url_.is_valid() || 1043c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch allowed_unsafe_redirect_url_ != location; 1044c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 1045c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::IsSafeRedirect(const GURL& location) { 1047b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // HTTP is always safe. 1048b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // TODO(pauljensen): Remove once crbug.com/146591 is fixed. 1049b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (location.is_valid() && 1050b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) (location.scheme() == "http" || location.scheme() == "https")) { 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1053c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Delegates may mark a URL as safe for redirection. 1054c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (allowed_unsafe_redirect_url_.is_valid() && 1055c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch allowed_unsafe_redirect_url_ == location) { 1056c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return true; 1057effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 1058b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Query URLRequestJobFactory as to whether |location| would be safe to 1059b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // redirect to. 1060b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return request_->context()->job_factory() && 1061b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) request_->context()->job_factory()->IsSafeRedirectTarget(location); 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::NeedsAuth() { 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int code = GetResponseCode(); 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (code == -1) 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if we need either Proxy or WWW Authentication. This could happen 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because we either provided no auth info, or provided incorrect info. 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (code) { 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 407: 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy_auth_state_ == AUTH_STATE_CANCELED) 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_auth_state_ = AUTH_STATE_NEED_AUTH; 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 401: 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (server_auth_state_ == AUTH_STATE_CANCELED) 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_auth_state_ = AUTH_STATE_NEED_AUTH; 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::GetAuthChallengeInfo( 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AuthChallengeInfo>* result) { 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(response_info_); 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sanity checks: 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(proxy_auth_state_ == AUTH_STATE_NEED_AUTH || 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_auth_state_ == AUTH_STATE_NEED_AUTH); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK((GetResponseHeaders()->response_code() == HTTP_UNAUTHORIZED) || 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (GetResponseHeaders()->response_code() == 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HTTP_PROXY_AUTHENTICATION_REQUIRED)); 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = response_info_->auth_challenge; 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::SetAuth(const AuthCredentials& credentials) { 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Proxy gets set first, then WWW. 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy_auth_state_ == AUTH_STATE_NEED_AUTH) { 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_auth_state_ = AUTH_STATE_HAVE_AUTH; 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(server_auth_state_, AUTH_STATE_NEED_AUTH); 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_auth_state_ = AUTH_STATE_HAVE_AUTH; 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestartTransactionWithAuth(credentials); 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::CancelAuth() { 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Proxy gets set first, then WWW. 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy_auth_state_ == AUTH_STATE_NEED_AUTH) { 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_auth_state_ = AUTH_STATE_CANCELED; 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(server_auth_state_, AUTH_STATE_NEED_AUTH); 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_auth_state_ = AUTH_STATE_CANCELED; 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These will be reset in OnStartCompleted. 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_ = NULL; 112690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) receive_headers_end_ = base::TimeTicks::Now(); 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_.clear(); 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetTimer(); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OK, let the consumer read the error page... 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Because we set the AUTH_STATE_CANCELED flag, NeedsAuth will return false, 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which will cause the consumer to receive OnResponseStarted instead of 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnAuthRequired. 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have to do this via InvokeLater to avoid "recursing" the consumer. 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 113990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestHttpJob::OnStartCompleted, 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), OK)); 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::ContinueWithCertificate( 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) X509Certificate* client_cert) { 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!response_info_) << "should not have a response yet"; 115090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) receive_headers_end_ = base::TimeTicks(); 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetTimer(); 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No matter what, we want to report our status as IO pending since we will 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be notifying our consumer asynchronously via OnStartCompleted. 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = transaction_->RestartWithCertificate(client_cert, start_callback_); 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The transaction started synchronously, but we need to notify the 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequest delegate via the message loop. 116490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestHttpJob::OnStartCompleted, 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), rv)); 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::ContinueDespiteLastError() { 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the transaction was destroyed, then the job was cancelled. 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!transaction_.get()) 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!response_info_) << "should not have a response yet"; 117690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) receive_headers_end_ = base::TimeTicks(); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetTimer(); 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No matter what, we want to report our status as IO pending since we will 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be notifying our consumer asynchronously via OnStartCompleted. 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = transaction_->RestartIgnoringLastError(start_callback_); 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The transaction started synchronously, but we need to notify the 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequest delegate via the message loop. 119090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestHttpJob::OnStartCompleted, 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), rv)); 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void URLRequestHttpJob::ResumeNetworkStart() { 11975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(transaction_.get()); 11985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transaction_->ResumeNetworkStart(); 11995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 12005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::ShouldFixMismatchedContentLength(int rv) const { 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some servers send the body compressed, but specify the content length as 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the uncompressed size. Although this violates the HTTP spec we want to 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // support it (as IE and FireFox do), but *only* for an exact match. 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://crbug.com/79694. 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == net::ERR_CONTENT_LENGTH_MISMATCH || 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv == net::ERR_INCOMPLETE_CHUNKED_ENCODING) { 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_ && request_->response_headers()) { 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 expected_length = request_->response_headers()->GetContentLength(); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << __FUNCTION__ << "() " 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "\"" << request_->url().spec() << "\"" 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " content-length = " << expected_length 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " pre total = " << prefilter_bytes_read() 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " post total = " << postfilter_bytes_read(); 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (postfilter_bytes_read() == expected_length) { 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the error. 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::ReadRawData(IOBuffer* buf, int buf_size, 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* bytes_read) { 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(buf_size, 0); 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bytes_read); 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!read_in_progress_); 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = transaction_->Read( 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf, buf_size, 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestHttpJob::OnReadCompleted, base::Unretained(this))); 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ShouldFixMismatchedContentLength(rv)) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = 0; 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv >= 0) { 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bytes_read = rv; 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!rv) 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneWithRequest(FINISHED); 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) { 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_in_progress_ = true; 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::StopCaching() { 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transaction_.get()) 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction_->StopCaching(); 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool URLRequestHttpJob::GetFullRequestHeaders( 1260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpRequestHeaders* headers) const { 1261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!transaction_) 1262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 1263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return transaction_->GetFullRequestHeaders(headers); 1265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 1266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 12675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int64 URLRequestHttpJob::GetTotalReceivedBytes() const { 12685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!transaction_) 12695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 12705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return transaction_->GetTotalReceivedBytes(); 12725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 12735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::DoneReading() { 1275effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (transaction_) { 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction_->DoneReading(); 1277effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 1278effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DoneWithRequest(FINISHED); 1279effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 1280effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1281effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid URLRequestHttpJob::DoneReadingRedirectResponse() { 1282effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (transaction_) { 1283effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (transaction_->GetResponseInfo()->headers->IsRedirect(NULL)) { 1284effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // If the original headers indicate a redirect, go ahead and cache the 1285effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // response, even if the |override_response_headers_| are a redirect to 1286effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // another location. 1287effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch transaction_->DoneReading(); 1288effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 1289effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Otherwise, |override_response_headers_| must be non-NULL and contain 1290effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // bogus headers indicating a redirect. 1291effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(override_response_headers_); 1292effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(override_response_headers_->IsRedirect(NULL)); 1293effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch transaction_->StopCaching(); 1294effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 1295effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneWithRequest(FINISHED); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostPortPair URLRequestHttpJob::GetSocketAddress() const { 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return response_info_ ? response_info_->socket_address : HostPortPair(); 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::RecordTimer() { 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_creation_time_.is_null()) { 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "The same transaction shouldn't start twice without new timing."; 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta to_start = base::Time::Now() - request_creation_time_; 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_creation_time_ = base::Time(); 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpTimeToFirstByte", to_start); 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::ResetTimer() { 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_creation_time_.is_null()) { 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "The timer was reset before it was recorded."; 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_creation_time_ = base::Time::Now(); 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::UpdatePacketReadTimes() { 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!packet_timing_enabled_) 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (filter_input_byte_count() <= bytes_observed_in_packets_) { 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(filter_input_byte_count(), bytes_observed_in_packets_); 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // No new bytes have arrived. 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final_packet_time_ = base::Time::Now(); 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bytes_observed_in_packets_) 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_snapshot_ = request_ ? request_->request_time() : base::Time(); 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_observed_in_packets_ = filter_input_byte_count(); 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::RecordPacketStats( 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilterContext::StatisticSelector statistic) const { 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!packet_timing_enabled_ || (final_packet_time_ == base::Time())) 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta duration = final_packet_time_ - request_time_snapshot_; 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (statistic) { 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FilterContext::SDCH_DECODE: { 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS("Sdch3.Network_Decode_Bytes_Processed_b", 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(bytes_observed_in_packets_), 500, 100000, 100); 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FilterContext::SDCH_PASSTHROUGH: { 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Despite advertising a dictionary, we handled non-sdch compressed 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // content. 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FilterContext::SDCH_EXPERIMENT_DECODE: { 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES("Sdch3.Experiment2_Decode", 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) duration, 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(20), 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMinutes(10), 100); 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FilterContext::SDCH_EXPERIMENT_HOLDBACK: { 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES("Sdch3.Experiment2_Holdback", 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) duration, 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(20), 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMinutes(10), 100); 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The common type of histogram we use for all compression-tracking histograms. 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPRESSION_HISTOGRAM(name, sample) \ 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS("Net.Compress." name, sample, \ 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 500, 1000000, 100); \ 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (0) 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::RecordCompressionHistograms() { 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_); 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_) 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_cached_content_ || // Don't record cached content 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !GetStatus().is_success() || // Don't record failed content 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !IsCompressibleContent() || // Only record compressible content 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !prefilter_bytes_read()) // Zero-byte responses aren't useful. 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Miniature requests aren't really compressible. Don't count them. 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMinSize = 16; 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefilter_bytes_read() < kMinSize) 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only record for http or https urls. 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_http = request_->url().SchemeIs("http"); 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_https = request_->url().SchemeIs("https"); 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_http && !is_https) 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int compressed_B = prefilter_bytes_read(); 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int decompressed_B = postfilter_bytes_read(); 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_filtered = HasFilter(); 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want to record how often downloaded resources are compressed. 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // But, we recognize that different protocols may have different 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // properties. So, for each request, we'll put it into one of 3 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // groups: 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a) SSL resources 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Proxies cannot tamper with compression headers with SSL. 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // b) Non-SSL, loaded-via-proxy resources 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In this case, we know a proxy might have interfered. 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // c) Non-SSL, loaded-without-proxy resources 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In this case, we know there was no explicit proxy. However, 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it is possible that a transparent proxy was still interfering. 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each group, we record the same 3 histograms. 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_https) { 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (was_filtered) { 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPRESSION_HISTOGRAM("SSL.BytesBeforeCompression", compressed_B); 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPRESSION_HISTOGRAM("SSL.BytesAfterCompression", decompressed_B); 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPRESSION_HISTOGRAM("SSL.ShouldHaveBeenCompressed", decompressed_B); 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_->was_fetched_via_proxy()) { 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (was_filtered) { 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPRESSION_HISTOGRAM("Proxy.BytesBeforeCompression", compressed_B); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPRESSION_HISTOGRAM("Proxy.BytesAfterCompression", decompressed_B); 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPRESSION_HISTOGRAM("Proxy.ShouldHaveBeenCompressed", decompressed_B); 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (was_filtered) { 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPRESSION_HISTOGRAM("NoProxy.BytesBeforeCompression", compressed_B); 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPRESSION_HISTOGRAM("NoProxy.BytesAfterCompression", decompressed_B); 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPRESSION_HISTOGRAM("NoProxy.ShouldHaveBeenCompressed", decompressed_B); 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::IsCompressibleContent() const { 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string mime_type; 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetMimeType(&mime_type) && 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (IsSupportedJavascriptMimeType(mime_type.c_str()) || 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsSupportedNonImageMimeType(mime_type.c_str())); 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::RecordPerfHistograms(CompletionCause reason) { 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (start_time_.is_null()) 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta total_time = base::TimeTicks::Now() - start_time_; 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTime", total_time); 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reason == FINISHED) { 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeSuccess", total_time); 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeCancel", total_time); 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_info_) { 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_info_->was_cached) { 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeCached", total_time); 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeNotCached", total_time); 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (request_info_.load_flags & LOAD_PREFETCH && !request_->was_cached()) 14830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Net.Prefetch.PrefilterBytesReadFromNetwork", 14840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) prefilter_bytes_read()); 14850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_time_ = base::TimeTicks(); 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::DoneWithRequest(CompletionCause reason) { 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (done_) 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_ = true; 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordPerfHistograms(reason); 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reason == FINISHED) { 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->set_received_response_content_length(prefilter_bytes_read()); 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordCompressionHistograms(); 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseHeaders* URLRequestHttpJob::GetResponseHeaders() const { 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_->GetResponseInfo()); 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return override_response_headers_.get() ? 1504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) override_response_headers_.get() : 1505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_->GetResponseInfo()->headers.get(); 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::NotifyURLRequestDestroyed() { 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) awaiting_callback_ = false; 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1513