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 <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/http/http_basic_state.h" 22 #include "net/log/net_log_with_source.h" 23 #include "net/websockets/websocket_handshake_stream_base.h" 24 #include "net/websockets/websocket_stream.h" 25 #include "third_party/abseil-cpp/absl/types/optional.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 SSLCertRequestInfo; 40 class SSLInfo; 41 class WebSocketEndpointLockManager; 42 class WebSocketStreamRequestAPI; 43 struct AlternativeService; 44 struct HttpRequestInfo; 45 struct LoadTimingInfo; 46 struct NetErrorDetails; 47 struct WebSocketExtensionParams; 48 49 class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream final 50 : public WebSocketHandshakeStreamBase { 51 public: 52 // |connect_delegate| and |failure_message| must out-live this object. 53 WebSocketBasicHandshakeStream( 54 std::unique_ptr<ClientSocketHandle> connection, 55 WebSocketStream::ConnectDelegate* connect_delegate, 56 bool using_proxy, 57 std::vector<std::string> requested_sub_protocols, 58 std::vector<std::string> requested_extensions, 59 WebSocketStreamRequestAPI* request, 60 WebSocketEndpointLockManager* websocket_endpoint_lock_manager); 61 62 WebSocketBasicHandshakeStream(const WebSocketBasicHandshakeStream&) = delete; 63 WebSocketBasicHandshakeStream& operator=( 64 const WebSocketBasicHandshakeStream&) = delete; 65 66 ~WebSocketBasicHandshakeStream() 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 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override; 93 int GetRemoteEndpoint(IPEndPoint* endpoint) override; 94 void Drain(HttpNetworkSession* session) override; 95 void SetPriority(RequestPriority priority) override; 96 void PopulateNetErrorDetails(NetErrorDetails* details) override; 97 std::unique_ptr<HttpStream> RenewStreamForAuth() override; 98 const std::set<std::string>& GetDnsAliases() const override; 99 base::StringPiece GetAcceptChViaAlps() const override; 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 bool CanReadFromStream() const override; 108 109 base::WeakPtr<WebSocketHandshakeStreamBase> GetWeakPtr() override; 110 111 // Set the value used for the next Sec-WebSocket-Key header 112 // deterministically. The key is only used once, and then discarded. 113 // For tests only. 114 void SetWebSocketKeyForTesting(const std::string& key); 115 116 private: 117 // A wrapper for the ReadResponseHeaders callback that checks whether or not 118 // the connection has been accepted. 119 void ReadResponseHeadersCallback(CompletionOnceCallback callback, int result); 120 121 // Validates the response and sends the finished handshake event. 122 int ValidateResponse(int rv); 123 124 // Check that the headers are well-formed for a 101 response, and returns 125 // OK if they are, otherwise returns ERR_INVALID_RESPONSE. 126 int ValidateUpgradeResponse(const HttpResponseHeaders* headers); 127 128 void OnFailure(const std::string& message, 129 int net_error, 130 absl::optional<int> response_code); 131 parser()132 HttpStreamParser* parser() const { return state_.parser(); } 133 134 HandshakeResult result_ = HandshakeResult::INCOMPLETE; 135 136 // The request URL. 137 GURL url_; 138 139 // HttpBasicState holds most of the handshake-related state. 140 HttpBasicState state_; 141 142 // Owned by another object. 143 // |connect_delegate| will live during the lifetime of this object. 144 const raw_ptr<WebSocketStream::ConnectDelegate, DanglingUntriaged> 145 connect_delegate_; 146 147 // This is stored in SendRequest() for use by ReadResponseHeaders(). 148 raw_ptr<HttpResponseInfo> http_response_info_ = nullptr; 149 150 // The key to be sent in the next Sec-WebSocket-Key header. Usually NULL (the 151 // key is generated on the fly). 152 absl::optional<std::string> handshake_challenge_for_testing_; 153 154 // The required value for the Sec-WebSocket-Accept header. 155 std::string handshake_challenge_response_; 156 157 // The sub-protocols we requested. 158 std::vector<std::string> requested_sub_protocols_; 159 160 // The extensions we requested. 161 std::vector<std::string> requested_extensions_; 162 163 // The sub-protocol selected by the server. 164 std::string sub_protocol_; 165 166 // The extension(s) selected by the server. 167 std::string extensions_; 168 169 // The extension parameters. The class is defined in the implementation file 170 // to avoid including extension-related header files here. 171 std::unique_ptr<WebSocketExtensionParams> extension_params_; 172 173 const raw_ptr<WebSocketStreamRequestAPI, DanglingUntriaged> stream_request_; 174 175 const raw_ptr<WebSocketEndpointLockManager> websocket_endpoint_lock_manager_; 176 177 NetLogWithSource net_log_; 178 179 // The request to send. 180 // Set to null before the response body is read. This is to allow |this| to 181 // be shared for reading and to possibly outlive request_info_'s owner. 182 // Setting to null happens after headers are completely read or upload data 183 // stream is uploaded, whichever is later. 184 raw_ptr<const HttpRequestInfo> request_info_; 185 186 base::WeakPtrFactory<WebSocketBasicHandshakeStream> weak_ptr_factory_{this}; 187 }; 188 189 } // namespace net 190 191 #endif // NET_WEBSOCKETS_WEBSOCKET_BASIC_HANDSHAKE_STREAM_H_ 192