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