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 <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/io_buffer.h" 20 #include "net/base/net_export.h" 21 #include "net/base/request_priority.h" 22 #include "net/log/net_log_with_source.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 struct LoadTimingInfo; 32 class SSLInfo; 33 class IOBuffer; 34 class SSLCertRequestInfo; 35 class IPEndPoint; 36 class HttpNetworkSession; 37 struct NetErrorDetails; 38 class HttpStream; 39 class HttpResponseHeaders; 40 struct HttpRequestInfo; 41 class HttpResponseInfo; 42 class SpdySession; 43 struct AlternativeService; 44 class SpdyStreamRequest; 45 struct WebSocketExtensionParams; 46 47 class NET_EXPORT_PRIVATE WebSocketHttp2HandshakeStream 48 : public WebSocketHandshakeStreamBase, 49 public WebSocketSpdyStreamAdapter::Delegate { 50 public: 51 // |connect_delegate| and |request| must out-live this object. 52 WebSocketHttp2HandshakeStream( 53 base::WeakPtr<SpdySession> 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 WebSocketHttp2HandshakeStream(const WebSocketHttp2HandshakeStream&) = delete; 61 WebSocketHttp2HandshakeStream& operator=( 62 const WebSocketHttp2HandshakeStream&) = delete; 63 64 ~WebSocketHttp2HandshakeStream() 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 base::WeakPtr<WebSocketHandshakeStreamBase> GetWeakPtr() override; 108 109 // WebSocketSpdyStreamAdapter::Delegate methods. 110 void OnHeadersSent() override; 111 void OnHeadersReceived( 112 const spdy::Http2HeaderBlock& response_headers) override; 113 void OnClose(int status) override; 114 115 // Called by |spdy_stream_request_| when requested stream is ready. 116 void StartRequestCallback(int rv); 117 118 private: 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 absl::optional<int> response_code); 129 130 HandshakeResult result_ = HandshakeResult::HTTP2_INCOMPLETE; 131 132 // The connection to open the Websocket stream on. 133 base::WeakPtr<SpdySession> session_; 134 135 // Owned by another object. 136 // |connect_delegate| will live during the lifetime of this object. 137 const raw_ptr<WebSocketStream::ConnectDelegate, DanglingUntriaged> 138 connect_delegate_; 139 140 raw_ptr<HttpResponseInfo> http_response_info_ = nullptr; 141 142 spdy::Http2HeaderBlock http2_request_headers_; 143 144 // The sub-protocols we requested. 145 std::vector<std::string> requested_sub_protocols_; 146 147 // The extensions we requested. 148 std::vector<std::string> requested_extensions_; 149 150 const raw_ptr<WebSocketStreamRequestAPI, DanglingUntriaged> stream_request_; 151 152 raw_ptr<const HttpRequestInfo, DanglingUntriaged> request_info_ = nullptr; 153 154 RequestPriority priority_; 155 156 NetLogWithSource net_log_; 157 158 // SpdyStreamRequest that will create the stream. 159 std::unique_ptr<SpdyStreamRequest> spdy_stream_request_; 160 161 // SpdyStream corresponding to the request. 162 base::WeakPtr<SpdyStream> stream_; 163 164 // WebSocketSpdyStreamAdapter holding a WeakPtr to |stream_|. 165 // This can be passed on to WebSocketBasicStream when created. 166 std::unique_ptr<WebSocketSpdyStreamAdapter> stream_adapter_; 167 168 // True if |stream_| has been created then closed. 169 bool stream_closed_ = false; 170 171 // The error code corresponding to the reason for closing the stream. 172 // Only meaningful if |stream_closed_| is true. 173 int stream_error_ = OK; 174 175 // True if complete response headers have been received. 176 bool response_headers_complete_ = false; 177 178 // Save callback provided in asynchronous HttpStream methods. 179 CompletionOnceCallback callback_; 180 181 // The sub-protocol selected by the server. 182 std::string sub_protocol_; 183 184 // The extension(s) selected by the server. 185 std::string extensions_; 186 187 // The extension parameters. The class is defined in the implementation file 188 // to avoid including extension-related header files here. 189 std::unique_ptr<WebSocketExtensionParams> extension_params_; 190 191 // Stores any DNS aliases for the remote endpoint. Includes all known aliases, 192 // e.g. from A, AAAA, or HTTPS, not just from the address used for the 193 // connection, in no particular order. These are stored in the stream instead 194 // of the session due to complications related to IP-pooling. 195 std::set<std::string> dns_aliases_; 196 197 base::WeakPtrFactory<WebSocketHttp2HandshakeStream> weak_ptr_factory_{this}; 198 }; 199 200 } // namespace net 201 202 #endif // NET_WEBSOCKETS_WEBSOCKET_HTTP2_HANDSHAKE_STREAM_H_ 203