url_request_http_job.cc revision c7f5f8508d98d5952d42ed7648c2a8f30a4da156
1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/url_request/url_request_http_job.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/base_switches.h" 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/command_line.h" 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/compiler_specific.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_util.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_version_info.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/rand_util.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/cert_status_flags.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/cookie_policy.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/filter.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/https_prober.h" 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/transport_security_state.h" 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/load_flags.h" 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h" 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_util.h" 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/sdch_manager.h" 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/ssl_cert_request_info.h" 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_response_headers.h" 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_response_info.h" 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_transaction.h" 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_transaction_factory.h" 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_util.h" 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/url_request/url_request.h" 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/url_request/url_request_context.h" 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/url_request/url_request_error_job.h" 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/url_request/url_request_redirect_job.h" 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// TODO(darin): make sure the port blocking code is not lost 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottURLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& scheme) { 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(scheme == "http" || scheme == "https"); 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int port = request->url().IntPort(); 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!net::IsPortAllowedByDefault(port) && !net::IsPortAllowedByOverride(port)) 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new URLRequestErrorJob(request, net::ERR_UNSAFE_PORT); 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!request->context() || 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !request->context()->http_transaction_factory()) { 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED() << "requires a valid context"; 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new URLRequestErrorJob(request, net::ERR_INVALID_ARGUMENT); 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::TransportSecurityState::DomainState domain_state; 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (scheme == "http" && 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (request->url().port().empty() || port == 80) && 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request->context()->transport_security_state() && 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request->context()->transport_security_state()->IsEnabledForHost( 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &domain_state, request->url().host())) { 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (domain_state.mode == 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::TransportSecurityState::DomainState::MODE_STRICT) { 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK_EQ(request->url().scheme(), "http"); 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott url_canon::Replacements<char> replacements; 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const char kNewScheme[] = "https"; 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott replacements.SetScheme(kNewScheme, 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott url_parse::Component(0, strlen(kNewScheme))); 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GURL new_location = request->url().ReplaceComponents(replacements); 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new URLRequestRedirectJob(request, new_location); 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(agl): implement opportunistic HTTPS upgrade. 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new URLRequestHttpJob(request); 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottURLRequestHttpJob::URLRequestHttpJob(URLRequest* request) 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : URLRequestJob(request), 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott context_(request->context()), 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_info_(NULL), 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_cookies_save_index_(0), 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott proxy_auth_state_(net::AUTH_STATE_DONT_NEED_AUTH), 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott server_auth_state_(net::AUTH_STATE_DONT_NEED_AUTH), 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ALLOW_THIS_IN_INITIALIZER_LIST(can_get_cookies_callback_( 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &URLRequestHttpJob::OnCanGetCookiesCompleted)), 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ALLOW_THIS_IN_INITIALIZER_LIST(can_set_cookie_callback_( 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &URLRequestHttpJob::OnCanSetCookieCompleted)), 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ALLOW_THIS_IN_INITIALIZER_LIST(start_callback_( 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &URLRequestHttpJob::OnStartCompleted)), 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ALLOW_THIS_IN_INITIALIZER_LIST(read_callback_( 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &URLRequestHttpJob::OnReadCompleted)), 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_in_progress_(false), 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott transaction_(NULL), 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sdch_dictionary_advertised_(false), 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sdch_test_activated_(false), 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sdch_test_control_(false), 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott is_cached_content_(false) { 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottURLRequestHttpJob::~URLRequestHttpJob() { 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!sdch_test_control_ || !sdch_test_activated_); 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!IsCachedContent()) { 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sdch_test_control_) 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RecordPacketStats(SDCH_EXPERIMENT_HOLDBACK); 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sdch_test_activated_) 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RecordPacketStats(SDCH_EXPERIMENT_DECODE); 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Make sure SDCH filters are told to emit histogram data while this class 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // can still service the IsCachedContent() call. 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DestroyFilters(); 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sdch_dictionary_url_.is_valid()) { 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Prior to reaching the destructor, request_ has been set to a NULL 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // pointer, so request_->url() is no longer valid in the destructor, and we 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // use an alternate copy |request_info_.url|. 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SdchManager* manager = SdchManager::Global(); 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // To be extra safe, since this is a "different time" from when we decided 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to get the dictionary, we'll validate that an SdchManager is available. 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // At shutdown time, care is taken to be sure that we don't delete this 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // globally useful instance "too soon," so this check is just defensive 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // coding to assure that IF the system is shutting down, we don't have any 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // problem if the manager was deleted ahead of time. 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (manager) // Defensive programming. 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott manager->FetchDictionary(request_info_.url, sdch_dictionary_url_); 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::SetUpload(net::UploadData* upload) { 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!transaction_.get()) << "cannot change once started"; 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.upload_data = upload; 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::SetExtraRequestHeaders( 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& headers) { 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!transaction_.get()) << "cannot change once started"; 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.extra_headers = headers; 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::Start() { 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!transaction_.get()); 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Ensure that we do not send username and password fields in the referrer. 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GURL referrer(request_->GetSanitizedReferrer()); 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.url = request_->url(); 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.referrer = referrer; 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.method = request_->method(); 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.load_flags = request_->load_flags(); 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.priority = request_->priority(); 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (request_->context()) { 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.user_agent = 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->context()->GetUserAgent(request_->url()); 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddExtraHeaders(); 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddCookieHeaderAndStart(); 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::Kill() { 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!transaction_.get()) 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DestroyTransaction(); 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott URLRequestJob::Kill(); 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnet::LoadState URLRequestHttpJob::GetLoadState() const { 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return transaction_.get() ? 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott transaction_->GetLoadState() : net::LOAD_STATE_IDLE; 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottuint64 URLRequestHttpJob::GetUploadProgress() const { 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return transaction_.get() ? transaction_->GetUploadProgress() : 0; 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool URLRequestHttpJob::GetMimeType(std::string* mime_type) const { 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(transaction_.get()); 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!response_info_) 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return response_info_->headers->GetMimeType(mime_type); 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool URLRequestHttpJob::GetCharset(std::string* charset) { 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(transaction_.get()); 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!response_info_) 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return response_info_->headers->GetCharset(charset); 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::GetResponseInfo(net::HttpResponseInfo* info) { 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(request_); 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(transaction_.get()); 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (response_info_) 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *info = *response_info_; 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool URLRequestHttpJob::GetResponseCookies( 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::vector<std::string>* cookies) { 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(transaction_.get()); 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!response_info_) 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(darin): Why are we extracting response cookies again? Perhaps we 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // should just leverage response_cookies_. 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cookies->clear(); 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FetchResponseCookies(response_info_, cookies); 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint URLRequestHttpJob::GetResponseCode() const { 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(transaction_.get()); 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!response_info_) 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return response_info_->headers->response_code(); 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool URLRequestHttpJob::GetContentEncodings( 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::vector<Filter::FilterType>* encoding_types) { 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(transaction_.get()); 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!response_info_) 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(encoding_types->empty()); 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string encoding_type; 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* iter = NULL; 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (response_info_->headers->EnumerateHeader(&iter, "Content-Encoding", 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &encoding_type)) { 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott encoding_types->push_back(Filter::ConvertEncodingToType(encoding_type)); 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Even if encoding types are empty, there is a chance that we need to add 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // some decoding, as some proxies strip encoding completely. In such cases, 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // we may need to add (for example) SDCH filtering (when the context suggests 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // it is appropriate). 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Filter::FixupEncodingTypes(*this, encoding_types); 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return !encoding_types->empty(); 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool URLRequestHttpJob::IsSdchResponse() const { 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return sdch_dictionary_advertised_; 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool URLRequestHttpJob::IsSafeRedirect(const GURL& location) { 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We only allow redirects to certain "safe" protocols. This does not 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // restrict redirects to externally handled protocols. Our consumer would 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // need to take care of those. 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!URLRequest::IsHandledURL(location)) 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const char* kSafeSchemes[] = { 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "http", 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "https", 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "ftp" 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = 0; i < arraysize(kSafeSchemes); ++i) { 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (location.SchemeIs(kSafeSchemes[i])) 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool URLRequestHttpJob::NeedsAuth() { 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int code = GetResponseCode(); 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (code == -1) 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Check if we need either Proxy or WWW Authentication. This could happen 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // because we either provided no auth info, or provided incorrect info. 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switch (code) { 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case 407: 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (proxy_auth_state_ == net::AUTH_STATE_CANCELED) 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott proxy_auth_state_ = net::AUTH_STATE_NEED_AUTH; 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case 401: 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (server_auth_state_ == net::AUTH_STATE_CANCELED) 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott server_auth_state_ = net::AUTH_STATE_NEED_AUTH; 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::GetAuthChallengeInfo( 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<net::AuthChallengeInfo>* result) { 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(transaction_.get()); 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(response_info_); 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // sanity checks: 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(proxy_auth_state_ == net::AUTH_STATE_NEED_AUTH || 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott server_auth_state_ == net::AUTH_STATE_NEED_AUTH); 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(response_info_->headers->response_code() == 401 || 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_info_->headers->response_code() == 407); 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *result = response_info_->auth_challenge; 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::SetAuth(const std::wstring& username, 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::wstring& password) { 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(transaction_.get()); 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Proxy gets set first, then WWW. 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (proxy_auth_state_ == net::AUTH_STATE_NEED_AUTH) { 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott proxy_auth_state_ = net::AUTH_STATE_HAVE_AUTH; 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(server_auth_state_ == net::AUTH_STATE_NEED_AUTH); 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott server_auth_state_ = net::AUTH_STATE_HAVE_AUTH; 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RestartTransactionWithAuth(username, password); 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::RestartTransactionWithAuth( 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::wstring& username, 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::wstring& password) { 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott username_ = username; 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott password_ = password; 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // These will be reset in OnStartCompleted. 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_info_ = NULL; 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_cookies_.clear(); 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Update the cookies, since the cookie store may have been updated from the 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // headers in the 401/407. Since cookies were already appended to 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // extra_headers, we need to strip them out before adding them again. 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const char* const cookie_name[] = { "cookie" }; 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.extra_headers = net::HttpUtil::StripHeaders( 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.extra_headers, cookie_name, arraysize(cookie_name)); 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddCookieHeaderAndStart(); 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::CancelAuth() { 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Proxy gets set first, then WWW. 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (proxy_auth_state_ == net::AUTH_STATE_NEED_AUTH) { 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott proxy_auth_state_ = net::AUTH_STATE_CANCELED; 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(server_auth_state_ == net::AUTH_STATE_NEED_AUTH); 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott server_auth_state_ = net::AUTH_STATE_CANCELED; 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // These will be reset in OnStartCompleted. 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_info_ = NULL; 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_cookies_.clear(); 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OK, let the consumer read the error page... 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Because we set the AUTH_STATE_CANCELED flag, NeedsAuth will return false, 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // which will cause the consumer to receive OnResponseStarted instead of 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OnAuthRequired. 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We have to do this via InvokeLater to avoid "recursing" the consumer. 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &URLRequestHttpJob::OnStartCompleted, net::OK)); 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::ContinueWithCertificate( 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::X509Certificate* client_cert) { 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(transaction_.get()); 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!response_info_) << "should not have a response yet"; 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // No matter what, we want to report our status as IO pending since we will 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be notifying our consumer asynchronously via OnStartCompleted. 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = transaction_->RestartWithCertificate(client_cert, &start_callback_); 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The transaction started synchronously, but we need to notify the 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // URLRequest delegate via the message loop. 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &URLRequestHttpJob::OnStartCompleted, rv)); 387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::ContinueDespiteLastError() { 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the transaction was destroyed, then the job was cancelled. 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!transaction_.get()) 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!response_info_) << "should not have a response yet"; 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // No matter what, we want to report our status as IO pending since we will 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be notifying our consumer asynchronously via OnStartCompleted. 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = transaction_->RestartIgnoringLastError(&start_callback_); 401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The transaction started synchronously, but we need to notify the 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // URLRequest delegate via the message loop. 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &URLRequestHttpJob::OnStartCompleted, rv)); 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool URLRequestHttpJob::ReadRawData(net::IOBuffer* buf, int buf_size, 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int *bytes_read) { 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK_NE(buf_size, 0); 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(bytes_read); 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!read_in_progress_); 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = transaction_->Read(buf, buf_size, &read_callback_); 417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv >= 0) { 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *bytes_read = rv; 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) { 423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_in_progress_ = true; 424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::OnCanGetCookiesCompleted(int policy) { 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the request was destroyed, then there is no more work to do. 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (request_ && request_->delegate()) { 435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (policy == net::OK && request_->context()->cookie_store()) { 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::CookieOptions options; 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott options.set_include_httponly(); 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string cookies = 439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->context()->cookie_store()->GetCookiesWithOptions( 440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->url(), options); 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (request_->context()->InterceptRequestCookies(request_, cookies) && 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !cookies.empty()) 443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.extra_headers += "Cookie: " + cookies + "\r\n"; 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott StartTransaction(); 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Release(); // Balance AddRef taken in AddCookieHeaderAndStart 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::OnCanSetCookieCompleted(int policy) { 451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the request was destroyed, then there is no more work to do. 452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (request_ && request_->delegate()) { 453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (policy == net::OK && request_->context()->cookie_store()) { 454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OK to save the current response cookie now. 455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::CookieOptions options; 456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott options.set_include_httponly(); 457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->context()->cookie_store()->SetCookieWithOptions( 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->url(), response_cookies_[response_cookies_save_index_], 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott options); 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_cookies_save_index_++; 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SaveNextCookie(); 463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Release(); // Balance AddRef taken in SaveNextCookie 465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::OnStartCompleted(int result) { 468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the request was destroyed, then there is no more work to do. 469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!request_ || !request_->delegate()) 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the transaction was destroyed, then the job was cancelled, and 473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // we can just ignore this notification. 474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!transaction_.get()) 475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Clear the IO_PENDING status 478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetStatus(URLRequestStatus()); 479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result == net::OK) { 481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SaveCookiesAndNotifyHeadersComplete(); 482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (ShouldTreatAsCertificateError(result)) { 483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We encountered an SSL certificate error. Ask our delegate to decide 484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // what we should do. 485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(wtc): also pass ssl_info.cert_status, or just pass the whole 486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ssl_info. 487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->delegate()->OnSSLCertificateError( 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_, result, transaction_->GetResponseInfo()->ssl_info.cert); 489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (result == net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->delegate()->OnCertificateRequested( 491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_, transaction_->GetResponseInfo()->cert_request_info); 492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); 494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::OnReadCompleted(int result) { 498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_in_progress_ = false; 499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result == 0) { 501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NotifyDone(URLRequestStatus()); 502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (result < 0) { 503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); 504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Clear the IO_PENDING status 506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetStatus(URLRequestStatus()); 507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NotifyReadComplete(result); 510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool URLRequestHttpJob::ShouldTreatAsCertificateError(int result) { 513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!net::IsCertificateError(result)) 514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Check whether our context is using Strict-Transport-Security. 517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!context_->transport_security_state()) 518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::TransportSecurityState::DomainState domain_state; 521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(agl): don't ignore opportunistic mode. 522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const bool r = context_->transport_security_state()->IsEnabledForHost( 523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &domain_state, request_info_.url.host()); 524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return !r || domain_state.mode == 526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::TransportSecurityState::DomainState::MODE_OPPORTUNISTIC; 527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::NotifyHeadersComplete() { 530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!response_info_); 531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_info_ = transaction_->GetResponseInfo(); 533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Save boolean, as we'll need this info at destruction time, and filters may 535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // also need this info. 536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott is_cached_content_ = response_info_->was_cached; 537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProcessStrictTransportSecurityHeader(); 539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (SdchManager::Global() && 541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SdchManager::Global()->IsInSupportedDomain(request_->url())) { 542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const std::string name = "Get-Dictionary"; 543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string url_text; 544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* iter = NULL; 545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(jar): We need to not fetch dictionaries the first time they are 546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // seen, but rather wait until we can justify their usefulness. 547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // For now, we will only fetch the first dictionary, which will at least 548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // require multiple suggestions before we get additional ones for this site. 549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Eventually we should wait until a dictionary is requested several times 550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // before we even download it (so that we don't waste memory or bandwidth). 551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (response_info_->headers->EnumerateHeader(&iter, name, &url_text)) { 552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // request_->url() won't be valid in the destructor, so we use an 553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // alternate copy. 554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(request_->url() == request_info_.url); 555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Resolve suggested URL relative to request url. 556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sdch_dictionary_url_ = request_info_.url.Resolve(url_text); 557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The HTTP transaction may be restarted several times for the purposes 561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // of sending authorization information. Each time it restarts, we get 562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // notified of the headers completion so that we can update the cookie store. 563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (transaction_->IsReadyToRestartForAuth()) { 564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!response_info_->auth_challenge.get()); 565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RestartTransactionWithAuth(std::wstring(), std::wstring()); 566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott URLRequestJob::NotifyHeadersComplete(); 570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#pragma optimize("", off) 574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#pragma warning(disable:4748) 575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::DestroyTransaction() { 577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CHECK(transaction_.get()); 578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(rvargas): remove this after finding the cause for bug 31723. 579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char local_obj[sizeof(*this)]; 580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(local_obj, this, sizeof(local_obj)); 581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott transaction_.reset(); 583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_info_ = NULL; 584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#pragma warning(default:4748) 587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#pragma optimize("", on) 588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::StartTransaction() { 591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // NOTE: This method assumes that request_info_ is already setup properly. 592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If we already have a transaction, then we should restart the transaction 594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // with auth provided by username_ and password_. 595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv; 597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (transaction_.get()) { 598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = transaction_->RestartWithAuth(username_, password_, &start_callback_); 599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott username_.clear(); 600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott password_.clear(); 601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(request_->context()); 603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(request_->context()->http_transaction_factory()); 604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = request_->context()->http_transaction_factory()->CreateTransaction( 606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &transaction_); 607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::OK) { 608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = transaction_->Start( 609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &request_info_, &start_callback_, request_->load_log()); 610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == net::ERR_IO_PENDING) 614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The transaction started synchronously, but we need to notify the 617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // URLRequest delegate via the message loop. 618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this, &URLRequestHttpJob::OnStartCompleted, rv)); 620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::AddExtraHeaders() { 623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(jar): Consider optimizing away SDCH advertising bytes when the URL is 624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // probably an img or such (and SDCH encoding is not likely). 625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool advertise_sdch = SdchManager::Global() && 626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SdchManager::Global()->IsInSupportedDomain(request_->url()); 627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string avail_dictionaries; 628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (advertise_sdch) { 629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SdchManager::Global()->GetAvailDictionaryList(request_->url(), 630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &avail_dictionaries); 631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The AllowLatencyExperiment() is only true if we've successfully done a 633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // full SDCH compression recently in this browser session for this host. 634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that for this path, there might be no applicable dictionaries, and 635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // hence we can't participate in the experiment. 636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!avail_dictionaries.empty() && 637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SdchManager::Global()->AllowLatencyExperiment(request_->url())) { 638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We are participating in the test (or control), and hence we'll 639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // eventually record statistics via either SDCH_EXPERIMENT_DECODE or 640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // SDCH_EXPERIMENT_HOLDBACK, and we'll need some packet timing data. 641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EnablePacketCounting(kSdchPacketHistogramCount); 642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (base::RandDouble() < .01) { 643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sdch_test_control_ = true; // 1% probability. 644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott advertise_sdch = false; 645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sdch_test_activated_ = true; 647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Supply Accept-Encoding headers first so that it is more likely that they 652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // will be in the first transmitted packet. This can sometimes make it easier 653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to filter and analyze the streams to assure that a proxy has not damaged 654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // these headers. Some proxies deliberately corrupt Accept-Encoding headers. 655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!advertise_sdch) { 656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Tell the server what compression formats we support (other than SDCH). 657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.extra_headers += "Accept-Encoding: gzip,deflate\r\n"; 658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Include SDCH in acceptable list. 660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.extra_headers += "Accept-Encoding: " 661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "gzip,deflate,sdch\r\n"; 662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!avail_dictionaries.empty()) { 663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_info_.extra_headers += "Avail-Dictionary: " 664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott + avail_dictionaries + "\r\n"; 665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sdch_dictionary_advertised_ = true; 666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Since we're tagging this transaction as advertising a dictionary, we'll 667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // definately employ an SDCH filter (or tentative sdch filter) when we get 668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // a response. When done, we'll record histograms via SDCH_DECODE or 669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // SDCH_PASSTHROUGH. Hence we need to record packet arrival times. 670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EnablePacketCounting(kSdchPacketHistogramCount); 671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott URLRequestContext* context = request_->context(); 675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (context) { 676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Only add default Accept-Language and Accept-Charset if the request 677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // didn't have them specified. 678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::HttpUtil::AppendHeaderIfMissing("Accept-Language", 679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott context->accept_language(), 680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &request_info_.extra_headers); 681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::HttpUtil::AppendHeaderIfMissing("Accept-Charset", 682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott context->accept_charset(), 683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &request_info_.extra_headers); 684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::AddCookieHeaderAndStart() { 688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // No matter what, we want to report our status as IO pending since we will 689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be notifying our consumer asynchronously via OnStartCompleted. 690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddRef(); // Balanced in OnCanGetCookiesCompleted 693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int policy = net::OK; 695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (request_info_.load_flags & net::LOAD_DO_NOT_SEND_COOKIES) { 697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott policy = net::ERR_ACCESS_DENIED; 698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (request_->context()->cookie_policy()) { 699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott policy = request_->context()->cookie_policy()->CanGetCookies( 700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->url(), 701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->first_party_for_cookies(), 702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &can_get_cookies_callback_); 703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (policy == net::ERR_IO_PENDING) 704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; // Wait for completion callback 705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OnCanGetCookiesCompleted(policy); 708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete() { 711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(transaction_.get()); 712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const net::HttpResponseInfo* response_info = transaction_->GetResponseInfo(); 714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(response_info); 715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_cookies_.clear(); 717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_cookies_save_index_ = 0; 718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FetchResponseCookies(response_info, &response_cookies_); 720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Now, loop over the response cookies, and attempt to persist each. 722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SaveNextCookie(); 723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::SaveNextCookie() { 726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (response_cookies_save_index_ == response_cookies_.size()) { 727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_cookies_.clear(); 728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_cookies_save_index_ = 0; 729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetStatus(URLRequestStatus()); // Clear the IO_PENDING status 730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NotifyHeadersComplete(); 731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // No matter what, we want to report our status as IO pending since we will 735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be notifying our consumer asynchronously via OnStartCompleted. 736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddRef(); // Balanced in OnCanSetCookieCompleted 739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int policy = net::OK; 741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (request_info_.load_flags & net::LOAD_DO_NOT_SAVE_COOKIES) { 743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott policy = net::ERR_ACCESS_DENIED; 744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (request_->context()->cookie_policy()) { 745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott policy = request_->context()->cookie_policy()->CanSetCookie( 746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->url(), 747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott request_->first_party_for_cookies(), 748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott response_cookies_[response_cookies_save_index_], 749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &can_set_cookie_callback_); 750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (policy == net::ERR_IO_PENDING) 751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; // Wait for completion callback 752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OnCanSetCookieCompleted(policy); 755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::FetchResponseCookies( 758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const net::HttpResponseInfo* response_info, 759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::vector<std::string>* cookies) { 760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string name = "Set-Cookie"; 761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string value; 762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* iter = NULL; 764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (response_info->headers->EnumerateHeader(&iter, name, &value)) { 765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (request_->context()->InterceptResponseCookie(request_, value)) 766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cookies->push_back(value); 767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass HTTPSProberDelegate : public net::HTTPSProberDelegate { 771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HTTPSProberDelegate(const std::string& host, int max_age, 773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool include_subdomains, 774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::TransportSecurityState* sts) 775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : host_(host), 776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott max_age_(max_age), 777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott include_subdomains_(include_subdomains), 778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sts_(sts) { } 779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void ProbeComplete(bool result) { 781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result) { 782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::Time current_time(base::Time::Now()); 783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta max_age_delta = base::TimeDelta::FromSeconds(max_age_); 784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::TransportSecurityState::DomainState domain_state; 786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott domain_state.expiry = current_time + max_age_delta; 787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott domain_state.mode = 788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::TransportSecurityState::DomainState::MODE_OPPORTUNISTIC; 789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott domain_state.include_subdomains = include_subdomains_; 790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sts_->EnableHost(host_, domain_state); 792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete this; 795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string host_; 799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int max_age_; 800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const bool include_subdomains_; 801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<net::TransportSecurityState> sts_; 802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid URLRequestHttpJob::ProcessStrictTransportSecurityHeader() { 805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(response_info_); 806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott URLRequestContext* ctx = request_->context(); 808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ctx || !ctx->transport_security_state()) 809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const bool https = response_info_->ssl_info.is_valid(); 812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const bool valid_https = 813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott https && 814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !(response_info_->ssl_info.cert_status & net::CERT_STATUS_ALL_ERRORS); 815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string name = "Strict-Transport-Security"; 817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string value; 818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int max_age; 820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool include_subdomains; 821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* iter = NULL; 823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (response_info_->headers->EnumerateHeader(&iter, name, &value)) { 824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const bool ok = net::TransportSecurityState::ParseHeader( 825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value, &max_age, &include_subdomains); 826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ok) 827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We will only accept strict mode if we saw the header from an HTTPS 829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // connection with no certificate problems. 830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!valid_https) 831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::Time current_time(base::Time::Now()); 833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta max_age_delta = base::TimeDelta::FromSeconds(max_age); 834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::TransportSecurityState::DomainState domain_state; 836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott domain_state.expiry = current_time + max_age_delta; 837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott domain_state.mode = net::TransportSecurityState::DomainState::MODE_STRICT; 838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott domain_state.include_subdomains = include_subdomains; 839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ctx->transport_security_state()->EnableHost(request_info_.url.host(), 841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott domain_state); 842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(agl): change this over when we have fixed things at the server end. 845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The string should be "Opportunistic-Transport-Security"; 846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name = "X-Bodge-Transport-Security"; 847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (response_info_->headers->EnumerateHeader(&iter, name, &value)) { 849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const bool ok = net::TransportSecurityState::ParseHeader( 850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value, &max_age, &include_subdomains); 851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ok) 852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If we saw an opportunistic request over HTTPS, then clearly we can make 854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // HTTPS connections to the host so we should remember this. 855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (https) { 856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::Time current_time(base::Time::Now()); 857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta max_age_delta = base::TimeDelta::FromSeconds(max_age); 858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::TransportSecurityState::DomainState domain_state; 860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott domain_state.expiry = current_time + max_age_delta; 861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott domain_state.mode = 862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::TransportSecurityState::DomainState::MODE_SPDY_ONLY; 863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott domain_state.include_subdomains = include_subdomains; 864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ctx->transport_security_state()->EnableHost(request_info_.url.host(), 866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott domain_state); 867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!request()) 871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // At this point, we have a request for opportunistic encryption over HTTP. 874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // In this case we need to probe to check that we can make HTTPS 875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // connections to that host. 876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::HTTPSProber* const prober = Singleton<net::HTTPSProber>::get(); 877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (prober->HaveProbed(request_info_.url.host()) || 878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott prober->InFlight(request_info_.url.host())) { 879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott net::HTTPSProberDelegate* delegate = 883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new HTTPSProberDelegate(request_info_.url.host(), max_age, 884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott include_subdomains, 885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ctx->transport_security_state()); 886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!prober->ProbeHost(request_info_.url.host(), request()->context(), 887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delegate)) { 888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete delegate; 889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 892