yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 1 | // Copyright 2015 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 | #include "net/websockets/websocket_stream_create_test_base.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 6 | #include "base/memory/raw_ptr.h" |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 7 | |
dcheng | c7eeda42 | 2015-12-26 03:56:48 | [diff] [blame] | 8 | #include <utility> |
| 9 | |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 10 | #include "base/callback.h" |
Tsuyoshi Horo | 01faed6 | 2019-02-20 22:11:37 | [diff] [blame] | 11 | #include "net/base/ip_endpoint.h" |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 12 | #include "net/http/http_request_headers.h" |
| 13 | #include "net/http/http_response_headers.h" |
mikecirone | f22f981 | 2016-10-04 03:40:19 | [diff] [blame] | 14 | #include "net/log/net_log_with_source.h" |
Adam Langley | acbad24 | 2020-08-18 15:14:52 | [diff] [blame] | 15 | #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 16 | #include "net/websockets/websocket_basic_handshake_stream.h" |
| 17 | #include "net/websockets/websocket_handshake_request_info.h" |
| 18 | #include "net/websockets/websocket_handshake_response_info.h" |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 19 | #include "net/websockets/websocket_stream.h" |
| 20 | #include "url/gurl.h" |
mkwst | 4997ce8 | 2015-07-25 12:00:05 | [diff] [blame] | 21 | #include "url/origin.h" |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 22 | |
| 23 | namespace net { |
| 24 | |
| 25 | using HeaderKeyValuePair = WebSocketStreamCreateTestBase::HeaderKeyValuePair; |
| 26 | |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 27 | class WebSocketStreamCreateTestBase::TestConnectDelegate |
| 28 | : public WebSocketStream::ConnectDelegate { |
| 29 | public: |
| 30 | TestConnectDelegate(WebSocketStreamCreateTestBase* owner, |
Steve Kobes | 3ad84b5 | 2020-07-09 00:30:02 | [diff] [blame] | 31 | base::OnceClosure done_callback) |
| 32 | : owner_(owner), done_callback_(std::move(done_callback)) {} |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 33 | |
Peter Boström | 407869b | 2021-10-07 04:42:48 | [diff] [blame] | 34 | TestConnectDelegate(const TestConnectDelegate&) = delete; |
| 35 | TestConnectDelegate& operator=(const TestConnectDelegate&) = delete; |
| 36 | |
yhirano | 4a59383 | 2016-10-24 18:58:22 | [diff] [blame] | 37 | void OnCreateRequest(URLRequest* request) override { |
| 38 | owner_->url_request_ = request; |
| 39 | } |
| 40 | |
Yoichi Osato | 1ead61a | 2020-01-06 04:52:57 | [diff] [blame] | 41 | void OnSuccess( |
| 42 | std::unique_ptr<WebSocketStream> stream, |
| 43 | std::unique_ptr<WebSocketHandshakeResponseInfo> response) override { |
| 44 | if (owner_->response_info_) |
| 45 | ADD_FAILURE(); |
| 46 | owner_->response_info_ = std::move(response); |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 47 | stream.swap(owner_->stream_); |
Steve Kobes | 3ad84b5 | 2020-07-09 00:30:02 | [diff] [blame] | 48 | std::move(done_callback_).Run(); |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 49 | } |
| 50 | |
Adam Langley | a48b636a | 2020-11-12 23:42:52 | [diff] [blame] | 51 | void OnFailure(const std::string& message, |
| 52 | int net_error, |
Anton Bikineev | 068d291 | 2021-05-15 20:43:52 | [diff] [blame] | 53 | absl::optional<int> response_code) override { |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 54 | owner_->has_failed_ = true; |
| 55 | owner_->failure_message_ = message; |
Adam Langley | a48b636a | 2020-11-12 23:42:52 | [diff] [blame] | 56 | owner_->failure_response_code_ = response_code.value_or(-1); |
Steve Kobes | 3ad84b5 | 2020-07-09 00:30:02 | [diff] [blame] | 57 | std::move(done_callback_).Run(); |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 58 | } |
| 59 | |
| 60 | void OnStartOpeningHandshake( |
danakj | 9c5cab5 | 2016-04-16 00:54:33 | [diff] [blame] | 61 | std::unique_ptr<WebSocketHandshakeRequestInfo> request) override { |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 62 | // Can be called multiple times (in the case of HTTP auth). Last call |
| 63 | // wins. |
dcheng | c7eeda42 | 2015-12-26 03:56:48 | [diff] [blame] | 64 | owner_->request_info_ = std::move(request); |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 65 | } |
| 66 | |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 67 | void OnSSLCertificateError( |
danakj | 9c5cab5 | 2016-04-16 00:54:33 | [diff] [blame] | 68 | std::unique_ptr<WebSocketEventInterface::SSLErrorCallbacks> |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 69 | ssl_error_callbacks, |
Emily Stark | 79fba584 | 2019-04-25 04:59:36 | [diff] [blame] | 70 | int net_error, |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 71 | const SSLInfo& ssl_info, |
| 72 | bool fatal) override { |
dcheng | c7eeda42 | 2015-12-26 03:56:48 | [diff] [blame] | 73 | owner_->ssl_error_callbacks_ = std::move(ssl_error_callbacks); |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 74 | owner_->ssl_info_ = ssl_info; |
| 75 | owner_->ssl_fatal_ = fatal; |
| 76 | } |
| 77 | |
Emily Stark | f2c9bbd | 2019-04-09 17:08:58 | [diff] [blame] | 78 | int OnAuthRequired(const AuthChallengeInfo& auth_info, |
Yutaka Hirano | 70fa2591 | 2018-06-06 05:26:54 | [diff] [blame] | 79 | scoped_refptr<HttpResponseHeaders> response_headers, |
Tsuyoshi Horo | 01faed6 | 2019-02-20 22:11:37 | [diff] [blame] | 80 | const IPEndPoint& remote_endpoint, |
Yutaka Hirano | 70fa2591 | 2018-06-06 05:26:54 | [diff] [blame] | 81 | base::OnceCallback<void(const AuthCredentials*)> callback, |
Anton Bikineev | 068d291 | 2021-05-15 20:43:52 | [diff] [blame] | 82 | absl::optional<AuthCredentials>* credentials) override { |
Yutaka Hirano | 70fa2591 | 2018-06-06 05:26:54 | [diff] [blame] | 83 | owner_->run_loop_waiting_for_on_auth_required_.Quit(); |
Emily Stark | f2c9bbd | 2019-04-09 17:08:58 | [diff] [blame] | 84 | owner_->auth_challenge_info_ = auth_info; |
Yutaka Hirano | 70fa2591 | 2018-06-06 05:26:54 | [diff] [blame] | 85 | *credentials = owner_->auth_credentials_; |
| 86 | owner_->on_auth_required_callback_ = std::move(callback); |
| 87 | return owner_->on_auth_required_rv_; |
| 88 | } |
| 89 | |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 90 | private: |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 91 | raw_ptr<WebSocketStreamCreateTestBase> owner_; |
Steve Kobes | 3ad84b5 | 2020-07-09 00:30:02 | [diff] [blame] | 92 | base::OnceClosure done_callback_; |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 93 | }; |
| 94 | |
Tsuyoshi Horo | 432981d5 | 2022-06-09 09:50:13 | [diff] [blame] | 95 | WebSocketStreamCreateTestBase::WebSocketStreamCreateTestBase() = default; |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 96 | |
Chris Watkins | 28c2fdd | 2017-11-30 06:06:52 | [diff] [blame] | 97 | WebSocketStreamCreateTestBase::~WebSocketStreamCreateTestBase() = default; |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 98 | |
| 99 | void WebSocketStreamCreateTestBase::CreateAndConnectStream( |
tyoshino | 8572d57 | 2016-07-13 06:29:48 | [diff] [blame] | 100 | const GURL& socket_url, |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 101 | const std::vector<std::string>& sub_protocols, |
mkwst | 4997ce8 | 2015-07-25 12:00:05 | [diff] [blame] | 102 | const url::Origin& origin, |
Maks Orlovich | 8be0e25 | 2019-12-09 18:35:49 | [diff] [blame] | 103 | const SiteForCookies& site_for_cookies, |
Matt Menke | 29a538d | 2020-04-29 16:12:17 | [diff] [blame] | 104 | const IsolationInfo& isolation_info, |
Yutaka Hirano | 2f65eec | 2018-05-23 01:58:22 | [diff] [blame] | 105 | const HttpRequestHeaders& additional_headers, |
tzik | 08d8d6e | 2018-07-09 04:11:47 | [diff] [blame] | 106 | std::unique_ptr<base::OneShotTimer> timer) { |
Bence Béky | 6562397 | 2018-03-05 15:31:56 | [diff] [blame] | 107 | auto connect_delegate = std::make_unique<TestConnectDelegate>( |
| 108 | this, connect_run_loop_.QuitClosure()); |
Adam Rice | 6f75c0f | 2018-06-04 08:00:05 | [diff] [blame] | 109 | auto api_delegate = std::make_unique<TestWebSocketStreamRequestAPI>(); |
tyoshino | ccfcfde | 2016-07-21 14:06:55 | [diff] [blame] | 110 | stream_request_ = WebSocketStream::CreateAndConnectStreamForTesting( |
Matt Menke | 29a538d | 2020-04-29 16:12:17 | [diff] [blame] | 111 | socket_url, sub_protocols, origin, site_for_cookies, isolation_info, |
| 112 | additional_headers, url_request_context_host_.GetURLRequestContext(), |
Adam Langley | acbad24 | 2020-08-18 15:14:52 | [diff] [blame] | 113 | NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS, |
| 114 | std::move(connect_delegate), |
tzik | 08d8d6e | 2018-07-09 04:11:47 | [diff] [blame] | 115 | timer ? std::move(timer) : std::make_unique<base::OneShotTimer>(), |
Adam Rice | 6f75c0f | 2018-06-04 08:00:05 | [diff] [blame] | 116 | std::move(api_delegate)); |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 117 | } |
| 118 | |
| 119 | std::vector<HeaderKeyValuePair> |
| 120 | WebSocketStreamCreateTestBase::RequestHeadersToVector( |
| 121 | const HttpRequestHeaders& headers) { |
| 122 | HttpRequestHeaders::Iterator it(headers); |
| 123 | std::vector<HeaderKeyValuePair> result; |
| 124 | while (it.GetNext()) |
Tsuyoshi Horo | ebc50788 | 2022-06-30 11:16:45 | [diff] [blame] | 125 | result.emplace_back(it.name(), it.value()); |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 126 | return result; |
| 127 | } |
| 128 | |
| 129 | std::vector<HeaderKeyValuePair> |
| 130 | WebSocketStreamCreateTestBase::ResponseHeadersToVector( |
| 131 | const HttpResponseHeaders& headers) { |
olli.raula | 33c282f | 2016-01-21 12:12:49 | [diff] [blame] | 132 | size_t iter = 0; |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 133 | std::string name, value; |
| 134 | std::vector<HeaderKeyValuePair> result; |
| 135 | while (headers.EnumerateHeaderLines(&iter, &name, &value)) |
Tsuyoshi Horo | ebc50788 | 2022-06-30 11:16:45 | [diff] [blame] | 136 | result.emplace_back(name, value); |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 137 | return result; |
| 138 | } |
| 139 | |
| 140 | void WebSocketStreamCreateTestBase::WaitUntilConnectDone() { |
| 141 | connect_run_loop_.Run(); |
| 142 | } |
| 143 | |
Yutaka Hirano | 70fa2591 | 2018-06-06 05:26:54 | [diff] [blame] | 144 | void WebSocketStreamCreateTestBase::WaitUntilOnAuthRequired() { |
| 145 | run_loop_waiting_for_on_auth_required_.Run(); |
| 146 | } |
| 147 | |
yhirano | 01a5d66 | 2015-02-12 04:33:06 | [diff] [blame] | 148 | std::vector<std::string> WebSocketStreamCreateTestBase::NoSubProtocols() { |
| 149 | return std::vector<std::string>(); |
| 150 | } |
| 151 | |
| 152 | } // namespace net |