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