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 #ifndef NET_WEBSOCKETS_WEBSOCKET_CHANNEL_H_ 6*6777b538SAndroid Build Coastguard Worker #define NET_WEBSOCKETS_WEBSOCKET_CHANNEL_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 9*6777b538SAndroid Build Coastguard Worker #include <stdint.h> 10*6777b538SAndroid Build Coastguard Worker 11*6777b538SAndroid Build Coastguard Worker #include <memory> 12*6777b538SAndroid Build Coastguard Worker #include <optional> 13*6777b538SAndroid Build Coastguard Worker #include <string> 14*6777b538SAndroid Build Coastguard Worker #include <vector> 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker #include "base/containers/queue.h" 17*6777b538SAndroid Build Coastguard Worker #include "base/containers/span.h" 18*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h" 19*6777b538SAndroid Build Coastguard Worker #include "base/i18n/streaming_utf8_validator.h" 20*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h" 21*6777b538SAndroid Build Coastguard Worker #include "base/memory/scoped_refptr.h" 22*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 23*6777b538SAndroid Build Coastguard Worker #include "base/timer/timer.h" 24*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h" 25*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_event_interface.h" 26*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_frame.h" 27*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_stream.h" 28*6777b538SAndroid Build Coastguard Worker #include "url/gurl.h" 29*6777b538SAndroid Build Coastguard Worker 30*6777b538SAndroid Build Coastguard Worker namespace url { 31*6777b538SAndroid Build Coastguard Worker class Origin; 32*6777b538SAndroid Build Coastguard Worker } // namespace url 33*6777b538SAndroid Build Coastguard Worker 34*6777b538SAndroid Build Coastguard Worker namespace net { 35*6777b538SAndroid Build Coastguard Worker 36*6777b538SAndroid Build Coastguard Worker class AuthChallengeInfo; 37*6777b538SAndroid Build Coastguard Worker class AuthCredentials; 38*6777b538SAndroid Build Coastguard Worker class HttpRequestHeaders; 39*6777b538SAndroid Build Coastguard Worker class HttpResponseHeaders; 40*6777b538SAndroid Build Coastguard Worker class IOBuffer; 41*6777b538SAndroid Build Coastguard Worker class IPEndPoint; 42*6777b538SAndroid Build Coastguard Worker class IsolationInfo; 43*6777b538SAndroid Build Coastguard Worker class NetLogWithSource; 44*6777b538SAndroid Build Coastguard Worker class SSLInfo; 45*6777b538SAndroid Build Coastguard Worker class SiteForCookies; 46*6777b538SAndroid Build Coastguard Worker class URLRequest; 47*6777b538SAndroid Build Coastguard Worker class URLRequestContext; 48*6777b538SAndroid Build Coastguard Worker struct NetworkTrafficAnnotationTag; 49*6777b538SAndroid Build Coastguard Worker struct WebSocketHandshakeRequestInfo; 50*6777b538SAndroid Build Coastguard Worker struct WebSocketHandshakeResponseInfo; 51*6777b538SAndroid Build Coastguard Worker 52*6777b538SAndroid Build Coastguard Worker // Transport-independent implementation of WebSockets. Implements protocol 53*6777b538SAndroid Build Coastguard Worker // semantics that do not depend on the underlying transport. Provides the 54*6777b538SAndroid Build Coastguard Worker // interface to the content layer. Some WebSocket concepts are used here without 55*6777b538SAndroid Build Coastguard Worker // definition; please see the RFC at http://tools.ietf.org/html/rfc6455 for 56*6777b538SAndroid Build Coastguard Worker // clarification. 57*6777b538SAndroid Build Coastguard Worker class NET_EXPORT WebSocketChannel { 58*6777b538SAndroid Build Coastguard Worker public: 59*6777b538SAndroid Build Coastguard Worker // The type of a WebSocketStream creator callback. Must match the signature of 60*6777b538SAndroid Build Coastguard Worker // WebSocketStream::CreateAndConnectStream(). 61*6777b538SAndroid Build Coastguard Worker typedef base::OnceCallback<std::unique_ptr<WebSocketStreamRequest>( 62*6777b538SAndroid Build Coastguard Worker const GURL&, 63*6777b538SAndroid Build Coastguard Worker const std::vector<std::string>&, 64*6777b538SAndroid Build Coastguard Worker const url::Origin&, 65*6777b538SAndroid Build Coastguard Worker const SiteForCookies&, 66*6777b538SAndroid Build Coastguard Worker bool, 67*6777b538SAndroid Build Coastguard Worker const IsolationInfo&, 68*6777b538SAndroid Build Coastguard Worker const HttpRequestHeaders&, 69*6777b538SAndroid Build Coastguard Worker URLRequestContext*, 70*6777b538SAndroid Build Coastguard Worker const NetLogWithSource&, 71*6777b538SAndroid Build Coastguard Worker NetworkTrafficAnnotationTag, 72*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketStream::ConnectDelegate>)> 73*6777b538SAndroid Build Coastguard Worker WebSocketStreamRequestCreationCallback; 74*6777b538SAndroid Build Coastguard Worker 75*6777b538SAndroid Build Coastguard Worker // Methods which return a value of type ChannelState may delete |this|. If the 76*6777b538SAndroid Build Coastguard Worker // return value is CHANNEL_DELETED, then the caller must return without making 77*6777b538SAndroid Build Coastguard Worker // any further access to member variables or methods. 78*6777b538SAndroid Build Coastguard Worker enum ChannelState { CHANNEL_ALIVE, CHANNEL_DELETED }; 79*6777b538SAndroid Build Coastguard Worker 80*6777b538SAndroid Build Coastguard Worker // Creates a new WebSocketChannel in an idle state. 81*6777b538SAndroid Build Coastguard Worker // SendAddChannelRequest() must be called immediately afterwards to start the 82*6777b538SAndroid Build Coastguard Worker // connection process. 83*6777b538SAndroid Build Coastguard Worker WebSocketChannel(std::unique_ptr<WebSocketEventInterface> event_interface, 84*6777b538SAndroid Build Coastguard Worker URLRequestContext* url_request_context); 85*6777b538SAndroid Build Coastguard Worker 86*6777b538SAndroid Build Coastguard Worker WebSocketChannel(const WebSocketChannel&) = delete; 87*6777b538SAndroid Build Coastguard Worker WebSocketChannel& operator=(const WebSocketChannel&) = delete; 88*6777b538SAndroid Build Coastguard Worker 89*6777b538SAndroid Build Coastguard Worker virtual ~WebSocketChannel(); 90*6777b538SAndroid Build Coastguard Worker 91*6777b538SAndroid Build Coastguard Worker // Starts the connection process. 92*6777b538SAndroid Build Coastguard Worker void SendAddChannelRequest( 93*6777b538SAndroid Build Coastguard Worker const GURL& socket_url, 94*6777b538SAndroid Build Coastguard Worker const std::vector<std::string>& requested_protocols, 95*6777b538SAndroid Build Coastguard Worker const url::Origin& origin, 96*6777b538SAndroid Build Coastguard Worker const SiteForCookies& site_for_cookies, 97*6777b538SAndroid Build Coastguard Worker bool has_storage_access, 98*6777b538SAndroid Build Coastguard Worker const IsolationInfo& isolation_info, 99*6777b538SAndroid Build Coastguard Worker const HttpRequestHeaders& additional_headers, 100*6777b538SAndroid Build Coastguard Worker NetworkTrafficAnnotationTag traffic_annotation); 101*6777b538SAndroid Build Coastguard Worker 102*6777b538SAndroid Build Coastguard Worker // Sends a data frame to the remote side. It is the responsibility of the 103*6777b538SAndroid Build Coastguard Worker // caller to ensure that they have sufficient send quota to send this data, 104*6777b538SAndroid Build Coastguard Worker // otherwise the connection will be closed without sending. |fin| indicates 105*6777b538SAndroid Build Coastguard Worker // the last frame in a message, equivalent to "FIN" as specified in section 106*6777b538SAndroid Build Coastguard Worker // 5.2 of RFC6455. |buffer->data()| is the "Payload Data". If |op_code| is 107*6777b538SAndroid Build Coastguard Worker // kOpCodeText, or it is kOpCodeContinuation and the type the message is 108*6777b538SAndroid Build Coastguard Worker // Text, then |buffer->data()| must be a chunk of a valid UTF-8 message, 109*6777b538SAndroid Build Coastguard Worker // however there is no requirement for |buffer->data()| to be split on 110*6777b538SAndroid Build Coastguard Worker // character boundaries. Calling SendFrame may result in synchronous calls to 111*6777b538SAndroid Build Coastguard Worker // |event_interface_| which may result in this object being deleted. In that 112*6777b538SAndroid Build Coastguard Worker // case, the return value will be CHANNEL_DELETED. 113*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState SendFrame(bool fin, 114*6777b538SAndroid Build Coastguard Worker WebSocketFrameHeader::OpCode op_code, 115*6777b538SAndroid Build Coastguard Worker scoped_refptr<IOBuffer> buffer, 116*6777b538SAndroid Build Coastguard Worker size_t buffer_size); 117*6777b538SAndroid Build Coastguard Worker 118*6777b538SAndroid Build Coastguard Worker // Calls WebSocketStream::ReadFrames() with the appropriate arguments. Stops 119*6777b538SAndroid Build Coastguard Worker // calling ReadFrames if no writable buffer in dataframe or WebSocketStream 120*6777b538SAndroid Build Coastguard Worker // starts async read. 121*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState ReadFrames(); 122*6777b538SAndroid Build Coastguard Worker 123*6777b538SAndroid Build Coastguard Worker // Starts the closing handshake for a client-initiated shutdown of the 124*6777b538SAndroid Build Coastguard Worker // connection. There is no API to close the connection without a closing 125*6777b538SAndroid Build Coastguard Worker // handshake, but destroying the WebSocketChannel object while connected will 126*6777b538SAndroid Build Coastguard Worker // effectively do that. |code| must be in the range 1000-4999. |reason| should 127*6777b538SAndroid Build Coastguard Worker // be a valid UTF-8 string or empty. 128*6777b538SAndroid Build Coastguard Worker // 129*6777b538SAndroid Build Coastguard Worker // Calling this function may result in synchronous calls to |event_interface_| 130*6777b538SAndroid Build Coastguard Worker // which may result in this object being deleted. In that case, the return 131*6777b538SAndroid Build Coastguard Worker // value will be CHANNEL_DELETED. 132*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState StartClosingHandshake(uint16_t code, 133*6777b538SAndroid Build Coastguard Worker const std::string& reason); 134*6777b538SAndroid Build Coastguard Worker 135*6777b538SAndroid Build Coastguard Worker // Starts the connection process, using a specified creator callback rather 136*6777b538SAndroid Build Coastguard Worker // than the default. This is exposed for testing. 137*6777b538SAndroid Build Coastguard Worker void SendAddChannelRequestForTesting( 138*6777b538SAndroid Build Coastguard Worker const GURL& socket_url, 139*6777b538SAndroid Build Coastguard Worker const std::vector<std::string>& requested_protocols, 140*6777b538SAndroid Build Coastguard Worker const url::Origin& origin, 141*6777b538SAndroid Build Coastguard Worker const SiteForCookies& site_for_cookies, 142*6777b538SAndroid Build Coastguard Worker bool has_storage_access, 143*6777b538SAndroid Build Coastguard Worker const IsolationInfo& isolation_info, 144*6777b538SAndroid Build Coastguard Worker const HttpRequestHeaders& additional_headers, 145*6777b538SAndroid Build Coastguard Worker NetworkTrafficAnnotationTag traffic_annotation, 146*6777b538SAndroid Build Coastguard Worker WebSocketStreamRequestCreationCallback callback); 147*6777b538SAndroid Build Coastguard Worker 148*6777b538SAndroid Build Coastguard Worker // The default timout for the closing handshake is a sensible value (see 149*6777b538SAndroid Build Coastguard Worker // kClosingHandshakeTimeoutSeconds in websocket_channel.cc). However, we can 150*6777b538SAndroid Build Coastguard Worker // set it to a very small value for testing purposes. 151*6777b538SAndroid Build Coastguard Worker void SetClosingHandshakeTimeoutForTesting(base::TimeDelta delay); 152*6777b538SAndroid Build Coastguard Worker 153*6777b538SAndroid Build Coastguard Worker // The default timout for the underlying connection close is a sensible value 154*6777b538SAndroid Build Coastguard Worker // (see kUnderlyingConnectionCloseTimeoutSeconds in websocket_channel.cc). 155*6777b538SAndroid Build Coastguard Worker // However, we can set it to a very small value for testing purposes. 156*6777b538SAndroid Build Coastguard Worker void SetUnderlyingConnectionCloseTimeoutForTesting(base::TimeDelta delay); 157*6777b538SAndroid Build Coastguard Worker 158*6777b538SAndroid Build Coastguard Worker // Called when the stream starts the WebSocket Opening Handshake. 159*6777b538SAndroid Build Coastguard Worker // This method is public for testing. 160*6777b538SAndroid Build Coastguard Worker void OnStartOpeningHandshake( 161*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketHandshakeRequestInfo> request); 162*6777b538SAndroid Build Coastguard Worker 163*6777b538SAndroid Build Coastguard Worker private: 164*6777b538SAndroid Build Coastguard Worker // The object passes through a linear progression of states from 165*6777b538SAndroid Build Coastguard Worker // FRESHLY_CONSTRUCTED to CLOSED, except that the SEND_CLOSED and RECV_CLOSED 166*6777b538SAndroid Build Coastguard Worker // states may be skipped in case of error. 167*6777b538SAndroid Build Coastguard Worker enum State { 168*6777b538SAndroid Build Coastguard Worker FRESHLY_CONSTRUCTED, 169*6777b538SAndroid Build Coastguard Worker CONNECTING, 170*6777b538SAndroid Build Coastguard Worker CONNECTED, 171*6777b538SAndroid Build Coastguard Worker SEND_CLOSED, // A Close frame has been sent but not received. 172*6777b538SAndroid Build Coastguard Worker RECV_CLOSED, // Used briefly between receiving a Close frame and sending 173*6777b538SAndroid Build Coastguard Worker // the response. Once the response is sent, the state changes 174*6777b538SAndroid Build Coastguard Worker // to CLOSED. 175*6777b538SAndroid Build Coastguard Worker CLOSE_WAIT, // The Closing Handshake has completed, but the remote server 176*6777b538SAndroid Build Coastguard Worker // has not yet closed the connection. 177*6777b538SAndroid Build Coastguard Worker CLOSED, // The Closing Handshake has completed and the connection 178*6777b538SAndroid Build Coastguard Worker // has been closed; or the connection is failed. 179*6777b538SAndroid Build Coastguard Worker }; 180*6777b538SAndroid Build Coastguard Worker 181*6777b538SAndroid Build Coastguard Worker // Implementation of WebSocketStream::ConnectDelegate for 182*6777b538SAndroid Build Coastguard Worker // WebSocketChannel. WebSocketChannel does not inherit from 183*6777b538SAndroid Build Coastguard Worker // WebSocketStream::ConnectDelegate directly to avoid cluttering the public 184*6777b538SAndroid Build Coastguard Worker // interface with the implementation of those methods, and because the 185*6777b538SAndroid Build Coastguard Worker // lifetime of a WebSocketChannel is longer than the lifetime of the 186*6777b538SAndroid Build Coastguard Worker // connection process. 187*6777b538SAndroid Build Coastguard Worker class ConnectDelegate; 188*6777b538SAndroid Build Coastguard Worker 189*6777b538SAndroid Build Coastguard Worker // Starts the connection process, using the supplied stream request creation 190*6777b538SAndroid Build Coastguard Worker // callback. 191*6777b538SAndroid Build Coastguard Worker void SendAddChannelRequestWithSuppliedCallback( 192*6777b538SAndroid Build Coastguard Worker const GURL& socket_url, 193*6777b538SAndroid Build Coastguard Worker const std::vector<std::string>& requested_protocols, 194*6777b538SAndroid Build Coastguard Worker const url::Origin& origin, 195*6777b538SAndroid Build Coastguard Worker const SiteForCookies& site_for_cookies, 196*6777b538SAndroid Build Coastguard Worker bool has_storage_access, 197*6777b538SAndroid Build Coastguard Worker const IsolationInfo& isolation_info, 198*6777b538SAndroid Build Coastguard Worker const HttpRequestHeaders& additional_headers, 199*6777b538SAndroid Build Coastguard Worker NetworkTrafficAnnotationTag traffic_annotation, 200*6777b538SAndroid Build Coastguard Worker WebSocketStreamRequestCreationCallback callback); 201*6777b538SAndroid Build Coastguard Worker 202*6777b538SAndroid Build Coastguard Worker // Called when a URLRequest is created for handshaking. 203*6777b538SAndroid Build Coastguard Worker void OnCreateURLRequest(URLRequest* request); 204*6777b538SAndroid Build Coastguard Worker 205*6777b538SAndroid Build Coastguard Worker // Called when a URLRequest's OnConnected is called. Forwards the call to the 206*6777b538SAndroid Build Coastguard Worker // |event_interface_| 207*6777b538SAndroid Build Coastguard Worker void OnURLRequestConnected(URLRequest* request, const TransportInfo& info); 208*6777b538SAndroid Build Coastguard Worker 209*6777b538SAndroid Build Coastguard Worker // Success callback from WebSocketStream::CreateAndConnectStream(). Reports 210*6777b538SAndroid Build Coastguard Worker // success to the event interface. May delete |this|. 211*6777b538SAndroid Build Coastguard Worker void OnConnectSuccess( 212*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketStream> stream, 213*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketHandshakeResponseInfo> response); 214*6777b538SAndroid Build Coastguard Worker 215*6777b538SAndroid Build Coastguard Worker // Failure callback from WebSocketStream::CreateAndConnectStream(). Reports 216*6777b538SAndroid Build Coastguard Worker // failure to the event interface. May delete |this|. 217*6777b538SAndroid Build Coastguard Worker void OnConnectFailure(const std::string& message, 218*6777b538SAndroid Build Coastguard Worker int net_error, 219*6777b538SAndroid Build Coastguard Worker std::optional<int> response_code); 220*6777b538SAndroid Build Coastguard Worker 221*6777b538SAndroid Build Coastguard Worker // SSL certificate error callback from 222*6777b538SAndroid Build Coastguard Worker // WebSocketStream::CreateAndConnectStream(). Forwards the request to the 223*6777b538SAndroid Build Coastguard Worker // event interface. 224*6777b538SAndroid Build Coastguard Worker void OnSSLCertificateError( 225*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketEventInterface::SSLErrorCallbacks> 226*6777b538SAndroid Build Coastguard Worker ssl_error_callbacks, 227*6777b538SAndroid Build Coastguard Worker int net_error, 228*6777b538SAndroid Build Coastguard Worker const SSLInfo& ssl_info, 229*6777b538SAndroid Build Coastguard Worker bool fatal); 230*6777b538SAndroid Build Coastguard Worker 231*6777b538SAndroid Build Coastguard Worker // Authentication request from WebSocketStream::CreateAndConnectStream(). 232*6777b538SAndroid Build Coastguard Worker // Forwards the request to the event interface. 233*6777b538SAndroid Build Coastguard Worker int OnAuthRequired(const AuthChallengeInfo& auth_info, 234*6777b538SAndroid Build Coastguard Worker scoped_refptr<HttpResponseHeaders> response_headers, 235*6777b538SAndroid Build Coastguard Worker const IPEndPoint& remote_endpoint, 236*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(const AuthCredentials*)> callback, 237*6777b538SAndroid Build Coastguard Worker std::optional<AuthCredentials>* credentials); 238*6777b538SAndroid Build Coastguard Worker 239*6777b538SAndroid Build Coastguard Worker // Sets |state_| to |new_state| and updates UMA if necessary. 240*6777b538SAndroid Build Coastguard Worker void SetState(State new_state); 241*6777b538SAndroid Build Coastguard Worker 242*6777b538SAndroid Build Coastguard Worker // Returns true if state_ is SEND_CLOSED, CLOSE_WAIT or CLOSED. 243*6777b538SAndroid Build Coastguard Worker bool InClosingState() const; 244*6777b538SAndroid Build Coastguard Worker 245*6777b538SAndroid Build Coastguard Worker // Calls WebSocketStream::WriteFrames() with the appropriate arguments 246*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState WriteFrames(); 247*6777b538SAndroid Build Coastguard Worker 248*6777b538SAndroid Build Coastguard Worker // Callback from WebSocketStream::WriteFrames. Sends pending data or adjusts 249*6777b538SAndroid Build Coastguard Worker // the send quota of the renderer channel as appropriate. |result| is a net 250*6777b538SAndroid Build Coastguard Worker // error code, usually OK. If |synchronous| is true, then OnWriteDone() is 251*6777b538SAndroid Build Coastguard Worker // being called from within the WriteFrames() loop and does not need to call 252*6777b538SAndroid Build Coastguard Worker // WriteFrames() itself. 253*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState OnWriteDone(bool synchronous, int result); 254*6777b538SAndroid Build Coastguard Worker 255*6777b538SAndroid Build Coastguard Worker // Callback from WebSocketStream::ReadFrames. Handles any errors and processes 256*6777b538SAndroid Build Coastguard Worker // the returned chunks appropriately to their type. |result| is a net error 257*6777b538SAndroid Build Coastguard Worker // code. If |synchronous| is true, then OnReadDone() is being called from 258*6777b538SAndroid Build Coastguard Worker // within the ReadFrames() loop and does not need to call ReadFrames() itself. 259*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState OnReadDone(bool synchronous, int result); 260*6777b538SAndroid Build Coastguard Worker 261*6777b538SAndroid Build Coastguard Worker // Handles a single frame that the object has received enough of to process. 262*6777b538SAndroid Build Coastguard Worker // May call |event_interface_| methods, send responses to the server, and 263*6777b538SAndroid Build Coastguard Worker // change the value of |state_|. 264*6777b538SAndroid Build Coastguard Worker // 265*6777b538SAndroid Build Coastguard Worker // This method performs sanity checks on the frame that are needed regardless 266*6777b538SAndroid Build Coastguard Worker // of the current state. Then, calls the HandleFrameByState() method below 267*6777b538SAndroid Build Coastguard Worker // which performs the appropriate action(s) depending on the current state. 268*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState HandleFrame(std::unique_ptr<WebSocketFrame> frame); 269*6777b538SAndroid Build Coastguard Worker 270*6777b538SAndroid Build Coastguard Worker // Handles a single frame depending on the current state. It's used by the 271*6777b538SAndroid Build Coastguard Worker // HandleFrame() method. 272*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState HandleFrameByState( 273*6777b538SAndroid Build Coastguard Worker const WebSocketFrameHeader::OpCode opcode, 274*6777b538SAndroid Build Coastguard Worker bool final, 275*6777b538SAndroid Build Coastguard Worker base::span<const char> payload); 276*6777b538SAndroid Build Coastguard Worker 277*6777b538SAndroid Build Coastguard Worker // Forwards a received data frame to the renderer, if connected. If 278*6777b538SAndroid Build Coastguard Worker // |expecting_continuation| is not equal to |expecting_to_read_continuation_|, 279*6777b538SAndroid Build Coastguard Worker // will fail the channel. Also checks the UTF-8 validity of text frames. 280*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState HandleDataFrame( 281*6777b538SAndroid Build Coastguard Worker WebSocketFrameHeader::OpCode opcode, 282*6777b538SAndroid Build Coastguard Worker bool final, 283*6777b538SAndroid Build Coastguard Worker base::span<const char> payload); 284*6777b538SAndroid Build Coastguard Worker 285*6777b538SAndroid Build Coastguard Worker // Handles an incoming close frame with |code| and |reason|. 286*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState HandleCloseFrame(uint16_t code, 287*6777b538SAndroid Build Coastguard Worker const std::string& reason); 288*6777b538SAndroid Build Coastguard Worker 289*6777b538SAndroid Build Coastguard Worker // Responds to a closing handshake initiated by the server. 290*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState RespondToClosingHandshake(); 291*6777b538SAndroid Build Coastguard Worker 292*6777b538SAndroid Build Coastguard Worker // Low-level method to send a single frame. Used for both data and control 293*6777b538SAndroid Build Coastguard Worker // frames. Either sends the frame immediately or buffers it to be scheduled 294*6777b538SAndroid Build Coastguard Worker // when the current write finishes. |fin| and |op_code| are defined as for 295*6777b538SAndroid Build Coastguard Worker // SendFrame() above, except that |op_code| may also be a control frame 296*6777b538SAndroid Build Coastguard Worker // opcode. 297*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState SendFrameInternal( 298*6777b538SAndroid Build Coastguard Worker bool fin, 299*6777b538SAndroid Build Coastguard Worker WebSocketFrameHeader::OpCode op_code, 300*6777b538SAndroid Build Coastguard Worker scoped_refptr<IOBuffer> buffer, 301*6777b538SAndroid Build Coastguard Worker uint64_t buffer_size); 302*6777b538SAndroid Build Coastguard Worker 303*6777b538SAndroid Build Coastguard Worker // Performs the "Fail the WebSocket Connection" operation as defined in 304*6777b538SAndroid Build Coastguard Worker // RFC6455. A NotifyFailure message is sent to the renderer with |message|. 305*6777b538SAndroid Build Coastguard Worker // The renderer will log the message to the console but not expose it to 306*6777b538SAndroid Build Coastguard Worker // Javascript. Javascript will see a Close code of AbnormalClosure (1006) with 307*6777b538SAndroid Build Coastguard Worker // an empty reason string. If state_ is CONNECTED then a Close message is sent 308*6777b538SAndroid Build Coastguard Worker // to the remote host containing the supplied |code| and |reason|. If the 309*6777b538SAndroid Build Coastguard Worker // stream is open, closes it and sets state_ to CLOSED. This function deletes 310*6777b538SAndroid Build Coastguard Worker // |this|. 311*6777b538SAndroid Build Coastguard Worker void FailChannel(const std::string& message, 312*6777b538SAndroid Build Coastguard Worker uint16_t code, 313*6777b538SAndroid Build Coastguard Worker const std::string& reason); 314*6777b538SAndroid Build Coastguard Worker 315*6777b538SAndroid Build Coastguard Worker // Sends a Close frame to Start the WebSocket Closing Handshake, or to respond 316*6777b538SAndroid Build Coastguard Worker // to a Close frame from the server. As a special case, setting |code| to 317*6777b538SAndroid Build Coastguard Worker // kWebSocketErrorNoStatusReceived will create a Close frame with no payload; 318*6777b538SAndroid Build Coastguard Worker // this is symmetric with the behaviour of ParseClose. 319*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ChannelState SendClose(uint16_t code, 320*6777b538SAndroid Build Coastguard Worker const std::string& reason); 321*6777b538SAndroid Build Coastguard Worker 322*6777b538SAndroid Build Coastguard Worker // Parses a Close frame payload. If no status code is supplied, then |code| is 323*6777b538SAndroid Build Coastguard Worker // set to 1005 (No status code) with empty |reason|. If the reason text is not 324*6777b538SAndroid Build Coastguard Worker // valid UTF-8, then |reason| is set to an empty string. If the payload size 325*6777b538SAndroid Build Coastguard Worker // is 1, or the supplied code is not permitted to be sent over the network, 326*6777b538SAndroid Build Coastguard Worker // then false is returned and |message| is set to an appropriate console 327*6777b538SAndroid Build Coastguard Worker // message. 328*6777b538SAndroid Build Coastguard Worker bool ParseClose(base::span<const char> payload, 329*6777b538SAndroid Build Coastguard Worker uint16_t* code, 330*6777b538SAndroid Build Coastguard Worker std::string* reason, 331*6777b538SAndroid Build Coastguard Worker std::string* message); 332*6777b538SAndroid Build Coastguard Worker 333*6777b538SAndroid Build Coastguard Worker // Drop this channel. 334*6777b538SAndroid Build Coastguard Worker // If there are pending opening handshake notifications, notify them 335*6777b538SAndroid Build Coastguard Worker // before dropping. This function deletes |this|. 336*6777b538SAndroid Build Coastguard Worker void DoDropChannel(bool was_clean, uint16_t code, const std::string& reason); 337*6777b538SAndroid Build Coastguard Worker 338*6777b538SAndroid Build Coastguard Worker // Called if the closing handshake times out. Closes the connection and 339*6777b538SAndroid Build Coastguard Worker // informs the |event_interface_| if appropriate. 340*6777b538SAndroid Build Coastguard Worker void CloseTimeout(); 341*6777b538SAndroid Build Coastguard Worker 342*6777b538SAndroid Build Coastguard Worker // The URL of the remote server. 343*6777b538SAndroid Build Coastguard Worker GURL socket_url_; 344*6777b538SAndroid Build Coastguard Worker 345*6777b538SAndroid Build Coastguard Worker // The object receiving events. 346*6777b538SAndroid Build Coastguard Worker const std::unique_ptr<WebSocketEventInterface> event_interface_; 347*6777b538SAndroid Build Coastguard Worker 348*6777b538SAndroid Build Coastguard Worker // The URLRequestContext to pass to the WebSocketStream creator. 349*6777b538SAndroid Build Coastguard Worker const raw_ptr<URLRequestContext> url_request_context_; 350*6777b538SAndroid Build Coastguard Worker 351*6777b538SAndroid Build Coastguard Worker // The WebSocketStream on which to send and receive data. 352*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketStream> stream_; 353*6777b538SAndroid Build Coastguard Worker 354*6777b538SAndroid Build Coastguard Worker // A data structure containing a vector of frames to be sent and the total 355*6777b538SAndroid Build Coastguard Worker // number of bytes contained in the vector. 356*6777b538SAndroid Build Coastguard Worker class SendBuffer; 357*6777b538SAndroid Build Coastguard Worker 358*6777b538SAndroid Build Coastguard Worker // Data that is currently pending write, or NULL if no write is pending. 359*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SendBuffer> data_being_sent_; 360*6777b538SAndroid Build Coastguard Worker // Data that is queued up to write after the current write completes. 361*6777b538SAndroid Build Coastguard Worker // Only non-NULL when such data actually exists. 362*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SendBuffer> data_to_send_next_; 363*6777b538SAndroid Build Coastguard Worker 364*6777b538SAndroid Build Coastguard Worker // Destination for the current call to WebSocketStream::ReadFrames 365*6777b538SAndroid Build Coastguard Worker std::vector<std::unique_ptr<WebSocketFrame>> read_frames_; 366*6777b538SAndroid Build Coastguard Worker 367*6777b538SAndroid Build Coastguard Worker // Handle to an in-progress WebSocketStream creation request. Only non-NULL 368*6777b538SAndroid Build Coastguard Worker // during the connection process. 369*6777b538SAndroid Build Coastguard Worker std::unique_ptr<WebSocketStreamRequest> stream_request_; 370*6777b538SAndroid Build Coastguard Worker 371*6777b538SAndroid Build Coastguard Worker // Timer for the closing handshake. 372*6777b538SAndroid Build Coastguard Worker base::OneShotTimer close_timer_; 373*6777b538SAndroid Build Coastguard Worker 374*6777b538SAndroid Build Coastguard Worker // Timeout for the closing handshake. 375*6777b538SAndroid Build Coastguard Worker base::TimeDelta closing_handshake_timeout_; 376*6777b538SAndroid Build Coastguard Worker 377*6777b538SAndroid Build Coastguard Worker // Timeout for the underlying connection close after completion of closing 378*6777b538SAndroid Build Coastguard Worker // handshake. 379*6777b538SAndroid Build Coastguard Worker base::TimeDelta underlying_connection_close_timeout_; 380*6777b538SAndroid Build Coastguard Worker 381*6777b538SAndroid Build Coastguard Worker // Storage for the status code and reason from the time the Close frame 382*6777b538SAndroid Build Coastguard Worker // arrives until the connection is closed and they are passed to 383*6777b538SAndroid Build Coastguard Worker // OnDropChannel(). 384*6777b538SAndroid Build Coastguard Worker bool has_received_close_frame_ = false; 385*6777b538SAndroid Build Coastguard Worker uint16_t received_close_code_ = 0; 386*6777b538SAndroid Build Coastguard Worker std::string received_close_reason_; 387*6777b538SAndroid Build Coastguard Worker 388*6777b538SAndroid Build Coastguard Worker // The current state of the channel. Mainly used for sanity checking, but also 389*6777b538SAndroid Build Coastguard Worker // used to track the close state. 390*6777b538SAndroid Build Coastguard Worker State state_ = FRESHLY_CONSTRUCTED; 391*6777b538SAndroid Build Coastguard Worker 392*6777b538SAndroid Build Coastguard Worker // UTF-8 validator for outgoing Text messages. 393*6777b538SAndroid Build Coastguard Worker base::StreamingUtf8Validator outgoing_utf8_validator_; 394*6777b538SAndroid Build Coastguard Worker bool sending_text_message_ = false; 395*6777b538SAndroid Build Coastguard Worker 396*6777b538SAndroid Build Coastguard Worker // UTF-8 validator for incoming Text messages. 397*6777b538SAndroid Build Coastguard Worker base::StreamingUtf8Validator incoming_utf8_validator_; 398*6777b538SAndroid Build Coastguard Worker bool receiving_text_message_ = false; 399*6777b538SAndroid Build Coastguard Worker 400*6777b538SAndroid Build Coastguard Worker // True if we are in the middle of receiving a message. 401*6777b538SAndroid Build Coastguard Worker bool expecting_to_handle_continuation_ = false; 402*6777b538SAndroid Build Coastguard Worker 403*6777b538SAndroid Build Coastguard Worker // True if we have already sent the type (Text or Binary) of the current 404*6777b538SAndroid Build Coastguard Worker // message to the renderer. This can be false if the message is empty so far. 405*6777b538SAndroid Build Coastguard Worker bool initial_frame_forwarded_ = false; 406*6777b538SAndroid Build Coastguard Worker 407*6777b538SAndroid Build Coastguard Worker // True if we're waiting for OnReadDone() callback. 408*6777b538SAndroid Build Coastguard Worker bool is_reading_ = false; 409*6777b538SAndroid Build Coastguard Worker }; 410*6777b538SAndroid Build Coastguard Worker 411*6777b538SAndroid Build Coastguard Worker } // namespace net 412*6777b538SAndroid Build Coastguard Worker 413*6777b538SAndroid Build Coastguard Worker #endif // NET_WEBSOCKETS_WEBSOCKET_CHANNEL_H_ 414