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