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_
|