1 // Copyright 2018 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_HTTP2_HANDSHAKE_STREAM_H_ 6 #define NET_WEBSOCKETS_WEBSOCKET_HTTP2_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 "net/base/completion_once_callback.h" 20 #include "net/base/io_buffer.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/third_party/quiche/src/quiche/spdy/core/http2_header_block.h" 26 #include "net/websockets/websocket_basic_stream_adapters.h" 27 #include "net/websockets/websocket_handshake_stream_base.h" 28 #include "net/websockets/websocket_stream.h" 29 30 namespace net { 31 32 class HttpNetworkSession; 33 class HttpRequestHeaders; 34 class HttpResponseHeaders; 35 class HttpResponseInfo; 36 class HttpStream; 37 class IOBuffer; 38 class IPEndPoint; 39 class SSLInfo; 40 class SpdySession; 41 class SpdyStream; 42 class SpdyStreamRequest; 43 struct AlternativeService; 44 struct HttpRequestInfo; 45 struct LoadTimingInfo; 46 struct NetErrorDetails; 47 struct WebSocketExtensionParams; 48 49 class NET_EXPORT_PRIVATE WebSocketHttp2HandshakeStream 50 : public WebSocketHandshakeStreamBase, 51 public WebSocketSpdyStreamAdapter::Delegate { 52 public: 53 // |connect_delegate| and |request| must out-live this object. 54 WebSocketHttp2HandshakeStream( 55 base::WeakPtr<SpdySession> session, 56 WebSocketStream::ConnectDelegate* connect_delegate, 57 std::vector<std::string> requested_sub_protocols, 58 std::vector<std::string> requested_extensions, 59 WebSocketStreamRequestAPI* request, 60 std::set<std::string> dns_aliases); 61 62 WebSocketHttp2HandshakeStream(const WebSocketHttp2HandshakeStream&) = delete; 63 WebSocketHttp2HandshakeStream& operator=( 64 const WebSocketHttp2HandshakeStream&) = delete; 65 66 ~WebSocketHttp2HandshakeStream() override; 67 68 // HttpStream methods. 69 void RegisterRequest(const HttpRequestInfo* request_info) override; 70 int InitializeStream(bool can_send_early, 71 RequestPriority priority, 72 const NetLogWithSource& net_log, 73 CompletionOnceCallback callback) override; 74 int SendRequest(const HttpRequestHeaders& request_headers, 75 HttpResponseInfo* response, 76 CompletionOnceCallback callback) override; 77 int ReadResponseHeaders(CompletionOnceCallback callback) override; 78 int ReadResponseBody(IOBuffer* buf, 79 int buf_len, 80 CompletionOnceCallback callback) override; 81 void Close(bool not_reusable) override; 82 bool IsResponseBodyComplete() const override; 83 bool IsConnectionReused() const override; 84 void SetConnectionReused() override; 85 bool CanReuseConnection() const override; 86 int64_t GetTotalReceivedBytes() const override; 87 int64_t GetTotalSentBytes() const override; 88 bool GetAlternativeService( 89 AlternativeService* alternative_service) const override; 90 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; 91 void GetSSLInfo(SSLInfo* ssl_info) override; 92 int GetRemoteEndpoint(IPEndPoint* endpoint) override; 93 void Drain(HttpNetworkSession* session) override; 94 void SetPriority(RequestPriority priority) override; 95 void PopulateNetErrorDetails(NetErrorDetails* details) override; 96 std::unique_ptr<HttpStream> RenewStreamForAuth() override; 97 const std::set<std::string>& GetDnsAliases() const override; 98 std::string_view GetAcceptChViaAlps() const override; 99 100 // WebSocketHandshakeStreamBase methods. 101 102 // This is called from the top level once correct handshake response headers 103 // have been received. It creates an appropriate subclass of WebSocketStream 104 // depending on what extensions were negotiated. This object is unusable after 105 // Upgrade() has been called and should be disposed of as soon as possible. 106 std::unique_ptr<WebSocketStream> Upgrade() override; 107 108 bool CanReadFromStream() const override; 109 110 base::WeakPtr<WebSocketHandshakeStreamBase> GetWeakPtr() override; 111 112 // WebSocketSpdyStreamAdapter::Delegate methods. 113 void OnHeadersSent() override; 114 void OnHeadersReceived( 115 const spdy::Http2HeaderBlock& response_headers) override; 116 void OnClose(int status) override; 117 118 // Called by |spdy_stream_request_| when requested stream is ready. 119 void StartRequestCallback(int rv); 120 121 private: 122 // Validates the response and sends the finished handshake event. 123 int ValidateResponse(); 124 125 // Check that the headers are well-formed and have a 200 status code, 126 // in which case returns OK, otherwise returns ERR_INVALID_RESPONSE. 127 int ValidateUpgradeResponse(const HttpResponseHeaders* headers); 128 129 void OnFailure(const std::string& message, 130 int net_error, 131 std::optional<int> response_code); 132 133 HandshakeResult result_ = HandshakeResult::HTTP2_INCOMPLETE; 134 135 // The connection to open the Websocket stream on. 136 base::WeakPtr<SpdySession> session_; 137 138 // Owned by another object. 139 // |connect_delegate| will live during the lifetime of this object. 140 const raw_ptr<WebSocketStream::ConnectDelegate> connect_delegate_; 141 142 raw_ptr<HttpResponseInfo> http_response_info_ = nullptr; 143 144 spdy::Http2HeaderBlock http2_request_headers_; 145 146 // The sub-protocols we requested. 147 std::vector<std::string> requested_sub_protocols_; 148 149 // The extensions we requested. 150 std::vector<std::string> requested_extensions_; 151 152 const raw_ptr<WebSocketStreamRequestAPI> stream_request_; 153 154 raw_ptr<const HttpRequestInfo> request_info_ = nullptr; 155 156 RequestPriority priority_; 157 158 NetLogWithSource net_log_; 159 160 // SpdyStreamRequest that will create the stream. 161 std::unique_ptr<SpdyStreamRequest> spdy_stream_request_; 162 163 // SpdyStream corresponding to the request. 164 base::WeakPtr<SpdyStream> stream_; 165 166 // WebSocketSpdyStreamAdapter holding a WeakPtr to |stream_|. 167 // This can be passed on to WebSocketBasicStream when created. 168 std::unique_ptr<WebSocketSpdyStreamAdapter> stream_adapter_; 169 170 // True if |stream_| has been created then closed. 171 bool stream_closed_ = false; 172 173 // The error code corresponding to the reason for closing the stream. 174 // Only meaningful if |stream_closed_| is true. 175 int stream_error_ = OK; 176 177 // True if complete response headers have been received. 178 bool response_headers_complete_ = false; 179 180 // Save callback provided in asynchronous HttpStream methods. 181 CompletionOnceCallback callback_; 182 183 // The sub-protocol selected by the server. 184 std::string sub_protocol_; 185 186 // The extension(s) selected by the server. 187 std::string extensions_; 188 189 // The extension parameters. The class is defined in the implementation file 190 // to avoid including extension-related header files here. 191 std::unique_ptr<WebSocketExtensionParams> extension_params_; 192 193 // Stores any DNS aliases for the remote endpoint. Includes all known aliases, 194 // e.g. from A, AAAA, or HTTPS, not just from the address used for the 195 // connection, in no particular order. These are stored in the stream instead 196 // of the session due to complications related to IP-pooling. 197 std::set<std::string> dns_aliases_; 198 199 base::WeakPtrFactory<WebSocketHttp2HandshakeStream> weak_ptr_factory_{this}; 200 }; 201 202 } // namespace net 203 204 #endif // NET_WEBSOCKETS_WEBSOCKET_HTTP2_HANDSHAKE_STREAM_H_ 205