1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_HTTP_HTTP_STREAM_FACTORY_H_ 6 #define NET_HTTP_HTTP_STREAM_FACTORY_H_ 7 8 #include <stddef.h> 9 10 #include <map> 11 #include <memory> 12 #include <set> 13 #include <string> 14 #include <vector> 15 16 #include "base/containers/unique_ptr_adapters.h" 17 #include "base/gtest_prod_util.h" 18 #include "base/memory/raw_ptr.h" 19 #include "net/base/host_port_pair.h" 20 #include "net/base/load_states.h" 21 #include "net/base/net_export.h" 22 #include "net/base/network_anonymization_key.h" 23 #include "net/base/privacy_mode.h" 24 #include "net/base/proxy_server.h" 25 #include "net/base/request_priority.h" 26 #include "net/dns/public/secure_dns_policy.h" 27 #include "net/http/http_request_info.h" 28 #include "net/http/http_server_properties.h" 29 #include "net/http/http_stream_request.h" 30 #include "net/log/net_log_source.h" 31 #include "net/log/net_log_with_source.h" 32 #include "net/proxy_resolution/proxy_info.h" 33 #include "net/socket/socket_tag.h" 34 #include "net/socket/ssl_client_socket.h" 35 #include "net/spdy/spdy_session_key.h" 36 #include "net/ssl/ssl_config.h" 37 #include "net/websockets/websocket_handshake_stream_base.h" 38 39 namespace net { 40 41 class HostMappingRules; 42 class HttpNetworkSession; 43 class HttpResponseHeaders; 44 45 class NET_EXPORT HttpStreamFactory { 46 public: 47 class NET_EXPORT_PRIVATE Job; 48 class NET_EXPORT_PRIVATE JobController; 49 class NET_EXPORT_PRIVATE JobFactory; 50 51 enum JobType { 52 // Job that will connect via HTTP/1 or HTTP/2. This may be paused for a 53 // while when ALTERNATIVE or DNS_ALPN_H3 job was created. 54 MAIN, 55 // Job that will connect via HTTP/3 iff Chrome has received an Alt-Svc 56 // header from the origin. 57 ALTERNATIVE, 58 // Job that will connect via HTTP/3 iff an "h3" value was found in the ALPN 59 // list of an HTTPS DNS record. 60 DNS_ALPN_H3, 61 // Job that will preconnect. This uses HTTP/3 iff Chrome has received an 62 // Alt-Svc header from the origin. Otherwise, it use HTTP/1 or HTTP/2. 63 PRECONNECT, 64 // Job that will preconnect via HTTP/3 iff an "h3" value was found in the 65 // ALPN list of an HTTPS DNS record. 66 PRECONNECT_DNS_ALPN_H3, 67 }; 68 69 // This is the subset of HttpRequestInfo needed by the HttpStreamFactory 70 // layer. It's separated out largely to avoid dangling pointers when jobs are 71 // orphaned, though it also avoids creating multiple copies of fields that 72 // aren't needed, like HttpRequestHeaders. 73 // 74 // See HttpRequestInfo for description of most fields. 75 struct NET_EXPORT StreamRequestInfo { 76 StreamRequestInfo(); 77 explicit StreamRequestInfo(const HttpRequestInfo& http_request_info); 78 79 StreamRequestInfo(const StreamRequestInfo& other); 80 StreamRequestInfo& operator=(const StreamRequestInfo& other); 81 StreamRequestInfo(StreamRequestInfo&& other); 82 StreamRequestInfo& operator=(StreamRequestInfo&& other); 83 84 ~StreamRequestInfo(); 85 86 std::string method; 87 NetworkAnonymizationKey network_anonymization_key; 88 89 // Whether HTTP/1.x can be used. Extracted from 90 // UploadDataStream::AllowHTTP1(). 91 bool is_http1_allowed = true; 92 93 int load_flags = 0; 94 PrivacyMode privacy_mode = PRIVACY_MODE_DISABLED; 95 SecureDnsPolicy secure_dns_policy = SecureDnsPolicy::kAllow; 96 SocketTag socket_tag; 97 }; 98 99 // Calculates an appropriate SPDY session key for the given parameters. 100 static SpdySessionKey GetSpdySessionKey( 101 const ProxyChain& proxy_chain, 102 const GURL& origin_url, 103 const StreamRequestInfo& request_info); 104 105 // Returns whether an appropriate SPDY session would correspond to either a 106 // connection to the last proxy server in the chain (for the traditional HTTP 107 // proxying behavior of sending a GET request to the proxy server) or a 108 // connection through the entire proxy chain (for tunneled requests). Note 109 // that for QUIC proxies we no longer support the former. 110 static bool IsGetToProxy(const ProxyChain& proxy_chain, 111 const GURL& origin_url); 112 113 explicit HttpStreamFactory(HttpNetworkSession* session); 114 115 HttpStreamFactory(const HttpStreamFactory&) = delete; 116 HttpStreamFactory& operator=(const HttpStreamFactory&) = delete; 117 118 virtual ~HttpStreamFactory(); 119 120 void ProcessAlternativeServices( 121 HttpNetworkSession* session, 122 const NetworkAnonymizationKey& network_anonymization_key, 123 const HttpResponseHeaders* headers, 124 const url::SchemeHostPort& http_server); 125 126 // Request a stream. 127 // Will call delegate->OnStreamReady on successful completion. 128 std::unique_ptr<HttpStreamRequest> RequestStream( 129 const HttpRequestInfo& info, 130 RequestPriority priority, 131 const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs, 132 HttpStreamRequest::Delegate* delegate, 133 bool enable_ip_based_pooling, 134 bool enable_alternative_services, 135 const NetLogWithSource& net_log); 136 137 // Request a WebSocket handshake stream. 138 // Will call delegate->OnWebSocketHandshakeStreamReady on successful 139 // completion. 140 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream( 141 const HttpRequestInfo& info, 142 RequestPriority priority, 143 const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs, 144 HttpStreamRequest::Delegate* delegate, 145 WebSocketHandshakeStreamBase::CreateHelper* create_helper, 146 bool enable_ip_based_pooling, 147 bool enable_alternative_services, 148 const NetLogWithSource& net_log); 149 150 // Request a BidirectionalStreamImpl. 151 // Will call delegate->OnBidirectionalStreamImplReady on successful 152 // completion. 153 // TODO(crbug.com/40573539): This method is virtual to avoid cronet_test 154 // failure on iOS that is caused by Network Thread TLS getting the wrong slot. 155 virtual std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl( 156 const HttpRequestInfo& info, 157 RequestPriority priority, 158 const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs, 159 HttpStreamRequest::Delegate* delegate, 160 bool enable_ip_based_pooling, 161 bool enable_alternative_services, 162 const NetLogWithSource& net_log); 163 164 // Requests that enough connections for |num_streams| be opened. 165 // 166 // TODO: Make this take StreamRequestInfo instead. 167 void PreconnectStreams(int num_streams, HttpRequestInfo& info); 168 169 const HostMappingRules* GetHostMappingRules() const; 170 171 private: 172 FRIEND_TEST_ALL_PREFIXES(HttpStreamRequestTest, SetPriority); 173 174 friend class HttpStreamFactoryPeer; 175 176 using JobControllerSet = 177 std::set<std::unique_ptr<JobController>, base::UniquePtrComparator>; 178 179 url::SchemeHostPort RewriteHost(const url::SchemeHostPort& server); 180 181 // Values must not be changed or reused. Keep in sync with identically named 182 // enum in histograms.xml. 183 enum AlternativeServiceType { 184 NO_ALTERNATIVE_SERVICE = 0, 185 QUIC_SAME_DESTINATION = 1, 186 QUIC_DIFFERENT_DESTINATION = 2, 187 NOT_QUIC_SAME_DESTINATION = 3, 188 NOT_QUIC_DIFFERENT_DESTINATION = 4, 189 MAX_ALTERNATIVE_SERVICE_TYPE 190 }; 191 192 std::unique_ptr<HttpStreamRequest> RequestStreamInternal( 193 const HttpRequestInfo& info, 194 RequestPriority priority, 195 const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs, 196 HttpStreamRequest::Delegate* delegate, 197 WebSocketHandshakeStreamBase::CreateHelper* create_helper, 198 HttpStreamRequest::StreamType stream_type, 199 bool is_websocket, 200 bool enable_ip_based_pooling, 201 bool enable_alternative_services, 202 const NetLogWithSource& net_log); 203 204 // Called when the Preconnect completes. Used for testing. OnPreconnectsCompleteInternal()205 virtual void OnPreconnectsCompleteInternal() {} 206 207 // Called when the JobController finishes service. Delete the JobController 208 // from |job_controller_set_|. 209 void OnJobControllerComplete(JobController* controller); 210 211 const raw_ptr<HttpNetworkSession> session_; 212 213 // Factory used by job controllers for creating jobs. 214 std::unique_ptr<JobFactory> job_factory_; 215 216 // All Requests/Preconnects are assigned with a JobController to manage 217 // serving Job(s). JobController might outlive Request when Request 218 // is served while there's some working Job left. JobController will be 219 // deleted from |job_controller_set_| when it determines the completion of 220 // its work. 221 JobControllerSet job_controller_set_; 222 }; 223 224 } // namespace net 225 226 #endif // NET_HTTP_HTTP_STREAM_FACTORY_H_ 227