1 // Copyright 2013 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_BASIC_HANDSHAKE_STREAM_H_ 6 #define NET_WEBSOCKETS_WEBSOCKET_BASIC_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/net_export.h" 21 #include "net/base/request_priority.h" 22 #include "net/http/http_basic_state.h" 23 #include "net/log/net_log_with_source.h" 24 #include "net/websockets/websocket_handshake_stream_base.h" 25 #include "net/websockets/websocket_stream.h" 26 #include "url/gurl.h" 27 28 namespace net { 29 30 class ClientSocketHandle; 31 class HttpNetworkSession; 32 class HttpRequestHeaders; 33 class HttpResponseHeaders; 34 class HttpResponseInfo; 35 class HttpStream; 36 class HttpStreamParser; 37 class IOBuffer; 38 class IPEndPoint; 39 class SSLInfo; 40 class WebSocketEndpointLockManager; 41 class WebSocketStreamRequestAPI; 42 struct AlternativeService; 43 struct HttpRequestInfo; 44 struct LoadTimingInfo; 45 struct NetErrorDetails; 46 struct WebSocketExtensionParams; 47 48 class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream final 49 : public WebSocketHandshakeStreamBase { 50 public: 51 // |connect_delegate| and |failure_message| must out-live this object. 52 WebSocketBasicHandshakeStream( 53 std::unique_ptr<ClientSocketHandle> connection, 54 WebSocketStream::ConnectDelegate* connect_delegate, 55 bool using_proxy, 56 std::vector<std::string> requested_sub_protocols, 57 std::vector<std::string> requested_extensions, 58 WebSocketStreamRequestAPI* request, 59 WebSocketEndpointLockManager* websocket_endpoint_lock_manager); 60 61 WebSocketBasicHandshakeStream(const WebSocketBasicHandshakeStream&) = delete; 62 WebSocketBasicHandshakeStream& operator=( 63 const WebSocketBasicHandshakeStream&) = delete; 64 65 ~WebSocketBasicHandshakeStream() override; 66 67 // HttpStream methods 68 void RegisterRequest(const HttpRequestInfo* request_info) override; 69 int InitializeStream(bool can_send_early, 70 RequestPriority priority, 71 const NetLogWithSource& net_log, 72 CompletionOnceCallback callback) override; 73 int SendRequest(const HttpRequestHeaders& request_headers, 74 HttpResponseInfo* response, 75 CompletionOnceCallback callback) override; 76 int ReadResponseHeaders(CompletionOnceCallback callback) override; 77 int ReadResponseBody(IOBuffer* buf, 78 int buf_len, 79 CompletionOnceCallback callback) override; 80 void Close(bool not_reusable) override; 81 bool IsResponseBodyComplete() const override; 82 bool IsConnectionReused() const override; 83 void SetConnectionReused() override; 84 bool CanReuseConnection() const override; 85 int64_t GetTotalReceivedBytes() const override; 86 int64_t GetTotalSentBytes() const override; 87 bool GetAlternativeService( 88 AlternativeService* alternative_service) const override; 89 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; 90 void GetSSLInfo(SSLInfo* ssl_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 std::string_view GetAcceptChViaAlps() const override; 98 99 // This is called from the top level once correct handshake response headers 100 // have been received. It creates an appropriate subclass of WebSocketStream 101 // depending on what extensions were negotiated. This object is unusable after 102 // Upgrade() has been called and should be disposed of as soon as possible. 103 std::unique_ptr<WebSocketStream> Upgrade() override; 104 105 bool CanReadFromStream() const override; 106 107 base::WeakPtr<WebSocketHandshakeStreamBase> GetWeakPtr() override; 108 109 // Set the value used for the next Sec-WebSocket-Key header 110 // deterministically. The key is only used once, and then discarded. 111 // For tests only. 112 void SetWebSocketKeyForTesting(const std::string& key); 113 114 private: 115 // A wrapper for the ReadResponseHeaders callback that checks whether or not 116 // the connection has been accepted. 117 void ReadResponseHeadersCallback(CompletionOnceCallback callback, int result); 118 119 // Validates the response and sends the finished handshake event. 120 int ValidateResponse(int rv); 121 122 // Check that the headers are well-formed for a 101 response, and returns 123 // OK if they are, otherwise returns ERR_INVALID_RESPONSE. 124 int ValidateUpgradeResponse(const HttpResponseHeaders* headers); 125 126 void OnFailure(const std::string& message, 127 int net_error, 128 std::optional<int> response_code); 129 parser()130 HttpStreamParser* parser() const { return state_.parser(); } 131 132 HandshakeResult result_ = HandshakeResult::INCOMPLETE; 133 134 // The request URL. 135 GURL url_; 136 137 // HttpBasicState holds most of the handshake-related state. 138 HttpBasicState state_; 139 140 // Owned by another object. 141 // |connect_delegate| will live during the lifetime of this object. 142 const raw_ptr<WebSocketStream::ConnectDelegate> connect_delegate_; 143 144 // This is stored in SendRequest() for use by ReadResponseHeaders(). 145 raw_ptr<HttpResponseInfo> http_response_info_ = nullptr; 146 147 // The key to be sent in the next Sec-WebSocket-Key header. Usually NULL (the 148 // key is generated on the fly). 149 std::optional<std::string> handshake_challenge_for_testing_; 150 151 // The required value for the Sec-WebSocket-Accept header. 152 std::string handshake_challenge_response_; 153 154 // The sub-protocols we requested. 155 std::vector<std::string> requested_sub_protocols_; 156 157 // The extensions we requested. 158 std::vector<std::string> requested_extensions_; 159 160 // The sub-protocol selected by the server. 161 std::string sub_protocol_; 162 163 // The extension(s) selected by the server. 164 std::string extensions_; 165 166 // The extension parameters. The class is defined in the implementation file 167 // to avoid including extension-related header files here. 168 std::unique_ptr<WebSocketExtensionParams> extension_params_; 169 170 const raw_ptr<WebSocketStreamRequestAPI> stream_request_; 171 172 const raw_ptr<WebSocketEndpointLockManager> websocket_endpoint_lock_manager_; 173 174 NetLogWithSource net_log_; 175 176 // The request to send. 177 // Set to null before the response body is read. This is to allow |this| to 178 // be shared for reading and to possibly outlive request_info_'s owner. 179 // Setting to null happens after headers are completely read or upload data 180 // stream is uploaded, whichever is later. 181 raw_ptr<const HttpRequestInfo> request_info_; 182 183 base::WeakPtrFactory<WebSocketBasicHandshakeStream> weak_ptr_factory_{this}; 184 }; 185 186 } // namespace net 187 188 #endif // NET_WEBSOCKETS_WEBSOCKET_BASIC_HANDSHAKE_STREAM_H_ 189