1 // Copyright 2018 The Chromium Authors. All rights reserved.
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/weak_ptr.h"
11 #include "net/base/completion_once_callback.h"
12 #include "net/base/net_export.h"
13 #include "net/spdy/spdy_read_queue.h"
14 #include "net/spdy/spdy_stream.h"
15 #include "net/traffic_annotation/network_traffic_annotation.h"
16 #include "net/websockets/websocket_basic_stream.h"
17 
18 namespace net {
19 
20 class ClientSocketHandle;
21 class IOBuffer;
22 class SpdyBuffer;
23 
24 // Trivial adapter to make WebSocketBasicStream use a TCP/IP or TLS socket.
25 class NET_EXPORT_PRIVATE WebSocketClientSocketHandleAdapter
26     : public WebSocketBasicStream::Adapter {
27  public:
28   WebSocketClientSocketHandleAdapter() = delete;
29   explicit WebSocketClientSocketHandleAdapter(
30       std::unique_ptr<ClientSocketHandle> connection);
31   ~WebSocketClientSocketHandleAdapter() override;
32 
33   int Read(IOBuffer* buf,
34            int buf_len,
35            CompletionOnceCallback callback) override;
36   int Write(IOBuffer* buf,
37             int buf_len,
38             CompletionOnceCallback callback,
39             const NetworkTrafficAnnotationTag& traffic_annotation) override;
40   void Disconnect() override;
41   bool is_initialized() const override;
42 
43  private:
44   std::unique_ptr<ClientSocketHandle> connection_;
45 };
46 
47 // Adapter to make WebSocketBasicStream use an HTTP/2 stream.
48 // Sets itself as a delegate of the SpdyStream, and forwards headers-related
49 // methods to WebSocketHttp2HandshakeStream, which implements
50 // WebSocketSpdyStreamAdapter::Delegate.  After the handshake, ownership of this
51 // object can be passed to WebSocketBasicStream, which can read and write using
52 // a ClientSocketHandle-like interface.
53 class NET_EXPORT_PRIVATE WebSocketSpdyStreamAdapter
54     : public WebSocketBasicStream::Adapter,
55       public SpdyStream::Delegate {
56  public:
57   // Interface for forwarding SpdyStream::Delegate methods necessary for the
58   // handshake.
59   class Delegate {
60    public:
61     virtual ~Delegate() = default;
62     virtual void OnHeadersSent() = 0;
63     virtual void OnHeadersReceived(
64         const spdy::Http2HeaderBlock& response_headers) = 0;
65     // Might destroy |this|.
66     virtual void OnClose(int status) = 0;
67   };
68 
69   // |delegate| must be valid until DetachDelegate() is called.
70   WebSocketSpdyStreamAdapter(base::WeakPtr<SpdyStream> stream,
71                              Delegate* delegate,
72                              NetLogWithSource net_log);
73   ~WebSocketSpdyStreamAdapter() override;
74 
75   // Called by WebSocketSpdyStreamAdapter::Delegate before it is destroyed.
76   void DetachDelegate();
77 
78   // WebSocketBasicStream::Adapter methods.
79 
80   int Read(IOBuffer* buf,
81            int buf_len,
82            CompletionOnceCallback callback) override;
83 
84   // Write() must not be called before Delegate::OnHeadersSent() is called.
85   // Write() always returns asynchronously.
86   int Write(IOBuffer* buf,
87             int buf_len,
88             CompletionOnceCallback callback,
89             const NetworkTrafficAnnotationTag& traffic_annotation) override;
90 
91   void Disconnect() override;
92   bool is_initialized() const override;
93 
94   // SpdyStream::Delegate methods.
95 
96   void OnHeadersSent() override;
97   void OnHeadersReceived(
98       const spdy::Http2HeaderBlock& response_headers,
99       const spdy::Http2HeaderBlock* pushed_request_headers) override;
100   void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override;
101   void OnDataSent() override;
102   void OnTrailers(const spdy::Http2HeaderBlock& trailers) override;
103   void OnClose(int status) override;
104   bool CanGreaseFrameType() const override;
105   NetLogSource source_dependency() const override;
106 
107  private:
108   // Copy data from read_data_ to read_buffer_.
109   int CopySavedReadDataIntoBuffer();
110 
111   // Call WebSocketSpdyStreamAdapter::Delegate::OnClose().
112   void CallDelegateOnClose();
113 
114   // True if SpdyStream::Delegate::OnHeadersSent() has been called.
115   // SpdyStream::SendData() must not be called before that.
116   bool headers_sent_;
117 
118   // The underlying SpdyStream.
119   base::WeakPtr<SpdyStream> stream_;
120 
121   // The error code with which SpdyStream was closed.
122   int stream_error_;
123 
124   Delegate* delegate_;
125 
126   // Buffer data pushed by SpdyStream until read through Read().
127   SpdyReadQueue read_data_;
128 
129   // Read buffer and length used for both synchronous and asynchronous
130   // read operations.
131   IOBuffer* read_buffer_;
132   size_t read_length_;
133 
134   // Read callback saved for asynchronous reads.
135   // Whenever |read_data_| is not empty, |read_callback_| must be null.
136   CompletionOnceCallback read_callback_;
137 
138   // Write length saved to be passed to |write_callback_|.  This is necessary
139   // because SpdyStream::Delegate::OnDataSent() does not pass number of bytes
140   // written.
141   int write_length_;
142 
143   // Write callback saved for asynchronous writes (all writes are asynchronous).
144   CompletionOnceCallback write_callback_;
145 
146   NetLogWithSource net_log_;
147 
148   base::WeakPtrFactory<WebSocketSpdyStreamAdapter> weak_factory_{this};
149 };
150 
151 }  // namespace net
152 
153 #endif  // NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_
154