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