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