1 // Copyright 2024 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_POOL_JOB_CONTROLLER_H_ 6 #define NET_HTTP_HTTP_STREAM_POOL_JOB_CONTROLLER_H_ 7 8 #include <memory> 9 #include <optional> 10 #include <vector> 11 12 #include "base/memory/raw_ptr.h" 13 #include "base/memory/weak_ptr.h" 14 #include "net/base/load_states.h" 15 #include "net/base/network_anonymization_key.h" 16 #include "net/base/request_priority.h" 17 #include "net/dns/public/resolve_error_info.h" 18 #include "net/http/alternative_service.h" 19 #include "net/http/http_stream_key.h" 20 #include "net/http/http_stream_pool.h" 21 #include "net/http/http_stream_pool_job.h" 22 #include "net/http/http_stream_pool_request_info.h" 23 #include "net/http/http_stream_request.h" 24 #include "net/quic/quic_session_alias_key.h" 25 #include "net/socket/next_proto.h" 26 #include "net/ssl/ssl_config.h" 27 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h" 28 29 namespace net { 30 31 class NetLogWithSource; 32 class SSLCertRequestInfo; 33 class HttpStream; 34 struct NetErrorDetails; 35 36 // Manages a single HttpStreamRequest and its associated Job(s). 37 class HttpStreamPool::JobController : public HttpStreamPool::Job::Delegate, 38 public HttpStreamRequest::Helper { 39 public: 40 JobController(HttpStreamPool* pool, 41 HttpStreamPoolRequestInfo request_info, 42 RequestPriority priority, 43 std::vector<SSLConfig::CertAndStatus> allowed_bad_certs, 44 bool enable_ip_based_pooling, 45 bool enable_alternative_services); 46 47 JobController(const JobController&) = delete; 48 JobController& operator=(const JobController&) = delete; 49 50 ~JobController() override; 51 52 // Creates an HttpStreamRequest and starts Job(s) to handle it. 53 std::unique_ptr<HttpStreamRequest> RequestStream( 54 HttpStreamRequest::Delegate* delegate, 55 const NetLogWithSource& net_log); 56 57 // Requests that enough connections/sessions for `num_streams` be opened. 58 // `callback` is only invoked when the return value is `ERR_IO_PENDING`. 59 int Preconnect(size_t num_streams, CompletionOnceCallback callback); 60 61 // HttpStreamPool::Job::Delegate implementation: 62 RequestPriority priority() const override; 63 RespectLimits respect_limits() const override; 64 const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs() 65 const override; 66 bool enable_ip_based_pooling() const override; 67 bool enable_alternative_services() const override; 68 bool is_http1_allowed() const override; 69 const ProxyInfo& proxy_info() const override; 70 void OnStreamReady(Job* job, 71 std::unique_ptr<HttpStream> stream, 72 NextProto negotiated_protocol) override; 73 void OnStreamFailed(Job* job, 74 int status, 75 const NetErrorDetails& net_error_details, 76 ResolveErrorInfo resolve_error_info) override; 77 void OnCertificateError(Job* job, 78 int status, 79 const SSLInfo& ssl_info) override; 80 void OnNeedsClientAuth(Job* job, SSLCertRequestInfo* cert_info) override; 81 82 // HttpStreamRequest::Helper implementation: 83 LoadState GetLoadState() const override; 84 void OnRequestComplete() override; 85 int RestartTunnelWithProxyAuth() override; 86 void SetPriority(RequestPriority priority) override; 87 88 private: 89 // Represents an alternative endpoint for the request. 90 struct Alternative { 91 HttpStreamKey stream_key; 92 NextProto protocol = NextProto::kProtoUnknown; 93 quic::ParsedQuicVersion quic_version = 94 quic::ParsedQuicVersion::Unsupported(); 95 QuicSessionAliasKey quic_key; 96 }; 97 98 // Calculate an alternative endpoint for the request. 99 static std::optional<Alternative> CalculateAlternative( 100 HttpStreamPool* pool, 101 const HttpStreamKey& origin_stream_key, 102 const HttpStreamPoolRequestInfo& request_info, 103 bool enable_alternative_services); 104 105 QuicSessionPool* quic_session_pool(); 106 SpdySessionPool* spdy_session_pool(); 107 108 // When there is a QUIC session that can serve an HttpStream for the request, 109 // creates an HttpStream and returns it. 110 std::unique_ptr<HttpStream> MaybeCreateStreamFromExistingQuicSession(); 111 std::unique_ptr<HttpStream> MaybeCreateStreamFromExistingQuicSessionInternal( 112 const QuicSessionAliasKey& key); 113 114 // Returns true when a QUIC session can be used for the request. 115 bool CanUseExistingQuicSession(); 116 117 // Calls the request's Complete() and tells the delegate that `stream` is 118 // ready. Used when there is an existing QUIC/SPDY session that can serve 119 // the request. 120 void CallRequestCompleteAndStreamReady(std::unique_ptr<HttpStream> stream, 121 NextProto negotiated_protocol); 122 123 // Calls the request's stream failed callback. 124 void CallOnStreamFailed(int status, 125 const NetErrorDetails& net_error_details, 126 ResolveErrorInfo resolve_error_info); 127 128 // Calls the request's certificate error callback. 129 void CallOnCertificateError(int status, const SSLInfo& ssl_info); 130 131 // Calls the request's client auth callback. 132 void CallOnNeedsClientAuth(SSLCertRequestInfo* cert_info); 133 134 // Sets the result of `job`. 135 void SetJobResult(Job* job, int status); 136 137 // Cancels jobs other than `job` to handle a failure that require user 138 // interaction such as certificate errors and a client authentication is 139 // requested. 140 void CancelOtherJob(Job* job); 141 142 // Returns true when all jobs complete. 143 bool AllJobsFinished(); 144 145 // Called when all jobs complete. Record brokenness of the alternative 146 // service if the origin job has no error and the alternative job has an 147 // error. 148 void MaybeMarkAlternativeServiceBroken(); 149 150 const raw_ptr<HttpStreamPool> pool_; 151 const RequestPriority priority_; 152 const std::vector<SSLConfig::CertAndStatus> allowed_bad_certs_; 153 const bool enable_ip_based_pooling_; 154 const bool enable_alternative_services_; 155 const RespectLimits respect_limits_; 156 const bool is_http1_allowed_; 157 const ProxyInfo proxy_info_; 158 const AlternativeServiceInfo alternative_service_info_; 159 160 const HttpStreamKey origin_stream_key_; 161 const QuicSessionAliasKey origin_quic_key_; 162 quic::ParsedQuicVersion origin_quic_version_ = 163 quic::ParsedQuicVersion::Unsupported(); 164 165 const std::optional<Alternative> alternative_; 166 167 raw_ptr<HttpStreamRequest::Delegate> delegate_; 168 raw_ptr<HttpStreamRequest> stream_request_; 169 170 std::unique_ptr<Job> origin_job_; 171 std::optional<int> origin_job_result_; 172 173 std::unique_ptr<Job> alternative_job_; 174 // Set to `OK` when the alternative job is not needed. 175 std::optional<int> alternative_job_result_; 176 177 base::WeakPtrFactory<JobController> weak_ptr_factory_{this}; 178 }; 179 180 } // namespace net 181 182 #endif // NET_HTTP_HTTP_STREAM_POOL_JOB_CONTROLLER_H_ 183