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