1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_stream.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <optional>
8*6777b538SAndroid Build Coastguard Worker #include <ostream>
9*6777b538SAndroid Build Coastguard Worker #include <utility>
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_functions.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/strings/strcat.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/timer/timer.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/base/auth.h"
24*6777b538SAndroid Build Coastguard Worker #include "net/base/isolation_info.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/base/load_flags.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/base/request_priority.h"
28*6777b538SAndroid Build Coastguard Worker #include "net/base/url_util.h"
29*6777b538SAndroid Build Coastguard Worker #include "net/http/http_request_headers.h"
30*6777b538SAndroid Build Coastguard Worker #include "net/http/http_response_headers.h"
31*6777b538SAndroid Build Coastguard Worker #include "net/http/http_response_info.h"
32*6777b538SAndroid Build Coastguard Worker #include "net/http/http_status_code.h"
33*6777b538SAndroid Build Coastguard Worker #include "net/traffic_annotation/network_traffic_annotation.h"
34*6777b538SAndroid Build Coastguard Worker #include "net/url_request/redirect_info.h"
35*6777b538SAndroid Build Coastguard Worker #include "net/url_request/url_request.h"
36*6777b538SAndroid Build Coastguard Worker #include "net/url_request/url_request_context.h"
37*6777b538SAndroid Build Coastguard Worker #include "net/url_request/websocket_handshake_userdata_key.h"
38*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_basic_handshake_stream.h"
39*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_event_interface.h"
40*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_handshake_constants.h"
41*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_handshake_response_info.h"
42*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_handshake_stream_base.h"
43*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_handshake_stream_create_helper.h"
44*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_http2_handshake_stream.h"
45*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_http3_handshake_stream.h"
46*6777b538SAndroid Build Coastguard Worker #include "url/gurl.h"
47*6777b538SAndroid Build Coastguard Worker #include "url/origin.h"
48*6777b538SAndroid Build Coastguard Worker
49*6777b538SAndroid Build Coastguard Worker namespace net {
50*6777b538SAndroid Build Coastguard Worker class SSLCertRequestInfo;
51*6777b538SAndroid Build Coastguard Worker class SSLInfo;
52*6777b538SAndroid Build Coastguard Worker class SiteForCookies;
53*6777b538SAndroid Build Coastguard Worker
54*6777b538SAndroid Build Coastguard Worker namespace {
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker // The timeout duration of WebSocket handshake.
57*6777b538SAndroid Build Coastguard Worker // It is defined as the same value as the TCP connection timeout value in
58*6777b538SAndroid Build Coastguard Worker // net/socket/websocket_transport_client_socket_pool.cc to make it hard for
59*6777b538SAndroid Build Coastguard Worker // JavaScript programs to recognize the timeout cause.
60*6777b538SAndroid Build Coastguard Worker constexpr int kHandshakeTimeoutIntervalInSeconds = 240;
61*6777b538SAndroid Build Coastguard Worker
62*6777b538SAndroid Build Coastguard Worker class WebSocketStreamRequestImpl;
63*6777b538SAndroid Build Coastguard Worker
64*6777b538SAndroid Build Coastguard Worker class Delegate : public URLRequest::Delegate {
65*6777b538SAndroid Build Coastguard Worker public:
Delegate(WebSocketStreamRequestImpl * owner)66*6777b538SAndroid Build Coastguard Worker explicit Delegate(WebSocketStreamRequestImpl* owner) : owner_(owner) {}
67*6777b538SAndroid Build Coastguard Worker ~Delegate() override = default;
68*6777b538SAndroid Build Coastguard Worker
69*6777b538SAndroid Build Coastguard Worker // Implementation of URLRequest::Delegate methods.
70*6777b538SAndroid Build Coastguard Worker int OnConnected(URLRequest* request,
71*6777b538SAndroid Build Coastguard Worker const TransportInfo& info,
72*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback) override;
73*6777b538SAndroid Build Coastguard Worker
74*6777b538SAndroid Build Coastguard Worker void OnReceivedRedirect(URLRequest* request,
75*6777b538SAndroid Build Coastguard Worker const RedirectInfo& redirect_info,
76*6777b538SAndroid Build Coastguard Worker bool* defer_redirect) override;
77*6777b538SAndroid Build Coastguard Worker
78*6777b538SAndroid Build Coastguard Worker void OnResponseStarted(URLRequest* request, int net_error) override;
79*6777b538SAndroid Build Coastguard Worker
80*6777b538SAndroid Build Coastguard Worker void OnAuthRequired(URLRequest* request,
81*6777b538SAndroid Build Coastguard Worker const AuthChallengeInfo& auth_info) override;
82*6777b538SAndroid Build Coastguard Worker
83*6777b538SAndroid Build Coastguard Worker void OnCertificateRequested(URLRequest* request,
84*6777b538SAndroid Build Coastguard Worker SSLCertRequestInfo* cert_request_info) override;
85*6777b538SAndroid Build Coastguard Worker
86*6777b538SAndroid Build Coastguard Worker void OnSSLCertificateError(URLRequest* request,
87*6777b538SAndroid Build Coastguard Worker int net_error,
88*6777b538SAndroid Build Coastguard Worker const SSLInfo& ssl_info,
89*6777b538SAndroid Build Coastguard Worker bool fatal) override;
90*6777b538SAndroid Build Coastguard Worker
91*6777b538SAndroid Build Coastguard Worker void OnReadCompleted(URLRequest* request, int bytes_read) override;
92*6777b538SAndroid Build Coastguard Worker
93*6777b538SAndroid Build Coastguard Worker private:
94*6777b538SAndroid Build Coastguard Worker void OnAuthRequiredComplete(URLRequest* request,
95*6777b538SAndroid Build Coastguard Worker const AuthCredentials* auth_credentials);
96*6777b538SAndroid Build Coastguard Worker
97*6777b538SAndroid Build Coastguard Worker raw_ptr<WebSocketStreamRequestImpl> owner_;
98*6777b538SAndroid Build Coastguard Worker };
99*6777b538SAndroid Build Coastguard Worker
100*6777b538SAndroid Build Coastguard Worker class WebSocketStreamRequestImpl : public WebSocketStreamRequestAPI {
101*6777b538SAndroid Build Coastguard Worker public:
WebSocketStreamRequestImpl(const GURL & url,const std::vector<std::string> & requested_subprotocols,const URLRequestContext * context,const url::Origin & origin,const SiteForCookies & site_for_cookies,bool has_storage_access,const IsolationInfo & isolation_info,const HttpRequestHeaders & additional_headers,NetworkTrafficAnnotationTag traffic_annotation,std::unique_ptr<WebSocketStream::ConnectDelegate> connect_delegate,std::unique_ptr<WebSocketStreamRequestAPI> api_delegate)102*6777b538SAndroid Build Coastguard Worker WebSocketStreamRequestImpl(
103*6777b538SAndroid Build Coastguard Worker const GURL& url,
104*6777b538SAndroid Build Coastguard Worker const std::vector<std::string>& requested_subprotocols,
105*6777b538SAndroid Build Coastguard Worker const URLRequestContext* context,
106*6777b538SAndroid Build Coastguard Worker const url::Origin& origin,
107*6777b538SAndroid Build Coastguard Worker const SiteForCookies& site_for_cookies,
108*6777b538SAndroid Build Coastguard Worker bool has_storage_access,
109*6777b538SAndroid Build Coastguard Worker const IsolationInfo& isolation_info,
110*6777b538SAndroid Build Coastguard Worker const HttpRequestHeaders& additional_headers,
111*6777b538SAndroid Build Coastguard Worker NetworkTrafficAnnotationTag traffic_annotation,
112*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketStream::ConnectDelegate> connect_delegate,
113*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketStreamRequestAPI> api_delegate)
114*6777b538SAndroid Build Coastguard Worker : delegate_(this),
115*6777b538SAndroid Build Coastguard Worker connect_delegate_(std::move(connect_delegate)),
116*6777b538SAndroid Build Coastguard Worker url_request_(context->CreateRequest(url,
117*6777b538SAndroid Build Coastguard Worker DEFAULT_PRIORITY,
118*6777b538SAndroid Build Coastguard Worker &delegate_,
119*6777b538SAndroid Build Coastguard Worker traffic_annotation,
120*6777b538SAndroid Build Coastguard Worker /*is_for_websockets=*/true)),
121*6777b538SAndroid Build Coastguard Worker api_delegate_(std::move(api_delegate)) {
122*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(IsolationInfo::RequestType::kOther,
123*6777b538SAndroid Build Coastguard Worker isolation_info.request_type());
124*6777b538SAndroid Build Coastguard Worker
125*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders headers = additional_headers;
126*6777b538SAndroid Build Coastguard Worker headers.SetHeader(websockets::kUpgrade, websockets::kWebSocketLowercase);
127*6777b538SAndroid Build Coastguard Worker headers.SetHeader(HttpRequestHeaders::kConnection, websockets::kUpgrade);
128*6777b538SAndroid Build Coastguard Worker headers.SetHeader(HttpRequestHeaders::kOrigin, origin.Serialize());
129*6777b538SAndroid Build Coastguard Worker headers.SetHeader(websockets::kSecWebSocketVersion,
130*6777b538SAndroid Build Coastguard Worker websockets::kSupportedVersion);
131*6777b538SAndroid Build Coastguard Worker
132*6777b538SAndroid Build Coastguard Worker // Remove HTTP headers that are important to websocket connections: they
133*6777b538SAndroid Build Coastguard Worker // will be added later.
134*6777b538SAndroid Build Coastguard Worker headers.RemoveHeader(websockets::kSecWebSocketExtensions);
135*6777b538SAndroid Build Coastguard Worker headers.RemoveHeader(websockets::kSecWebSocketKey);
136*6777b538SAndroid Build Coastguard Worker headers.RemoveHeader(websockets::kSecWebSocketProtocol);
137*6777b538SAndroid Build Coastguard Worker
138*6777b538SAndroid Build Coastguard Worker url_request_->SetExtraRequestHeaders(headers);
139*6777b538SAndroid Build Coastguard Worker url_request_->set_initiator(origin);
140*6777b538SAndroid Build Coastguard Worker url_request_->set_site_for_cookies(site_for_cookies);
141*6777b538SAndroid Build Coastguard Worker url_request_->set_has_storage_access(has_storage_access);
142*6777b538SAndroid Build Coastguard Worker url_request_->set_isolation_info(isolation_info);
143*6777b538SAndroid Build Coastguard Worker
144*6777b538SAndroid Build Coastguard Worker auto create_helper = std::make_unique<WebSocketHandshakeStreamCreateHelper>(
145*6777b538SAndroid Build Coastguard Worker connect_delegate_.get(), requested_subprotocols, this);
146*6777b538SAndroid Build Coastguard Worker url_request_->SetUserData(kWebSocketHandshakeUserDataKey,
147*6777b538SAndroid Build Coastguard Worker std::move(create_helper));
148*6777b538SAndroid Build Coastguard Worker url_request_->SetLoadFlags(LOAD_DISABLE_CACHE | LOAD_BYPASS_CACHE);
149*6777b538SAndroid Build Coastguard Worker connect_delegate_->OnCreateRequest(url_request_.get());
150*6777b538SAndroid Build Coastguard Worker }
151*6777b538SAndroid Build Coastguard Worker
152*6777b538SAndroid Build Coastguard Worker // Destroying this object destroys the URLRequest, which cancels the request
153*6777b538SAndroid Build Coastguard Worker // and so terminates the handshake if it is incomplete.
~WebSocketStreamRequestImpl()154*6777b538SAndroid Build Coastguard Worker ~WebSocketStreamRequestImpl() override {
155*6777b538SAndroid Build Coastguard Worker if (ws_upgrade_success_) {
156*6777b538SAndroid Build Coastguard Worker CHECK(url_request_);
157*6777b538SAndroid Build Coastguard Worker // "Cancel" the request with an error code indicating the upgrade
158*6777b538SAndroid Build Coastguard Worker // succeeded.
159*6777b538SAndroid Build Coastguard Worker url_request_->CancelWithError(ERR_WS_UPGRADE);
160*6777b538SAndroid Build Coastguard Worker }
161*6777b538SAndroid Build Coastguard Worker }
162*6777b538SAndroid Build Coastguard Worker
OnBasicHandshakeStreamCreated(WebSocketBasicHandshakeStream * handshake_stream)163*6777b538SAndroid Build Coastguard Worker void OnBasicHandshakeStreamCreated(
164*6777b538SAndroid Build Coastguard Worker WebSocketBasicHandshakeStream* handshake_stream) override {
165*6777b538SAndroid Build Coastguard Worker if (api_delegate_) {
166*6777b538SAndroid Build Coastguard Worker api_delegate_->OnBasicHandshakeStreamCreated(handshake_stream);
167*6777b538SAndroid Build Coastguard Worker }
168*6777b538SAndroid Build Coastguard Worker OnHandshakeStreamCreated(handshake_stream);
169*6777b538SAndroid Build Coastguard Worker }
170*6777b538SAndroid Build Coastguard Worker
OnHttp2HandshakeStreamCreated(WebSocketHttp2HandshakeStream * handshake_stream)171*6777b538SAndroid Build Coastguard Worker void OnHttp2HandshakeStreamCreated(
172*6777b538SAndroid Build Coastguard Worker WebSocketHttp2HandshakeStream* handshake_stream) override {
173*6777b538SAndroid Build Coastguard Worker if (api_delegate_) {
174*6777b538SAndroid Build Coastguard Worker api_delegate_->OnHttp2HandshakeStreamCreated(handshake_stream);
175*6777b538SAndroid Build Coastguard Worker }
176*6777b538SAndroid Build Coastguard Worker OnHandshakeStreamCreated(handshake_stream);
177*6777b538SAndroid Build Coastguard Worker }
178*6777b538SAndroid Build Coastguard Worker
OnHttp3HandshakeStreamCreated(WebSocketHttp3HandshakeStream * handshake_stream)179*6777b538SAndroid Build Coastguard Worker void OnHttp3HandshakeStreamCreated(
180*6777b538SAndroid Build Coastguard Worker WebSocketHttp3HandshakeStream* handshake_stream) override {
181*6777b538SAndroid Build Coastguard Worker if (api_delegate_) {
182*6777b538SAndroid Build Coastguard Worker api_delegate_->OnHttp3HandshakeStreamCreated(handshake_stream);
183*6777b538SAndroid Build Coastguard Worker }
184*6777b538SAndroid Build Coastguard Worker OnHandshakeStreamCreated(handshake_stream);
185*6777b538SAndroid Build Coastguard Worker }
186*6777b538SAndroid Build Coastguard Worker
OnFailure(const std::string & message,int net_error,std::optional<int> response_code)187*6777b538SAndroid Build Coastguard Worker void OnFailure(const std::string& message,
188*6777b538SAndroid Build Coastguard Worker int net_error,
189*6777b538SAndroid Build Coastguard Worker std::optional<int> response_code) override {
190*6777b538SAndroid Build Coastguard Worker if (api_delegate_)
191*6777b538SAndroid Build Coastguard Worker api_delegate_->OnFailure(message, net_error, response_code);
192*6777b538SAndroid Build Coastguard Worker failure_message_ = message;
193*6777b538SAndroid Build Coastguard Worker failure_net_error_ = net_error;
194*6777b538SAndroid Build Coastguard Worker failure_response_code_ = response_code;
195*6777b538SAndroid Build Coastguard Worker }
196*6777b538SAndroid Build Coastguard Worker
Start(std::unique_ptr<base::OneShotTimer> timer)197*6777b538SAndroid Build Coastguard Worker void Start(std::unique_ptr<base::OneShotTimer> timer) {
198*6777b538SAndroid Build Coastguard Worker DCHECK(timer);
199*6777b538SAndroid Build Coastguard Worker base::TimeDelta timeout(base::Seconds(kHandshakeTimeoutIntervalInSeconds));
200*6777b538SAndroid Build Coastguard Worker timer_ = std::move(timer);
201*6777b538SAndroid Build Coastguard Worker timer_->Start(FROM_HERE, timeout,
202*6777b538SAndroid Build Coastguard Worker base::BindOnce(&WebSocketStreamRequestImpl::OnTimeout,
203*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
204*6777b538SAndroid Build Coastguard Worker url_request_->Start();
205*6777b538SAndroid Build Coastguard Worker }
206*6777b538SAndroid Build Coastguard Worker
PerformUpgrade()207*6777b538SAndroid Build Coastguard Worker void PerformUpgrade() {
208*6777b538SAndroid Build Coastguard Worker DCHECK(timer_);
209*6777b538SAndroid Build Coastguard Worker DCHECK(connect_delegate_);
210*6777b538SAndroid Build Coastguard Worker
211*6777b538SAndroid Build Coastguard Worker timer_->Stop();
212*6777b538SAndroid Build Coastguard Worker
213*6777b538SAndroid Build Coastguard Worker if (!handshake_stream_) {
214*6777b538SAndroid Build Coastguard Worker ReportFailureWithMessage(
215*6777b538SAndroid Build Coastguard Worker "No handshake stream has been created or handshake stream is already "
216*6777b538SAndroid Build Coastguard Worker "destroyed.",
217*6777b538SAndroid Build Coastguard Worker ERR_FAILED, std::nullopt);
218*6777b538SAndroid Build Coastguard Worker return;
219*6777b538SAndroid Build Coastguard Worker }
220*6777b538SAndroid Build Coastguard Worker
221*6777b538SAndroid Build Coastguard Worker if (!handshake_stream_->CanReadFromStream()) {
222*6777b538SAndroid Build Coastguard Worker ReportFailureWithMessage("Handshake stream is not readable.",
223*6777b538SAndroid Build Coastguard Worker ERR_CONNECTION_CLOSED, std::nullopt);
224*6777b538SAndroid Build Coastguard Worker return;
225*6777b538SAndroid Build Coastguard Worker }
226*6777b538SAndroid Build Coastguard Worker
227*6777b538SAndroid Build Coastguard Worker ws_upgrade_success_ = true;
228*6777b538SAndroid Build Coastguard Worker WebSocketHandshakeStreamBase* handshake_stream = handshake_stream_.get();
229*6777b538SAndroid Build Coastguard Worker handshake_stream_.reset();
230*6777b538SAndroid Build Coastguard Worker auto handshake_response_info =
231*6777b538SAndroid Build Coastguard Worker std::make_unique<WebSocketHandshakeResponseInfo>(
232*6777b538SAndroid Build Coastguard Worker url_request_->url(), url_request_->response_headers(),
233*6777b538SAndroid Build Coastguard Worker url_request_->GetResponseRemoteEndpoint(),
234*6777b538SAndroid Build Coastguard Worker url_request_->response_time());
235*6777b538SAndroid Build Coastguard Worker connect_delegate_->OnSuccess(handshake_stream->Upgrade(),
236*6777b538SAndroid Build Coastguard Worker std::move(handshake_response_info));
237*6777b538SAndroid Build Coastguard Worker }
238*6777b538SAndroid Build Coastguard Worker
FailureMessageFromNetError(int net_error)239*6777b538SAndroid Build Coastguard Worker std::string FailureMessageFromNetError(int net_error) {
240*6777b538SAndroid Build Coastguard Worker if (net_error == ERR_TUNNEL_CONNECTION_FAILED) {
241*6777b538SAndroid Build Coastguard Worker // This error is common and confusing, so special-case it.
242*6777b538SAndroid Build Coastguard Worker // TODO(ricea): Include the HostPortPair of the selected proxy server in
243*6777b538SAndroid Build Coastguard Worker // the error message. This is not currently possible because it isn't set
244*6777b538SAndroid Build Coastguard Worker // in HttpResponseInfo when a ERR_TUNNEL_CONNECTION_FAILED error happens.
245*6777b538SAndroid Build Coastguard Worker return "Establishing a tunnel via proxy server failed.";
246*6777b538SAndroid Build Coastguard Worker } else {
247*6777b538SAndroid Build Coastguard Worker return base::StrCat(
248*6777b538SAndroid Build Coastguard Worker {"Error in connection establishment: ", ErrorToString(net_error)});
249*6777b538SAndroid Build Coastguard Worker }
250*6777b538SAndroid Build Coastguard Worker }
251*6777b538SAndroid Build Coastguard Worker
ReportFailure(int net_error,std::optional<int> response_code)252*6777b538SAndroid Build Coastguard Worker void ReportFailure(int net_error, std::optional<int> response_code) {
253*6777b538SAndroid Build Coastguard Worker DCHECK(timer_);
254*6777b538SAndroid Build Coastguard Worker timer_->Stop();
255*6777b538SAndroid Build Coastguard Worker if (failure_message_.empty()) {
256*6777b538SAndroid Build Coastguard Worker switch (net_error) {
257*6777b538SAndroid Build Coastguard Worker case OK:
258*6777b538SAndroid Build Coastguard Worker case ERR_IO_PENDING:
259*6777b538SAndroid Build Coastguard Worker break;
260*6777b538SAndroid Build Coastguard Worker case ERR_ABORTED:
261*6777b538SAndroid Build Coastguard Worker failure_message_ = "WebSocket opening handshake was canceled";
262*6777b538SAndroid Build Coastguard Worker break;
263*6777b538SAndroid Build Coastguard Worker case ERR_TIMED_OUT:
264*6777b538SAndroid Build Coastguard Worker failure_message_ = "WebSocket opening handshake timed out";
265*6777b538SAndroid Build Coastguard Worker break;
266*6777b538SAndroid Build Coastguard Worker default:
267*6777b538SAndroid Build Coastguard Worker failure_message_ = FailureMessageFromNetError(net_error);
268*6777b538SAndroid Build Coastguard Worker break;
269*6777b538SAndroid Build Coastguard Worker }
270*6777b538SAndroid Build Coastguard Worker }
271*6777b538SAndroid Build Coastguard Worker
272*6777b538SAndroid Build Coastguard Worker ReportFailureWithMessage(
273*6777b538SAndroid Build Coastguard Worker failure_message_, failure_net_error_.value_or(net_error),
274*6777b538SAndroid Build Coastguard Worker failure_response_code_ ? failure_response_code_ : response_code);
275*6777b538SAndroid Build Coastguard Worker }
276*6777b538SAndroid Build Coastguard Worker
ReportFailureWithMessage(const std::string & failure_message,int net_error,std::optional<int> response_code)277*6777b538SAndroid Build Coastguard Worker void ReportFailureWithMessage(const std::string& failure_message,
278*6777b538SAndroid Build Coastguard Worker int net_error,
279*6777b538SAndroid Build Coastguard Worker std::optional<int> response_code) {
280*6777b538SAndroid Build Coastguard Worker connect_delegate_->OnFailure(failure_message, net_error, response_code);
281*6777b538SAndroid Build Coastguard Worker }
282*6777b538SAndroid Build Coastguard Worker
connect_delegate() const283*6777b538SAndroid Build Coastguard Worker WebSocketStream::ConnectDelegate* connect_delegate() const {
284*6777b538SAndroid Build Coastguard Worker return connect_delegate_.get();
285*6777b538SAndroid Build Coastguard Worker }
286*6777b538SAndroid Build Coastguard Worker
OnTimeout()287*6777b538SAndroid Build Coastguard Worker void OnTimeout() {
288*6777b538SAndroid Build Coastguard Worker url_request_->CancelWithError(ERR_TIMED_OUT);
289*6777b538SAndroid Build Coastguard Worker }
290*6777b538SAndroid Build Coastguard Worker
291*6777b538SAndroid Build Coastguard Worker private:
OnHandshakeStreamCreated(WebSocketHandshakeStreamBase * handshake_stream)292*6777b538SAndroid Build Coastguard Worker void OnHandshakeStreamCreated(
293*6777b538SAndroid Build Coastguard Worker WebSocketHandshakeStreamBase* handshake_stream) {
294*6777b538SAndroid Build Coastguard Worker DCHECK(handshake_stream);
295*6777b538SAndroid Build Coastguard Worker
296*6777b538SAndroid Build Coastguard Worker handshake_stream_ = handshake_stream->GetWeakPtr();
297*6777b538SAndroid Build Coastguard Worker }
298*6777b538SAndroid Build Coastguard Worker
299*6777b538SAndroid Build Coastguard Worker // |delegate_| needs to be declared before |url_request_| so that it gets
300*6777b538SAndroid Build Coastguard Worker // initialised first and destroyed second.
301*6777b538SAndroid Build Coastguard Worker Delegate delegate_;
302*6777b538SAndroid Build Coastguard Worker
303*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketStream::ConnectDelegate> connect_delegate_;
304*6777b538SAndroid Build Coastguard Worker
305*6777b538SAndroid Build Coastguard Worker // Deleting the WebSocketStreamRequestImpl object deletes this URLRequest
306*6777b538SAndroid Build Coastguard Worker // object, cancelling the whole connection. Must be destroyed before
307*6777b538SAndroid Build Coastguard Worker // `delegate_`, since `url_request_` has a pointer to it, and before
308*6777b538SAndroid Build Coastguard Worker // `connect_delegate_`, because there may be a pointer to it further down the
309*6777b538SAndroid Build Coastguard Worker // stack.
310*6777b538SAndroid Build Coastguard Worker const std::unique_ptr<URLRequest> url_request_;
311*6777b538SAndroid Build Coastguard Worker
312*6777b538SAndroid Build Coastguard Worker // This is owned by the caller of
313*6777b538SAndroid Build Coastguard Worker // WebsocketHandshakeStreamCreateHelper::CreateBasicStream() or
314*6777b538SAndroid Build Coastguard Worker // CreateHttp2Stream() or CreateHttp3Stream(). Both the stream and this
315*6777b538SAndroid Build Coastguard Worker // object will be destroyed during the destruction of the URLRequest object
316*6777b538SAndroid Build Coastguard Worker // associated with the handshake. This is only guaranteed to be a valid
317*6777b538SAndroid Build Coastguard Worker // pointer if the handshake succeeded.
318*6777b538SAndroid Build Coastguard Worker base::WeakPtr<WebSocketHandshakeStreamBase> handshake_stream_;
319*6777b538SAndroid Build Coastguard Worker
320*6777b538SAndroid Build Coastguard Worker // The failure information supplied by WebSocketBasicHandshakeStream, if any.
321*6777b538SAndroid Build Coastguard Worker std::string failure_message_;
322*6777b538SAndroid Build Coastguard Worker std::optional<int> failure_net_error_;
323*6777b538SAndroid Build Coastguard Worker std::optional<int> failure_response_code_;
324*6777b538SAndroid Build Coastguard Worker
325*6777b538SAndroid Build Coastguard Worker // A timer for handshake timeout.
326*6777b538SAndroid Build Coastguard Worker std::unique_ptr<base::OneShotTimer> timer_;
327*6777b538SAndroid Build Coastguard Worker
328*6777b538SAndroid Build Coastguard Worker // Set to true if the websocket upgrade succeeded.
329*6777b538SAndroid Build Coastguard Worker bool ws_upgrade_success_ = false;
330*6777b538SAndroid Build Coastguard Worker
331*6777b538SAndroid Build Coastguard Worker // A delegate for On*HandshakeCreated and OnFailure calls.
332*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketStreamRequestAPI> api_delegate_;
333*6777b538SAndroid Build Coastguard Worker };
334*6777b538SAndroid Build Coastguard Worker
335*6777b538SAndroid Build Coastguard Worker class SSLErrorCallbacks : public WebSocketEventInterface::SSLErrorCallbacks {
336*6777b538SAndroid Build Coastguard Worker public:
SSLErrorCallbacks(URLRequest * url_request)337*6777b538SAndroid Build Coastguard Worker explicit SSLErrorCallbacks(URLRequest* url_request)
338*6777b538SAndroid Build Coastguard Worker : url_request_(url_request->GetWeakPtr()) {}
339*6777b538SAndroid Build Coastguard Worker
CancelSSLRequest(int error,const SSLInfo * ssl_info)340*6777b538SAndroid Build Coastguard Worker void CancelSSLRequest(int error, const SSLInfo* ssl_info) override {
341*6777b538SAndroid Build Coastguard Worker if (!url_request_)
342*6777b538SAndroid Build Coastguard Worker return;
343*6777b538SAndroid Build Coastguard Worker
344*6777b538SAndroid Build Coastguard Worker if (ssl_info) {
345*6777b538SAndroid Build Coastguard Worker url_request_->CancelWithSSLError(error, *ssl_info);
346*6777b538SAndroid Build Coastguard Worker } else {
347*6777b538SAndroid Build Coastguard Worker url_request_->CancelWithError(error);
348*6777b538SAndroid Build Coastguard Worker }
349*6777b538SAndroid Build Coastguard Worker }
350*6777b538SAndroid Build Coastguard Worker
ContinueSSLRequest()351*6777b538SAndroid Build Coastguard Worker void ContinueSSLRequest() override {
352*6777b538SAndroid Build Coastguard Worker if (url_request_)
353*6777b538SAndroid Build Coastguard Worker url_request_->ContinueDespiteLastError();
354*6777b538SAndroid Build Coastguard Worker }
355*6777b538SAndroid Build Coastguard Worker
356*6777b538SAndroid Build Coastguard Worker private:
357*6777b538SAndroid Build Coastguard Worker base::WeakPtr<URLRequest> url_request_;
358*6777b538SAndroid Build Coastguard Worker };
359*6777b538SAndroid Build Coastguard Worker
OnConnected(URLRequest * request,const TransportInfo & info,CompletionOnceCallback callback)360*6777b538SAndroid Build Coastguard Worker int Delegate::OnConnected(URLRequest* request,
361*6777b538SAndroid Build Coastguard Worker const TransportInfo& info,
362*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback) {
363*6777b538SAndroid Build Coastguard Worker owner_->connect_delegate()->OnURLRequestConnected(request, info);
364*6777b538SAndroid Build Coastguard Worker return OK;
365*6777b538SAndroid Build Coastguard Worker }
366*6777b538SAndroid Build Coastguard Worker
OnReceivedRedirect(URLRequest * request,const RedirectInfo & redirect_info,bool * defer_redirect)367*6777b538SAndroid Build Coastguard Worker void Delegate::OnReceivedRedirect(URLRequest* request,
368*6777b538SAndroid Build Coastguard Worker const RedirectInfo& redirect_info,
369*6777b538SAndroid Build Coastguard Worker bool* defer_redirect) {
370*6777b538SAndroid Build Coastguard Worker // This code should never be reached for externally generated redirects,
371*6777b538SAndroid Build Coastguard Worker // as WebSocketBasicHandshakeStream is responsible for filtering out
372*6777b538SAndroid Build Coastguard Worker // all response codes besides 101, 401, and 407. As such, the URLRequest
373*6777b538SAndroid Build Coastguard Worker // should never see a redirect sent over the network. However, internal
374*6777b538SAndroid Build Coastguard Worker // redirects also result in this method being called, such as those
375*6777b538SAndroid Build Coastguard Worker // caused by HSTS.
376*6777b538SAndroid Build Coastguard Worker // Because it's security critical to prevent externally-generated
377*6777b538SAndroid Build Coastguard Worker // redirects in WebSockets, perform additional checks to ensure this
378*6777b538SAndroid Build Coastguard Worker // is only internal.
379*6777b538SAndroid Build Coastguard Worker GURL::Replacements replacements;
380*6777b538SAndroid Build Coastguard Worker replacements.SetSchemeStr("wss");
381*6777b538SAndroid Build Coastguard Worker GURL expected_url = request->original_url().ReplaceComponents(replacements);
382*6777b538SAndroid Build Coastguard Worker if (redirect_info.new_method != "GET" ||
383*6777b538SAndroid Build Coastguard Worker redirect_info.new_url != expected_url) {
384*6777b538SAndroid Build Coastguard Worker // This should not happen.
385*6777b538SAndroid Build Coastguard Worker DLOG(FATAL) << "Unauthorized WebSocket redirect to "
386*6777b538SAndroid Build Coastguard Worker << redirect_info.new_method << " "
387*6777b538SAndroid Build Coastguard Worker << redirect_info.new_url.spec();
388*6777b538SAndroid Build Coastguard Worker request->Cancel();
389*6777b538SAndroid Build Coastguard Worker }
390*6777b538SAndroid Build Coastguard Worker }
391*6777b538SAndroid Build Coastguard Worker
OnResponseStarted(URLRequest * request,int net_error)392*6777b538SAndroid Build Coastguard Worker void Delegate::OnResponseStarted(URLRequest* request, int net_error) {
393*6777b538SAndroid Build Coastguard Worker DCHECK_NE(ERR_IO_PENDING, net_error);
394*6777b538SAndroid Build Coastguard Worker
395*6777b538SAndroid Build Coastguard Worker const bool is_http2 =
396*6777b538SAndroid Build Coastguard Worker request->response_info().connection_info == HttpConnectionInfo::kHTTP2;
397*6777b538SAndroid Build Coastguard Worker
398*6777b538SAndroid Build Coastguard Worker // All error codes, including OK and ABORTED, as with
399*6777b538SAndroid Build Coastguard Worker // Net.ErrorCodesForMainFrame4
400*6777b538SAndroid Build Coastguard Worker base::UmaHistogramSparse("Net.WebSocket.ErrorCodes", -net_error);
401*6777b538SAndroid Build Coastguard Worker if (is_http2) {
402*6777b538SAndroid Build Coastguard Worker base::UmaHistogramSparse("Net.WebSocket.ErrorCodes.Http2", -net_error);
403*6777b538SAndroid Build Coastguard Worker }
404*6777b538SAndroid Build Coastguard Worker if (net::IsLocalhost(request->url())) {
405*6777b538SAndroid Build Coastguard Worker base::UmaHistogramSparse("Net.WebSocket.ErrorCodes_Localhost", -net_error);
406*6777b538SAndroid Build Coastguard Worker } else {
407*6777b538SAndroid Build Coastguard Worker base::UmaHistogramSparse("Net.WebSocket.ErrorCodes_NotLocalhost",
408*6777b538SAndroid Build Coastguard Worker -net_error);
409*6777b538SAndroid Build Coastguard Worker }
410*6777b538SAndroid Build Coastguard Worker
411*6777b538SAndroid Build Coastguard Worker if (net_error != OK) {
412*6777b538SAndroid Build Coastguard Worker DVLOG(3) << "OnResponseStarted (request failed)";
413*6777b538SAndroid Build Coastguard Worker owner_->ReportFailure(net_error, std::nullopt);
414*6777b538SAndroid Build Coastguard Worker return;
415*6777b538SAndroid Build Coastguard Worker }
416*6777b538SAndroid Build Coastguard Worker const int response_code = request->GetResponseCode();
417*6777b538SAndroid Build Coastguard Worker DVLOG(3) << "OnResponseStarted (response code " << response_code << ")";
418*6777b538SAndroid Build Coastguard Worker
419*6777b538SAndroid Build Coastguard Worker if (is_http2) {
420*6777b538SAndroid Build Coastguard Worker if (response_code == HTTP_OK) {
421*6777b538SAndroid Build Coastguard Worker owner_->PerformUpgrade();
422*6777b538SAndroid Build Coastguard Worker return;
423*6777b538SAndroid Build Coastguard Worker }
424*6777b538SAndroid Build Coastguard Worker
425*6777b538SAndroid Build Coastguard Worker owner_->ReportFailure(net_error, std::nullopt);
426*6777b538SAndroid Build Coastguard Worker return;
427*6777b538SAndroid Build Coastguard Worker }
428*6777b538SAndroid Build Coastguard Worker
429*6777b538SAndroid Build Coastguard Worker switch (response_code) {
430*6777b538SAndroid Build Coastguard Worker case HTTP_SWITCHING_PROTOCOLS:
431*6777b538SAndroid Build Coastguard Worker owner_->PerformUpgrade();
432*6777b538SAndroid Build Coastguard Worker return;
433*6777b538SAndroid Build Coastguard Worker
434*6777b538SAndroid Build Coastguard Worker case HTTP_UNAUTHORIZED:
435*6777b538SAndroid Build Coastguard Worker owner_->ReportFailureWithMessage(
436*6777b538SAndroid Build Coastguard Worker "HTTP Authentication failed; no valid credentials available",
437*6777b538SAndroid Build Coastguard Worker net_error, response_code);
438*6777b538SAndroid Build Coastguard Worker return;
439*6777b538SAndroid Build Coastguard Worker
440*6777b538SAndroid Build Coastguard Worker case HTTP_PROXY_AUTHENTICATION_REQUIRED:
441*6777b538SAndroid Build Coastguard Worker owner_->ReportFailureWithMessage("Proxy authentication failed", net_error,
442*6777b538SAndroid Build Coastguard Worker response_code);
443*6777b538SAndroid Build Coastguard Worker return;
444*6777b538SAndroid Build Coastguard Worker
445*6777b538SAndroid Build Coastguard Worker default:
446*6777b538SAndroid Build Coastguard Worker owner_->ReportFailure(net_error, response_code);
447*6777b538SAndroid Build Coastguard Worker }
448*6777b538SAndroid Build Coastguard Worker }
449*6777b538SAndroid Build Coastguard Worker
OnAuthRequired(URLRequest * request,const AuthChallengeInfo & auth_info)450*6777b538SAndroid Build Coastguard Worker void Delegate::OnAuthRequired(URLRequest* request,
451*6777b538SAndroid Build Coastguard Worker const AuthChallengeInfo& auth_info) {
452*6777b538SAndroid Build Coastguard Worker std::optional<AuthCredentials> credentials;
453*6777b538SAndroid Build Coastguard Worker // This base::Unretained(this) relies on an assumption that |callback| can
454*6777b538SAndroid Build Coastguard Worker // be called called during the opening handshake.
455*6777b538SAndroid Build Coastguard Worker int rv = owner_->connect_delegate()->OnAuthRequired(
456*6777b538SAndroid Build Coastguard Worker auth_info, request->response_headers(),
457*6777b538SAndroid Build Coastguard Worker request->GetResponseRemoteEndpoint(),
458*6777b538SAndroid Build Coastguard Worker base::BindOnce(&Delegate::OnAuthRequiredComplete, base::Unretained(this),
459*6777b538SAndroid Build Coastguard Worker request),
460*6777b538SAndroid Build Coastguard Worker &credentials);
461*6777b538SAndroid Build Coastguard Worker request->LogBlockedBy("WebSocketStream::Delegate::OnAuthRequired");
462*6777b538SAndroid Build Coastguard Worker if (rv == ERR_IO_PENDING)
463*6777b538SAndroid Build Coastguard Worker return;
464*6777b538SAndroid Build Coastguard Worker if (rv != OK) {
465*6777b538SAndroid Build Coastguard Worker request->LogUnblocked();
466*6777b538SAndroid Build Coastguard Worker owner_->ReportFailure(rv, std::nullopt);
467*6777b538SAndroid Build Coastguard Worker return;
468*6777b538SAndroid Build Coastguard Worker }
469*6777b538SAndroid Build Coastguard Worker OnAuthRequiredComplete(request, nullptr);
470*6777b538SAndroid Build Coastguard Worker }
471*6777b538SAndroid Build Coastguard Worker
OnAuthRequiredComplete(URLRequest * request,const AuthCredentials * credentials)472*6777b538SAndroid Build Coastguard Worker void Delegate::OnAuthRequiredComplete(URLRequest* request,
473*6777b538SAndroid Build Coastguard Worker const AuthCredentials* credentials) {
474*6777b538SAndroid Build Coastguard Worker request->LogUnblocked();
475*6777b538SAndroid Build Coastguard Worker if (!credentials) {
476*6777b538SAndroid Build Coastguard Worker request->CancelAuth();
477*6777b538SAndroid Build Coastguard Worker return;
478*6777b538SAndroid Build Coastguard Worker }
479*6777b538SAndroid Build Coastguard Worker request->SetAuth(*credentials);
480*6777b538SAndroid Build Coastguard Worker }
481*6777b538SAndroid Build Coastguard Worker
OnCertificateRequested(URLRequest * request,SSLCertRequestInfo * cert_request_info)482*6777b538SAndroid Build Coastguard Worker void Delegate::OnCertificateRequested(URLRequest* request,
483*6777b538SAndroid Build Coastguard Worker SSLCertRequestInfo* cert_request_info) {
484*6777b538SAndroid Build Coastguard Worker // This method is called when a client certificate is requested, and the
485*6777b538SAndroid Build Coastguard Worker // request context does not already contain a client certificate selection for
486*6777b538SAndroid Build Coastguard Worker // the endpoint. In this case, a main frame resource request would pop-up UI
487*6777b538SAndroid Build Coastguard Worker // to permit selection of a client certificate, but since WebSockets are
488*6777b538SAndroid Build Coastguard Worker // sub-resources they should not pop-up UI and so there is nothing more we can
489*6777b538SAndroid Build Coastguard Worker // do.
490*6777b538SAndroid Build Coastguard Worker request->Cancel();
491*6777b538SAndroid Build Coastguard Worker }
492*6777b538SAndroid Build Coastguard Worker
OnSSLCertificateError(URLRequest * request,int net_error,const SSLInfo & ssl_info,bool fatal)493*6777b538SAndroid Build Coastguard Worker void Delegate::OnSSLCertificateError(URLRequest* request,
494*6777b538SAndroid Build Coastguard Worker int net_error,
495*6777b538SAndroid Build Coastguard Worker const SSLInfo& ssl_info,
496*6777b538SAndroid Build Coastguard Worker bool fatal) {
497*6777b538SAndroid Build Coastguard Worker owner_->connect_delegate()->OnSSLCertificateError(
498*6777b538SAndroid Build Coastguard Worker std::make_unique<SSLErrorCallbacks>(request), net_error, ssl_info, fatal);
499*6777b538SAndroid Build Coastguard Worker }
500*6777b538SAndroid Build Coastguard Worker
OnReadCompleted(URLRequest * request,int bytes_read)501*6777b538SAndroid Build Coastguard Worker void Delegate::OnReadCompleted(URLRequest* request, int bytes_read) {
502*6777b538SAndroid Build Coastguard Worker NOTREACHED();
503*6777b538SAndroid Build Coastguard Worker }
504*6777b538SAndroid Build Coastguard Worker
505*6777b538SAndroid Build Coastguard Worker } // namespace
506*6777b538SAndroid Build Coastguard Worker
507*6777b538SAndroid Build Coastguard Worker WebSocketStreamRequest::~WebSocketStreamRequest() = default;
508*6777b538SAndroid Build Coastguard Worker
509*6777b538SAndroid Build Coastguard Worker WebSocketStream::WebSocketStream() = default;
510*6777b538SAndroid Build Coastguard Worker WebSocketStream::~WebSocketStream() = default;
511*6777b538SAndroid Build Coastguard Worker
512*6777b538SAndroid Build Coastguard Worker WebSocketStream::ConnectDelegate::~ConnectDelegate() = default;
513*6777b538SAndroid Build Coastguard Worker
CreateAndConnectStream(const GURL & socket_url,const std::vector<std::string> & requested_subprotocols,const url::Origin & origin,const SiteForCookies & site_for_cookies,bool has_storage_access,const IsolationInfo & isolation_info,const HttpRequestHeaders & additional_headers,URLRequestContext * url_request_context,const NetLogWithSource & net_log,NetworkTrafficAnnotationTag traffic_annotation,std::unique_ptr<ConnectDelegate> connect_delegate)514*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketStreamRequest> WebSocketStream::CreateAndConnectStream(
515*6777b538SAndroid Build Coastguard Worker const GURL& socket_url,
516*6777b538SAndroid Build Coastguard Worker const std::vector<std::string>& requested_subprotocols,
517*6777b538SAndroid Build Coastguard Worker const url::Origin& origin,
518*6777b538SAndroid Build Coastguard Worker const SiteForCookies& site_for_cookies,
519*6777b538SAndroid Build Coastguard Worker bool has_storage_access,
520*6777b538SAndroid Build Coastguard Worker const IsolationInfo& isolation_info,
521*6777b538SAndroid Build Coastguard Worker const HttpRequestHeaders& additional_headers,
522*6777b538SAndroid Build Coastguard Worker URLRequestContext* url_request_context,
523*6777b538SAndroid Build Coastguard Worker const NetLogWithSource& net_log,
524*6777b538SAndroid Build Coastguard Worker NetworkTrafficAnnotationTag traffic_annotation,
525*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ConnectDelegate> connect_delegate) {
526*6777b538SAndroid Build Coastguard Worker auto request = std::make_unique<WebSocketStreamRequestImpl>(
527*6777b538SAndroid Build Coastguard Worker socket_url, requested_subprotocols, url_request_context, origin,
528*6777b538SAndroid Build Coastguard Worker site_for_cookies, has_storage_access, isolation_info, additional_headers,
529*6777b538SAndroid Build Coastguard Worker traffic_annotation, std::move(connect_delegate), nullptr);
530*6777b538SAndroid Build Coastguard Worker request->Start(std::make_unique<base::OneShotTimer>());
531*6777b538SAndroid Build Coastguard Worker return std::move(request);
532*6777b538SAndroid Build Coastguard Worker }
533*6777b538SAndroid Build Coastguard Worker
534*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketStreamRequest>
CreateAndConnectStreamForTesting(const GURL & socket_url,const std::vector<std::string> & requested_subprotocols,const url::Origin & origin,const SiteForCookies & site_for_cookies,bool has_storage_access,const IsolationInfo & isolation_info,const HttpRequestHeaders & additional_headers,URLRequestContext * url_request_context,const NetLogWithSource & net_log,NetworkTrafficAnnotationTag traffic_annotation,std::unique_ptr<WebSocketStream::ConnectDelegate> connect_delegate,std::unique_ptr<base::OneShotTimer> timer,std::unique_ptr<WebSocketStreamRequestAPI> api_delegate)535*6777b538SAndroid Build Coastguard Worker WebSocketStream::CreateAndConnectStreamForTesting(
536*6777b538SAndroid Build Coastguard Worker const GURL& socket_url,
537*6777b538SAndroid Build Coastguard Worker const std::vector<std::string>& requested_subprotocols,
538*6777b538SAndroid Build Coastguard Worker const url::Origin& origin,
539*6777b538SAndroid Build Coastguard Worker const SiteForCookies& site_for_cookies,
540*6777b538SAndroid Build Coastguard Worker bool has_storage_access,
541*6777b538SAndroid Build Coastguard Worker const IsolationInfo& isolation_info,
542*6777b538SAndroid Build Coastguard Worker const HttpRequestHeaders& additional_headers,
543*6777b538SAndroid Build Coastguard Worker URLRequestContext* url_request_context,
544*6777b538SAndroid Build Coastguard Worker const NetLogWithSource& net_log,
545*6777b538SAndroid Build Coastguard Worker NetworkTrafficAnnotationTag traffic_annotation,
546*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketStream::ConnectDelegate> connect_delegate,
547*6777b538SAndroid Build Coastguard Worker std::unique_ptr<base::OneShotTimer> timer,
548*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketStreamRequestAPI> api_delegate) {
549*6777b538SAndroid Build Coastguard Worker auto request = std::make_unique<WebSocketStreamRequestImpl>(
550*6777b538SAndroid Build Coastguard Worker socket_url, requested_subprotocols, url_request_context, origin,
551*6777b538SAndroid Build Coastguard Worker site_for_cookies, has_storage_access, isolation_info, additional_headers,
552*6777b538SAndroid Build Coastguard Worker traffic_annotation, std::move(connect_delegate), std::move(api_delegate));
553*6777b538SAndroid Build Coastguard Worker request->Start(std::move(timer));
554*6777b538SAndroid Build Coastguard Worker return std::move(request);
555*6777b538SAndroid Build Coastguard Worker }
556*6777b538SAndroid Build Coastguard Worker
557*6777b538SAndroid Build Coastguard Worker } // namespace net
558