File: http_stream_pool_job_controller.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (217 lines) | stat: -rw-r--r-- 8,094 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_HTTP_HTTP_STREAM_POOL_JOB_CONTROLLER_H_
#define NET_HTTP_HTTP_STREAM_POOL_JOB_CONTROLLER_H_

#include <memory>
#include <optional>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/values.h"
#include "net/base/load_states.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/request_priority.h"
#include "net/dns/public/resolve_error_info.h"
#include "net/http/alternative_service.h"
#include "net/http/http_stream_key.h"
#include "net/http/http_stream_pool.h"
#include "net/http/http_stream_pool_job.h"
#include "net/http/http_stream_pool_request_info.h"
#include "net/http/http_stream_request.h"
#include "net/log/net_log.h"
#include "net/quic/quic_session_alias_key.h"
#include "net/socket/next_proto.h"
#include "net/ssl/ssl_config.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"

namespace net {

class NetLogWithSource;
class SSLCertRequestInfo;
class HttpStream;
struct NetErrorDetails;

// Manages a single HttpStreamRequest or a preconnect. Creates and owns Jobs.
class HttpStreamPool::JobController : public HttpStreamPool::Job::Delegate,
                                      public HttpStreamRequest::Helper {
 public:
  JobController(HttpStreamPool* pool,
                HttpStreamPoolRequestInfo request_info,
                RequestPriority priority,
                std::vector<SSLConfig::CertAndStatus> allowed_bad_certs,
                bool enable_ip_based_pooling,
                bool enable_alternative_services);

  JobController(const JobController&) = delete;
  JobController& operator=(const JobController&) = delete;

  ~JobController() override;

  // Takes over the responsibility of processing an already created `request`.
  void HandleStreamRequest(HttpStreamRequest* stream_request,
                           HttpStreamRequest::Delegate* delegate);

  // Requests that enough connections/sessions for `num_streams` be opened.
  // `callback` is only invoked when the return value is `ERR_IO_PENDING`.
  int Preconnect(size_t num_streams, CompletionOnceCallback callback);

  // HttpStreamPool::Job::Delegate implementation:
  RequestPriority priority() const override;
  RespectLimits respect_limits() const override;
  const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs()
      const override;
  bool enable_ip_based_pooling() const override;
  bool enable_alternative_services() const override;
  NextProtoSet allowed_alpns() const override;
  const ProxyInfo& proxy_info() const override;
  const NetLogWithSource& net_log() const override;
  void OnStreamReady(Job* job,
                     std::unique_ptr<HttpStream> stream,
                     NextProto negotiated_protocol) override;
  void OnStreamFailed(Job* job,
                      int status,
                      const NetErrorDetails& net_error_details,
                      ResolveErrorInfo resolve_error_info) override;
  void OnCertificateError(Job* job,
                          int status,
                          const SSLInfo& ssl_info) override;
  void OnNeedsClientAuth(Job* job, SSLCertRequestInfo* cert_info) override;
  void OnPreconnectComplete(Job* job, int status) override;

  // HttpStreamRequest::Helper implementation:
  LoadState GetLoadState() const override;
  void OnRequestComplete() override;
  int RestartTunnelWithProxyAuth() override;
  void SetPriority(RequestPriority priority) override;

  base::Value::Dict GetInfoAsValue() const;

 private:
  // Represents an alternative endpoint for the request.
  struct Alternative {
    HttpStreamKey stream_key;
    NextProto protocol = NextProto::kProtoUnknown;
    quic::ParsedQuicVersion quic_version =
        quic::ParsedQuicVersion::Unsupported();
    QuicSessionAliasKey quic_key;
  };

  struct StreamWithProtocol {
    StreamWithProtocol(std::unique_ptr<HttpStream> stream,
                       NextProto negotiated_protocol);
    ~StreamWithProtocol();

    std::unique_ptr<HttpStream> stream;
    NextProto negotiated_protocol;
  };

  // Calculate an alternative endpoint for the request.
  static std::optional<Alternative> CalculateAlternative(
      HttpStreamPool* pool,
      const HttpStreamKey& origin_stream_key,
      const HttpStreamPoolRequestInfo& request_info,
      bool enable_alternative_services);

  QuicSessionPool* quic_session_pool();
  SpdySessionPool* spdy_session_pool();

  // Returns an HttpStream and its negotiated protocol if there is an
  // existing session or an idle stream that can serve the request. Otherwise,
  // returns std::nullopt.
  std::optional<StreamWithProtocol> MaybeCreateStreamFromExistingSession();

  // When there is a QUIC session that can serve an HttpStream for the request,
  // creates an HttpStream and returns it.
  std::unique_ptr<HttpStream> MaybeCreateStreamFromExistingQuicSession();
  std::unique_ptr<HttpStream> MaybeCreateStreamFromExistingQuicSessionInternal(
      const QuicSessionAliasKey& key);

  // May start an alternative job. Returns true when an alternative job is
  // started.
  bool MaybeStartAlternativeJob();

  // Returns true when a QUIC session can be used for the request.
  bool CanUseExistingQuicSession();

  // Calls the request's Complete() and tells the delegate that `stream` is
  // ready. Used when there is an existing QUIC/SPDY session that can serve
  // the request.
  void CallRequestCompleteAndStreamReady(std::unique_ptr<HttpStream> stream,
                                         NextProto negotiated_protocol);

  // Calls the request's stream failed callback.
  void CallOnStreamFailed(int status,
                          const NetErrorDetails& net_error_details,
                          ResolveErrorInfo resolve_error_info);

  // Calls the request's certificate error callback.
  void CallOnCertificateError(int status, const SSLInfo& ssl_info);

  // Calls the request's client auth callback.
  void CallOnNeedsClientAuth(SSLCertRequestInfo* cert_info);

  // Resets `job` and invokes the preconnect callback.
  void ResetJobAndInvokePreconnectCallback(Job* job, int status);

  // Sets the result of `job`.
  void SetJobResult(Job* job, int status);

  // Cancels jobs other than `job` to handle a failure that require user
  // interaction such as certificate errors and a client authentication is
  // requested.
  void CancelOtherJob(Job* job);

  // Returns true when all jobs complete.
  bool AllJobsFinished();

  // Called when all jobs complete. Record brokenness of the alternative
  // service if the origin job has no error and the alternative job has an
  // error.
  void MaybeMarkAlternativeServiceBroken();

  const raw_ptr<HttpStreamPool> pool_;
  RequestPriority priority_;
  const std::vector<SSLConfig::CertAndStatus> allowed_bad_certs_;
  const bool enable_ip_based_pooling_;
  const bool enable_alternative_services_;
  const RespectLimits respect_limits_;
  NextProtoSet allowed_alpns_;
  const ProxyInfo proxy_info_;
  const AlternativeServiceInfo alternative_service_info_;

  const HttpStreamKey origin_stream_key_;
  const QuicSessionAliasKey origin_quic_key_;
  quic::ParsedQuicVersion origin_quic_version_ =
      quic::ParsedQuicVersion::Unsupported();

  const std::optional<Alternative> alternative_;

  const NetLogWithSource net_log_;

  const base::TimeTicks created_time_;

  // Fields specific to stream request.
  raw_ptr<HttpStreamRequest::Delegate> delegate_;
  raw_ptr<HttpStreamRequest> stream_request_;

  // Field specific to preconnect.
  CompletionOnceCallback preconnect_callback_;

  std::unique_ptr<Job> origin_job_;
  std::optional<int> origin_job_result_;

  std::unique_ptr<Job> alternative_job_;
  // Set to `OK` when the alternative job is not needed.
  std::optional<int> alternative_job_result_;

  base::WeakPtrFactory<JobController> weak_ptr_factory_{this};
};

}  // namespace net

#endif  // NET_HTTP_HTTP_STREAM_POOL_JOB_CONTROLLER_H_