blob: 3dcf3361ce2b9621e40a8e619f567704270d82fc [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>
ricea433bdab2015-01-26 07:25:3712#include <string>
13
14#include "base/bind.h"
15#include "base/bind_helpers.h"
16#include "base/callback.h"
skyostil4891b25b2015-06-11 11:43:4517#include "base/location.h"
Avi Drissman13fc8932015-12-20 04:40:4618#include "base/macros.h"
ricea433bdab2015-01-26 07:25:3719#include "base/memory/scoped_ptr.h"
ricea433bdab2015-01-26 07:25:3720#include "base/run_loop.h"
skyostil4891b25b2015-06-11 11:43:4521#include "base/single_thread_task_runner.h"
Adam Ricecb76ac62015-02-20 05:33:2522#include "base/strings/string_piece.h"
skyostil4891b25b2015-06-11 11:43:4523#include "base/thread_task_runner_handle.h"
ricea433bdab2015-01-26 07:25:3724#include "net/base/auth.h"
ryansturm7de050c2016-02-23 00:10:2125#include "net/base/proxy_delegate.h"
ricea433bdab2015-01-26 07:25:3726#include "net/base/test_data_directory.h"
27#include "net/proxy/proxy_service.h"
tommycli59a63432015-11-06 00:10:5528#include "net/test/embedded_test_server/embedded_test_server.h"
ricea433bdab2015-01-26 07:25:3729#include "net/test/spawned_test_server/spawned_test_server.h"
30#include "net/url_request/url_request_test_util.h"
31#include "net/websockets/websocket_channel.h"
32#include "net/websockets/websocket_event_interface.h"
33#include "testing/gtest/include/gtest/gtest.h"
mkwst4997ce82015-07-25 12:00:0534#include "url/origin.h"
ricea433bdab2015-01-26 07:25:3735
36namespace net {
37
38namespace {
39
40static const char kEchoServer[] = "echo-with-no-extension";
41
Adam Ricecb76ac62015-02-20 05:33:2542// Simplify changing URL schemes.
43GURL ReplaceUrlScheme(const GURL& in_url, const base::StringPiece& scheme) {
44 GURL::Replacements replacements;
45 replacements.SetSchemeStr(scheme);
46 return in_url.ReplaceComponents(replacements);
47}
48
ricea433bdab2015-01-26 07:25:3749// An implementation of WebSocketEventInterface that waits for and records the
50// results of the connect.
51class ConnectTestingEventInterface : public WebSocketEventInterface {
52 public:
53 ConnectTestingEventInterface();
54
55 void WaitForResponse();
56
57 bool failed() const { return failed_; }
58
59 // Only set if the handshake failed, otherwise empty.
60 std::string failure_message() const;
61
62 std::string selected_subprotocol() const;
63
64 std::string extensions() const;
65
66 // Implementation of WebSocketEventInterface.
tyoshinoc06da562015-03-06 06:02:4267 ChannelState OnAddChannelResponse(const std::string& selected_subprotocol,
ricea433bdab2015-01-26 07:25:3768 const std::string& extensions) override;
69
70 ChannelState OnDataFrame(bool fin,
71 WebSocketMessageType type,
72 const std::vector<char>& data) override;
73
tfarina8a2c66c22015-10-13 19:14:4974 ChannelState OnFlowControl(int64_t quota) override;
ricea433bdab2015-01-26 07:25:3775
76 ChannelState OnClosingHandshake() override;
77
78 ChannelState OnDropChannel(bool was_clean,
tfarina8a2c66c22015-10-13 19:14:4979 uint16_t code,
ricea433bdab2015-01-26 07:25:3780 const std::string& reason) override;
81
82 ChannelState OnFailChannel(const std::string& message) override;
83
84 ChannelState OnStartOpeningHandshake(
85 scoped_ptr<WebSocketHandshakeRequestInfo> request) override;
86
87 ChannelState OnFinishOpeningHandshake(
88 scoped_ptr<WebSocketHandshakeResponseInfo> response) override;
89
90 ChannelState OnSSLCertificateError(
91 scoped_ptr<SSLErrorCallbacks> ssl_error_callbacks,
92 const GURL& url,
93 const SSLInfo& ssl_info,
94 bool fatal) override;
95
96 private:
97 void QuitNestedEventLoop();
98
99 // failed_ is true if the handshake failed (ie. OnFailChannel was called).
100 bool failed_;
101 std::string selected_subprotocol_;
102 std::string extensions_;
103 std::string failure_message_;
104 base::RunLoop run_loop_;
105
106 DISALLOW_COPY_AND_ASSIGN(ConnectTestingEventInterface);
107};
108
tyoshinoc06da562015-03-06 06:02:42109ConnectTestingEventInterface::ConnectTestingEventInterface() : failed_(false) {
ricea433bdab2015-01-26 07:25:37110}
111
112void ConnectTestingEventInterface::WaitForResponse() {
113 run_loop_.Run();
114}
115
116std::string ConnectTestingEventInterface::failure_message() const {
117 return failure_message_;
118}
119
120std::string ConnectTestingEventInterface::selected_subprotocol() const {
121 return selected_subprotocol_;
122}
123
124std::string ConnectTestingEventInterface::extensions() const {
125 return extensions_;
126}
127
128// Make the function definitions below less verbose.
129typedef ConnectTestingEventInterface::ChannelState ChannelState;
130
131ChannelState ConnectTestingEventInterface::OnAddChannelResponse(
ricea433bdab2015-01-26 07:25:37132 const std::string& selected_subprotocol,
133 const std::string& extensions) {
ricea433bdab2015-01-26 07:25:37134 selected_subprotocol_ = selected_subprotocol;
135 extensions_ = extensions;
136 QuitNestedEventLoop();
tyoshinoc06da562015-03-06 06:02:42137 return CHANNEL_ALIVE;
ricea433bdab2015-01-26 07:25:37138}
139
140ChannelState ConnectTestingEventInterface::OnDataFrame(
141 bool fin,
142 WebSocketMessageType type,
143 const std::vector<char>& data) {
144 return CHANNEL_ALIVE;
145}
146
tfarina8a2c66c22015-10-13 19:14:49147ChannelState ConnectTestingEventInterface::OnFlowControl(int64_t quota) {
ricea433bdab2015-01-26 07:25:37148 return CHANNEL_ALIVE;
149}
150
151ChannelState ConnectTestingEventInterface::OnClosingHandshake() {
152 return CHANNEL_ALIVE;
153}
154
155ChannelState ConnectTestingEventInterface::OnDropChannel(
156 bool was_clean,
tfarina8a2c66c22015-10-13 19:14:49157 uint16_t code,
ricea433bdab2015-01-26 07:25:37158 const std::string& reason) {
159 return CHANNEL_DELETED;
160}
161
162ChannelState ConnectTestingEventInterface::OnFailChannel(
163 const std::string& message) {
164 failed_ = true;
165 failure_message_ = message;
166 QuitNestedEventLoop();
167 return CHANNEL_DELETED;
168}
169
170ChannelState ConnectTestingEventInterface::OnStartOpeningHandshake(
171 scoped_ptr<WebSocketHandshakeRequestInfo> request) {
172 return CHANNEL_ALIVE;
173}
174
175ChannelState ConnectTestingEventInterface::OnFinishOpeningHandshake(
176 scoped_ptr<WebSocketHandshakeResponseInfo> response) {
177 return CHANNEL_ALIVE;
178}
179
180ChannelState ConnectTestingEventInterface::OnSSLCertificateError(
181 scoped_ptr<SSLErrorCallbacks> ssl_error_callbacks,
182 const GURL& url,
183 const SSLInfo& ssl_info,
184 bool fatal) {
skyostil4891b25b2015-06-11 11:43:45185 base::ThreadTaskRunnerHandle::Get()->PostTask(
ricea433bdab2015-01-26 07:25:37186 FROM_HERE, base::Bind(&SSLErrorCallbacks::CancelSSLRequest,
187 base::Owned(ssl_error_callbacks.release()),
188 ERR_SSL_PROTOCOL_ERROR, &ssl_info));
189 return CHANNEL_ALIVE;
190}
191
192void ConnectTestingEventInterface::QuitNestedEventLoop() {
193 run_loop_.Quit();
194}
195
196// A subclass of TestNetworkDelegate that additionally implements the
197// OnResolveProxy callback and records the information passed to it.
ryansturm7de050c2016-02-23 00:10:21198class TestProxyDelegateWithProxyInfo : public ProxyDelegate {
ricea433bdab2015-01-26 07:25:37199 public:
ryansturm7de050c2016-02-23 00:10:21200 TestProxyDelegateWithProxyInfo() {}
ricea433bdab2015-01-26 07:25:37201
202 struct ResolvedProxyInfo {
203 GURL url;
204 ProxyInfo proxy_info;
205 };
206
207 const ResolvedProxyInfo& resolved_proxy_info() const {
208 return resolved_proxy_info_;
209 }
210
211 protected:
212 void OnResolveProxy(const GURL& url,
213 int load_flags,
214 const ProxyService& proxy_service,
215 ProxyInfo* result) override {
216 resolved_proxy_info_.url = url;
217 resolved_proxy_info_.proxy_info = *result;
218 }
219
ryansturm7de050c2016-02-23 00:10:21220 void OnTunnelConnectCompleted(const HostPortPair& endpoint,
221 const HostPortPair& proxy_server,
222 int net_error) override {}
223 void OnFallback(const ProxyServer& bad_proxy, int net_error) override {}
224 void OnBeforeSendHeaders(URLRequest* request,
225 const ProxyInfo& proxy_info,
226 HttpRequestHeaders* headers) override {}
227 void OnBeforeTunnelRequest(const HostPortPair& proxy_server,
228 HttpRequestHeaders* extra_headers) override {}
229 void OnTunnelHeadersReceived(
230 const HostPortPair& origin,
231 const HostPortPair& proxy_server,
232 const HttpResponseHeaders& response_headers) override {}
233 bool IsTrustedSpdyProxy(const net::ProxyServer& proxy_server) override {
234 return true;
235 }
236
ricea433bdab2015-01-26 07:25:37237 private:
238 ResolvedProxyInfo resolved_proxy_info_;
239
ryansturm7de050c2016-02-23 00:10:21240 DISALLOW_COPY_AND_ASSIGN(TestProxyDelegateWithProxyInfo);
ricea433bdab2015-01-26 07:25:37241};
242
243class WebSocketEndToEndTest : public ::testing::Test {
244 protected:
245 WebSocketEndToEndTest()
Adam Ricecb76ac62015-02-20 05:33:25246 : event_interface_(),
ryansturm7de050c2016-02-23 00:10:21247 proxy_delegate_(new TestProxyDelegateWithProxyInfo),
ricea433bdab2015-01-26 07:25:37248 context_(true),
Adam Ricecb76ac62015-02-20 05:33:25249 channel_(),
ricea433bdab2015-01-26 07:25:37250 initialised_context_(false) {}
251
252 // Initialise the URLRequestContext. Normally done automatically by
253 // ConnectAndWait(). This method is for the use of tests that need the
254 // URLRequestContext initialised before calling ConnectAndWait().
255 void InitialiseContext() {
ryansturm7de050c2016-02-23 00:10:21256 context_.set_proxy_delegate(proxy_delegate_.get());
ricea433bdab2015-01-26 07:25:37257 context_.Init();
258 initialised_context_ = true;
259 }
260
261 // Send the connect request to |socket_url| and wait for a response. Returns
262 // true if the handshake succeeded.
263 bool ConnectAndWait(const GURL& socket_url) {
264 if (!initialised_context_) {
265 InitialiseContext();
266 }
mkwst4997ce82015-07-25 12:00:05267 url::Origin origin(GURL("http://localhost"));
Adam Ricecb76ac62015-02-20 05:33:25268 event_interface_ = new ConnectTestingEventInterface;
269 channel_.reset(
270 new WebSocketChannel(make_scoped_ptr(event_interface_), &context_));
ricea5acb1faf72015-03-16 15:34:00271 channel_->SendAddChannelRequest(GURL(socket_url), sub_protocols_, origin);
ricea433bdab2015-01-26 07:25:37272 event_interface_->WaitForResponse();
273 return !event_interface_->failed();
274 }
275
276 ConnectTestingEventInterface* event_interface_; // owned by channel_
ryansturm7de050c2016-02-23 00:10:21277 scoped_ptr<TestProxyDelegateWithProxyInfo> proxy_delegate_;
ricea433bdab2015-01-26 07:25:37278 TestURLRequestContext context_;
Adam Ricecb76ac62015-02-20 05:33:25279 scoped_ptr<WebSocketChannel> channel_;
ricea5acb1faf72015-03-16 15:34:00280 std::vector<std::string> sub_protocols_;
ricea433bdab2015-01-26 07:25:37281 bool initialised_context_;
282};
283
284// None of these tests work on Android.
285// TODO(ricea): Make these tests work on Android. See crbug.com/441711.
286#if defined(OS_ANDROID)
287#define DISABLED_ON_ANDROID(test) DISABLED_##test
288#else
289#define DISABLED_ON_ANDROID(test) test
290#endif
291
292// Basic test of connectivity. If this test fails, nothing else can be expected
293// to work.
294TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(BasicSmokeTest)) {
295 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
296 SpawnedTestServer::kLocalhost,
297 GetWebSocketTestDataDirectory());
298 ASSERT_TRUE(ws_server.Start());
299 EXPECT_TRUE(ConnectAndWait(ws_server.GetURL(kEchoServer)));
300}
301
302// Test for issue crbug.com/433695 "Unencrypted WebSocket connection via
303// authenticated proxy times out"
304// TODO(ricea): Enable this when the issue is fixed.
305TEST_F(WebSocketEndToEndTest, DISABLED_HttpsProxyUnauthedFails) {
306 SpawnedTestServer proxy_server(SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
307 SpawnedTestServer::kLocalhost,
308 base::FilePath());
309 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
310 SpawnedTestServer::kLocalhost,
311 GetWebSocketTestDataDirectory());
312 ASSERT_TRUE(proxy_server.StartInBackground());
313 ASSERT_TRUE(ws_server.StartInBackground());
314 ASSERT_TRUE(proxy_server.BlockUntilStarted());
315 ASSERT_TRUE(ws_server.BlockUntilStarted());
316 std::string proxy_config =
317 "https=" + proxy_server.host_port_pair().ToString();
318 scoped_ptr<ProxyService> proxy_service(
319 ProxyService::CreateFixed(proxy_config));
320 ASSERT_TRUE(proxy_service);
321 context_.set_proxy_service(proxy_service.get());
322 EXPECT_FALSE(ConnectAndWait(ws_server.GetURL(kEchoServer)));
323 EXPECT_EQ("Proxy authentication failed", event_interface_->failure_message());
324}
325
326TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HttpsWssProxyUnauthedFails)) {
327 SpawnedTestServer proxy_server(SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
328 SpawnedTestServer::kLocalhost,
329 base::FilePath());
330 SpawnedTestServer wss_server(SpawnedTestServer::TYPE_WSS,
331 SpawnedTestServer::kLocalhost,
332 GetWebSocketTestDataDirectory());
333 ASSERT_TRUE(proxy_server.StartInBackground());
334 ASSERT_TRUE(wss_server.StartInBackground());
335 ASSERT_TRUE(proxy_server.BlockUntilStarted());
336 ASSERT_TRUE(wss_server.BlockUntilStarted());
337 std::string proxy_config =
338 "https=" + proxy_server.host_port_pair().ToString();
339 scoped_ptr<ProxyService> proxy_service(
340 ProxyService::CreateFixed(proxy_config));
341 ASSERT_TRUE(proxy_service);
342 context_.set_proxy_service(proxy_service.get());
343 EXPECT_FALSE(ConnectAndWait(wss_server.GetURL(kEchoServer)));
344 EXPECT_EQ("Proxy authentication failed", event_interface_->failure_message());
345}
346
347// Regression test for crbug/426736 "WebSocket connections not using configured
348// system HTTPS Proxy".
349TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HttpsProxyUsed)) {
350 SpawnedTestServer proxy_server(SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
351 SpawnedTestServer::kLocalhost,
352 base::FilePath());
353 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
354 SpawnedTestServer::kLocalhost,
355 GetWebSocketTestDataDirectory());
356 ASSERT_TRUE(proxy_server.StartInBackground());
357 ASSERT_TRUE(ws_server.StartInBackground());
358 ASSERT_TRUE(proxy_server.BlockUntilStarted());
359 ASSERT_TRUE(ws_server.BlockUntilStarted());
360 std::string proxy_config = "https=" +
361 proxy_server.host_port_pair().ToString() + ";" +
362 "http=" + proxy_server.host_port_pair().ToString();
363 scoped_ptr<ProxyService> proxy_service(
364 ProxyService::CreateFixed(proxy_config));
365 context_.set_proxy_service(proxy_service.get());
366 InitialiseContext();
367
368 // The test server doesn't have an unauthenticated proxy mode. WebSockets
369 // cannot provide auth information that isn't already cached, so it's
370 // necessary to preflight an HTTP request to authenticate against the proxy.
ricea433bdab2015-01-26 07:25:37371 // It doesn't matter what the URL is, as long as it is an HTTP navigation.
372 GURL http_page =
Adam Ricecb76ac62015-02-20 05:33:25373 ReplaceUrlScheme(ws_server.GetURL("connect_check.html"), "http");
ricea433bdab2015-01-26 07:25:37374 TestDelegate delegate;
375 delegate.set_credentials(
376 AuthCredentials(base::ASCIIToUTF16("foo"), base::ASCIIToUTF16("bar")));
377 {
378 scoped_ptr<URLRequest> request(
davidben151423e2015-03-23 18:48:36379 context_.CreateRequest(http_page, DEFAULT_PRIORITY, &delegate));
ricea433bdab2015-01-26 07:25:37380 request->Start();
381 // TestDelegate exits the message loop when the request completes by
382 // default.
383 base::RunLoop().Run();
384 EXPECT_TRUE(delegate.auth_required_called());
385 }
386
387 GURL ws_url = ws_server.GetURL(kEchoServer);
388 EXPECT_TRUE(ConnectAndWait(ws_url));
ryansturm7de050c2016-02-23 00:10:21389 const TestProxyDelegateWithProxyInfo::ResolvedProxyInfo& info =
390 proxy_delegate_->resolved_proxy_info();
ricea433bdab2015-01-26 07:25:37391 EXPECT_EQ(ws_url, info.url);
392 EXPECT_TRUE(info.proxy_info.is_http());
393}
394
ricea23c3f942015-02-02 13:35:13395// This is a regression test for crbug.com/408061 Crash in
396// net::WebSocketBasicHandshakeStream::Upgrade.
397TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(TruncatedResponse)) {
398 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
399 SpawnedTestServer::kLocalhost,
400 GetWebSocketTestDataDirectory());
401 ASSERT_TRUE(ws_server.Start());
402 InitialiseContext();
403
404 GURL ws_url = ws_server.GetURL("truncated-headers");
405 EXPECT_FALSE(ConnectAndWait(ws_url));
406}
407
Adam Ricecb76ac62015-02-20 05:33:25408// Regression test for crbug.com/455215 "HSTS not applied to WebSocket"
409TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HstsHttpsToWebSocket)) {
tommycli59a63432015-11-06 00:10:55410 EmbeddedTestServer https_server(net::EmbeddedTestServer::Type::TYPE_HTTPS);
411 https_server.SetSSLConfig(
412 net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
413 https_server.ServeFilesFromSourceDirectory("net/data/url_request_unittest");
414
estarka5da76702015-04-09 04:00:16415 SpawnedTestServer::SSLOptions ssl_options(
416 SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
Adam Ricecb76ac62015-02-20 05:33:25417 SpawnedTestServer wss_server(SpawnedTestServer::TYPE_WSS, ssl_options,
418 GetWebSocketTestDataDirectory());
estarka5da76702015-04-09 04:00:16419
tommycli59a63432015-11-06 00:10:55420 ASSERT_TRUE(https_server.Start());
421 ASSERT_TRUE(wss_server.Start());
Adam Ricecb76ac62015-02-20 05:33:25422 InitialiseContext();
423 // Set HSTS via https:
424 TestDelegate delegate;
tommycli59a63432015-11-06 00:10:55425 GURL https_page = https_server.GetURL("/hsts-headers.html");
Adam Ricecb76ac62015-02-20 05:33:25426 scoped_ptr<URLRequest> request(
davidben151423e2015-03-23 18:48:36427 context_.CreateRequest(https_page, DEFAULT_PRIORITY, &delegate));
Adam Ricecb76ac62015-02-20 05:33:25428 request->Start();
429 // TestDelegate exits the message loop when the request completes.
430 base::RunLoop().Run();
431 EXPECT_TRUE(request->status().is_success());
432
433 // Check HSTS with ws:
434 // Change the scheme from wss: to ws: to verify that it is switched back.
435 GURL ws_url = ReplaceUrlScheme(wss_server.GetURL(kEchoServer), "ws");
436 EXPECT_TRUE(ConnectAndWait(ws_url));
437}
438
439TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HstsWebSocketToHttps)) {
tommycli59a63432015-11-06 00:10:55440 EmbeddedTestServer https_server(net::EmbeddedTestServer::Type::TYPE_HTTPS);
441 https_server.SetSSLConfig(
442 net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
443 https_server.ServeFilesFromSourceDirectory("net/data/url_request_unittest");
444
estarka5da76702015-04-09 04:00:16445 SpawnedTestServer::SSLOptions ssl_options(
446 SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
Adam Ricecb76ac62015-02-20 05:33:25447 SpawnedTestServer wss_server(SpawnedTestServer::TYPE_WSS, ssl_options,
448 GetWebSocketTestDataDirectory());
tommycli59a63432015-11-06 00:10:55449 ASSERT_TRUE(https_server.Start());
450 ASSERT_TRUE(wss_server.Start());
Adam Ricecb76ac62015-02-20 05:33:25451 InitialiseContext();
452 // Set HSTS via wss:
453 GURL wss_url = wss_server.GetURL("set-hsts");
454 EXPECT_TRUE(ConnectAndWait(wss_url));
455
456 // Verify via http:
457 TestDelegate delegate;
458 GURL http_page =
tommycli59a63432015-11-06 00:10:55459 ReplaceUrlScheme(https_server.GetURL("/simple.html"), "http");
Adam Ricecb76ac62015-02-20 05:33:25460 scoped_ptr<URLRequest> request(
davidben151423e2015-03-23 18:48:36461 context_.CreateRequest(http_page, DEFAULT_PRIORITY, &delegate));
Adam Ricecb76ac62015-02-20 05:33:25462 request->Start();
463 // TestDelegate exits the message loop when the request completes.
464 base::RunLoop().Run();
465 EXPECT_TRUE(request->status().is_success());
466 EXPECT_TRUE(request->url().SchemeIs("https"));
467}
468
469TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HstsWebSocketToWebSocket)) {
estarka5da76702015-04-09 04:00:16470 SpawnedTestServer::SSLOptions ssl_options(
471 SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
Adam Ricecb76ac62015-02-20 05:33:25472 SpawnedTestServer wss_server(SpawnedTestServer::TYPE_WSS, ssl_options,
473 GetWebSocketTestDataDirectory());
474 ASSERT_TRUE(wss_server.Start());
475 InitialiseContext();
476 // Set HSTS via wss:
477 GURL wss_url = wss_server.GetURL("set-hsts");
478 EXPECT_TRUE(ConnectAndWait(wss_url));
479
480 // Verify via wss:
481 GURL ws_url = ReplaceUrlScheme(wss_server.GetURL(kEchoServer), "ws");
482 EXPECT_TRUE(ConnectAndWait(ws_url));
483}
484
ricea5acb1faf72015-03-16 15:34:00485// Regression test for crbug.com/180504 "WebSocket handshake fails when HTTP
486// headers have trailing LWS".
487TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(TrailingWhitespace)) {
488 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
489 SpawnedTestServer::kLocalhost,
490 GetWebSocketTestDataDirectory());
491 ASSERT_TRUE(ws_server.Start());
492
493 GURL ws_url = ws_server.GetURL("trailing-whitespace");
494 sub_protocols_.push_back("sip");
495 EXPECT_TRUE(ConnectAndWait(ws_url));
496 EXPECT_EQ("sip", event_interface_->selected_subprotocol());
497}
498
riceae1d67672015-03-19 10:10:17499// This is a regression test for crbug.com/169448 "WebSockets should support
500// header continuations"
501// TODO(ricea): HTTP continuation headers have been deprecated by RFC7230. If
502// support for continuation headers is removed from Chrome, then this test will
503// break and should be removed.
504TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HeaderContinuations)) {
505 SpawnedTestServer ws_server(SpawnedTestServer::TYPE_WS,
506 SpawnedTestServer::kLocalhost,
507 GetWebSocketTestDataDirectory());
508 ASSERT_TRUE(ws_server.Start());
509
510 GURL ws_url = ws_server.GetURL("header-continuation");
511
512 EXPECT_TRUE(ConnectAndWait(ws_url));
513 EXPECT_EQ("permessage-deflate; server_max_window_bits=10",
514 event_interface_->extensions());
515}
516
ricea433bdab2015-01-26 07:25:37517} // namespace
518
519} // namespace net