xref: /aosp_15_r20/external/cronet/net/websockets/websocket_http2_handshake_stream.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_HTTP2_HANDSHAKE_STREAM_H_
6 #define NET_WEBSOCKETS_WEBSOCKET_HTTP2_HANDSHAKE_STREAM_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <optional>
12 #include <set>
13 #include <string>
14 #include <string_view>
15 #include <vector>
16 
17 #include "base/memory/raw_ptr.h"
18 #include "base/memory/weak_ptr.h"
19 #include "net/base/completion_once_callback.h"
20 #include "net/base/io_buffer.h"
21 #include "net/base/net_errors.h"
22 #include "net/base/net_export.h"
23 #include "net/base/request_priority.h"
24 #include "net/log/net_log_with_source.h"
25 #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"
26 #include "net/websockets/websocket_basic_stream_adapters.h"
27 #include "net/websockets/websocket_handshake_stream_base.h"
28 #include "net/websockets/websocket_stream.h"
29 
30 namespace net {
31 
32 class HttpNetworkSession;
33 class HttpRequestHeaders;
34 class HttpResponseHeaders;
35 class HttpResponseInfo;
36 class HttpStream;
37 class IOBuffer;
38 class IPEndPoint;
39 class SSLInfo;
40 class SpdySession;
41 class SpdyStream;
42 class SpdyStreamRequest;
43 struct AlternativeService;
44 struct HttpRequestInfo;
45 struct LoadTimingInfo;
46 struct NetErrorDetails;
47 struct WebSocketExtensionParams;
48 
49 class NET_EXPORT_PRIVATE WebSocketHttp2HandshakeStream
50     : public WebSocketHandshakeStreamBase,
51       public WebSocketSpdyStreamAdapter::Delegate {
52  public:
53   // |connect_delegate| and |request| must out-live this object.
54   WebSocketHttp2HandshakeStream(
55       base::WeakPtr<SpdySession> session,
56       WebSocketStream::ConnectDelegate* connect_delegate,
57       std::vector<std::string> requested_sub_protocols,
58       std::vector<std::string> requested_extensions,
59       WebSocketStreamRequestAPI* request,
60       std::set<std::string> dns_aliases);
61 
62   WebSocketHttp2HandshakeStream(const WebSocketHttp2HandshakeStream&) = delete;
63   WebSocketHttp2HandshakeStream& operator=(
64       const WebSocketHttp2HandshakeStream&) = delete;
65 
66   ~WebSocketHttp2HandshakeStream() override;
67 
68   // HttpStream methods.
69   void RegisterRequest(const HttpRequestInfo* request_info) override;
70   int InitializeStream(bool can_send_early,
71                        RequestPriority priority,
72                        const NetLogWithSource& net_log,
73                        CompletionOnceCallback callback) override;
74   int SendRequest(const HttpRequestHeaders& request_headers,
75                   HttpResponseInfo* response,
76                   CompletionOnceCallback callback) override;
77   int ReadResponseHeaders(CompletionOnceCallback callback) override;
78   int ReadResponseBody(IOBuffer* buf,
79                        int buf_len,
80                        CompletionOnceCallback callback) override;
81   void Close(bool not_reusable) override;
82   bool IsResponseBodyComplete() const override;
83   bool IsConnectionReused() const override;
84   void SetConnectionReused() override;
85   bool CanReuseConnection() const override;
86   int64_t GetTotalReceivedBytes() const override;
87   int64_t GetTotalSentBytes() const override;
88   bool GetAlternativeService(
89       AlternativeService* alternative_service) const override;
90   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
91   void GetSSLInfo(SSLInfo* ssl_info) override;
92   int GetRemoteEndpoint(IPEndPoint* endpoint) override;
93   void Drain(HttpNetworkSession* session) override;
94   void SetPriority(RequestPriority priority) override;
95   void PopulateNetErrorDetails(NetErrorDetails* details) override;
96   std::unique_ptr<HttpStream> RenewStreamForAuth() override;
97   const std::set<std::string>& GetDnsAliases() const override;
98   std::string_view GetAcceptChViaAlps() const override;
99 
100   // WebSocketHandshakeStreamBase methods.
101 
102   // This is called from the top level once correct handshake response headers
103   // have been received. It creates an appropriate subclass of WebSocketStream
104   // depending on what extensions were negotiated. This object is unusable after
105   // Upgrade() has been called and should be disposed of as soon as possible.
106   std::unique_ptr<WebSocketStream> Upgrade() override;
107 
108   bool CanReadFromStream() const override;
109 
110   base::WeakPtr<WebSocketHandshakeStreamBase> GetWeakPtr() override;
111 
112   // WebSocketSpdyStreamAdapter::Delegate methods.
113   void OnHeadersSent() override;
114   void OnHeadersReceived(
115       const spdy::Http2HeaderBlock& response_headers) override;
116   void OnClose(int status) override;
117 
118   // Called by |spdy_stream_request_| when requested stream is ready.
119   void StartRequestCallback(int rv);
120 
121  private:
122   // Validates the response and sends the finished handshake event.
123   int ValidateResponse();
124 
125   // Check that the headers are well-formed and have a 200 status code,
126   // in which case returns OK, otherwise returns ERR_INVALID_RESPONSE.
127   int ValidateUpgradeResponse(const HttpResponseHeaders* headers);
128 
129   void OnFailure(const std::string& message,
130                  int net_error,
131                  std::optional<int> response_code);
132 
133   HandshakeResult result_ = HandshakeResult::HTTP2_INCOMPLETE;
134 
135   // The connection to open the Websocket stream on.
136   base::WeakPtr<SpdySession> session_;
137 
138   // Owned by another object.
139   // |connect_delegate| will live during the lifetime of this object.
140   const raw_ptr<WebSocketStream::ConnectDelegate> connect_delegate_;
141 
142   raw_ptr<HttpResponseInfo> http_response_info_ = nullptr;
143 
144   spdy::Http2HeaderBlock http2_request_headers_;
145 
146   // The sub-protocols we requested.
147   std::vector<std::string> requested_sub_protocols_;
148 
149   // The extensions we requested.
150   std::vector<std::string> requested_extensions_;
151 
152   const raw_ptr<WebSocketStreamRequestAPI> stream_request_;
153 
154   raw_ptr<const HttpRequestInfo> request_info_ = nullptr;
155 
156   RequestPriority priority_;
157 
158   NetLogWithSource net_log_;
159 
160   // SpdyStreamRequest that will create the stream.
161   std::unique_ptr<SpdyStreamRequest> spdy_stream_request_;
162 
163   // SpdyStream corresponding to the request.
164   base::WeakPtr<SpdyStream> stream_;
165 
166   // WebSocketSpdyStreamAdapter holding a WeakPtr to |stream_|.
167   // This can be passed on to WebSocketBasicStream when created.
168   std::unique_ptr<WebSocketSpdyStreamAdapter> stream_adapter_;
169 
170   // True if |stream_| has been created then closed.
171   bool stream_closed_ = false;
172 
173   // The error code corresponding to the reason for closing the stream.
174   // Only meaningful if |stream_closed_| is true.
175   int stream_error_ = OK;
176 
177   // True if complete response headers have been received.
178   bool response_headers_complete_ = false;
179 
180   // Save callback provided in asynchronous HttpStream methods.
181   CompletionOnceCallback callback_;
182 
183   // The sub-protocol selected by the server.
184   std::string sub_protocol_;
185 
186   // The extension(s) selected by the server.
187   std::string extensions_;
188 
189   // The extension parameters. The class is defined in the implementation file
190   // to avoid including extension-related header files here.
191   std::unique_ptr<WebSocketExtensionParams> extension_params_;
192 
193   // Stores any DNS aliases for the remote endpoint. Includes all known aliases,
194   // e.g. from A, AAAA, or HTTPS, not just from the address used for the
195   // connection, in no particular order. These are stored in the stream instead
196   // of the session due to complications related to IP-pooling.
197   std::set<std::string> dns_aliases_;
198 
199   base::WeakPtrFactory<WebSocketHttp2HandshakeStream> weak_ptr_factory_{this};
200 };
201 
202 }  // namespace net
203 
204 #endif  // NET_WEBSOCKETS_WEBSOCKET_HTTP2_HANDSHAKE_STREAM_H_
205