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