// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_ #define NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_ #include #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "net/base/completion_once_callback.h" #include "net/base/net_export.h" #include "net/spdy/spdy_read_queue.h" #include "net/spdy/spdy_stream.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/websockets/websocket_basic_stream.h" namespace net { class ClientSocketHandle; class IOBuffer; class SpdyBuffer; // Trivial adapter to make WebSocketBasicStream use a TCP/IP or TLS socket. class NET_EXPORT_PRIVATE WebSocketClientSocketHandleAdapter : public WebSocketBasicStream::Adapter { public: WebSocketClientSocketHandleAdapter() = delete; explicit WebSocketClientSocketHandleAdapter( std::unique_ptr connection); ~WebSocketClientSocketHandleAdapter() override; int Read(IOBuffer* buf, int buf_len, CompletionOnceCallback callback) override; int Write(IOBuffer* buf, int buf_len, CompletionOnceCallback callback, const NetworkTrafficAnnotationTag& traffic_annotation) override; void Disconnect() override; bool is_initialized() const override; private: std::unique_ptr connection_; }; // Adapter to make WebSocketBasicStream use an HTTP/2 stream. // Sets itself as a delegate of the SpdyStream, and forwards headers-related // methods to WebSocketHttp2HandshakeStream, which implements // WebSocketSpdyStreamAdapter::Delegate. After the handshake, ownership of this // object can be passed to WebSocketBasicStream, which can read and write using // a ClientSocketHandle-like interface. class NET_EXPORT_PRIVATE WebSocketSpdyStreamAdapter : public WebSocketBasicStream::Adapter, public SpdyStream::Delegate { public: // Interface for forwarding SpdyStream::Delegate methods necessary for the // handshake. class Delegate { public: virtual ~Delegate() = default; virtual void OnHeadersSent() = 0; virtual void OnHeadersReceived( const spdy::Http2HeaderBlock& response_headers) = 0; // Might destroy |this|. virtual void OnClose(int status) = 0; }; // |delegate| must be valid until DetachDelegate() is called. WebSocketSpdyStreamAdapter(base::WeakPtr stream, Delegate* delegate, NetLogWithSource net_log); ~WebSocketSpdyStreamAdapter() override; // Called by WebSocketSpdyStreamAdapter::Delegate before it is destroyed. void DetachDelegate(); // WebSocketBasicStream::Adapter methods. int Read(IOBuffer* buf, int buf_len, CompletionOnceCallback callback) override; // Write() must not be called before Delegate::OnHeadersSent() is called. // Write() always returns asynchronously. int Write(IOBuffer* buf, int buf_len, CompletionOnceCallback callback, const NetworkTrafficAnnotationTag& traffic_annotation) override; void Disconnect() override; bool is_initialized() const override; // SpdyStream::Delegate methods. void OnHeadersSent() override; void OnEarlyHintsReceived(const spdy::Http2HeaderBlock& headers) override; void OnHeadersReceived( const spdy::Http2HeaderBlock& response_headers, const spdy::Http2HeaderBlock* pushed_request_headers) override; void OnDataReceived(std::unique_ptr buffer) override; void OnDataSent() override; void OnTrailers(const spdy::Http2HeaderBlock& trailers) override; void OnClose(int status) override; bool CanGreaseFrameType() const override; NetLogSource source_dependency() const override; private: // Copy data from read_data_ to read_buffer_. int CopySavedReadDataIntoBuffer(); // Call WebSocketSpdyStreamAdapter::Delegate::OnClose(). void CallDelegateOnClose(); // True if SpdyStream::Delegate::OnHeadersSent() has been called. // SpdyStream::SendData() must not be called before that. bool headers_sent_ = false; // The underlying SpdyStream. base::WeakPtr stream_; // The error code with which SpdyStream was closed. int stream_error_ = ERR_CONNECTION_CLOSED; raw_ptr delegate_; // Buffer data pushed by SpdyStream until read through Read(). SpdyReadQueue read_data_; // Read buffer and length used for both synchronous and asynchronous // read operations. raw_ptr read_buffer_; size_t read_length_; // Read callback saved for asynchronous reads. // Whenever |read_data_| is not empty, |read_callback_| must be null. CompletionOnceCallback read_callback_; // Write length saved to be passed to |write_callback_|. This is necessary // because SpdyStream::Delegate::OnDataSent() does not pass number of bytes // written. int write_length_ = 0; // Write callback saved for asynchronous writes (all writes are asynchronous). CompletionOnceCallback write_callback_; NetLogWithSource net_log_; base::WeakPtrFactory weak_factory_{this}; }; } // namespace net #endif // NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_