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