blob: 0b7248ca18a05358dfec86cdc0d9d366dff65ef0 [file] [log] [blame]
ricea433bdab2015-01-26 07:25:371// Copyright 2014 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// End-to-end tests for WebSocket.
6//
7// A python server is (re)started for each test, which is moderately
8// inefficient. However, it makes these tests a good fit for scenarios which
9// require special server configurations.
10
tfarina8a2c66c22015-10-13 19:14:4911#include <stdint.h>
ryansturm4bab06832016-03-03 23:41:0712
danakj9c5cab52016-04-16 00:54:3313#include <memory>
ricea433bdab2015-01-26 07:25:3714#include <string>
15
16#include "base/bind.h"
17#include "base/bind_helpers.h"
18#include "base/callback.h"
skyostil4891b25b2015-06-11 11:43:4519#include "base/location.h"
Avi Drissman13fc8932015-12-20 04:40:4620#include "base/macros.h"
danakj9c5cab52016-04-16 00:54:3321#include "base/memory/ptr_util.h"
ricea433bdab2015-01-26 07:25:3722#include "base/run_loop.h"
skyostil4891b25b2015-06-11 11:43:4523#include "base/single_thread_task_runner.h"
Adam Ricecb76ac62015-02-20 05:33:2524#include "base/strings/string_piece.h"
gabf767595f2016-05-11 18:50:3525#include "base/threading/thread_task_runner_handle.h"
ricea433bdab2015-01-26 07:25:3726#include "net/base/auth.h"
ryansturm7de050c2016-02-23 00:10:2127#include "net/base/proxy_delegate.h"
ricea433bdab2015-01-26 07:25:3728#include "net/proxy/proxy_service.h"
tommycli59a63432015-11-06 00:10:5529#include "net/test/embedded_test_server/embedded_test_server.h"
ricea433bdab2015-01-26 07:25:3730#include "net/test/spawned_test_server/spawned_test_server.h"
rsleevia69c79a2016-06-22 03:28:4331#include "net/test/test_data_directory.h"
ricea433bdab2015-01-26 07:25:3732#include "net/url_request/url_request_test_util.h"
33#include "net/websockets/websocket_channel.h"
34#include "net/websockets/websocket_event_interface.h"
35#include "testing/gtest/include/gtest/gtest.h"
mkwst4997ce82015-07-25 12:00:0536#include "url/origin.h"
ricea433bdab2015-01-26 07:25:3737
38namespace net {
39
40namespace {
41
42static const char kEchoServer[] = "echo-with-no-extension";
43
Adam Ricecb76ac62015-02-20 05:33:2544// Simplify changing URL schemes.
45GURL ReplaceUrlScheme(const GURL& in_url, const base::StringPiece& scheme) {
46 GURL::Replacements replacements;
47 replacements.SetSchemeStr(scheme);
48 return in_url.ReplaceComponents(replacements);
49}
50
ricea433bdab2015-01-26 07:25:3751// An implementation of WebSocketEventInterface that waits for and records the
52// results of the connect.
53class ConnectTestingEventInterface : public WebSocketEventInterface {
54 public:
55 ConnectTestingEventInterface();
56
57 void WaitForResponse();
58
59 bool failed() const { return failed_; }
60
61 // Only set if the handshake failed, otherwise empty.
62 std::string failure_message() const;
63
64 std::string selected_subprotocol() const;
65
66 std::string extensions() const;
67
68 // Implementation of WebSocketEventInterface.
tyoshinoc06da562015-03-06 06:02:4269 ChannelState OnAddChannelResponse(const std::string& selected_subprotocol,
ricea433bdab2015-01-26 07:25:3770 const std::string& extensions) override;
71
72 ChannelState OnDataFrame(bool fin,
73 WebSocketMessageType type,
74 const std::vector<char>& data) override;
75
tfarina8a2c66c22015-10-13 19:14:4976 ChannelState OnFlowControl(int64_t quota) override;
ricea433bdab2015-01-26 07:25:3777
78 ChannelState OnClosingHandshake() override;
79
80 ChannelState OnDropChannel(bool was_clean,
tfarina8a2c66c22015-10-13 19:14:4981 uint16_t code,
ricea433bdab2015-01-26 07:25:3782 const std::string& reason) override;
83
84 ChannelState OnFailChannel(const std::string& message) override;
85
86 ChannelState OnStartOpeningHandshake(
danakj9c5cab52016-04-16 00:54:3387 std::unique_ptr<WebSocketHandshakeRequestInfo> request) override;
ricea433bdab2015-01-26 07:25:3788
89 ChannelState OnFinishOpeningHandshake(
danakj9c5cab52016-04-16 00:54:3390 std::unique_ptr<WebSocketHandshakeResponseInfo> response) override;
ricea433bdab2015-01-26 07:25:3791
92 ChannelState OnSSLCertificateError(
danakj9c5cab52016-04-16 00:54:3393 std::unique_ptr<SSLErrorCallbacks> ssl_error_callbacks,
ricea433bdab2015-01-26 07:25:3794 const GURL& url,
95 const SSLInfo& ssl_info,
96 bool fatal) override;
97
98 private:
99 void QuitNestedEventLoop();
100
101 // failed_ is true if the handshake failed (ie. OnFailChannel was called).
102 bool failed_;
103 std::string selected_subprotocol_;
104 std::string extensions_;
105 std::string failure_message_;
106 base::RunLoop run_loop_;
107
108 DISALLOW_COPY_AND_ASSIGN(ConnectTestingEventInterface);
109};
110
tyoshinoc06da562015-03-06 06:02:42111ConnectTestingEventInterface::ConnectTestingEventInterface() : failed_(false) {
ricea433bdab2015-01-26 07:25:37112}
113
114void ConnectTestingEventInterface::WaitForResponse() {
115 run_loop_.Run();
116}
117
118std::string ConnectTestingEventInterface::failure_message() const {
119 return failure_message_;
120}
121
122std::string ConnectTestingEventInterface::selected_subprotocol() const {
123 return selected_subprotocol_;
124}
125
126std::string ConnectTestingEventInterface::extensions() const {
127 return extensions_;
128}
129
130// Make the function definitions below less verbose.
131typedef ConnectTestingEventInterface::ChannelState ChannelState;
132
133ChannelState ConnectTestingEventInterface::OnAddChannelResponse(
ricea433bdab2015-01-26 07:25:37134 const std::string& selected_subprotocol,
135 const std::string& extensions) {
ricea433bdab2015-01-26 07:25:37136 selected_subprotocol_ = selected_subprotocol;
137 extensions_ = extensions;
138 QuitNestedEventLoop();
tyoshinoc06da562015-03-06 06:02:42139 return CHANNEL_ALIVE;
ricea433bdab2015-01-26 07:25:37140}
141
142ChannelState ConnectTestingEventInterface::OnDataFrame(
143 bool fin,
144 WebSocketMessageType type,
145 const std::vector<char>& data) {
146 return CHANNEL_ALIVE;
147}
148
tfarina8a2c66c22015-10-13 19:14:49149ChannelState ConnectTestingEventInterface::OnFlowControl(int64_t quota) {
ricea433bdab2015-01-26 07:25:37150 return CHANNEL_ALIVE;
151}
152
153ChannelState ConnectTestingEventInterface::OnClosingHandshake() {
154 return CHANNEL_ALIVE;
155}
156
157ChannelState ConnectTestingEventInterface::OnDropChannel(
158 bool was_clean,
tfarina8a2c66c22015-10-13 19:14:49159 uint16_t code,
ricea433bdab2015-01-26 07:25:37160 const std::string& reason) {
161 return CHANNEL_DELETED;
162}
163
164ChannelState ConnectTestingEventInterface::OnFailChannel(
165 const std::string& message) {
166 failed_ = true;
167 failure_message_ = message;
168 QuitNestedEventLoop();
169 return CHANNEL_DELETED;
170}
171
172ChannelState ConnectTestingEventInterface::OnStartOpeningHandshake(
danakj9c5cab52016-04-16 00:54:33173 std::unique_ptr<WebSocketHandshakeRequestInfo> request) {
ricea433bdab2015-01-26 07:25:37174 return CHANNEL_ALIVE;
175}
176
177ChannelState ConnectTestingEventInterface::OnFinishOpeningHandshake(
danakj9c5cab52016-04-16 00:54:33178 std::unique_ptr<WebSocketHandshakeResponseInfo> response) {
ricea433bdab2015-01-26 07:25:37179 return CHANNEL_ALIVE;
180}
181
182ChannelState ConnectTestingEventInterface::OnSSLCertificateError(
danakj9c5cab52016-04-16 00:54:33183 std::unique_ptr<SSLErrorCallbacks> ssl_error_callbacks,
ricea433bdab2015-01-26 07:25:37184 const GURL& url,
185 const SSLInfo& ssl_info,
186 bool fatal) {
skyostil4891b25b2015-06-11 11:43:45187 base::ThreadTaskRunnerHandle::Get()->PostTask(
ricea433bdab2015-01-26 07:25:37188 FROM_HERE, base::Bind(&SSLErrorCallbacks::CancelSSLRequest,
189 base::Owned(ssl_error_callbacks.release()),
190 ERR_SSL_PROTOCOL_ERROR, &ssl_info));
191 return CHANNEL_ALIVE;
192}
193
194void ConnectTestingEventInterface::QuitNestedEventLoop() {
195 run_loop_.Quit();
196}
197
198// A subclass of TestNetworkDelegate that additionally implements the
199// OnResolveProxy callback and records the information passed to it.
ryansturm7de050c2016-02-23 00:10:21200class TestProxyDelegateWithProxyInfo : public ProxyDelegate {
ricea433bdab2015-01-26 07:25:37201 public:
ryansturm7de050c2016-02-23 00:10:21202 TestProxyDelegateWithProxyInfo() {}
ricea433bdab2015-01-26 07:25:37203
204 struct ResolvedProxyInfo {
205 GURL url;
206 ProxyInfo proxy_info;
207 };
208
209 const ResolvedProxyInfo& resolved_proxy_info() const {
210 return resolved_proxy_info_;
211 }
212
213 protected:
214 void OnResolveProxy(const GURL& url,
ryansturm4bab06832016-03-03 23:41:07215 const std::string& method,
ricea433bdab2015-01-26 07:25:37216 const ProxyService& proxy_service,
217 ProxyInfo* result) override {
218 resolved_proxy_info_.url = url;
219 resolved_proxy_info_.proxy_info = *result;
220 }
221
ryansturm7de050c2016-02-23 00:10:21222 void OnTunnelConnectCompleted(const HostPortPair& endpoint,
223 const HostPortPair& proxy_server,
224 int net_error) override {}
225 void OnFallback(const ProxyServer& bad_proxy, int net_error) override {}
ryansturm7de050c2016-02-23 00:10:21226 void OnBeforeTunnelRequest(const HostPortPair& proxy_server,
227 HttpRequestHeaders* extra_headers) override {}
228 void OnTunnelHeadersReceived(
229 const HostPortPair& origin,
230 const HostPortPair& proxy_server,
231 const HttpResponseHeaders& response_headers) override {}
232 bool IsTrustedSpdyProxy(const net::ProxyServer& proxy_server) override {
233 return true;
234 }
tbansalc3308d72016-08-27 10:25:04235 void GetAlternativeProxy(
236 const GURL& url,
237 const ProxyServer& resolved_proxy_server,
238 ProxyServer* alternative_proxy_server) const override {}
239 void OnAlternativeProxyBroken(
240 const ProxyServer& alternative_proxy_server) override {}
ryansturm7de050c2016-02-23 00:10:21241
ricea433bdab2015-01-26 07:25:37242 private:
243 ResolvedProxyInfo resolved_proxy_info_;
244
ryansturm7de050c2016-02-23 00:10:21245 DISALLOW_COPY_AND_ASSIGN(TestProxyDelegateWithProxyInfo);
ricea433bdab2015-01-26 07:25:37246};
247
248class WebSocketEndToEndTest : public ::testing::Test {
249 protected:
250 WebSocketEndToEndTest()
Adam Ricecb76ac62015-02-20 05:33:25251 : event_interface_(),
ryansturm7de050c2016-02-23 00:10:21252 proxy_delegate_(new TestProxyDelegateWithProxyInfo),
ricea433bdab2015-01-26 07:25:37253 context_(true),
Adam Ricecb76ac62015-02-20 05:33:25254 channel_(),
ricea433bdab2015-01-26 07:25:37255 initialised_context_(false) {}
256
257 // Initialise the URLRequestContext. Normally done automatically by
258 // ConnectAndWait(). This method is for the use of tests that need the
259 // URLRequestContext initialised before calling ConnectAndWait().
260 void InitialiseContext() {
ryansturm7de050c2016-02-23 00:10:21261 context_.set_proxy_delegate(proxy_delegate_.get());
ricea433bdab2015-01-26 07:25:37262 context_.Init();
263 initialised_context_ = true;
264 }
265
266 // Send the connect request to |socket_url| and wait for a response. Returns
267 // true if the handshake succeeded.
268 bool ConnectAndWait(const GURL& socket_url) {
269 if (!initialised_context_) {
270 InitialiseContext();
271 }
mkwst4997ce82015-07-25 12:00:05272 url::Origin origin(GURL("http://localhost"));
tyoshino8572d572016-07-13 06:29:48273 GURL first_party_for_cookies("http://localhost/");
Adam Ricecb76ac62015-02-20 05:33:25274 event_interface_ = new ConnectTestingEventInterface;
275 channel_.reset(
danakj9c5cab52016-04-16 00:54:33276 new WebSocketChannel(base::WrapUnique(event_interface_), &context_));
alladacef397d2016-06-29 17:52:23277 channel_->SendAddChannelRequest(GURL(socket_url), sub_protocols_, origin,
tyoshino8572d572016-07-13 06:29:48278 first_party_for_cookies, "");
ricea433bdab2015-01-26 07:25:37279 event_interface_->WaitForResponse();
280 return !event_interface_->failed();
281 }
282
283 ConnectTestingEventInterface* event_interface_; // owned by channel_
danakj9c5cab52016-04-16 00:54:33284 std::unique_ptr<TestProxyDelegateWithProxyInfo> proxy_delegate_;
ricea433bdab2015-01-26 07:25:37285 TestURLRequestContext context_;
danakj9c5cab52016-04-16 00:54:33286 std::unique_ptr<WebSocketChannel> channel_;
ricea5acb1faf72015-03-16 15:34:00287 std::vector<std::string> sub_protocols_;
ricea433bdab2015-01-26 07:25:37288 bool initialised_context_;
289};
290
291// None of these tests work on Android.
292// TODO(ricea): Make these tests work on Android. See crbug.com/441711.
293#if defined(OS_ANDROID)
294#define DISABLED_ON_ANDROID(test) DISABLED_##test
295#else
296#define DISABLED_ON_ANDROID(test) test
297#endif
298
299// Basic test of connectivity. If this test fails, nothing else can be expected
300// to work.
301TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(BasicSmokeTest)) {
302 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
303 SpawnedTestServer::kLocalhost,
304 GetWebSocketTestDataDirectory());
305 ASSERT_TRUE(ws_server.Start());
306 EXPECT_TRUE(ConnectAndWait(ws_server.GetURL(kEchoServer)));
307}
308
309// Test for issue crbug.com/433695 "Unencrypted WebSocket connection via
310// authenticated proxy times out"
311// TODO(ricea): Enable this when the issue is fixed.
312TEST_F(WebSocketEndToEndTest, DISABLED_HttpsProxyUnauthedFails) {
313 SpawnedTestServer proxy_server(SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
314 SpawnedTestServer::kLocalhost,
315 base::FilePath());
316 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
317 SpawnedTestServer::kLocalhost,
318 GetWebSocketTestDataDirectory());
319 ASSERT_TRUE(proxy_server.StartInBackground());
320 ASSERT_TRUE(ws_server.StartInBackground());
321 ASSERT_TRUE(proxy_server.BlockUntilStarted());
322 ASSERT_TRUE(ws_server.BlockUntilStarted());
323 std::string proxy_config =
324 "https=" + proxy_server.host_port_pair().ToString();
danakj9c5cab52016-04-16 00:54:33325 std::unique_ptr<ProxyService> proxy_service(
ricea433bdab2015-01-26 07:25:37326 ProxyService::CreateFixed(proxy_config));
327 ASSERT_TRUE(proxy_service);
328 context_.set_proxy_service(proxy_service.get());
329 EXPECT_FALSE(ConnectAndWait(ws_server.GetURL(kEchoServer)));
330 EXPECT_EQ("Proxy authentication failed", event_interface_->failure_message());
331}
332
333TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HttpsWssProxyUnauthedFails)) {
334 SpawnedTestServer proxy_server(SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
335 SpawnedTestServer::kLocalhost,
336 base::FilePath());
337 SpawnedTestServer wss_server(SpawnedTestServer::TYPE_WSS,
338 SpawnedTestServer::kLocalhost,
339 GetWebSocketTestDataDirectory());
340 ASSERT_TRUE(proxy_server.StartInBackground());
341 ASSERT_TRUE(wss_server.StartInBackground());
342 ASSERT_TRUE(proxy_server.BlockUntilStarted());
343 ASSERT_TRUE(wss_server.BlockUntilStarted());
344 std::string proxy_config =
345 "https=" + proxy_server.host_port_pair().ToString();
danakj9c5cab52016-04-16 00:54:33346 std::unique_ptr<ProxyService> proxy_service(
ricea433bdab2015-01-26 07:25:37347 ProxyService::CreateFixed(proxy_config));
348 ASSERT_TRUE(proxy_service);
349 context_.set_proxy_service(proxy_service.get());
350 EXPECT_FALSE(ConnectAndWait(wss_server.GetURL(kEchoServer)));
351 EXPECT_EQ("Proxy authentication failed", event_interface_->failure_message());
352}
353
354// Regression test for crbug/426736 "WebSocket connections not using configured
355// system HTTPS Proxy".
356TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HttpsProxyUsed)) {
357 SpawnedTestServer proxy_server(SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
358 SpawnedTestServer::kLocalhost,
359 base::FilePath());
360 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
361 SpawnedTestServer::kLocalhost,
362 GetWebSocketTestDataDirectory());
363 ASSERT_TRUE(proxy_server.StartInBackground());
364 ASSERT_TRUE(ws_server.StartInBackground());
365 ASSERT_TRUE(proxy_server.BlockUntilStarted());
366 ASSERT_TRUE(ws_server.BlockUntilStarted());
367 std::string proxy_config = "https=" +
368 proxy_server.host_port_pair().ToString() + ";" +
369 "http=" + proxy_server.host_port_pair().ToString();
danakj9c5cab52016-04-16 00:54:33370 std::unique_ptr<ProxyService> proxy_service(
ricea433bdab2015-01-26 07:25:37371 ProxyService::CreateFixed(proxy_config));
372 context_.set_proxy_service(proxy_service.get());
373 InitialiseContext();
374
375 // The test server doesn't have an unauthenticated proxy mode. WebSockets
376 // cannot provide auth information that isn't already cached, so it's
377 // necessary to preflight an HTTP request to authenticate against the proxy.
ricea433bdab2015-01-26 07:25:37378 // It doesn't matter what the URL is, as long as it is an HTTP navigation.
379 GURL http_page =
Adam Ricecb76ac62015-02-20 05:33:25380 ReplaceUrlScheme(ws_server.GetURL("connect_check.html"), "http");
ricea433bdab2015-01-26 07:25:37381 TestDelegate delegate;
382 delegate.set_credentials(
383 AuthCredentials(base::ASCIIToUTF16("foo"), base::ASCIIToUTF16("bar")));
384 {
danakj9c5cab52016-04-16 00:54:33385 std::unique_ptr<URLRequest> request(
davidben151423e2015-03-23 18:48:36386 context_.CreateRequest(http_page, DEFAULT_PRIORITY, &delegate));
ricea433bdab2015-01-26 07:25:37387 request->Start();
388 // TestDelegate exits the message loop when the request completes by
389 // default.
390 base::RunLoop().Run();
391 EXPECT_TRUE(delegate.auth_required_called());
392 }
393
394 GURL ws_url = ws_server.GetURL(kEchoServer);
395 EXPECT_TRUE(ConnectAndWait(ws_url));
ryansturm7de050c2016-02-23 00:10:21396 const TestProxyDelegateWithProxyInfo::ResolvedProxyInfo& info =
397 proxy_delegate_->resolved_proxy_info();
ricea433bdab2015-01-26 07:25:37398 EXPECT_EQ(ws_url, info.url);
399 EXPECT_TRUE(info.proxy_info.is_http());
400}
401
ricea23c3f942015-02-02 13:35:13402// This is a regression test for crbug.com/408061 Crash in
403// net::WebSocketBasicHandshakeStream::Upgrade.
404TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(TruncatedResponse)) {
405 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
406 SpawnedTestServer::kLocalhost,
407 GetWebSocketTestDataDirectory());
408 ASSERT_TRUE(ws_server.Start());
409 InitialiseContext();
410
411 GURL ws_url = ws_server.GetURL("truncated-headers");
412 EXPECT_FALSE(ConnectAndWait(ws_url));
413}
414
Adam Ricecb76ac62015-02-20 05:33:25415// Regression test for crbug.com/455215 "HSTS not applied to WebSocket"
416TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HstsHttpsToWebSocket)) {
tommycli59a63432015-11-06 00:10:55417 EmbeddedTestServer https_server(net::EmbeddedTestServer::Type::TYPE_HTTPS);
418 https_server.SetSSLConfig(
419 net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
420 https_server.ServeFilesFromSourceDirectory("net/data/url_request_unittest");
421
estarka5da76702015-04-09 04:00:16422 SpawnedTestServer::SSLOptions ssl_options(
423 SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
Adam Ricecb76ac62015-02-20 05:33:25424 SpawnedTestServer wss_server(SpawnedTestServer::TYPE_WSS, ssl_options,
425 GetWebSocketTestDataDirectory());
estarka5da76702015-04-09 04:00:16426
tommycli59a63432015-11-06 00:10:55427 ASSERT_TRUE(https_server.Start());
428 ASSERT_TRUE(wss_server.Start());
Adam Ricecb76ac62015-02-20 05:33:25429 InitialiseContext();
430 // Set HSTS via https:
431 TestDelegate delegate;
tommycli59a63432015-11-06 00:10:55432 GURL https_page = https_server.GetURL("/hsts-headers.html");
danakj9c5cab52016-04-16 00:54:33433 std::unique_ptr<URLRequest> request(
davidben151423e2015-03-23 18:48:36434 context_.CreateRequest(https_page, DEFAULT_PRIORITY, &delegate));
Adam Ricecb76ac62015-02-20 05:33:25435 request->Start();
436 // TestDelegate exits the message loop when the request completes.
437 base::RunLoop().Run();
438 EXPECT_TRUE(request->status().is_success());
439
440 // Check HSTS with ws:
441 // Change the scheme from wss: to ws: to verify that it is switched back.
442 GURL ws_url = ReplaceUrlScheme(wss_server.GetURL(kEchoServer), "ws");
443 EXPECT_TRUE(ConnectAndWait(ws_url));
444}
445
446TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HstsWebSocketToHttps)) {
tommycli59a63432015-11-06 00:10:55447 EmbeddedTestServer https_server(net::EmbeddedTestServer::Type::TYPE_HTTPS);
448 https_server.SetSSLConfig(
449 net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
450 https_server.ServeFilesFromSourceDirectory("net/data/url_request_unittest");
451
estarka5da76702015-04-09 04:00:16452 SpawnedTestServer::SSLOptions ssl_options(
453 SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
Adam Ricecb76ac62015-02-20 05:33:25454 SpawnedTestServer wss_server(SpawnedTestServer::TYPE_WSS, ssl_options,
455 GetWebSocketTestDataDirectory());
tommycli59a63432015-11-06 00:10:55456 ASSERT_TRUE(https_server.Start());
457 ASSERT_TRUE(wss_server.Start());
Adam Ricecb76ac62015-02-20 05:33:25458 InitialiseContext();
459 // Set HSTS via wss:
460 GURL wss_url = wss_server.GetURL("set-hsts");
461 EXPECT_TRUE(ConnectAndWait(wss_url));
462
463 // Verify via http:
464 TestDelegate delegate;
465 GURL http_page =
tommycli59a63432015-11-06 00:10:55466 ReplaceUrlScheme(https_server.GetURL("/simple.html"), "http");
danakj9c5cab52016-04-16 00:54:33467 std::unique_ptr<URLRequest> request(
davidben151423e2015-03-23 18:48:36468 context_.CreateRequest(http_page, DEFAULT_PRIORITY, &delegate));
Adam Ricecb76ac62015-02-20 05:33:25469 request->Start();
470 // TestDelegate exits the message loop when the request completes.
471 base::RunLoop().Run();
472 EXPECT_TRUE(request->status().is_success());
473 EXPECT_TRUE(request->url().SchemeIs("https"));
474}
475
476TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HstsWebSocketToWebSocket)) {
estarka5da76702015-04-09 04:00:16477 SpawnedTestServer::SSLOptions ssl_options(
478 SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
Adam Ricecb76ac62015-02-20 05:33:25479 SpawnedTestServer wss_server(SpawnedTestServer::TYPE_WSS, ssl_options,
480 GetWebSocketTestDataDirectory());
481 ASSERT_TRUE(wss_server.Start());
482 InitialiseContext();
483 // Set HSTS via wss:
484 GURL wss_url = wss_server.GetURL("set-hsts");
485 EXPECT_TRUE(ConnectAndWait(wss_url));
486
487 // Verify via wss:
488 GURL ws_url = ReplaceUrlScheme(wss_server.GetURL(kEchoServer), "ws");
489 EXPECT_TRUE(ConnectAndWait(ws_url));
490}
491
ricea5acb1faf72015-03-16 15:34:00492// Regression test for crbug.com/180504 "WebSocket handshake fails when HTTP
493// headers have trailing LWS".
494TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(TrailingWhitespace)) {
495 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
496 SpawnedTestServer::kLocalhost,
497 GetWebSocketTestDataDirectory());
498 ASSERT_TRUE(ws_server.Start());
499
500 GURL ws_url = ws_server.GetURL("trailing-whitespace");
501 sub_protocols_.push_back("sip");
502 EXPECT_TRUE(ConnectAndWait(ws_url));
503 EXPECT_EQ("sip", event_interface_->selected_subprotocol());
504}
505
riceae1d67672015-03-19 10:10:17506// This is a regression test for crbug.com/169448 "WebSockets should support
507// header continuations"
508// TODO(ricea): HTTP continuation headers have been deprecated by RFC7230. If
509// support for continuation headers is removed from Chrome, then this test will
510// break and should be removed.
511TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HeaderContinuations)) {
512 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
513 SpawnedTestServer::kLocalhost,
514 GetWebSocketTestDataDirectory());
515 ASSERT_TRUE(ws_server.Start());
516
517 GURL ws_url = ws_server.GetURL("header-continuation");
518
519 EXPECT_TRUE(ConnectAndWait(ws_url));
520 EXPECT_EQ("permessage-deflate; server_max_window_bits=10",
521 event_interface_->extensions());
522}
523
ricea433bdab2015-01-26 07:25:37524} // namespace
525
526} // namespace net