xref: /aosp_15_r20/external/cronet/net/websockets/websocket_stream.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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