1 // Copyright 2018 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_ 6 #define NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_ 7 8 #include <memory> 9 10 #include "base/memory/raw_ptr.h" 11 #include "base/memory/weak_ptr.h" 12 #include "net/base/completion_once_callback.h" 13 #include "net/base/net_export.h" 14 #include "net/spdy/spdy_read_queue.h" 15 #include "net/spdy/spdy_stream.h" 16 #include "net/traffic_annotation/network_traffic_annotation.h" 17 #include "net/websockets/websocket_basic_stream.h" 18 #include "net/websockets/websocket_quic_spdy_stream.h" 19 20 namespace net { 21 22 class ClientSocketHandle; 23 class IOBuffer; 24 class SpdyBuffer; 25 26 // Trivial adapter to make WebSocketBasicStream use a TCP/IP or TLS socket. 27 class NET_EXPORT_PRIVATE WebSocketClientSocketHandleAdapter 28 : public WebSocketBasicStream::Adapter { 29 public: 30 WebSocketClientSocketHandleAdapter() = delete; 31 explicit WebSocketClientSocketHandleAdapter( 32 std::unique_ptr<ClientSocketHandle> connection); 33 ~WebSocketClientSocketHandleAdapter() override; 34 35 int Read(IOBuffer* buf, 36 int buf_len, 37 CompletionOnceCallback callback) override; 38 int Write(IOBuffer* buf, 39 int buf_len, 40 CompletionOnceCallback callback, 41 const NetworkTrafficAnnotationTag& traffic_annotation) override; 42 void Disconnect() override; 43 bool is_initialized() const override; 44 45 private: 46 std::unique_ptr<ClientSocketHandle> connection_; 47 }; 48 49 // Adapter to make WebSocketBasicStream use an HTTP/2 stream. 50 // Sets itself as a delegate of the SpdyStream, and forwards headers-related 51 // methods to WebSocketHttp2HandshakeStream, which implements 52 // WebSocketSpdyStreamAdapter::Delegate. After the handshake, ownership of this 53 // object can be passed to WebSocketBasicStream, which can read and write using 54 // a ClientSocketHandle-like interface. 55 class NET_EXPORT_PRIVATE WebSocketSpdyStreamAdapter 56 : public WebSocketBasicStream::Adapter, 57 public SpdyStream::Delegate { 58 public: 59 // Interface for forwarding SpdyStream::Delegate methods necessary for the 60 // handshake. 61 class Delegate { 62 public: 63 virtual ~Delegate() = default; 64 virtual void OnHeadersSent() = 0; 65 virtual void OnHeadersReceived( 66 const spdy::Http2HeaderBlock& response_headers) = 0; 67 // Might destroy |this|. 68 virtual void OnClose(int status) = 0; 69 }; 70 71 // |delegate| must be valid until DetachDelegate() is called. 72 WebSocketSpdyStreamAdapter(base::WeakPtr<SpdyStream> stream, 73 Delegate* delegate, 74 NetLogWithSource net_log); 75 ~WebSocketSpdyStreamAdapter() override; 76 77 // Called by WebSocketSpdyStreamAdapter::Delegate before it is destroyed. 78 void DetachDelegate(); 79 80 // WebSocketBasicStream::Adapter methods. 81 82 int Read(IOBuffer* buf, 83 int buf_len, 84 CompletionOnceCallback callback) override; 85 86 // Write() must not be called before Delegate::OnHeadersSent() is called. 87 // Write() always returns asynchronously. 88 int Write(IOBuffer* buf, 89 int buf_len, 90 CompletionOnceCallback callback, 91 const NetworkTrafficAnnotationTag& traffic_annotation) override; 92 93 void Disconnect() override; 94 bool is_initialized() const override; 95 96 // SpdyStream::Delegate methods. 97 98 void OnHeadersSent() override; 99 void OnEarlyHintsReceived(const spdy::Http2HeaderBlock& headers) override; 100 void OnHeadersReceived( 101 const spdy::Http2HeaderBlock& response_headers, 102 const spdy::Http2HeaderBlock* pushed_request_headers) override; 103 void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override; 104 void OnDataSent() override; 105 void OnTrailers(const spdy::Http2HeaderBlock& trailers) override; 106 void OnClose(int status) override; 107 bool CanGreaseFrameType() const override; 108 NetLogSource source_dependency() const override; 109 110 private: 111 // Copy data from read_data_ to read_buffer_. 112 int CopySavedReadDataIntoBuffer(); 113 114 // Call WebSocketSpdyStreamAdapter::Delegate::OnClose(). 115 void CallDelegateOnClose(); 116 117 // True if SpdyStream::Delegate::OnHeadersSent() has been called. 118 // SpdyStream::SendData() must not be called before that. 119 bool headers_sent_ = false; 120 121 // The underlying SpdyStream. 122 base::WeakPtr<SpdyStream> stream_; 123 124 // The error code with which SpdyStream was closed. 125 int stream_error_ = ERR_CONNECTION_CLOSED; 126 127 raw_ptr<Delegate> delegate_; 128 129 // Buffer data pushed by SpdyStream until read through Read(). 130 SpdyReadQueue read_data_; 131 132 // Read buffer and length used for both synchronous and asynchronous 133 // read operations. 134 raw_ptr<IOBuffer> read_buffer_ = nullptr; 135 size_t read_length_ = 0u; 136 137 // Read callback saved for asynchronous reads. 138 // Whenever |read_data_| is not empty, |read_callback_| must be null. 139 CompletionOnceCallback read_callback_; 140 141 // Write length saved to be passed to |write_callback_|. This is necessary 142 // because SpdyStream::Delegate::OnDataSent() does not pass number of bytes 143 // written. 144 int write_length_ = 0; 145 146 // Write callback saved for asynchronous writes (all writes are asynchronous). 147 CompletionOnceCallback write_callback_; 148 149 NetLogWithSource net_log_; 150 151 base::WeakPtrFactory<WebSocketSpdyStreamAdapter> weak_factory_{this}; 152 }; 153 154 // Adapter to make WebSocketBasicStream use an HTTP/3 stream. 155 // Sets itself as a delegate of the WebSocketQuicSpdyStream. Forwards 156 // headers-related methods to Delegate. 157 class NET_EXPORT_PRIVATE WebSocketQuicStreamAdapter 158 : public WebSocketBasicStream::Adapter, 159 public WebSocketQuicSpdyStream::Delegate { 160 public: 161 // The Delegate interface is implemented by WebSocketHttp3HandshakeStream the 162 // user of the WebSocketQuicStreamAdapter to receive events related to the 163 // lifecycle of the Adapter. 164 class Delegate { 165 public: 166 virtual ~Delegate() = default; 167 virtual void OnHeadersSent() = 0; 168 virtual void OnHeadersReceived( 169 const spdy::Http2HeaderBlock& response_headers) = 0; 170 virtual void OnClose(int status) = 0; 171 }; 172 173 explicit WebSocketQuicStreamAdapter( 174 WebSocketQuicSpdyStream* websocket_quic_spdy_stream, 175 Delegate* delegate); 176 177 WebSocketQuicStreamAdapter(const WebSocketQuicStreamAdapter&) = delete; 178 WebSocketQuicStreamAdapter& operator=(const WebSocketQuicStreamAdapter&) = 179 delete; 180 181 ~WebSocketQuicStreamAdapter() override; 182 183 // Called by WebSocketQuicStreamAdapter::Delegate before it is destroyed. clear_delegate()184 void clear_delegate() { delegate_ = nullptr; } 185 186 size_t WriteHeaders(spdy::Http2HeaderBlock header_block, bool fin); 187 188 // WebSocketBasicStream::Adapter methods. 189 // TODO(momoka): Add functions that are needed to implement 190 // WebSocketHttp3HandshakeStream. 191 int Read(IOBuffer* buf, 192 int buf_len, 193 CompletionOnceCallback callback) override; 194 int Write(IOBuffer* buf, 195 int buf_len, 196 CompletionOnceCallback callback, 197 const NetworkTrafficAnnotationTag& traffic_annotation) override; 198 void Disconnect() override; 199 bool is_initialized() const override; 200 201 // WebSocketQuicSpdyStream::Delegate methods. 202 void OnInitialHeadersComplete( 203 bool fin, 204 size_t frame_len, 205 const quic::QuicHeaderList& header_list) override; 206 void OnBodyAvailable() override; 207 void ClearStream() override; 208 209 private: 210 // `websocket_quic_spdy_stream_` notifies this object of its destruction, 211 // because they may be destroyed in any order. 212 raw_ptr<WebSocketQuicSpdyStream> websocket_quic_spdy_stream_; 213 214 raw_ptr<Delegate> delegate_; 215 216 // Read buffer, length and callback used for asynchronous read operations. 217 raw_ptr<IOBuffer> read_buffer_ = nullptr; 218 int read_length_ = 0u; 219 CompletionOnceCallback read_callback_; 220 }; 221 222 } // namespace net 223 224 #endif // NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_ 225