• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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