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" 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/proxy/proxy_info.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h" 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_config_service.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/fraudulent_certificate_reporter.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/http_user_agent_settings.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_error_job.h" 45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/url_request/url_request_job_factory.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_redirect_job.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_throttler_header_adapter.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_throttler_manager.h" 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/websockets/websocket_handshake_stream_base.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kAvailDictionaryHeader[] = "Avail-Dictionary"; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestHttpJob::HttpFilterContext : public FilterContext { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit HttpFilterContext(URLRequestHttpJob* job); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~HttpFilterContext(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FilterContext implementation. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetMimeType(std::string* mime_type) const OVERRIDE; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetURL(GURL* gurl) const OVERRIDE; 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual bool GetContentDisposition(std::string* disposition) const OVERRIDE; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual base::Time GetRequestTime() const OVERRIDE; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsCachedContent() const OVERRIDE; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsDownload() const OVERRIDE; 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual bool SdchResponseExpected() const OVERRIDE; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int64 GetByteReadCount() const OVERRIDE; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetResponseCode() const OVERRIDE; 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual const URLRequestContext* GetURLRequestContext() const OVERRIDE; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RecordPacketStats(StatisticSelector statistic) const OVERRIDE; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Method to allow us to reset filter context for a response that should have 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // been SDCH encoded when there is an update due to an explicit HTTP header. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetSdchResponseToFalse(); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestHttpJob* job_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(HttpFilterContext); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestHttpJob::HttpFilterContext::HttpFilterContext(URLRequestHttpJob* job) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : job_(job) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(job_); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestHttpJob::HttpFilterContext::~HttpFilterContext() { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::HttpFilterContext::GetMimeType( 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* mime_type) const { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job_->GetMimeType(mime_type); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::HttpFilterContext::GetURL(GURL* gurl) const { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!job_->request()) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *gurl = job_->request()->url(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool URLRequestHttpJob::HttpFilterContext::GetContentDisposition( 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::string* disposition) const { 105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch HttpResponseHeaders* headers = job_->GetResponseHeaders(); 106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void *iter = NULL; 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return headers->EnumerateHeader(&iter, "Content-Disposition", disposition); 108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Time URLRequestHttpJob::HttpFilterContext::GetRequestTime() const { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job_->request() ? job_->request()->request_time() : base::Time(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::HttpFilterContext::IsCachedContent() const { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job_->is_cached_content_; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::HttpFilterContext::IsDownload() const { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (job_->request_info_.load_flags & LOAD_IS_DOWNLOAD) != 0; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::HttpFilterContext::ResetSdchResponseToFalse() { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(job_->sdch_dictionary_advertised_); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_->sdch_dictionary_advertised_ = false; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool URLRequestHttpJob::HttpFilterContext::SdchResponseExpected() const { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job_->sdch_dictionary_advertised_; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 URLRequestHttpJob::HttpFilterContext::GetByteReadCount() const { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job_->filter_input_byte_count(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLRequestHttpJob::HttpFilterContext::GetResponseCode() const { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job_->GetResponseCode(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const URLRequestContext* 140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)URLRequestHttpJob::HttpFilterContext::GetURLRequestContext() const { 141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return job_->request() ? job_->request()->context() : NULL; 142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::HttpFilterContext::RecordPacketStats( 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StatisticSelector statistic) const { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_->RecordPacketStats(statistic); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(darin): make sure the port blocking code is not lost 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetworkDelegate* network_delegate, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme) { 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(scheme == "http" || scheme == "https" || scheme == "ws" || 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scheme == "wss"); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request->context()->http_transaction_factory()) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "requires a valid context"; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new URLRequestErrorJob( 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request, network_delegate, ERR_INVALID_ARGUMENT); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL redirect_url; 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request->GetHSTSRedirect(&redirect_url)) { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new URLRequestRedirectJob( 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request, network_delegate, redirect_url, 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Use status code 307 to preserve the method, so POST requests work. 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, "HSTS"); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new URLRequestHttpJob(request, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) network_delegate, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->context()->http_user_agent_settings()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestHttpJob::URLRequestHttpJob( 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequest* request, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetworkDelegate* network_delegate, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpUserAgentSettings* http_user_agent_settings) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : URLRequestJob(request, network_delegate), 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_(DEFAULT_PRIORITY), 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_(NULL), 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_save_index_(0), 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_auth_state_(AUTH_STATE_DONT_NEED_AUTH), 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_auth_state_(AUTH_STATE_DONT_NEED_AUTH), 1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) start_callback_(base::Bind(&URLRequestHttpJob::OnStartCompleted, 1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Unretained(this))), 1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) notify_before_headers_sent_callback_( 1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&URLRequestHttpJob::NotifyBeforeSendHeadersCallback, 1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Unretained(this))), 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_in_progress_(false), 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throttling_entry_(NULL), 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_dictionary_advertised_(false), 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_test_activated_(false), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_test_control_(false), 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_cached_content_(false), 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_creation_time_(), 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet_timing_enabled_(false), 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_(false), 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_observed_in_packets_(0), 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_snapshot_(), 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final_packet_time_(), 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) filter_context_(new HttpFilterContext(this)), 2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) on_headers_received_callback_( 2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&URLRequestHttpJob::OnHeadersReceivedCallback, 2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Unretained(this))), 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) awaiting_callback_(false), 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) http_user_agent_settings_(http_user_agent_settings), 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_factory_(this) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestThrottlerManager* manager = request->context()->throttler_manager(); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (manager) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throttling_entry_ = manager->RegisterRequestUrl(request->url()); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetTimer(); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)URLRequestHttpJob::~URLRequestHttpJob() { 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(!awaiting_callback_); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!sdch_test_control_ || !sdch_test_activated_); 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_cached_content_) { 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sdch_test_control_) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordPacketStats(FilterContext::SDCH_EXPERIMENT_HOLDBACK); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sdch_test_activated_) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordPacketStats(FilterContext::SDCH_EXPERIMENT_DECODE); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure SDCH filters are told to emit histogram data while 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // filter_context_ is still alive. 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DestroyFilters(); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoneWithRequest(ABORTED); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestHttpJob::SetPriority(RequestPriority priority) { 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_ = priority; 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (transaction_) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transaction_->SetPriority(priority_); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestHttpJob::Start() { 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!transaction_.get()); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // URLRequest::SetReferrer ensures that we do not send username and password 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // fields in the referrer. 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL referrer(request_->referrer()); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.url = request_->url(); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.method = request_->method(); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.load_flags = request_->load_flags(); 24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Enable privacy mode if cookie settings or flags tell us not send or 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // save cookies. 25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool enable_privacy_mode = 25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES) || 25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) || 25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CanEnablePrivacyMode(); 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Privacy mode could still be disabled in OnCookiesLoaded if we are going 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // to send previously saved cookies. 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request_info_.privacy_mode = enable_privacy_mode ? 258e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch PRIVACY_MODE_ENABLED : PRIVACY_MODE_DISABLED; 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Strip Referer from request_info_.extra_headers to prevent, e.g., plugins 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from overriding headers that are controlled using other means. Otherwise a 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // plugin could set a referrer although sending the referrer is inhibited. 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Our consumer should have made sure that this is a safe referrer. See for 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // instance WebCore::FrameLoader::HideReferrer. 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (referrer.is_valid()) { 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer, 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) referrer.spec()); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.extra_headers.SetHeaderIfMissing( 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HttpRequestHeaders::kUserAgent, 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_user_agent_settings_ ? 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) http_user_agent_settings_->GetUserAgent() : std::string()); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddExtraHeaders(); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddCookieHeaderAndStart(); 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestHttpJob::Kill() { 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!transaction_.get()) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DestroyTransaction(); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLRequestJob::Kill(); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 290116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid URLRequestHttpJob::NotifyBeforeSendProxyHeadersCallback( 291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ProxyInfo& proxy_info, 292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch HttpRequestHeaders* request_headers) { 293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(request_headers); 294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_NE(URLRequestStatus::CANCELED, GetStatus().status()); 295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (network_delegate()) { 296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch network_delegate()->NotifyBeforeSendProxyHeaders( 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request_, 298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch proxy_info, 299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request_headers); 300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::NotifyHeadersComplete() { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!response_info_); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_ = transaction_->GetResponseInfo(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save boolean, as we'll need this info at destruction time, and filters may 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // also need this info. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_cached_content_ = response_info_->was_cached; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!is_cached_content_ && throttling_entry_.get()) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestThrottlerHeaderAdapter response_adapter(GetResponseHeaders()); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throttling_entry_->UpdateWithResponse(request_info_.url.host(), 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &response_adapter); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The ordering of these calls is not important. 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessStrictTransportSecurityHeader(); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessPublicKeyPinsHeader(); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SdchManager* sdch_manager(request()->context()->sdch_manager()); 323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (sdch_manager && sdch_manager->IsInSupportedDomain(request_->url())) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string name = "Get-Dictionary"; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_text; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* iter = NULL; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jar): We need to not fetch dictionaries the first time they are 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // seen, but rather wait until we can justify their usefulness. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For now, we will only fetch the first dictionary, which will at least 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // require multiple suggestions before we get additional ones for this site. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Eventually we should wait until a dictionary is requested several times 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before we even download it (so that we don't waste memory or bandwidth). 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetResponseHeaders()->EnumerateHeader(&iter, name, &url_text)) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resolve suggested URL relative to request url. 335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GURL sdch_dictionary_url = request_->url().Resolve(url_text); 336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (sdch_dictionary_url.is_valid()) { 337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sdch_manager->FetchDictionary(request_->url(), sdch_dictionary_url); 338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The HTTP transaction may be restarted several times for the purposes 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of sending authorization information. Each time it restarts, we get 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notified of the headers completion so that we can update the cookie store. 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transaction_->IsReadyToRestartForAuth()) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!response_info_->auth_challenge.get()); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(battre): This breaks the webrequest API for 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequestTestHTTP.BasicAuthWithCookies 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // where OnBeforeSendHeaders -> OnSendHeaders -> OnBeforeSendHeaders 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occurs. 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestartTransactionWithAuth(AuthCredentials()); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestJob::NotifyHeadersComplete(); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::NotifyDone(const URLRequestStatus& status) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneWithRequest(FINISHED); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestJob::NotifyDone(status); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::DestroyTransaction() { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneWithRequest(ABORTED); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction_.reset(); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_ = NULL; 36990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) receive_headers_end_ = base::TimeTicks(); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::StartTransaction() { 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (network_delegate()) { 3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnCallToDelegate(); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rv = network_delegate()->NotifyBeforeSendHeaders( 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_, notify_before_headers_sent_callback_, 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &request_info_.extra_headers); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If an extension blocks the request, we rely on the callback to 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MaybeStartTransactionInternal(). 3801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (rv == ERR_IO_PENDING) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeStartTransactionInternal(rv); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTransactionInternal(); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::NotifyBeforeSendHeadersCallback(int result) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that there are no callbacks to already canceled requests. 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(URLRequestStatus::CANCELED, GetStatus().status()); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeStartTransactionInternal(result); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::MaybeStartTransactionInternal(int result) { 3961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnCallToDelegateComplete(); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == OK) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTransactionInternal(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string source("delegate"); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->net_log().AddEvent(NetLog::TYPE_CANCELLED, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::StringCallback("source", &source)); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyCanceled(); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::StartTransactionInternal() { 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: This method assumes that request_info_ is already setup properly. 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we already have a transaction, then we should restart the transaction 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with auth provided by auth_credentials_. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (network_delegate()) { 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) network_delegate()->NotifySendHeaders( 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_, request_info_.extra_headers); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transaction_.get()) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = transaction_->RestartWithAuth(auth_credentials_, start_callback_); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_credentials_ = AuthCredentials(); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_->context()->http_transaction_factory()); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = request_->context()->http_transaction_factory()->CreateTransaction( 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) priority_, &transaction_); 429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (rv == OK && request_info_.url.SchemeIsWSOrWSS()) { 431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::SupportsUserData::Data* data = request_->GetUserData( 432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) WebSocketHandshakeStreamBase::CreateHelper::DataKey()); 433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (data) { 434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) transaction_->SetWebSocketHandshakeStreamCreateHelper( 435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static_cast<WebSocketHandshakeStreamBase::CreateHelper*>(data)); 436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) rv = ERR_DISALLOWED_URL_SCHEME; 438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == OK) { 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transaction_->SetBeforeNetworkStartCallback( 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&URLRequestHttpJob::NotifyBeforeNetworkStart, 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this))); 445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch transaction_->SetBeforeProxyHeadersSentCallback( 446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&URLRequestHttpJob::NotifyBeforeSendProxyHeadersCallback, 447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this))); 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!throttling_entry_.get() || 4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !throttling_entry_->ShouldRejectRequest(*request_, 4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci network_delegate())) { 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = transaction_->Start( 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &request_info_, start_callback_, request_->net_log()); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_time_ = base::TimeTicks::Now(); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Special error code for the exponential back-off module. 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ERR_TEMPORARILY_THROTTLED; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The transaction started synchronously, but we need to notify the 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequest delegate via the message loop. 46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestHttpJob::OnStartCompleted, 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), rv)); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::AddExtraHeaders() { 474f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SdchManager* sdch_manager = request()->context()->sdch_manager(); 475f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Supply Accept-Encoding field only if it is not already provided. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It should be provided IF the content is known to have restrictions on 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // potential encoding, such as streaming multi-media. 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For details see bug 47381. 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jar, enal): jpeg files etc. should set up a request header if 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // possible. Right now it is done only by buffered_resource_loader and 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // simple_data_source. 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_info_.extra_headers.HasHeader( 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestHeaders::kAcceptEncoding)) { 485f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool advertise_sdch = sdch_manager && 486f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // We don't support SDCH responses to POST as there is a possibility 487f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // of having SDCH encoded responses returned (e.g. by the cache) 488f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // which we cannot decode, and in those situations, we will need 489f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // to retransmit the request without SDCH, which is illegal for a POST. 490f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) request()->method() != "POST" && 491f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sdch_manager->IsInSupportedDomain(request_->url()); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string avail_dictionaries; 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (advertise_sdch) { 494f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sdch_manager->GetAvailDictionaryList(request_->url(), 495f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &avail_dictionaries); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The AllowLatencyExperiment() is only true if we've successfully done a 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // full SDCH compression recently in this browser session for this host. 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that for this path, there might be no applicable dictionaries, 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and hence we can't participate in the experiment. 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!avail_dictionaries.empty() && 502f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sdch_manager->AllowLatencyExperiment(request_->url())) { 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We are participating in the test (or control), and hence we'll 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // eventually record statistics via either SDCH_EXPERIMENT_DECODE or 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SDCH_EXPERIMENT_HOLDBACK, and we'll need some packet timing data. 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet_timing_enabled_ = true; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::RandDouble() < .01) { 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_test_control_ = true; // 1% probability. 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) advertise_sdch = false; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_test_activated_ = true; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Supply Accept-Encoding headers first so that it is more likely that they 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be in the first transmitted packet. This can sometimes make it 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // easier to filter and analyze the streams to assure that a proxy has not 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // damaged these headers. Some proxies deliberately corrupt Accept-Encoding 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // headers. 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!advertise_sdch) { 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the server what compression formats we support (other than SDCH). 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.SetHeader( 5241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci HttpRequestHeaders::kAcceptEncoding, "gzip, deflate"); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Include SDCH in acceptable list. 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.SetHeader( 5281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci HttpRequestHeaders::kAcceptEncoding, "gzip, deflate, sdch"); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!avail_dictionaries.empty()) { 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.SetHeader( 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kAvailDictionaryHeader, 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) avail_dictionaries); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sdch_dictionary_advertised_ = true; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we're tagging this transaction as advertising a dictionary, 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we'll definitely employ an SDCH filter (or tentative sdch filter) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when we get a response. When done, we'll record histograms via 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // arrival times. 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet_timing_enabled_ = true; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (http_user_agent_settings_) { 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only add default Accept-Language if the request didn't have it 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // specified. 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string accept_language = 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_user_agent_settings_->GetAcceptLanguage(); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!accept_language.empty()) { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.SetHeaderIfMissing( 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestHeaders::kAcceptLanguage, 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_language); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::AddCookieHeaderAndStart() { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No matter what, we want to report our status as IO pending since we will 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be notifying our consumer asynchronously via OnStartCompleted. 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the request was destroyed, then there is no more work to do. 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 566a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CookieStore* cookie_store = GetCookieStore(); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cookie_store && !(request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES)) { 568effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch cookie_store->GetAllCookiesForURLAsync( 569effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_->url(), 570effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&URLRequestHttpJob::CheckCookiePolicyAndLoad, 571effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_factory_.GetWeakPtr())); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoStartTransaction(); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::DoLoadCookies() { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CookieOptions options; 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.set_include_httponly(); 580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetCookieStore()->GetCookiesWithOptionsAsync( 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->url(), options, 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestHttpJob::OnCookiesLoaded, 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::CheckCookiePolicyAndLoad( 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CookieList& cookie_list) { 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CanGetCookies(cookie_list)) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoLoadCookies(); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoStartTransaction(); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestHttpJob::OnCookiesLoaded(const std::string& cookie_line) { 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!cookie_line.empty()) { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.SetHeader( 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestHeaders::kCookie, cookie_line); 59890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Disable privacy mode as we are sending cookies anyway. 599e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch request_info_.privacy_mode = PRIVACY_MODE_DISABLED; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoStartTransaction(); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::DoStartTransaction() { 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We may have been canceled while retrieving cookies. 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetStatus().is_success()) { 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTransaction(); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyCanceled(); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete(int result) { 6141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // End of the call started in OnStartCompleted. 6151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnCallToDelegateComplete(); 6161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != net::OK) { 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string source("delegate"); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->net_log().AddEvent(NetLog::TYPE_CANCELLED, 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::StringCallback("source", &source)); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo* response_info = transaction_->GetResponseInfo(); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(response_info); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_.clear(); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_save_index_ = 0; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FetchResponseCookies(&response_cookies_); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetResponseHeaders()->GetDateValue(&response_date_)) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_date_ = base::Time(); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now, loop over the response cookies, and attempt to persist each. 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SaveNextCookie(); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the save occurs synchronously, SaveNextCookie will loop and save the next 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cookie. If the save is deferred, the callback is responsible for continuing 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to iterate through the cookies. 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(erikwright): Modify the CookieStore API to indicate via return value 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whether it completed synchronously or asynchronously. 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/131066. 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::SaveNextCookie() { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No matter what, we want to report our status as IO pending since we will 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be notifying our consumer asynchronously via OnStartCompleted. 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to communicate with the callback. See the implementation of 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnCookieSaved. 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SharedBoolean> callback_pending = new SharedBoolean(false); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SharedBoolean> save_next_cookie_running = 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SharedBoolean(true); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) && 660a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetCookieStore() && response_cookies_.size() > 0) { 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CookieOptions options; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.set_include_httponly(); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.set_server_time(response_date_); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CookieStore::SetCookiesCallback callback( 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestHttpJob::OnCookieSaved, 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save_next_cookie_running, 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_pending)); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loop through the cookies as long as SetCookieWithOptionsAsync completes 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // synchronously. 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!callback_pending->data && 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_save_index_ < response_cookies_.size()) { 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CanSetCookie( 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_[response_cookies_save_index_], &options)) { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_pending->data = true; 678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetCookieStore()->SetCookieWithOptionsAsync( 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->url(), response_cookies_[response_cookies_save_index_], 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options, callback); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++response_cookies_save_index_; 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save_next_cookie_running->data = false; 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!callback_pending->data) { 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_.clear(); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_save_index_ = 0; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus()); // Clear the IO_PENDING status 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyHeadersComplete(); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |save_next_cookie_running| is true when the callback is bound and set to 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// false when SaveNextCookie exits, allowing the callback to determine if the 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// save occurred synchronously or asynchronously. 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |callback_pending| is false when the callback is invoked and will be set to 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true by the callback, allowing SaveNextCookie to detect whether the save 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// occurred synchronously. 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See SaveNextCookie() for more information. 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::OnCookieSaved( 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SharedBoolean> save_next_cookie_running, 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SharedBoolean> callback_pending, 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool cookie_status) { 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_pending->data = false; 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we were called synchronously, return. 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (save_next_cookie_running->data) { 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We were called asynchronously, so trigger the next save. 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We may have been canceled within OnSetCookie. 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetStatus().is_success()) { 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SaveNextCookie(); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyCanceled(); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::FetchResponseCookies( 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>* cookies) { 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string name = "Set-Cookie"; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* iter = NULL; 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponseHeaders* headers = GetResponseHeaders(); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (headers->EnumerateHeader(&iter, name, &value)) { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value.empty()) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookies->push_back(value); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTE: |ProcessStrictTransportSecurityHeader| and 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |ProcessPublicKeyPinsHeader| have very similar structures, by design. 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::ProcessStrictTransportSecurityHeader() { 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(response_info_); 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransportSecurityState* security_state = 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->context()->transport_security_state(); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLInfo& ssl_info = response_info_->ssl_info; 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only accept HSTS headers on HTTPS connections that have no 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // certificate errors. 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !security_state) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec: 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a UA receives more than one STS header field in a HTTP response 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message over secure transport, then the UA MUST process only the 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // first such header field. 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HttpResponseHeaders* headers = GetResponseHeaders(); 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string value; 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (headers->EnumerateHeader(NULL, "Strict-Transport-Security", &value)) 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) security_state->AddHSTSHeader(request_info_.url.host(), value); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::ProcessPublicKeyPinsHeader() { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(response_info_); 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransportSecurityState* security_state = 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->context()->transport_security_state(); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLInfo& ssl_info = response_info_->ssl_info; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only accept HPKP headers on HTTPS connections that have no 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // certificate errors. 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) || 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !security_state) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // http://tools.ietf.org/html/draft-ietf-websec-key-pinning: 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If a UA receives more than one PKP header field in an HTTP 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // response message over secure transport, then the UA MUST process 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // only the first such header field. 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponseHeaders* headers = GetResponseHeaders(); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (headers->EnumerateHeader(NULL, "Public-Key-Pins", &value)) 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) security_state->AddHPKPHeader(request_info_.url.host(), value, ssl_info); 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::OnStartCompleted(int result) { 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordTimer(); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the request was destroyed, then there is no more work to do. 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 792a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If the job is done (due to cancellation), can just ignore this 793a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // notification. 794a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (done_) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) receive_headers_end_ = base::TimeTicks::Now(); 79890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the IO_PENDING status 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus()); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const URLRequestContext* context = request_->context(); 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction_->GetResponseInfo() != NULL) { 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FraudulentCertificateReporter* reporter = 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context->fraudulent_certificate_reporter(); 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reporter != NULL) { 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLInfo& ssl_info = transaction_->GetResponseInfo()->ssl_info; 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& host = request_->url().host(); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci reporter->SendReport(host, ssl_info); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == OK) { 817f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (transaction_ && transaction_->GetResponseInfo()) { 818f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SetProxyServer(transaction_->GetResponseInfo()->proxy_server); 819f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (network_delegate()) { 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that |this| may not be deleted until 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |on_headers_received_callback_| or 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |NetworkDelegate::URLRequestDestroyed()| has been called. 8251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnCallToDelegate(); 826effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch allowed_unsafe_redirect_url_ = GURL(); 8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int error = network_delegate()->NotifyHeadersReceived( 828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_, 829868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) on_headers_received_callback_, 830868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) headers.get(), 831effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &override_response_headers_, 832effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &allowed_unsafe_redirect_url_); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error != net::OK) { 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error == net::ERR_IO_PENDING) { 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) awaiting_callback_ = true; 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string source("delegate"); 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->net_log().AddEvent(NetLog::TYPE_CANCELLED, 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::StringCallback("source", 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &source)); 8411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnCallToDelegateComplete(); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, error)); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SaveCookiesAndNotifyHeadersComplete(net::OK); 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (IsCertificateError(result)) { 8508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // We encountered an SSL certificate error. 8518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (result == ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY || 8528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) result == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN) { 8538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // These are hard failures. They're handled separately and don't have 8548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // the correct cert status, so set it here. 8558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SSLInfo info(transaction_->GetResponseInfo()->ssl_info); 8568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) info.cert_status = MapNetErrorToCertStatus(result); 8578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NotifySSLCertificateError(info, true); 8588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 8598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Maybe overridable, maybe not. Ask the delegate to decide. 8608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const URLRequestContext* context = request_->context(); 861010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TransportSecurityState* state = context->transport_security_state(); 862010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const bool fatal = 8631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci state && state->ShouldSSLErrorsBeFatal(request_info_.url.host()); 8648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NotifySSLCertificateError( 8658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) transaction_->GetResponseInfo()->ssl_info, fatal); 8668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyCertificateRequested( 869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_->GetResponseInfo()->cert_request_info.get()); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Even on an error, there may be useful information in the response 8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // info (e.g. whether there's a cached copy). 8735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (transaction_.get()) 8745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) response_info_ = transaction_->GetResponseInfo(); 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::OnHeadersReceivedCallback(int result) { 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) awaiting_callback_ = false; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that there are no callbacks to already canceled requests. 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(URLRequestStatus::CANCELED, GetStatus().status()); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SaveCookiesAndNotifyHeadersComplete(result); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::OnReadCompleted(int result) { 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_in_progress_ = false; 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ShouldFixMismatchedContentLength(result)) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = OK; 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == OK) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus()); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (result < 0) { 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the IO_PENDING status 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus()); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyReadComplete(result); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::RestartTransactionWithAuth( 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AuthCredentials& credentials) { 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_credentials_ = credentials; 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These will be reset in OnStartCompleted. 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_ = NULL; 91290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) receive_headers_end_ = base::TimeTicks(); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_cookies_.clear(); 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetTimer(); 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the cookies, since the cookie store may have been updated from the 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // headers in the 401/407. Since cookies were already appended to 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extra_headers, we need to strip them out before adding them again. 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kCookie); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddCookieHeaderAndStart(); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestHttpJob::SetUpload(UploadDataStream* upload) { 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!transaction_.get()) << "cannot change once started"; 9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.upload_data_stream = upload; 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::SetExtraRequestHeaders( 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestHeaders& headers) { 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!transaction_.get()) << "cannot change once started"; 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers.CopyFrom(headers); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadState URLRequestHttpJob::GetLoadState() const { 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transaction_.get() ? 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction_->GetLoadState() : LOAD_STATE_IDLE; 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UploadProgress URLRequestHttpJob::GetUploadProgress() const { 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transaction_.get() ? 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction_->GetUploadProgress() : UploadProgress(); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::GetMimeType(std::string* mime_type) const { 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_info_) 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetResponseHeaders()->GetMimeType(mime_type); 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestHttpJob::GetCharset(std::string* charset) { 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transaction_.get()); 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_info_) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetResponseHeaders()->GetCharset(charset); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestHttpJob::GetResponseInfo(HttpResponseInfo* info) { 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_info_) { 9685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(transaction_.get()); 9695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *info = *response_info_; 971868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (override_response_headers_.get()) 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->headers = override_response_headers_; 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestHttpJob::GetLoadTimingInfo( 9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoadTimingInfo* load_timing_info) const { 97890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If haven't made it far enough to receive any headers, don't return 97990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // anything. This makes for more consistent behavior in the case of errors. 98090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!transaction_ || receive_headers_end_.is_null()) 981