xref: /aosp_15_r20/external/cronet/net/websockets/websocket_http3_handshake_stream.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2023 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_HTTP3_HANDSHAKE_STREAM_H_
6 #define NET_WEBSOCKETS_WEBSOCKET_HTTP3_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 "base/time/time.h"
20 #include "net/base/completion_once_callback.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/quic/quic_chromium_client_session.h"
26 #include "net/quic/quic_session_pool.h"
27 #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"
28 #include "net/websockets/websocket_basic_stream_adapters.h"
29 #include "net/websockets/websocket_handshake_stream_base.h"
30 #include "net/websockets/websocket_stream.h"
31 
32 namespace net {
33 
34 class HttpNetworkSession;
35 class HttpRequestHeaders;
36 class HttpResponseHeaders;
37 class HttpResponseInfo;
38 class HttpStream;
39 class IOBuffer;
40 class IPEndPoint;
41 class SSLInfo;
42 struct AlternativeService;
43 struct HttpRequestInfo;
44 struct LoadTimingInfo;
45 struct NetErrorDetails;
46 
47 class NET_EXPORT_PRIVATE WebSocketHttp3HandshakeStream final
48     : public WebSocketHandshakeStreamBase,
49       public WebSocketQuicStreamAdapter::Delegate {
50  public:
51   WebSocketHttp3HandshakeStream(
52       std::unique_ptr<QuicChromiumClientSession::Handle> session,
53       WebSocketStream::ConnectDelegate* connect_delegate,
54       std::vector<std::string> requested_sub_protocols,
55       std::vector<std::string> requested_extensions,
56       WebSocketStreamRequestAPI* request,
57       std::set<std::string> dns_aliases);
58 
59   WebSocketHttp3HandshakeStream(const WebSocketHttp3HandshakeStream&) = delete;
60   WebSocketHttp3HandshakeStream& operator=(
61       const WebSocketHttp3HandshakeStream&) = delete;
62 
63   ~WebSocketHttp3HandshakeStream() override;
64 
65   // HttpStream methods.
66   void RegisterRequest(const HttpRequestInfo* request_info) override;
67   int InitializeStream(bool can_send_early,
68                        RequestPriority priority,
69                        const NetLogWithSource& net_log,
70                        CompletionOnceCallback callback) override;
71   int SendRequest(const HttpRequestHeaders& request_headers,
72                   HttpResponseInfo* response,
73                   CompletionOnceCallback callback) override;
74   int ReadResponseHeaders(CompletionOnceCallback callback) override;
75   int ReadResponseBody(IOBuffer* buf,
76                        int buf_len,
77                        CompletionOnceCallback callback) override;
78   void Close(bool not_reusable) override;
79   bool IsResponseBodyComplete() const override;
80   bool IsConnectionReused() const override;
81   void SetConnectionReused() override;
82   bool CanReuseConnection() const override;
83   int64_t GetTotalReceivedBytes() const override;
84   int64_t GetTotalSentBytes() const override;
85   bool GetAlternativeService(
86       AlternativeService* alternative_service) const override;
87   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
88   void GetSSLInfo(SSLInfo* ssl_info) override;
89   int GetRemoteEndpoint(IPEndPoint* endpoint) override;
90   void Drain(HttpNetworkSession* session) override;
91   void SetPriority(RequestPriority priority) override;
92   void PopulateNetErrorDetails(NetErrorDetails* details) override;
93   std::unique_ptr<HttpStream> RenewStreamForAuth() override;
94   const std::set<std::string>& GetDnsAliases() const override;
95   std::string_view GetAcceptChViaAlps() const override;
96 
97   // WebSocketHandshakeStreamBase methods.
98 
99   // This is called from the top level once correct handshake response headers
100   // have been received. It creates an appropriate subclass of WebSocketStream
101   // depending on what extensions were negotiated. This object is unusable after
102   // Upgrade() has been called and should be disposed of as soon as possible.
103   std::unique_ptr<WebSocketStream> Upgrade() override;
104 
105   bool CanReadFromStream() const override;
106 
107   base::WeakPtr<WebSocketHandshakeStreamBase> GetWeakPtr() override;
108 
109   // WebSocketQuicStreamAdapter::Delegate methods.
110   void OnHeadersSent() override;
111   void OnHeadersReceived(
112       const spdy::Http2HeaderBlock& response_headers) override;
113   void OnClose(int status) override;
114 
115  private:
116   void ReceiveAdapterAndStartRequest(
117       std::unique_ptr<WebSocketQuicStreamAdapter> adapter);
118 
119   // Validates the response and sends the finished handshake event.
120   int ValidateResponse();
121 
122   // Check that the headers are well-formed and have a 200 status code,
123   // in which case returns OK, otherwise returns ERR_INVALID_RESPONSE.
124   int ValidateUpgradeResponse(const HttpResponseHeaders* headers);
125 
126   void OnFailure(const std::string& message,
127                  int net_error,
128                  std::optional<int> response_code);
129 
130   HandshakeResult result_ = HandshakeResult::HTTP3_INCOMPLETE;
131 
132   std::unique_ptr<WebSocketSpdyStreamAdapter> adapter_;
133 
134   // True if `stream_` has been created then closed.
135   bool stream_closed_ = false;
136 
137   // The error code corresponding to the reason for closing the stream.
138   // Only meaningful if `stream_closed_` is true.
139   int stream_error_ = OK;
140 
141   // True if complete response headers have been received.
142   bool response_headers_complete_ = false;
143 
144   // Time the request was issued.
145   base::Time request_time_;
146 
147   std::unique_ptr<QuicChromiumClientSession::Handle> session_;
148   // Owned by another object.
149   // `connect_delegate` will live during the lifetime of this object.
150   const raw_ptr<WebSocketStream::ConnectDelegate> connect_delegate_;
151 
152   raw_ptr<HttpResponseInfo> http_response_info_ = nullptr;
153 
154   spdy::Http2HeaderBlock http3_request_headers_;
155 
156   // The sub-protocols we requested.
157   std::vector<std::string> requested_sub_protocols_;
158 
159   // The extensions we requested.
160   std::vector<std::string> requested_extensions_;
161 
162   const raw_ptr<WebSocketStreamRequestAPI> stream_request_;
163 
164   raw_ptr<const HttpRequestInfo> request_info_ = nullptr;
165 
166   RequestPriority priority_;
167 
168   NetLogWithSource net_log_;
169 
170   // WebSocketQuicStreamAdapter holding a WeakPtr to `stream_`.
171   // This can be passed on to WebSocketBasicStream when created.
172   std::unique_ptr<WebSocketQuicStreamAdapter> stream_adapter_;
173 
174   CompletionOnceCallback callback_;
175 
176   // The sub-protocol selected by the server.
177   std::string sub_protocol_;
178 
179   // The extension(s) selected by the server.
180   std::string extensions_;
181 
182   // The extension parameters. The class is defined in the implementation file
183   // to avoid including extension-related header files here.
184   std::unique_ptr<WebSocketExtensionParams> extension_params_;
185 
186   std::set<std::string> dns_aliases_;
187 
188   base::WeakPtrFactory<WebSocketHttp3HandshakeStream> weak_ptr_factory_{this};
189 };
190 
191 }  // namespace net
192 
193 #endif  // NET_WEBSOCKETS_WEBSOCKET_HTTP3_HANDSHAKE_STREAM_H_
194