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/http/http_stream_factory_impl_job.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include <algorithm> 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string> 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h" 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/stringprintf.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/connection_type_histograms.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_basic_stream.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_proxy_client_socket.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_proxy_client_socket_pool.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_request_info.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_server_properties.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream_factory.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream_factory_impl_request.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_http_stream.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_handle.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_pool.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_pool_manager.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socks_client_socket_pool.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket_pool.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_http_stream.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session_pool.h" 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns parameters associated with the start of a HTTP stream job. 447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::Value* NetLogHttpStreamJobCallback(const GURL* original_url, 457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GURL* url, 467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RequestPriority priority, 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NetLog::LogLevel /* log_level */) { 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("original_url", original_url->GetOrigin().spec()); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("url", url->GetOrigin().spec()); 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dict->SetString("priority", RequestPriorityToString(priority)); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns parameters associated with the Proto (with NPN negotiation) of a HTTP 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stream. 577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::Value* NetLogHttpStreamProtoCallback( 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLClientSocket::NextProtoStatus status, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string* proto, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string* server_protos, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::LogLevel /* log_level */) { 627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("next_proto_status", 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLClientSocket::NextProtoStatusToString(status)); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("proto", *proto); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("server_protos", 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLClientSocket::ServerProtosToString(*server_protos)); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpNetworkSession* session, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestInfo& request_info, 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RequestPriority priority, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLConfig& server_ssl_config, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLConfig& proxy_ssl_config, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog* net_log) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : request_(NULL), 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_(request_info), 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_(priority), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ssl_config_(server_ssl_config), 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_ssl_config_(proxy_ssl_config), 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_HTTP_STREAM_JOB)), 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_(new ClientSocketHandle), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_(session), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_factory_(stream_factory), 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_(STATE_NONE), 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pac_request_(NULL), 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocking_job_(NULL), 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_job_(NULL), 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using_ssl_(false), 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using_spdy_(false), 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) using_quic_(false), 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) quic_request_(session_->quic_stream_factory()), 97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch using_existing_quic_session_(false), 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_certificate_error_(OK), 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) establishing_tunnel_(false), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_npn_negotiated_(false), 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_negotiated_(kProtoUnknown), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_streams_(0), 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_session_direct_(false), 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) job_status_(STATUS_RUNNING), 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) other_job_status_(STATUS_RUNNING), 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ptr_factory_(this) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(stream_factory); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(session); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpStreamFactoryImpl::Job::~Job() { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.EndEvent(NetLog::TYPE_HTTP_STREAM_JOB); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When we're in a partially constructed state, waiting for the user to 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provide certificate handling information or authentication, we can't reuse 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this stream at all. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_state_ == STATE_WAITING_USER_ACTION) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->socket()->Disconnect(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_.reset(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pac_request_) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->proxy_service()->CancelPacRequest(pac_request_); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The stream could be in a partial state. It is not reusable. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stream_.get() && next_state_ != STATE_DONE) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_->Close(true /* not reusable */); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::Start(Request* request) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_ = request; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartInternal(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::Preconnect(int num_streams) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(num_streams, 0); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostPortPair origin_server = 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostPortPair(request_info_.url.HostNoBrackets(), 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.url.EffectiveIntPort()); 141ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<HttpServerProperties> http_server_properties = 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->http_server_properties(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (http_server_properties && 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_server_properties->SupportsSpdy(origin_server)) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_streams_ = 1; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_streams_ = num_streams; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return StartInternal(); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::RestartTunnelWithProxyAuth( 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AuthCredentials& credentials) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(establishing_tunnel_); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_RESTART_TUNNEL_AUTH; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_.reset(); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RunLoop(OK); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (next_state_) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_RESOLVE_PROXY_COMPLETE: 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return session_->proxy_service()->GetLoadState(pac_request_); 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case STATE_INIT_CONNECTION_COMPLETE: 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_CREATE_STREAM_COMPLETE: 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LOAD_STATE_IDLE; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HttpStreamFactoryImpl::Job::MarkAsAlternate( 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& original_url, 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PortAlternateProtocolPair alternate) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!original_url_.get()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_url_.reset(new GURL(original_url)); 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (alternate.protocol == QUIC) { 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(session_->params().enable_quic); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) using_quic_ = true; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::WaitFor(Job* job) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STATE_NONE, next_state_); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STATE_NONE, job->next_state_); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!blocking_job_); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!job->waiting_job_); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocking_job_ = job; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job->waiting_job_ = this; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::Resume(Job* job) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(blocking_job_, job); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocking_job_ = NULL; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We know we're blocked if the next_state_ is STATE_WAIT_FOR_JOB_COMPLETE. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unblock |this|. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_state_ == STATE_WAIT_FOR_JOB_COMPLETE) { 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&HttpStreamFactoryImpl::Job::OnIOComplete, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr_factory_.GetWeakPtr(), OK)); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::Orphan(const Request* request) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_, request); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_ = NULL; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocking_job_) { 210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // We've been orphaned, but there's a job we're blocked on. Don't bother 211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // racing, just cancel ourself. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(blocking_job_->waiting_job_); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocking_job_->waiting_job_ = NULL; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocking_job_ = NULL; 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (stream_factory_->for_websockets_ && 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) connection_ && connection_->socket()) { 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection_->socket()->Disconnect(); 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream_factory_->OnOrphanedJobComplete(this); 220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (stream_factory_->for_websockets_) { 2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // We cancel this job because a WebSocketHandshakeStream can't be created 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the Request class and isn't accessible from this job. 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (connection_ && connection_->socket()) { 225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch connection_->socket()->Disconnect(); 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_factory_->OnOrphanedJobComplete(this); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void HttpStreamFactoryImpl::Job::SetPriority(RequestPriority priority) { 2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) priority_ = priority; 2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(akalin): Propagate this to |connection_| and maybe the 2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // preconnect state. 2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamFactoryImpl::Job::was_npn_negotiated() const { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return was_npn_negotiated_; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)NextProto HttpStreamFactoryImpl::Job::protocol_negotiated() const { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return protocol_negotiated_; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamFactoryImpl::Job::using_spdy() const { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return using_spdy_; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SSLConfig& HttpStreamFactoryImpl::Job::server_ssl_config() const { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return server_ssl_config_; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SSLConfig& HttpStreamFactoryImpl::Job::proxy_ssl_config() const { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return proxy_ssl_config_; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ProxyInfo& HttpStreamFactoryImpl::Job::proxy_info() const { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return proxy_info_; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::GetSSLInfo() { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(using_ssl_); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!establishing_tunnel_); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_.get() && connection_->socket()); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLClientSocket* ssl_socket = 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<SSLClientSocket*>(connection_->socket()); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_socket->GetSSLInfo(&ssl_info_); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)SpdySessionKey HttpStreamFactoryImpl::Job::GetSpdySessionKey() const { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In the case that we're using an HTTPS proxy for an HTTP url, 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we look for a SPDY session *to* the proxy, instead of to the 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // origin server. 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PrivacyMode privacy_mode = request_info_.privacy_mode; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsHttpsProxyAndHttpUrl()) { 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return SpdySessionKey(proxy_info_.proxy_server().host_port_pair(), 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ProxyServer::Direct(), 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) privacy_mode); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return SpdySessionKey(origin_, 28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) proxy_info_.proxy_server(), 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) privacy_mode); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamFactoryImpl::Job::CanUseExistingSpdySession() const { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to make sure that if a spdy session was created for 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // https://somehost/ that we don't use that session for http://somehost:443/. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The only time we can use an existing session is if the request URL is 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // https (the normal case) or if we're connection to a SPDY proxy, or 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if we're running with force_spdy_always_. crbug.com/133176 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(ricea): Add "wss" back to this list when SPDY WebSocket support is 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // working. 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return request_info_.url.SchemeIs("https") || 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_info_.proxy_server().is_https() || 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_->params().force_spdy_always; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(stream_.get()); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsPreconnecting()); 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!stream_factory_->for_websockets_); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsOrphaned()) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_factory_->OnOrphanedJobComplete(this); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->Complete(was_npn_negotiated(), 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_negotiated(), 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using_spdy(), 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->OnStreamReady(this, server_ssl_config_, proxy_info_, 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_.release()); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |this| may be deleted after this call. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void HttpStreamFactoryImpl::Job::OnWebSocketHandshakeStreamReadyCallback() { 317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(websocket_stream_); 318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!IsPreconnecting()); 319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(stream_factory_->for_websockets_); 320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // An orphaned WebSocket job will be closed immediately and 321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // never be ready. 322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!IsOrphaned()); 323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request_->Complete(was_npn_negotiated(), 324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protocol_negotiated(), 325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch using_spdy(), 326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net_log_); 3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) request_->OnWebSocketHandshakeStreamReady(this, 3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) server_ssl_config_, 3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) proxy_info_, 3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) websocket_stream_.release()); 331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // |this| may be deleted after this call. 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid HttpStreamFactoryImpl::Job::OnNewSpdySessionReadyCallback() { 335effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(stream_.get()); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsPreconnecting()); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(using_spdy()); 338effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Note: an event loop iteration has passed, so |new_spdy_session_| may be 339effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // NULL at this point if the SpdySession closed immediately after creation. 340ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> spdy_session = new_spdy_session_; 341ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch new_spdy_session_.reset(); 342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(jgraettinger): Notify the factory, and let that notify |request_|, 344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // rather than notifying |request_| directly. 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsOrphaned()) { 346effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (spdy_session) { 347effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch stream_factory_->OnNewSpdySessionReady( 348effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch spdy_session, spdy_session_direct_, server_ssl_config_, proxy_info_, 349effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch was_npn_negotiated(), protocol_negotiated(), using_spdy(), net_log_); 350effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_factory_->OnOrphanedJobComplete(this); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 353effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_->OnNewSpdySessionReady( 354effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch this, stream_.Pass(), spdy_session, spdy_session_direct_); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |this| may be deleted after this call. 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::OnStreamFailedCallback(int result) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsPreconnecting()); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsOrphaned()) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_factory_->OnOrphanedJobComplete(this); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->OnStreamFailed(this, result, server_ssl_config_); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |this| may be deleted after this call. 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::OnCertificateErrorCallback( 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result, const SSLInfo& ssl_info) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsPreconnecting()); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsOrphaned()) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_factory_->OnOrphanedJobComplete(this); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->OnCertificateError(this, result, server_ssl_config_, ssl_info); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |this| may be deleted after this call. 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::OnNeedsProxyAuthCallback( 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo& response, 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpAuthController* auth_controller) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsPreconnecting()); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsOrphaned()) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_factory_->OnOrphanedJobComplete(this); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->OnNeedsProxyAuth( 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, response, server_ssl_config_, proxy_info_, auth_controller); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |this| may be deleted after this call. 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::OnNeedsClientAuthCallback( 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLCertRequestInfo* cert_info) { 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsPreconnecting()); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsOrphaned()) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_factory_->OnOrphanedJobComplete(this); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->OnNeedsClientAuth(this, server_ssl_config_, cert_info); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |this| may be deleted after this call. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::OnHttpsProxyTunnelResponseCallback( 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpResponseInfo& response_info, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpStream* stream) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsPreconnecting()); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsOrphaned()) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_factory_->OnOrphanedJobComplete(this); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->OnHttpsProxyTunnelResponse( 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, response_info, server_ssl_config_, proxy_info_, stream); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |this| may be deleted after this call. 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::OnPreconnectsComplete() { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!request_); 414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_spdy_session_.get()) { 415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream_factory_->OnNewSpdySessionReady(new_spdy_session_, 416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spdy_session_direct_, 417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch server_ssl_config_, 418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch proxy_info_, 419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch was_npn_negotiated(), 420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protocol_negotiated(), 421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch using_spdy(), 422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net_log_); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_factory_->OnPreconnectsComplete(this); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |this| may be deleted after this call. 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::OnHostResolution( 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdySessionPool* spdy_session_pool, 43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const SpdySessionKey& spdy_session_key, 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AddressList& addresses, 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It is OK to dereference spdy_session_pool, because the 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ClientSocketPoolManager will be destroyed in the same callback that 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destroys the SpdySessionPool. 4377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return 4387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch spdy_session_pool->FindAvailableSession(spdy_session_key, net_log) ? 4397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ERR_SPDY_SESSION_ALREADY_EXISTS : OK; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::OnIOComplete(int result) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunLoop(result); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::RunLoop(int result) { 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = DoLoop(result); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERR_IO_PENDING) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there was an error, we should have already resumed the |waiting_job_|, 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if there was one. 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(result == OK || waiting_job_ == NULL); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsPreconnecting()) { 45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 45923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, 46023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ptr_factory_.GetWeakPtr())); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_IO_PENDING; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsCertificateError(result)) { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retrieve SSL information from the socket. 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetSSLInfo(); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_WAITING_USER_ACTION; 46990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 47123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&HttpStreamFactoryImpl::Job::OnCertificateErrorCallback, 47223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ptr_factory_.GetWeakPtr(), result, ssl_info_)); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_IO_PENDING; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (result) { 47723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case ERR_PROXY_AUTH_REQUESTED: { 478f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("Net.ProxyAuthRequested.HasConnection", 479f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) connection_.get() != NULL); 480f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!connection_.get()) 481f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ERR_PROXY_AUTH_REQUESTED_WITH_NO_CONNECTION; 482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK(connection_->socket()); 483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK(establishing_tunnel_); 48423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 48523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) next_state_ = STATE_WAITING_USER_ACTION; 48623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ProxyClientSocket* proxy_socket = 48723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) static_cast<ProxyClientSocket*>(connection_->socket()); 48823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::MessageLoop::current()->PostTask( 48923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) FROM_HERE, 49023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&Job::OnNeedsProxyAuthCallback, ptr_factory_.GetWeakPtr(), 49123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *proxy_socket->GetConnectResponseInfo(), 49223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) proxy_socket->GetAuthController())); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_IO_PENDING; 49423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_SSL_CLIENT_AUTH_CERT_NEEDED: 49790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 49923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&Job::OnNeedsClientAuthCallback, ptr_factory_.GetWeakPtr(), 50023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) connection_->ssl_error_response_info().cert_request_info)); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_IO_PENDING; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case ERR_HTTPS_PROXY_TUNNEL_RESPONSE: { 50423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(connection_.get()); 50523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(connection_->socket()); 50623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(establishing_tunnel_); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ProxyClientSocket* proxy_socket = 50923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) static_cast<ProxyClientSocket*>(connection_->socket()); 51023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::MessageLoop::current()->PostTask( 51123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) FROM_HERE, 51223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&Job::OnHttpsProxyTunnelResponseCallback, 51323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ptr_factory_.GetWeakPtr(), 51423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *proxy_socket->GetConnectResponseInfo(), 51523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) proxy_socket->CreateConnectResponseStream())); 51623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return ERR_IO_PENDING; 51723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OK: 520cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) job_status_ = STATUS_SUCCEEDED; 521cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MaybeMarkAlternateProtocolBroken(); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_DONE; 523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_spdy_session_.get()) { 52490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&Job::OnNewSpdySessionReadyCallback, 527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ptr_factory_.GetWeakPtr())); 528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (stream_factory_->for_websockets_) { 529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(websocket_stream_); 530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->PostTask( 531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FROM_HERE, 5321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, 5331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ptr_factory_.GetWeakPtr())); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 535eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(stream_.get()); 53690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 53823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_IO_PENDING; 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (job_status_ != STATUS_BROKEN) { 544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_EQ(STATUS_RUNNING, job_status_); 545cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) job_status_ = STATUS_FAILED; 546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MaybeMarkAlternateProtocolBroken(); 547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 54890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 55023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), 55123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) result)); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_IO_PENDING; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoLoop(int result) { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(next_state_, STATE_NONE); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = result; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State state = next_state_; 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_NONE; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state) { 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_START: 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoStart(); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_RESOLVE_PROXY: 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoResolveProxy(); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_RESOLVE_PROXY_COMPLETE: 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoResolveProxyComplete(rv); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_WAIT_FOR_JOB: 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoWaitForJob(); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_WAIT_FOR_JOB_COMPLETE: 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoWaitForJobComplete(rv); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_INIT_CONNECTION: 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoInitConnection(); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_INIT_CONNECTION_COMPLETE: 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoInitConnectionComplete(rv); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_WAITING_USER_ACTION: 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoWaitingUserAction(rv); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_RESTART_TUNNEL_AUTH: 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoRestartTunnelAuth(); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_RESTART_TUNNEL_AUTH_COMPLETE: 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoRestartTunnelAuthComplete(rv); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_CREATE_STREAM: 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoCreateStream(); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_CREATE_STREAM_COMPLETE: 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoCreateStreamComplete(rv); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "bad state"; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ERR_FAILED; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::StartInternal() { 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(STATE_NONE, next_state_); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_START; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = RunLoop(OK); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(ERR_IO_PENDING, rv); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoStart() { 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port = request_info_.url.EffectiveIntPort(); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_ = HostPortPair(request_info_.url.HostNoBrackets(), port); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_url_ = stream_factory_->ApplyHostMappingRules( 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.url, &origin_); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_JOB, 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&NetLogHttpStreamJobCallback, 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &request_info_.url, &origin_url_, 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_)); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't connect to restricted ports. 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_port_allowed = IsPortAllowedByDefault(port); 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request_info_.url.SchemeIs("ftp")) { 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Never share connection with other jobs for FTP requests. 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!waiting_job_); 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_port_allowed = IsPortAllowedByFtp(port); 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_port_allowed && !IsPortAllowedByOverride(port)) { 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (waiting_job_) { 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_job_->Resume(this); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_job_ = NULL; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNSAFE_PORT; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_RESOLVE_PROXY; 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoResolveProxy() { 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!pac_request_); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_RESOLVE_PROXY_COMPLETE; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_info_.load_flags & LOAD_BYPASS_PROXY) { 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_info_.UseDirect(); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return session_->proxy_service()->ResolveProxy( 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.url, &proxy_info_, io_callback_, &pac_request_, net_log_); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoResolveProxyComplete(int result) { 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pac_request_ = NULL; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == OK) { 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove unsupported proxies from the list. 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_info_.RemoveProxiesWithoutScheme( 6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_QUIC | 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyServer::SCHEME_HTTP | ProxyServer::SCHEME_HTTPS | 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy_info_.is_empty()) { 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No proxies/direct to choose from. This happens when we don't support 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any of the proxies in the returned list. 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = ERR_NO_SUPPORTED_PROXIES; 6814ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch } else if (using_quic_ && 6824ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { 6834ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // QUIC can not be spoken to non-QUIC proxies. This error should not be 6844ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // user visible, because the non-alternate job should be resumed. 6854ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch result = ERR_NO_SUPPORTED_PROXIES; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != OK) { 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (waiting_job_) { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_job_->Resume(this); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_job_ = NULL; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocking_job_) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_WAIT_FOR_JOB; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_INIT_CONNECTION; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamFactoryImpl::Job::ShouldForceSpdySSL() const { 705cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool rv = session_->params().force_spdy_always && 706cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_->params().force_spdy_over_ssl; 707cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return rv && !session_->HasSpdyExclusion(origin_); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamFactoryImpl::Job::ShouldForceSpdyWithoutSSL() const { 711cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool rv = session_->params().force_spdy_always && 712cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !session_->params().force_spdy_over_ssl; 713cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return rv && !session_->HasSpdyExclusion(origin_); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { 7177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return session_->params().enable_quic && 7187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session_->params().origin_to_force_quic_on.Equals(origin_) && 7197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch proxy_info_.is_direct(); 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoWaitForJob() { 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(blocking_job_); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_WAIT_FOR_JOB_COMPLETE; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_IO_PENDING; 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) { 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!blocking_job_); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, result); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_INIT_CONNECTION; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoInitConnection() { 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!blocking_job_); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!connection_->is_initialized()); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(proxy_info_.proxy_server().is_valid()); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_INIT_CONNECTION_COMPLETE; 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 741eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch using_ssl_ = request_info_.url.SchemeIs("https") || 742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request_info_.url.SchemeIs("wss") || ShouldForceSpdySSL(); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using_spdy_ = false; 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ShouldForceQuic()) 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) using_quic_ = true; 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (proxy_info_.is_quic()) 7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) using_quic_ = true; 7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (using_quic_) { 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(session_->params().enable_quic); 7535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (proxy_info_.is_quic() && !request_info_.url.SchemeIs("http")) { 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(rch): support QUIC proxies for HTTPS urls. 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ERR_NOT_IMPLEMENTED; 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 758a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HostPortPair destination = proxy_info_.is_quic() ? 7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) proxy_info_.proxy_server().host_port_pair() : origin_; 760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) next_state_ = STATE_INIT_CONNECTION_COMPLETE; 7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool secure_quic = using_ssl_ || proxy_info_.is_quic(); 7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int rv = quic_request_.Request( 763effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch destination, secure_quic, request_info_.privacy_mode, 764effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_info_.method, net_log_, io_callback_); 765a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (rv == OK) { 766a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch using_existing_quic_session_ = true; 767a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else { 768eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // OK, there's no available QUIC session. Let |waiting_job_| resume 769eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // if it's paused. 770eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (waiting_job_) { 771eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch waiting_job_->Resume(this); 772eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch waiting_job_ = NULL; 773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 774eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 775eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return rv; 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check first if we have a spdy session for this group. If so, then go 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // straight to using that. 78090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdySessionKey spdy_session_key = GetSpdySessionKey(); 781ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> spdy_session = 7827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session_->spdy_session_pool()->FindAvailableSession( 7837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch spdy_session_key, net_log_); 7847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (spdy_session && CanUseExistingSpdySession()) { 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're preconnecting, but we already have a SpdySession, we don't 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // actually need to preconnect any sockets, so we're done. 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsPreconnecting()) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using_spdy_ = true; 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_CREATE_STREAM; 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_spdy_session_ = spdy_session; 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 7936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } else if (request_ && !request_->HasSpdySessionKey() && 7946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) (using_ssl_ || ShouldForceSpdyWithoutSSL())) { 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the spdy session key for the request that launched this job. 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->SetSpdySessionKey(spdy_session_key); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OK, there's no available SPDY session. Let |waiting_job_| resume if it's 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // paused. 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (waiting_job_) { 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_job_->Resume(this); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_job_ = NULL; 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy_info_.is_http() || proxy_info_.is_https()) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) establishing_tunnel_ = using_ssl_; 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool want_spdy_over_npn = original_url_ != NULL; 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy_info_.is_https()) { 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitSSLConfig(proxy_info_.proxy_server().host_port_pair(), 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &proxy_ssl_config_, 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true /* is a proxy server */); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disable revocation checking for HTTPS proxies since the revocation 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // requests are probably going to need to go through the proxy too. 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_ssl_config_.rev_checking_enabled = false; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (using_ssl_) { 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InitSSLConfig(origin_, &server_ssl_config_, 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) false /* not a proxy server */); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsPreconnecting()) { 826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!stream_factory_->for_websockets_); 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PreconnectSocketsForHttpRequest( 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_url_, 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.extra_headers, 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_info_.load_flags, 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_, 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_, 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_info_, 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShouldForceSpdySSL(), 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) want_spdy_over_npn, 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ssl_config_, 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_ssl_config_, 83890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request_info_.privacy_mode, 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_, 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_streams_); 841cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 842cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 843cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // If we can't use a SPDY session, don't both checking for one after 844cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the hostname is resolved. 845cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnHostResolutionCallback resolution_callback = CanUseExistingSpdySession() ? 846cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&Job::OnHostResolution, session_->spdy_session_pool(), 847cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetSpdySessionKey()) : 848cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnHostResolutionCallback(); 849cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (stream_factory_->for_websockets_) { 850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(ricea): Re-enable NPN when WebSockets over SPDY is supported. 851cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SSLConfig websocket_server_ssl_config = server_ssl_config_; 852cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) websocket_server_ssl_config.next_protos.clear(); 853cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return InitSocketHandleForWebSocketRequest( 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_url_, request_info_.extra_headers, request_info_.load_flags, 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_, session_, proxy_info_, ShouldForceSpdySSL(), 856cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) want_spdy_over_npn, websocket_server_ssl_config, proxy_ssl_config_, 85790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request_info_.privacy_mode, net_log_, 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_.get(), resolution_callback, io_callback_); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 860cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 861cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return InitSocketHandleForHttpRequest( 862cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) origin_url_, request_info_.extra_headers, request_info_.load_flags, 863cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) priority_, session_, proxy_info_, ShouldForceSpdySSL(), 864cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) want_spdy_over_npn, server_ssl_config_, proxy_ssl_config_, 865cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) request_info_.privacy_mode, net_log_, 866cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) connection_.get(), resolution_callback, io_callback_); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsPreconnecting()) { 87190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (using_quic_) 87290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return result; 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, result); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We found a SPDY connection after resolving the host. This is 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // probably an IP pooled connection. 88090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdySessionKey spdy_session_key = GetSpdySessionKey(); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_spdy_session_ = 8827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch session_->spdy_session_pool()->FindAvailableSession( 8837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch spdy_session_key, net_log_); 8847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (existing_spdy_session_) { 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using_spdy_ = true; 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_CREATE_STREAM; 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It is possible that the spdy session no longer exists. 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReturnToStateInitConnection(true /* close connection */); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(willchan): Make this a bit more exact. Maybe there are recoverable 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // errors, such as ignoring certificate errors for Alternate-Protocol. 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result < 0 && waiting_job_) { 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_job_->Resume(this); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_job_ = NULL; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |result| may be the result of any of the stacked pools. The following 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // logic is used when determining how to interpret an error. 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |result| < 0: 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and connection_->socket() != NULL, then the SSL handshake ran and it 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is a potentially recoverable error. 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and connection_->socket == NULL and connection_->is_ssl_error() is true, 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // then the SSL handshake ran with an unrecoverable error. 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // otherwise, the error came from one of the other pools. 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->is_ssl_error()); 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl_started && (result == OK || IsCertificateError(result))) { 9137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (using_quic_ && result == OK) { 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_npn_negotiated_ = true; 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextProto protocol_negotiated = 9167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SSLClientSocket::NextProtoFromString("quic/1+spdy/3"); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_negotiated_ = protocol_negotiated; 9187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 9197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SSLClientSocket* ssl_socket = 9207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch static_cast<SSLClientSocket*>(connection_->socket()); 9217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (ssl_socket->WasNpnNegotiated()) { 9227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch was_npn_negotiated_ = true; 9237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string proto; 9247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string server_protos; 9257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SSLClientSocket::NextProtoStatus status = 9267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ssl_socket->GetNextProto(&proto, &server_protos); 9277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NextProto protocol_negotiated = 9287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SSLClientSocket::NextProtoFromString(proto); 9297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch protocol_negotiated_ = protocol_negotiated; 9307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch net_log_.AddEvent( 9317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NetLog::TYPE_HTTP_STREAM_REQUEST_PROTO, 9327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&NetLogHttpStreamProtoCallback, 9337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch status, &proto, &server_protos)); 9347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (ssl_socket->was_spdy_negotiated()) 9357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SwitchToSpdyMode(); 9367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 9377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (ShouldForceSpdySSL()) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SwitchToSpdyMode(); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (proxy_info_.is_https() && connection_->socket() && 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result == OK) { 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyClientSocket* proxy_socket = 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<ProxyClientSocket*>(connection_->socket()); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy_socket->IsUsingSpdy()) { 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_npn_negotiated_ = true; 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_negotiated_ = proxy_socket->GetProtocolNegotiated(); 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SwitchToSpdyMode(); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We may be using spdy without SSL 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ShouldForceSpdyWithoutSSL()) 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SwitchToSpdyMode(); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERR_PROXY_AUTH_REQUESTED || 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!ssl_started); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Other state (i.e. |using_ssl_|) suggests that |connection_| will have an 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SSL socket, but there was an error before that could happen. This 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // puts the in progress HttpProxy socket into |connection_| in order to 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // complete the auth (or read the response body). The tunnel restart code 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is careful to remove it before returning control to the rest of this 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // class. 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_.reset(connection_->release_pending_http_proxy_connection()); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 968cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!ssl_started && result < 0 && original_url_.get()) { 969cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) job_status_ = STATUS_BROKEN; 970cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MaybeMarkAlternateProtocolBroken(); 971cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return result; 972cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 973cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 974010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (using_quic_) { 975cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (result < 0) { 976cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) job_status_ = STATUS_BROKEN; 977cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MaybeMarkAlternateProtocolBroken(); 978010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return result; 979cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 980010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) stream_ = quic_request_.ReleaseStream(); 981010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) next_state_ = STATE_NONE; 982010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return OK; 983010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 984010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result < 0 && !ssl_started) 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReconsiderProxyAfterError(result); 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) establishing_tunnel_ = false; 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connection_->socket()) { 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogHttpConnectedMetrics(*connection_); 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We officially have a new connection. Record the type. 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!connection_->is_reused()) { 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectionType type = using_spdy_ ? CONNECTION_SPDY : CONNECTION_HTTP; 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateConnectionTypeHistograms(type); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle SSL errors below. 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (using_ssl_) { 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ssl_started); 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsCertificateError(result)) { 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (using_spdy_ && original_url_.get() && 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_url_->SchemeIs("http")) { 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We ignore certificate errors for http over spdy. 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_certificate_error_ = result; 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = OK; 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = HandleCertificateError(result); 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == OK && !connection_->socket()->IsConnectedAndIdle()) { 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReturnToStateInitConnection(true /* close connection */); 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result < 0) 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_CREATE_STREAM; 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoWaitingUserAction(int result) { 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This state indicates that the stream request is in a partially 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // completed state, and we've called back to the delegate for more 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // information. 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're always waiting here for the delegate to call us back. 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_IO_PENDING; 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoCreateStream() { 1034cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(connection_->socket() || existing_spdy_session_.get() || using_quic_); 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_CREATE_STREAM_COMPLETE; 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only set the socket motivation if we're the first to use 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this socket. Is there a race for two SPDY requests? We really 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // need to plumb this through to the connect level. 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connection_->socket() && !connection_->is_reused()) 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetSocketMotivation(); 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!using_spdy_) { 10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We may get ftp scheme when fetching ftp resources through proxy. 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && 10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (request_info_.url.SchemeIs("http") || 10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info_.url.SchemeIs("ftp")); 1049cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (stream_factory_->for_websockets_) { 1050eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(request_); 1051f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(request_->websocket_handshake_stream_create_helper()); 1052eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch websocket_stream_.reset( 1053f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_->websocket_handshake_stream_create_helper() 1054f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ->CreateBasicStream(connection_.Pass(), using_proxy)); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) stream_.reset(new HttpBasicStream(connection_.release(), using_proxy)); 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!stream_.get()); 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool direct = true; 1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProxyServer& proxy_server = proxy_info_.proxy_server(); 106590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PrivacyMode privacy_mode = request_info_.privacy_mode; 106690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdySessionKey spdy_session_key(origin_, proxy_server, privacy_mode); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsHttpsProxyAndHttpUrl()) { 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we don't have a direct SPDY session, and we're using an HTTPS 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // proxy, then we might have a SPDY session to the proxy. 107090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // We never use privacy mode for connection to proxy server. 107190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) spdy_session_key = SpdySessionKey(proxy_server.host_port_pair(), 107290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ProxyServer::Direct(), 1073e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch PRIVACY_MODE_DISABLED); 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) direct = false; 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1077ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> spdy_session; 1078868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (existing_spdy_session_.get()) { 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We picked up an existing session, so we don't need our socket. 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connection_->socket()) 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->socket()->Disconnect(); 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->Reset(); 1083ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::swap(spdy_session, existing_spdy_session_); 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdySessionPool* spdy_pool = session_->spdy_session_pool(); 10867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch spdy_session = spdy_pool->FindAvailableSession(spdy_session_key, net_log_); 10877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!spdy_session) { 1088cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<SpdySession> new_spdy_session = 10897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch spdy_pool->CreateAvailableSessionFromSocket(spdy_session_key, 10907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch connection_.Pass(), 1091868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net_log_, 1092868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spdy_certificate_error_, 1093868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) using_ssl_); 1094cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!new_spdy_session->HasAcceptableTransportSecurity()) { 1095cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new_spdy_session->CloseSessionOnError( 1096cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, ""); 1097cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY; 1098cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1099cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new_spdy_session_ = new_spdy_session; 1101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) spdy_session_direct_ = direct; 110290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const HostPortPair& host_port_pair = spdy_session_key.host_port_pair(); 1103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<HttpServerProperties> http_server_properties = 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->http_server_properties(); 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (http_server_properties) 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_server_properties->SetSupportsSpdy(host_port_pair, true); 1107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Create a SpdyHttpStream attached to the session; 1109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // OnNewSpdySessionReadyCallback is not called until an event loop 1110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // iteration later, so if the SpdySession is closed between then, allow 1111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // reuse state from the underlying socket, sampled by SpdyHttpStream, 1112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // bubble up to the request. 1113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool use_relative_url = direct || request_info_.url.SchemeIs("https"); 1114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch stream_.reset(new SpdyHttpStream(new_spdy_session_, use_relative_url)); 1115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1120ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!spdy_session) 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_CONNECTION_CLOSED; 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(willchan): Delete this code, because eventually, the 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // HttpStreamFactoryImpl will be creating all the SpdyHttpStreams, since it 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will know when SpdySessions become available. 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1127d7582f30d3b217d8144db8429955efdca442508fBo Liu // TODO(ricea): Restore the code for WebSockets over SPDY once it's 1128d7582f30d3b217d8144db8429955efdca442508fBo Liu // implemented. 1129d7582f30d3b217d8144db8429955efdca442508fBo Liu if (stream_factory_->for_websockets_) 1130d7582f30d3b217d8144db8429955efdca442508fBo Liu return ERR_NOT_IMPLEMENTED; 1131d7582f30d3b217d8144db8429955efdca442508fBo Liu 1132d7582f30d3b217d8144db8429955efdca442508fBo Liu bool use_relative_url = direct || request_info_.url.SchemeIs("https"); 1133d7582f30d3b217d8144db8429955efdca442508fBo Liu stream_.reset(new SpdyHttpStream(spdy_session, use_relative_url)); 1134d7582f30d3b217d8144db8429955efdca442508fBo Liu 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoCreateStreamComplete(int result) { 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result < 0) 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->proxy_service()->ReportSuccess(proxy_info_); 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_NONE; 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoRestartTunnelAuth() { 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_RESTART_TUNNEL_AUTH_COMPLETE; 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyClientSocket* proxy_socket = 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<ProxyClientSocket*>(connection_->socket()); 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return proxy_socket->RestartWithAuth(io_callback_); 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::DoRestartTunnelAuthComplete(int result) { 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERR_PROXY_AUTH_REQUESTED) 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == OK) { 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now that we've got the HttpProxyClientSocket connected. We have 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to release it as an idle socket into the pool and start the connection 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // process from the beginning. Trying to pass it in with the 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SSLSocketParams might cause a deadlock since params are dispatched 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interchangeably. This request won't necessarily get this http proxy 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // socket, but there will be forward progress. 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) establishing_tunnel_ = false; 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReturnToStateInitConnection(false /* do not close connection */); 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReconsiderProxyAfterError(result); 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::ReturnToStateInitConnection( 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool close_connection) { 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (close_connection && connection_->socket()) 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->socket()->Disconnect(); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->Reset(); 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (request_) 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->RemoveRequestFromSpdySessionRequestMap(); 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_INIT_CONNECTION; 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::SetSocketMotivation() { 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_info_.motivation == HttpRequestInfo::PRECONNECT_MOTIVATED) 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->socket()->SetSubresourceSpeculation(); 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (request_info_.motivation == HttpRequestInfo::OMNIBOX_MOTIVATED) 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->socket()->SetOmniboxSpeculation(); 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mbelshe): Add other motivations (like EARLY_LOAD_MOTIVATED). 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamFactoryImpl::Job::IsHttpsProxyAndHttpUrl() const { 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proxy_info_.is_https()) 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (original_url_.get()) { 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We currently only support Alternate-Protocol where the original scheme 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is http. 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(original_url_->SchemeIs("http")); 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return original_url_->SchemeIs("http"); 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return request_info_.url.SchemeIs("http"); 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets several fields of ssl_config for the given origin_server based on the 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proxy info and other factors. 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::InitSSLConfig( 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HostPortPair& origin_server, 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SSLConfig* ssl_config, 12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_proxy) const { 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy_info_.is_https() && ssl_config->send_client_cert) { 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When connecting through an HTTPS proxy, disable TLS False Start so 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that client authentication errors can be distinguished between those 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // originating from the proxy server (ERR_PROXY_CONNECTION_FAILED) and 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // those originating from the endpoint (ERR_SSL_PROTOCOL_ERROR / 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ERR_BAD_SSL_CLIENT_AUTH_CERT). 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(rch): This assumes that the HTTPS proxy will only request a 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // client certificate during the initial handshake. 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/59292 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_config->false_start_enabled = false; 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum { 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FALLBACK_NONE = 0, // SSL version fallback did not occur. 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FALLBACK_SSL3 = 1, // Fell back to SSL 3.0. 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FALLBACK_TLS1 = 2, // Fell back to TLS 1.0. 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FALLBACK_TLS1_1 = 3, // Fell back to TLS 1.1. 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FALLBACK_MAX 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fallback = FALLBACK_NONE; 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl_config->version_fallback) { 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (ssl_config->version_max) { 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SSL_PROTOCOL_VERSION_SSL3: 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fallback = FALLBACK_SSL3; 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SSL_PROTOCOL_VERSION_TLS1: 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fallback = FALLBACK_TLS1; 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SSL_PROTOCOL_VERSION_TLS1_1: 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fallback = FALLBACK_TLS1_1; 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Net.ConnectionUsedSSLVersionFallback", 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fallback, FALLBACK_MAX); 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We also wish to measure the amount of fallback connections for a host that 12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // we know implements TLS up to 1.2. Ideally there would be no fallback here 12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // but high numbers of SSLv3 would suggest that SSLv3 fallback is being 12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // caused by network middleware rather than buggy HTTPS servers. 12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& host = origin_server.host(); 12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_proxy && 12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host.size() >= 10 && 12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host.compare(host.size() - 10, 10, "google.com") == 0 && 12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (host.size() == 10 || host[host.size()-11] == '.')) { 12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Net.GoogleConnectionUsedSSLVersionFallback", 12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fallback, FALLBACK_MAX); 12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_info_.load_flags & LOAD_VERIFY_EV_CERT) 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_config->verify_ev_cert = true; 126390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 126490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Disable Channel ID if privacy mode is enabled. 1265e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (request_info_.privacy_mode == PRIVACY_MODE_ENABLED) 126690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ssl_config->channel_id_enabled = false; 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) { 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!pac_request_); 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A failure to resolve the hostname or any error related to establishing a 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TCP connection could be grounds for trying a new proxy configuration. 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Why do this when a hostname cannot be resolved? Some URLs only make sense 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to proxy servers. The hostname in those URLs might fail to resolve if we 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are still using a non-proxy config. We need to check if a proxy config 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // now exists that corresponds to a proxy server that could load the URL. 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (error) { 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_PROXY_CONNECTION_FAILED: 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_NAME_NOT_RESOLVED: 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_INTERNET_DISCONNECTED: 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_ADDRESS_UNREACHABLE: 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_CONNECTION_CLOSED: 12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ERR_CONNECTION_TIMED_OUT: 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_CONNECTION_RESET: 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_CONNECTION_REFUSED: 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_CONNECTION_ABORTED: 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_TIMED_OUT: 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_TUNNEL_CONNECTION_FAILED: 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_SOCKS_CONNECTION_FAILED: 12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This can happen in the case of trying to talk to a proxy using SSL, and 12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ending up talking to a captive portal that supports SSL instead. 12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ERR_PROXY_CERTIFICATE_INVALID: 12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This can happen when trying to talk SSL to a non-SSL server (Like a 12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // captive portal). 12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ERR_SSL_PROTOCOL_ERROR: 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERR_SOCKS_CONNECTION_HOST_UNREACHABLE: 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remap the SOCKS-specific "host unreachable" error to a more 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // generic error code (this way consumers like the link doctor 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // know to substitute their error page). 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that if the host resolving was done by the SOCKS5 proxy, we can't 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // differentiate between a proxy-side "host not found" versus a proxy-side 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "address unreachable" error, and will report both of these failures as 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ERR_ADDRESS_UNREACHABLE. 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_ADDRESS_UNREACHABLE; 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error; 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_info_.load_flags & LOAD_BYPASS_PROXY) { 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error; 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy_info_.is_https() && proxy_ssl_config_.send_client_cert) { 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->ssl_client_auth_cache()->Remove( 13215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) proxy_info_.proxy_server().host_port_pair()); 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = session_->proxy_service()->ReconsiderProxyAfterError( 1325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) request_info_.url, error, &proxy_info_, io_callback_, &pac_request_, 1326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net_log_); 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == OK || rv == ERR_IO_PENDING) { 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the error was during connection setup, there is no socket to 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disconnect. 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connection_->socket()) 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->socket()->Disconnect(); 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->Reset(); 1333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (request_) 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->RemoveRequestFromSpdySessionRequestMap(); 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_RESOLVE_PROXY_COMPLETE; 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If ReconsiderProxyAfterError() failed synchronously, it means 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there was nothing left to fall-back to, so fail the transaction 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with the last connection error we got. 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(eroman): This is a confusing contract, make it more obvious. 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = error; 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamFactoryImpl::Job::HandleCertificateError(int error) { 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(using_ssl_); 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsCertificateError(error)); 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLClientSocket* ssl_socket = 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<SSLClientSocket*>(connection_->socket()); 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_socket->GetSSLInfo(&ssl_info_); 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the bad certificate to the set of allowed certificates in the 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SSL config object. This data structure will be consulted after calling 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RestartIgnoringLastError(). And the user will be asked interactively 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before RestartIgnoringLastError() is ever called. 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLConfig::CertAndStatus bad_cert; 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |ssl_info_.cert| may be NULL if we failed to create 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // X509Certificate for whatever reason, but normally it shouldn't 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // happen, unless this code is used inside sandbox. 1364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ssl_info_.cert.get() == NULL || 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !X509Certificate::GetDEREncoded(ssl_info_.cert->os_cert_handle(), 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &bad_cert.der_cert)) { 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error; 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bad_cert.cert_status = ssl_info_.cert_status; 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ssl_config_.allowed_bad_certs.push_back(bad_cert); 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int load_flags = request_info_.load_flags; 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_->params().ignore_certificate_errors) 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl_socket->IgnoreCertError(error, load_flags)) 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error; 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::SwitchToSpdyMode() { 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HttpStreamFactory::spdy_enabled()) 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using_spdy_ = true; 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::Job::LogHttpConnectedMetrics( 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClientSocketHandle& handle) { 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Net.HttpSocketType", handle.reuse_type(), 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketHandle::NUM_TYPES); 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (handle.reuse_type()) { 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ClientSocketHandle::UNUSED: 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES("Net.HttpConnectionLatency", 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle.setup_time(), 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(1), 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMinutes(10), 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100); 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ClientSocketHandle::UNUSED_IDLE: 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES("Net.SocketIdleTimeBeforeNextUse_UnusedSocket", 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle.idle_time(), 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(1), 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMinutes(6), 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100); 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ClientSocketHandle::REUSED_IDLE: 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES("Net.SocketIdleTimeBeforeNextUse_ReusedSocket", 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle.idle_time(), 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(1), 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMinutes(6), 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100); 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamFactoryImpl::Job::IsPreconnecting() const { 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(num_streams_, 0); 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return num_streams_ > 0; 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamFactoryImpl::Job::IsOrphaned() const { 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !IsPreconnecting() && !request_; 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1428a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HttpStreamFactoryImpl::Job::ReportJobSuccededForRequest() { 1429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::AlternateProtocolExperiment alternate_protocol_experiment = 1430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT; 1431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<HttpServerProperties> http_server_properties = 1432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_->http_server_properties(); 1433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (http_server_properties) { 1434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alternate_protocol_experiment = 1435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) http_server_properties->GetAlternateProtocolExperiment(); 1436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1437a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (using_existing_quic_session_) { 1438a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // If an existing session was used, then no TCP connection was 1439a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // started. 1440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_NO_RACE, 1441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alternate_protocol_experiment); 1442a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else if (original_url_) { 1443a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // This job was the alternate protocol job, and hence won the race. 1444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE, 1445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alternate_protocol_experiment); 1446a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else { 1447a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // This job was the normal job, and hence the alternate protocol job lost 1448a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // the race. 1449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE, 1450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alternate_protocol_experiment); 1451a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 1452a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 1453a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 1454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HttpStreamFactoryImpl::Job::MarkOtherJobComplete(const Job& job) { 1455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_EQ(STATUS_RUNNING, other_job_status_); 1456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) other_job_status_ = job.job_status_; 1457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MaybeMarkAlternateProtocolBroken(); 1458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 1459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HttpStreamFactoryImpl::Job::MaybeMarkAlternateProtocolBroken() { 1461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (job_status_ == STATUS_RUNNING || other_job_status_ == STATUS_RUNNING) 1462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 1463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool is_alternate_protocol_job = original_url_.get() != NULL; 1465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (is_alternate_protocol_job) { 1466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (job_status_ == STATUS_BROKEN && other_job_status_ == STATUS_SUCCEEDED) { 1467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HistogramBrokenAlternateProtocolLocation( 1468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); 1469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_->http_server_properties()->SetBrokenAlternateProtocol( 1470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HostPortPair::FromURL(*original_url_)); 1471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (job_status_ == STATUS_SUCCEEDED && other_job_status_ == STATUS_BROKEN) { 1476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HistogramBrokenAlternateProtocolLocation( 1477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_MAIN); 1478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_->http_server_properties()->SetBrokenAlternateProtocol( 1479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HostPortPair::FromURL(request_info_.url)); 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1484