[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors. All rights reserved. |
| 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 | |
sclittle | be1ccf6 | 2015-09-02 19:40:36 | [diff] [blame] | 8 | #include <stdint.h> |
| 9 | |
danakj | 9c5cab5 | 2016-04-16 00:54:33 | [diff] [blame] | 10 | #include <memory> |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 11 | #include <string> |
| 12 | #include <vector> |
| 13 | |
tfarina | ea94afc23 | 2015-10-20 04:23:36 | [diff] [blame] | 14 | #include "base/macros.h" |
Bence Béky | 7d0c74d | 2018-03-05 08:31:09 | [diff] [blame] | 15 | #include "base/optional.h" |
Bence Béky | a25e3f7 | 2018-02-13 21:13:39 | [diff] [blame] | 16 | #include "net/base/completion_once_callback.h" |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 17 | #include "net/base/net_export.h" |
| 18 | #include "net/http/http_basic_state.h" |
| 19 | #include "net/websockets/websocket_handshake_stream_base.h" |
[email protected] | cd48ed1 | 2014-01-22 14:34:22 | [diff] [blame] | 20 | #include "url/gurl.h" |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 21 | |
| 22 | namespace net { |
| 23 | |
| 24 | class ClientSocketHandle; |
| 25 | class HttpResponseHeaders; |
| 26 | class HttpResponseInfo; |
| 27 | class HttpStreamParser; |
Bence Béky | da280c6 | 2018-04-12 15:08:37 | [diff] [blame] | 28 | class WebSocketEndpointLockManager; |
[email protected] | 0be9392 | 2014-01-29 00:42:45 | [diff] [blame] | 29 | struct WebSocketExtensionParams; |
Adam Rice | 6f75c0f | 2018-06-04 08:00:05 | [diff] [blame] | 30 | class WebSocketStreamRequestAPI; |
[email protected] | 0be9392 | 2014-01-29 00:42:45 | [diff] [blame] | 31 | |
Adam Rice | c786ad8a | 2018-05-22 09:49:15 | [diff] [blame] | 32 | class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream final |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 33 | : public WebSocketHandshakeStreamBase { |
| 34 | public: |
[email protected] | 8aba017 | 2014-07-03 12:09:53 | [diff] [blame] | 35 | // |connect_delegate| and |failure_message| must out-live this object. |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 36 | WebSocketBasicHandshakeStream( |
danakj | 9c5cab5 | 2016-04-16 00:54:33 | [diff] [blame] | 37 | std::unique_ptr<ClientSocketHandle> connection, |
[email protected] | cd48ed1 | 2014-01-22 14:34:22 | [diff] [blame] | 38 | WebSocketStream::ConnectDelegate* connect_delegate, |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 39 | bool using_proxy, |
| 40 | std::vector<std::string> requested_sub_protocols, |
[email protected] | 8aba017 | 2014-07-03 12:09:53 | [diff] [blame] | 41 | std::vector<std::string> requested_extensions, |
Adam Rice | 6f75c0f | 2018-06-04 08:00:05 | [diff] [blame] | 42 | WebSocketStreamRequestAPI* request, |
Bence Béky | da280c6 | 2018-04-12 15:08:37 | [diff] [blame] | 43 | WebSocketEndpointLockManager* websocket_endpoint_lock_manager); |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 44 | |
dcheng | b03027d | 2014-10-21 12:00:20 | [diff] [blame] | 45 | ~WebSocketBasicHandshakeStream() override; |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 46 | |
| 47 | // HttpStreamBase methods |
dcheng | b03027d | 2014-10-21 12:00:20 | [diff] [blame] | 48 | int InitializeStream(const HttpRequestInfo* request_info, |
Steven Valdez | b4ff041 | 2018-01-18 22:39:27 | [diff] [blame] | 49 | bool can_send_early, |
dcheng | b03027d | 2014-10-21 12:00:20 | [diff] [blame] | 50 | RequestPriority priority, |
tfarina | 42834111 | 2016-09-22 13:38:20 | [diff] [blame] | 51 | const NetLogWithSource& net_log, |
Bence Béky | a25e3f7 | 2018-02-13 21:13:39 | [diff] [blame] | 52 | CompletionOnceCallback callback) override; |
dcheng | b03027d | 2014-10-21 12:00:20 | [diff] [blame] | 53 | int SendRequest(const HttpRequestHeaders& request_headers, |
| 54 | HttpResponseInfo* response, |
Bence Béky | a25e3f7 | 2018-02-13 21:13:39 | [diff] [blame] | 55 | CompletionOnceCallback callback) override; |
| 56 | int ReadResponseHeaders(CompletionOnceCallback callback) override; |
dcheng | b03027d | 2014-10-21 12:00:20 | [diff] [blame] | 57 | int ReadResponseBody(IOBuffer* buf, |
| 58 | int buf_len, |
Bence Béky | a25e3f7 | 2018-02-13 21:13:39 | [diff] [blame] | 59 | CompletionOnceCallback callback) override; |
dcheng | b03027d | 2014-10-21 12:00:20 | [diff] [blame] | 60 | void Close(bool not_reusable) override; |
| 61 | bool IsResponseBodyComplete() const override; |
dcheng | b03027d | 2014-10-21 12:00:20 | [diff] [blame] | 62 | bool IsConnectionReused() const override; |
| 63 | void SetConnectionReused() override; |
mmenke | bd84c39 | 2015-09-02 14:12:34 | [diff] [blame] | 64 | bool CanReuseConnection() const override; |
sclittle | 4de1bab9 | 2015-09-22 21:28:24 | [diff] [blame] | 65 | int64_t GetTotalReceivedBytes() const override; |
sclittle | be1ccf6 | 2015-09-02 19:40:36 | [diff] [blame] | 66 | int64_t GetTotalSentBytes() const override; |
rch | cd37901 | 2017-04-12 21:53:32 | [diff] [blame] | 67 | bool GetAlternativeService( |
| 68 | AlternativeService* alternative_service) const override; |
dcheng | b03027d | 2014-10-21 12:00:20 | [diff] [blame] | 69 | bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; |
| 70 | void GetSSLInfo(SSLInfo* ssl_info) override; |
| 71 | void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override; |
ttuttle | d9dbc65 | 2015-09-29 20:00:59 | [diff] [blame] | 72 | bool GetRemoteEndpoint(IPEndPoint* endpoint) override; |
dcheng | b03027d | 2014-10-21 12:00:20 | [diff] [blame] | 73 | void Drain(HttpNetworkSession* session) override; |
| 74 | void SetPriority(RequestPriority priority) override; |
zhongyi | ca364fbb | 2015-12-12 03:39:12 | [diff] [blame] | 75 | void PopulateNetErrorDetails(NetErrorDetails* details) override; |
yhirano | a7e05bb | 2014-11-06 05:40:39 | [diff] [blame] | 76 | HttpStream* RenewStreamForAuth() override; |
| 77 | |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 78 | |
| 79 | // This is called from the top level once correct handshake response headers |
| 80 | // have been received. It creates an appropriate subclass of WebSocketStream |
| 81 | // depending on what extensions were negotiated. This object is unusable after |
| 82 | // Upgrade() has been called and should be disposed of as soon as possible. |
danakj | 9c5cab5 | 2016-04-16 00:54:33 | [diff] [blame] | 83 | std::unique_ptr<WebSocketStream> Upgrade() override; |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 84 | |
Bence Béky | ca0da43 | 2019-01-24 15:03:20 | [diff] [blame] | 85 | base::WeakPtr<WebSocketHandshakeStreamBase> GetWeakPtr() override; |
| 86 | |
[email protected] | a31ecc0 | 2013-12-05 08:30:55 | [diff] [blame] | 87 | // Set the value used for the next Sec-WebSocket-Key header |
| 88 | // deterministically. The key is only used once, and then discarded. |
| 89 | // For tests only. |
| 90 | void SetWebSocketKeyForTesting(const std::string& key); |
| 91 | |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 92 | private: |
| 93 | // A wrapper for the ReadResponseHeaders callback that checks whether or not |
| 94 | // the connection has been accepted. |
Bence Béky | a25e3f7 | 2018-02-13 21:13:39 | [diff] [blame] | 95 | void ReadResponseHeadersCallback(CompletionOnceCallback callback, int result); |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 96 | |
[email protected] | cd48ed1 | 2014-01-22 14:34:22 | [diff] [blame] | 97 | void OnFinishOpeningHandshake(); |
| 98 | |
[email protected] | e5760f52 | 2014-02-05 12:28:50 | [diff] [blame] | 99 | // Validates the response and sends the finished handshake event. |
ricea | 24c195f | 2015-02-26 12:18:55 | [diff] [blame] | 100 | int ValidateResponse(int rv); |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 101 | |
| 102 | // Check that the headers are well-formed for a 101 response, and returns |
| 103 | // OK if they are, otherwise returns ERR_INVALID_RESPONSE. |
[email protected] | e5760f52 | 2014-02-05 12:28:50 | [diff] [blame] | 104 | int ValidateUpgradeResponse(const HttpResponseHeaders* headers); |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 105 | |
tyoshino | ccfcfde | 2016-07-21 14:06:55 | [diff] [blame] | 106 | void OnFailure(const std::string& message); |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 107 | |
tyoshino | ccfcfde | 2016-07-21 14:06:55 | [diff] [blame] | 108 | HttpStreamParser* parser() const { return state_.parser(); } |
[email protected] | 8aba017 | 2014-07-03 12:09:53 | [diff] [blame] | 109 | |
Bence Béky | de0be31 | 2018-03-13 17:51:58 | [diff] [blame] | 110 | HandshakeResult result_; |
| 111 | |
[email protected] | cd48ed1 | 2014-01-22 14:34:22 | [diff] [blame] | 112 | // The request URL. |
| 113 | GURL url_; |
| 114 | |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 115 | // HttpBasicState holds most of the handshake-related state. |
| 116 | HttpBasicState state_; |
| 117 | |
[email protected] | cd48ed1 | 2014-01-22 14:34:22 | [diff] [blame] | 118 | // Owned by another object. |
| 119 | // |connect_delegate| will live during the lifetime of this object. |
Adam Rice | 8b382c60 | 2018-06-04 12:36:39 | [diff] [blame] | 120 | WebSocketStream::ConnectDelegate* const connect_delegate_; |
[email protected] | cd48ed1 | 2014-01-22 14:34:22 | [diff] [blame] | 121 | |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 122 | // This is stored in SendRequest() for use by ReadResponseHeaders(). |
| 123 | HttpResponseInfo* http_response_info_; |
| 124 | |
[email protected] | a31ecc0 | 2013-12-05 08:30:55 | [diff] [blame] | 125 | // The key to be sent in the next Sec-WebSocket-Key header. Usually NULL (the |
| 126 | // key is generated on the fly). |
Bence Béky | 7d0c74d | 2018-03-05 08:31:09 | [diff] [blame] | 127 | base::Optional<std::string> handshake_challenge_for_testing_; |
[email protected] | a31ecc0 | 2013-12-05 08:30:55 | [diff] [blame] | 128 | |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 129 | // The required value for the Sec-WebSocket-Accept header. |
| 130 | std::string handshake_challenge_response_; |
| 131 | |
| 132 | // The sub-protocols we requested. |
| 133 | std::vector<std::string> requested_sub_protocols_; |
| 134 | |
| 135 | // The extensions we requested. |
| 136 | std::vector<std::string> requested_extensions_; |
| 137 | |
| 138 | // The sub-protocol selected by the server. |
| 139 | std::string sub_protocol_; |
| 140 | |
| 141 | // The extension(s) selected by the server. |
| 142 | std::string extensions_; |
| 143 | |
[email protected] | 0be9392 | 2014-01-29 00:42:45 | [diff] [blame] | 144 | // The extension parameters. The class is defined in the implementation file |
| 145 | // to avoid including extension-related header files here. |
danakj | 9c5cab5 | 2016-04-16 00:54:33 | [diff] [blame] | 146 | std::unique_ptr<WebSocketExtensionParams> extension_params_; |
[email protected] | 0be9392 | 2014-01-29 00:42:45 | [diff] [blame] | 147 | |
Adam Rice | 6f75c0f | 2018-06-04 08:00:05 | [diff] [blame] | 148 | WebSocketStreamRequestAPI* const stream_request_; |
Bence Béky | da280c6 | 2018-04-12 15:08:37 | [diff] [blame] | 149 | |
| 150 | WebSocketEndpointLockManager* const websocket_endpoint_lock_manager_; |
[email protected] | 9686820 | 2014-01-09 10:38:04 | [diff] [blame] | 151 | |
Bence Béky | ca0da43 | 2019-01-24 15:03:20 | [diff] [blame] | 152 | base::WeakPtrFactory<WebSocketBasicHandshakeStream> weak_ptr_factory_; |
| 153 | |
[email protected] | d51365e | 2013-11-27 10:46:52 | [diff] [blame] | 154 | DISALLOW_COPY_AND_ASSIGN(WebSocketBasicHandshakeStream); |
| 155 | }; |
| 156 | |
| 157 | } // namespace net |
| 158 | |
| 159 | #endif // NET_WEBSOCKETS_WEBSOCKET_BASIC_HANDSHAKE_STREAM_H_ |