123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "net/http/http_stream_factory.h"
- #include <tuple>
- #include <utility>
- #include "base/check.h"
- #include "base/metrics/histogram_macros.h"
- #include "base/notreached.h"
- #include "base/strings/string_number_conversions.h"
- #include "base/strings/string_split.h"
- #include "base/strings/string_util.h"
- #include "base/strings/stringprintf.h"
- #include "base/time/time.h"
- #include "net/base/host_mapping_rules.h"
- #include "net/base/host_port_pair.h"
- #include "net/base/network_isolation_key.h"
- #include "net/base/parse_number.h"
- #include "net/base/port_util.h"
- #include "net/http/http_network_session.h"
- #include "net/http/http_response_headers.h"
- #include "net/http/http_server_properties.h"
- #include "net/http/http_stream_factory_job.h"
- #include "net/http/http_stream_factory_job_controller.h"
- #include "net/http/transport_security_state.h"
- #include "net/quic/quic_http_utils.h"
- #include "net/spdy/bidirectional_stream_spdy_impl.h"
- #include "net/spdy/spdy_http_stream.h"
- #include "net/third_party/quiche/src/quiche/quic/core/quic_packets.h"
- #include "net/third_party/quiche/src/quiche/quic/core/quic_server_id.h"
- #include "net/third_party/quiche/src/quiche/spdy/core/spdy_alt_svc_wire_format.h"
- #include "url/gurl.h"
- #include "url/scheme_host_port.h"
- #include "url/url_constants.h"
- namespace net {
- namespace {
- const char kAlternativeServiceHeader[] = "Alt-Svc";
- } // namespace
- HttpStreamFactory::HttpStreamFactory(HttpNetworkSession* session)
- : session_(session), job_factory_(std::make_unique<JobFactory>()) {}
- HttpStreamFactory::~HttpStreamFactory() = default;
- void HttpStreamFactory::ProcessAlternativeServices(
- HttpNetworkSession* session,
- const net::NetworkIsolationKey& network_isolation_key,
- const HttpResponseHeaders* headers,
- const url::SchemeHostPort& http_server) {
- if (!headers->HasHeader(kAlternativeServiceHeader))
- return;
- std::string alternative_service_str;
- headers->GetNormalizedHeader(kAlternativeServiceHeader,
- &alternative_service_str);
- spdy::SpdyAltSvcWireFormat::AlternativeServiceVector
- alternative_service_vector;
- if (!spdy::SpdyAltSvcWireFormat::ParseHeaderFieldValue(
- alternative_service_str, &alternative_service_vector)) {
- return;
- }
- session->http_server_properties()->SetAlternativeServices(
- RewriteHost(http_server), network_isolation_key,
- net::ProcessAlternativeServices(
- alternative_service_vector, session->params().enable_http2,
- session->params().enable_quic,
- session->context().quic_context->params()->supported_versions));
- }
- url::SchemeHostPort HttpStreamFactory::RewriteHost(
- const url::SchemeHostPort& server) {
- HostPortPair host_port_pair(server.host(), server.port());
- const HostMappingRules* mapping_rules = GetHostMappingRules();
- if (mapping_rules)
- mapping_rules->RewriteHost(&host_port_pair);
- return url::SchemeHostPort(server.scheme(), host_port_pair.host(),
- host_port_pair.port());
- }
- std::unique_ptr<HttpStreamRequest> HttpStreamFactory::RequestStream(
- const HttpRequestInfo& request_info,
- RequestPriority priority,
- const SSLConfig& server_ssl_config,
- const SSLConfig& proxy_ssl_config,
- HttpStreamRequest::Delegate* delegate,
- bool enable_ip_based_pooling,
- bool enable_alternative_services,
- const NetLogWithSource& net_log) {
- return RequestStreamInternal(
- request_info, priority, server_ssl_config, proxy_ssl_config, delegate,
- nullptr, HttpStreamRequest::HTTP_STREAM, false /* is_websocket */,
- enable_ip_based_pooling, enable_alternative_services, net_log);
- }
- std::unique_ptr<HttpStreamRequest>
- HttpStreamFactory::RequestWebSocketHandshakeStream(
- const HttpRequestInfo& request_info,
- RequestPriority priority,
- const SSLConfig& server_ssl_config,
- const SSLConfig& proxy_ssl_config,
- HttpStreamRequest::Delegate* delegate,
- WebSocketHandshakeStreamBase::CreateHelper* create_helper,
- bool enable_ip_based_pooling,
- bool enable_alternative_services,
- const NetLogWithSource& net_log) {
- DCHECK(create_helper);
- return RequestStreamInternal(
- request_info, priority, server_ssl_config, proxy_ssl_config, delegate,
- create_helper, HttpStreamRequest::HTTP_STREAM, true /* is_websocket */,
- enable_ip_based_pooling, enable_alternative_services, net_log);
- }
- std::unique_ptr<HttpStreamRequest>
- HttpStreamFactory::RequestBidirectionalStreamImpl(
- const HttpRequestInfo& request_info,
- RequestPriority priority,
- const SSLConfig& server_ssl_config,
- const SSLConfig& proxy_ssl_config,
- HttpStreamRequest::Delegate* delegate,
- bool enable_ip_based_pooling,
- bool enable_alternative_services,
- const NetLogWithSource& net_log) {
- DCHECK(request_info.url.SchemeIs(url::kHttpsScheme));
- return RequestStreamInternal(
- request_info, priority, server_ssl_config, proxy_ssl_config, delegate,
- nullptr, HttpStreamRequest::BIDIRECTIONAL_STREAM,
- false /* is_websocket */, enable_ip_based_pooling,
- enable_alternative_services, net_log);
- }
- std::unique_ptr<HttpStreamRequest> HttpStreamFactory::RequestStreamInternal(
- const HttpRequestInfo& request_info,
- RequestPriority priority,
- const SSLConfig& server_ssl_config,
- const SSLConfig& proxy_ssl_config,
- HttpStreamRequest::Delegate* delegate,
- WebSocketHandshakeStreamBase::CreateHelper*
- websocket_handshake_stream_create_helper,
- HttpStreamRequest::StreamType stream_type,
- bool is_websocket,
- bool enable_ip_based_pooling,
- bool enable_alternative_services,
- const NetLogWithSource& net_log) {
- auto job_controller = std::make_unique<JobController>(
- this, delegate, session_, job_factory_.get(), request_info,
- /* is_preconnect = */ false, is_websocket, enable_ip_based_pooling,
- enable_alternative_services,
- session_->context()
- .quic_context->params()
- ->delay_main_job_with_available_spdy_session,
- server_ssl_config, proxy_ssl_config);
- JobController* job_controller_raw_ptr = job_controller.get();
- job_controller_set_.insert(std::move(job_controller));
- return job_controller_raw_ptr->Start(delegate,
- websocket_handshake_stream_create_helper,
- net_log, stream_type, priority);
- }
- void HttpStreamFactory::PreconnectStreams(int num_streams,
- const HttpRequestInfo& request_info) {
- DCHECK(request_info.url.is_valid());
- auto job_controller = std::make_unique<JobController>(
- this, nullptr, session_, job_factory_.get(), request_info,
- /*is_preconnect=*/true,
- /*is_websocket=*/false,
- /*enable_ip_based_pooling=*/true,
- /*enable_alternative_services=*/true,
- session_->context()
- .quic_context->params()
- ->delay_main_job_with_available_spdy_session,
- /*server_ssl_config=*/SSLConfig(),
- /*proxy_ssl_config=*/SSLConfig());
- JobController* job_controller_raw_ptr = job_controller.get();
- job_controller_set_.insert(std::move(job_controller));
- job_controller_raw_ptr->Preconnect(num_streams);
- }
- const HostMappingRules* HttpStreamFactory::GetHostMappingRules() const {
- return &session_->params().host_mapping_rules;
- }
- void HttpStreamFactory::OnJobControllerComplete(JobController* controller) {
- auto it = job_controller_set_.find(controller);
- if (it != job_controller_set_.end()) {
- job_controller_set_.erase(it);
- } else {
- NOTREACHED();
- }
- }
- } // namespace net
|