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.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string> 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_server_properties.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream_factory_impl_job.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream_factory_impl_request.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_http_stream.h" 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL UpgradeUrlToHttps(const GURL& original_url, int port) { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL::Replacements replacements; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // new_sheme and new_port need to be in scope here because GURL::Replacements 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // references the memory contained by them directly. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string new_scheme = "https"; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string new_port = base::IntToString(port); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) replacements.SetSchemeStr(new_scheme); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) replacements.SetPortStr(new_port); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return original_url.ReplaceComponents(replacements); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochHttpStreamFactoryImpl::HttpStreamFactoryImpl(HttpNetworkSession* session, 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool for_websockets) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : session_(session), 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for_websockets_(for_websockets) {} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpStreamFactoryImpl::~HttpStreamFactoryImpl() { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_map_.empty()); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(spdy_session_request_map_.empty()); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<const Job*> tmp_job_set; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_job_set.swap(orphaned_job_set_); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteContainerPointers(tmp_job_set.begin(), tmp_job_set.end()); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(orphaned_job_set_.empty()); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_job_set.clear(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_job_set.swap(preconnect_job_set_); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteContainerPointers(tmp_job_set.begin(), tmp_job_set.end()); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(preconnect_job_set_.empty()); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpStreamRequest* HttpStreamFactoryImpl::RequestStream( 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestInfo& request_info, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RequestPriority priority, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLConfig& server_ssl_config, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLConfig& proxy_ssl_config, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpStreamRequest::Delegate* delegate, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!for_websockets_); 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return RequestStreamInternal(request_info, 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch priority, 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch server_ssl_config, 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch proxy_ssl_config, 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delegate, 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NULL, 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net_log); 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)HttpStreamRequest* HttpStreamFactoryImpl::RequestWebSocketHandshakeStream( 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const HttpRequestInfo& request_info, 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RequestPriority priority, 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SSLConfig& server_ssl_config, 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SSLConfig& proxy_ssl_config, 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpStreamRequest::Delegate* delegate, 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebSocketHandshakeStreamBase::CreateHelper* create_helper, 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const BoundNetLog& net_log) { 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(for_websockets_); 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(create_helper); 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return RequestStreamInternal(request_info, 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch priority, 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch server_ssl_config, 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch proxy_ssl_config, 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delegate, 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_helper, 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net_log); 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochHttpStreamRequest* HttpStreamFactoryImpl::RequestStreamInternal( 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const HttpRequestInfo& request_info, 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RequestPriority priority, 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SSLConfig& server_ssl_config, 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SSLConfig& proxy_ssl_config, 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HttpStreamRequest::Delegate* delegate, 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebSocketHandshakeStreamBase::CreateHelper* 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) websocket_handshake_stream_create_helper, 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const BoundNetLog& net_log) { 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Request* request = new Request(request_info.url, 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch this, 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delegate, 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) websocket_handshake_stream_create_helper, 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net_log); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL alternate_url; 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AlternateProtocolInfo alternate = 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetAlternateProtocolRequestFor(request_info.url, &alternate_url); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Job* alternate_job = NULL; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (alternate.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Never share connection with other jobs for FTP requests. 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!request_info.url.SchemeIs("ftp")); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo alternate_request_info = request_info; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alternate_request_info.url = alternate_url; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alternate_job = 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new Job(this, session_, alternate_request_info, priority, 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_ssl_config, proxy_ssl_config, net_log.net_log()); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->AttachJob(alternate_job); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) alternate_job->MarkAsAlternate(request_info.url, alternate); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Job* job = new Job(this, session_, request_info, priority, 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_ssl_config, proxy_ssl_config, net_log.net_log()); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->AttachJob(job); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (alternate_job) { 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Never share connection with other jobs for FTP requests. 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!request_info.url.SchemeIs("ftp")); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job->WaitFor(alternate_job); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure to wait until we call WaitFor(), before starting 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |alternate_job|, otherwise |alternate_job| will not notify |job| 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // appropriately. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alternate_job->Start(request); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Even if |alternate_job| has already finished, it won't have notified the 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // request yet, since we defer that to the next iteration of the MessageLoop, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so starting |job| is always safe. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job->Start(request); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return request; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::PreconnectStreams( 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_streams, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestInfo& request_info, 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RequestPriority priority, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLConfig& server_ssl_config, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLConfig& proxy_ssl_config) { 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!for_websockets_); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL alternate_url; 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AlternateProtocolInfo alternate = 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetAlternateProtocolRequestFor(request_info.url, &alternate_url); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Job* job = NULL; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (alternate.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestInfo alternate_request_info = request_info; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alternate_request_info.url = alternate_url; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job = new Job(this, session_, alternate_request_info, priority, 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_ssl_config, proxy_ssl_config, session_->net_log()); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job->MarkAsAlternate(request_info.url, alternate); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job = new Job(this, session_, request_info, priority, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_ssl_config, proxy_ssl_config, session_->net_log()); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preconnect_job_set_.insert(job); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job->Preconnect(num_streams); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return session_->params().host_mapping_rules; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175116680a4aac90f2aa7413d9095a592090648e557Ben MurdochAlternateProtocolInfo HttpStreamFactoryImpl::GetAlternateProtocolRequestFor( 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& original_url, 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL* alternate_url) { 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const AlternateProtocolInfo kNoAlternateProtocol = 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AlternateProtocolInfo(0, UNINITIALIZED_ALTERNATE_PROTOCOL, 0); 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!session_->params().use_alternate_protocols) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kNoAlternateProtocol; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (original_url.SchemeIs("ftp")) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kNoAlternateProtocol; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostPortPair origin = HostPortPair(original_url.HostNoBrackets(), 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_url.EffectiveIntPort()); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HttpServerProperties& http_server_properties = 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *session_->http_server_properties(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_server_properties.HasAlternateProtocol(origin)) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kNoAlternateProtocol; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AlternateProtocolInfo alternate = 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_server_properties.GetAlternateProtocol(origin); 197a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) { 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HistogramAlternateProtocolUsage( 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ALTERNATE_PROTOCOL_USAGE_BROKEN, 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) http_server_properties.GetAlternateProtocolExperiment()); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kNoAlternateProtocol; 202a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!IsAlternateProtocolValid(alternate.protocol)) { 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NOTREACHED(); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kNoAlternateProtocol; 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some shared unix systems may have user home directories (like 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://foo.com/~mike) which allow users to emit headers. This is a bad 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // idea already, but with Alternate-Protocol, it provides the ability for a 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // single user on a multi-user system to hijack the alternate protocol. 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These systems also enforce ports <1024 as restricted ports. So don't 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allow protocol upgrades to user-controllable ports. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kUnrestrictedPort = 1024; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!session_->params().enable_user_alternate_protocol_ports && 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (alternate.port >= kUnrestrictedPort && 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) origin.port() < kUnrestrictedPort)) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kNoAlternateProtocol; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin.set_port(alternate.port); 222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (alternate.protocol >= NPN_SPDY_MINIMUM_VERSION && 223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch alternate.protocol <= NPN_SPDY_MAXIMUM_VERSION) { 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!HttpStreamFactory::spdy_enabled()) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kNoAlternateProtocol; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (session_->HasSpdyExclusion(origin)) 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kNoAlternateProtocol; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *alternate_url = UpgradeUrlToHttps(original_url, alternate.port); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(QUIC, alternate.protocol); 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!session_->params().enable_quic) 2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return kNoAlternateProtocol; 235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(rch): Figure out how to make QUIC iteract with PAC 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // scripts. By not re-writing the URL, we will query the PAC script 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for the proxy to use to reach the original URL via TCP. But 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the alternate request will be going via UDP to a different port. 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *alternate_url = original_url; 241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return alternate; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::OrphanJob(Job* job, const Request* request) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ContainsKey(request_map_, job)); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_map_[job], request); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!ContainsKey(orphaned_job_set_, job)); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_map_.erase(job); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) orphaned_job_set_.insert(job); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job->Orphan(request); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid HttpStreamFactoryImpl::OnNewSpdySessionReady( 257ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::WeakPtr<SpdySession>& spdy_session, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool direct, 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLConfig& used_ssl_config, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyInfo& used_proxy_info, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_npn_negotiated, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextProto protocol_negotiated, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool using_spdy, 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch while (true) { 266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!spdy_session) 267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const SpdySessionKey& spdy_session_key = spdy_session->spdy_session_key(); 269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Each iteration may empty out the RequestSet for |spdy_session_key| in 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |spdy_session_request_map_|. So each time, check for RequestSet and use 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the first one. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(willchan): If it's important, switch RequestSet out for a FIFO 274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // queue (Order by priority first, then FIFO within same priority). Unclear 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that it matters here. 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ContainsKey(spdy_session_request_map_, spdy_session_key)) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Request* request = *spdy_session_request_map_[spdy_session_key].begin(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->Complete(was_npn_negotiated, 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_negotiated, 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using_spdy, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log); 283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (for_websockets_) { 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(ricea): Restore this code path when WebSocket over SPDY 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // implementation is ready. 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool use_relative_url = direct || request->url().SchemeIs("https"); 289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request->OnStreamReady( 290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NULL, 291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch used_ssl_config, 292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch used_proxy_info, 293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch new SpdyHttpStream(spdy_session, use_relative_url)); 294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mbelshe): Alert other valid requests. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::OnOrphanedJobComplete(const Job* job) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) orphaned_job_set_.erase(job); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete job; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamFactoryImpl::OnPreconnectsComplete(const Job* job) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preconnect_job_set_.erase(job); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete job; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPreconnectsCompleteInternal(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 311