Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(418)

Side by Side Diff: net/websockets/websocket_stream_test.cc

Issue 869073002: Add WebSocket cookie tests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/websockets/websocket_stream.h" 5 #include "net/websockets/websocket_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 11 matching lines...) Expand all
22 #include "net/base/test_data_directory.h" 22 #include "net/base/test_data_directory.h"
23 #include "net/http/http_request_headers.h" 23 #include "net/http/http_request_headers.h"
24 #include "net/http/http_response_headers.h" 24 #include "net/http/http_response_headers.h"
25 #include "net/proxy/proxy_service.h" 25 #include "net/proxy/proxy_service.h"
26 #include "net/socket/client_socket_handle.h" 26 #include "net/socket/client_socket_handle.h"
27 #include "net/socket/socket_test_util.h" 27 #include "net/socket/socket_test_util.h"
28 #include "net/test/cert_test_util.h" 28 #include "net/test/cert_test_util.h"
29 #include "net/url_request/url_request_test_util.h" 29 #include "net/url_request/url_request_test_util.h"
30 #include "net/websockets/websocket_basic_handshake_stream.h" 30 #include "net/websockets/websocket_basic_handshake_stream.h"
31 #include "net/websockets/websocket_frame.h" 31 #include "net/websockets/websocket_frame.h"
32 #include "net/websockets/websocket_handshake_request_info.h" 32 #include "net/websockets/websocket_stream_create_test_base.h"
33 #include "net/websockets/websocket_handshake_response_info.h"
34 #include "net/websockets/websocket_handshake_stream_create_helper.h"
35 #include "net/websockets/websocket_test_util.h" 33 #include "net/websockets/websocket_test_util.h"
36 #include "testing/gtest/include/gtest/gtest.h" 34 #include "testing/gtest/include/gtest/gtest.h"
37 #include "url/gurl.h" 35 #include "url/gurl.h"
38 #include "url/origin.h" 36 #include "url/origin.h"
39 37
40 namespace net { 38 namespace net {
41 namespace { 39 namespace {
42 40
43 typedef std::pair<std::string, std::string> HeaderKeyValuePair;
44
45 std::vector<HeaderKeyValuePair> ToVector(const HttpRequestHeaders& headers) {
46 HttpRequestHeaders::Iterator it(headers);
47 std::vector<HeaderKeyValuePair> result;
48 while (it.GetNext())
49 result.push_back(HeaderKeyValuePair(it.name(), it.value()));
50 return result;
51 }
52
53 std::vector<HeaderKeyValuePair> ToVector(const HttpResponseHeaders& headers) {
54 void* iter = NULL;
55 std::string name, value;
56 std::vector<HeaderKeyValuePair> result;
57 while (headers.EnumerateHeaderLines(&iter, &name, &value))
58 result.push_back(HeaderKeyValuePair(name, value));
59 return result;
60 }
61
62 // Simple builder for a DeterministicSocketData object to save repetitive code. 41 // Simple builder for a DeterministicSocketData object to save repetitive code.
63 // It always sets the connect data to MockConnect(SYNCHRONOUS, OK), so it cannot 42 // It always sets the connect data to MockConnect(SYNCHRONOUS, OK), so it cannot
64 // be used in tests where the connect fails. In practice, those tests never have 43 // be used in tests where the connect fails. In practice, those tests never have
65 // any read/write data and so can't benefit from it anyway. The arrays are not 44 // any read/write data and so can't benefit from it anyway. The arrays are not
66 // copied. It is up to the caller to ensure they stay in scope until the test 45 // copied. It is up to the caller to ensure they stay in scope until the test
67 // ends. 46 // ends.
68 template <size_t reads_count, size_t writes_count> 47 template <size_t reads_count, size_t writes_count>
69 scoped_ptr<DeterministicSocketData> BuildSocketData( 48 scoped_ptr<DeterministicSocketData> BuildSocketData(
70 MockRead (&reads)[reads_count], 49 MockRead (&reads)[reads_count],
71 MockWrite (&writes)[writes_count]) { 50 MockWrite (&writes)[writes_count]) {
(...skipping 10 matching lines...) Expand all
82 return make_scoped_ptr(new DeterministicSocketData(NULL, 0, NULL, 0)); 61 return make_scoped_ptr(new DeterministicSocketData(NULL, 0, NULL, 0));
83 } 62 }
84 63
85 class MockWeakTimer : public base::MockTimer, 64 class MockWeakTimer : public base::MockTimer,
86 public base::SupportsWeakPtr<MockWeakTimer> { 65 public base::SupportsWeakPtr<MockWeakTimer> {
87 public: 66 public:
88 MockWeakTimer(bool retain_user_task, bool is_repeating) 67 MockWeakTimer(bool retain_user_task, bool is_repeating)
89 : MockTimer(retain_user_task, is_repeating) {} 68 : MockTimer(retain_user_task, is_repeating) {}
90 }; 69 };
91 70
92 // A sub-class of WebSocketHandshakeStreamCreateHelper which always sets a 71 class WebSocketStreamCreateTest : public ::testing::Test,
93 // deterministic key to use in the WebSocket handshake. 72 public WebSocketStreamCreateTestBase {
94 class DeterministicKeyWebSocketHandshakeStreamCreateHelper
95 : public WebSocketHandshakeStreamCreateHelper {
96 public: 73 public:
97 DeterministicKeyWebSocketHandshakeStreamCreateHelper(
98 WebSocketStream::ConnectDelegate* connect_delegate,
99 const std::vector<std::string>& requested_subprotocols)
100 : WebSocketHandshakeStreamCreateHelper(connect_delegate,
101 requested_subprotocols) {}
102
103 void OnStreamCreated(WebSocketBasicHandshakeStream* stream) override {
104 stream->SetWebSocketKeyForTesting("dGhlIHNhbXBsZSBub25jZQ==");
105 }
106 };
107
108 class WebSocketStreamCreateTest : public ::testing::Test {
109 public:
110 WebSocketStreamCreateTest() : has_failed_(false), ssl_fatal_(false) {}
111 ~WebSocketStreamCreateTest() override { 74 ~WebSocketStreamCreateTest() override {
112 // Permit any endpoint locks to be released. 75 // Permit any endpoint locks to be released.
113 stream_request_.reset(); 76 stream_request_.reset();
114 stream_.reset(); 77 stream_.reset();
115 RunUntilIdle(); 78 base::RunLoop().RunUntilIdle();
116 } 79 }
117 80
118 void CreateAndConnectCustomResponse( 81 void CreateAndConnectCustomResponse(
119 const std::string& socket_url, 82 const std::string& socket_url,
120 const std::string& socket_host, 83 const std::string& socket_host,
121 const std::string& socket_path, 84 const std::string& socket_path,
122 const std::vector<std::string>& sub_protocols, 85 const std::vector<std::string>& sub_protocols,
123 const std::string& origin, 86 const std::string& origin,
124 const std::string& extra_request_headers, 87 const std::string& extra_request_headers,
125 const std::string& response_body, 88 const std::string& response_body,
(...skipping 29 matching lines...) Expand all
155 scoped_ptr<DeterministicSocketData> socket_data, 118 scoped_ptr<DeterministicSocketData> socket_data,
156 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { 119 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) {
157 AddRawExpectations(socket_data.Pass()); 120 AddRawExpectations(socket_data.Pass());
158 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); 121 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass());
159 } 122 }
160 123
161 // Add additional raw expectations for sockets created before the final one. 124 // Add additional raw expectations for sockets created before the final one.
162 void AddRawExpectations(scoped_ptr<DeterministicSocketData> socket_data) { 125 void AddRawExpectations(scoped_ptr<DeterministicSocketData> socket_data) {
163 url_request_context_host_.AddRawExpectations(socket_data.Pass()); 126 url_request_context_host_.AddRawExpectations(socket_data.Pass());
164 } 127 }
165
166 // A wrapper for CreateAndConnectStreamForTesting that knows about our default
167 // parameters.
168 void CreateAndConnectStream(const std::string& socket_url,
169 const std::vector<std::string>& sub_protocols,
170 const std::string& origin,
171 scoped_ptr<base::Timer> timer) {
172 for (size_t i = 0; i < ssl_data_.size(); ++i) {
173 scoped_ptr<SSLSocketDataProvider> ssl_data(ssl_data_[i]);
174 ssl_data_[i] = NULL;
175 url_request_context_host_.AddSSLSocketDataProvider(ssl_data.Pass());
176 }
177 ssl_data_.clear();
178 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate(
179 new TestConnectDelegate(this));
180 WebSocketStream::ConnectDelegate* delegate = connect_delegate.get();
181 scoped_ptr<WebSocketHandshakeStreamCreateHelper> create_helper(
182 new DeterministicKeyWebSocketHandshakeStreamCreateHelper(
183 delegate, sub_protocols));
184 stream_request_ = ::net::CreateAndConnectStreamForTesting(
185 GURL(socket_url),
186 create_helper.Pass(),
187 url::Origin(origin),
188 url_request_context_host_.GetURLRequestContext(),
189 BoundNetLog(),
190 connect_delegate.Pass(),
191 timer ? timer.Pass() : scoped_ptr<base::Timer>(
192 new base::Timer(false, false)));
193 }
194
195 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
196
197 // A simple function to make the tests more readable. Creates an empty vector.
198 static std::vector<std::string> NoSubProtocols() {
199 return std::vector<std::string>();
200 }
201
202 const std::string& failure_message() const { return failure_message_; }
203 bool has_failed() const { return has_failed_; }
204
205 class TestConnectDelegate : public WebSocketStream::ConnectDelegate {
206 public:
207 explicit TestConnectDelegate(WebSocketStreamCreateTest* owner)
208 : owner_(owner) {}
209
210 void OnSuccess(scoped_ptr<WebSocketStream> stream) override {
211 stream.swap(owner_->stream_);
212 }
213
214 void OnFailure(const std::string& message) override {
215 owner_->has_failed_ = true;
216 owner_->failure_message_ = message;
217 }
218
219 void OnStartOpeningHandshake(
220 scoped_ptr<WebSocketHandshakeRequestInfo> request) override {
221 // Can be called multiple times (in the case of HTTP auth). Last call
222 // wins.
223 owner_->request_info_ = request.Pass();
224 }
225 void OnFinishOpeningHandshake(
226 scoped_ptr<WebSocketHandshakeResponseInfo> response) override {
227 if (owner_->response_info_)
228 ADD_FAILURE();
229 owner_->response_info_ = response.Pass();
230 }
231 void OnSSLCertificateError(
232 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks>
233 ssl_error_callbacks,
234 const SSLInfo& ssl_info,
235 bool fatal) override {
236 owner_->ssl_error_callbacks_ = ssl_error_callbacks.Pass();
237 owner_->ssl_info_ = ssl_info;
238 owner_->ssl_fatal_ = fatal;
239 }
240
241 private:
242 WebSocketStreamCreateTest* owner_;
243 };
244
245 WebSocketTestURLRequestContextHost url_request_context_host_;
246 scoped_ptr<WebSocketStreamRequest> stream_request_;
247 // Only set if the connection succeeded.
248 scoped_ptr<WebSocketStream> stream_;
249 // Only set if the connection failed.
250 std::string failure_message_;
251 bool has_failed_;
252 scoped_ptr<WebSocketHandshakeRequestInfo> request_info_;
253 scoped_ptr<WebSocketHandshakeResponseInfo> response_info_;
254 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> ssl_error_callbacks_;
255 SSLInfo ssl_info_;
256 bool ssl_fatal_;
257 ScopedVector<SSLSocketDataProvider> ssl_data_;
258 ScopedWebSocketEndpointZeroUnlockDelay zero_unlock_delay_;
259 }; 128 };
260 129
261 // There are enough tests of the Sec-WebSocket-Extensions header that they 130 // There are enough tests of the Sec-WebSocket-Extensions header that they
262 // deserve their own test fixture. 131 // deserve their own test fixture.
263 class WebSocketStreamCreateExtensionTest : public WebSocketStreamCreateTest { 132 class WebSocketStreamCreateExtensionTest : public WebSocketStreamCreateTest {
264 public: 133 public:
265 // Performs a standard connect, with the value of the Sec-WebSocket-Extensions 134 // Performs a standard connect, with the value of the Sec-WebSocket-Extensions
266 // header in the response set to |extensions_header_value|. Runs the event 135 // header in the response set to |extensions_header_value|. Runs the event
267 // loop to allow the connect to complete. 136 // loop to allow the connect to complete.
268 void CreateAndConnectWithExtensions( 137 void CreateAndConnectWithExtensions(
269 const std::string& extensions_header_value) { 138 const std::string& extensions_header_value) {
270 CreateAndConnectStandard( 139 CreateAndConnectStandard(
271 "ws://localhost/testing_path", "localhost", "/testing_path", 140 "ws://localhost/testing_path", "localhost", "/testing_path",
272 NoSubProtocols(), "http://localhost", "", 141 NoSubProtocols(), "http://localhost", "",
273 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); 142 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n");
274 RunUntilIdle(); 143 WaitUntilConnectDone();
275 } 144 }
276 }; 145 };
277 146
278 // Common code to construct expectations for authentication tests that receive 147 // Common code to construct expectations for authentication tests that receive
279 // the auth challenge on one connection and then create a second connection to 148 // the auth challenge on one connection and then create a second connection to
280 // send the authenticated request on. 149 // send the authenticated request on.
281 class CommonAuthTestHelper { 150 class CommonAuthTestHelper {
282 public: 151 public:
283 CommonAuthTestHelper() : reads1_(), writes1_(), reads2_(), writes2_() {} 152 CommonAuthTestHelper() : reads1_(), writes1_(), reads2_(), writes2_() {}
284 153
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 : scoped_ptr<base::HistogramSamples>(); 292 : scoped_ptr<base::HistogramSamples>();
424 } 293 }
425 }; 294 };
426 295
427 // Confirm that the basic case works as expected. 296 // Confirm that the basic case works as expected.
428 TEST_F(WebSocketStreamCreateTest, SimpleSuccess) { 297 TEST_F(WebSocketStreamCreateTest, SimpleSuccess) {
429 CreateAndConnectStandard("ws://localhost/", "localhost", "/", 298 CreateAndConnectStandard("ws://localhost/", "localhost", "/",
430 NoSubProtocols(), "http://localhost", "", ""); 299 NoSubProtocols(), "http://localhost", "", "");
431 EXPECT_FALSE(request_info_); 300 EXPECT_FALSE(request_info_);
432 EXPECT_FALSE(response_info_); 301 EXPECT_FALSE(response_info_);
433 RunUntilIdle(); 302 WaitUntilConnectDone();
434 EXPECT_FALSE(has_failed()); 303 EXPECT_FALSE(has_failed());
435 EXPECT_TRUE(stream_); 304 EXPECT_TRUE(stream_);
436 EXPECT_TRUE(request_info_); 305 EXPECT_TRUE(request_info_);
437 EXPECT_TRUE(response_info_); 306 EXPECT_TRUE(response_info_);
438 } 307 }
439 308
440 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) { 309 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) {
441 static const char kResponse[] = 310 static const char kResponse[] =
442 "HTTP/1.1 101 Switching Protocols\r\n" 311 "HTTP/1.1 101 Switching Protocols\r\n"
443 "Upgrade: websocket\r\n" 312 "Upgrade: websocket\r\n"
444 "Connection: Upgrade\r\n" 313 "Connection: Upgrade\r\n"
445 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 314 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
446 "foo: bar, baz\r\n" 315 "foo: bar, baz\r\n"
447 "hoge: fuga\r\n" 316 "hoge: fuga\r\n"
448 "hoge: piyo\r\n" 317 "hoge: piyo\r\n"
449 "\r\n"; 318 "\r\n";
450 319
451 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", 320 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
452 NoSubProtocols(), "http://localhost", "", 321 NoSubProtocols(), "http://localhost", "",
453 kResponse); 322 kResponse);
454 EXPECT_FALSE(request_info_); 323 EXPECT_FALSE(request_info_);
455 EXPECT_FALSE(response_info_); 324 EXPECT_FALSE(response_info_);
456 RunUntilIdle(); 325 WaitUntilConnectDone();
457 EXPECT_TRUE(stream_); 326 EXPECT_TRUE(stream_);
458 ASSERT_TRUE(request_info_); 327 ASSERT_TRUE(request_info_);
459 ASSERT_TRUE(response_info_); 328 ASSERT_TRUE(response_info_);
460 std::vector<HeaderKeyValuePair> request_headers = 329 std::vector<HeaderKeyValuePair> request_headers =
461 ToVector(request_info_->headers); 330 RequestHeadersToVector(request_info_->headers);
462 // We examine the contents of request_info_ and response_info_ 331 // We examine the contents of request_info_ and response_info_
463 // mainly only in this test case. 332 // mainly only in this test case.
464 EXPECT_EQ(GURL("ws://localhost/"), request_info_->url); 333 EXPECT_EQ(GURL("ws://localhost/"), request_info_->url);
465 EXPECT_EQ(GURL("ws://localhost/"), response_info_->url); 334 EXPECT_EQ(GURL("ws://localhost/"), response_info_->url);
466 EXPECT_EQ(101, response_info_->status_code); 335 EXPECT_EQ(101, response_info_->status_code);
467 EXPECT_EQ("Switching Protocols", response_info_->status_text); 336 EXPECT_EQ("Switching Protocols", response_info_->status_text);
468 ASSERT_EQ(12u, request_headers.size()); 337 ASSERT_EQ(12u, request_headers.size());
469 EXPECT_EQ(HeaderKeyValuePair("Host", "localhost"), request_headers[0]); 338 EXPECT_EQ(HeaderKeyValuePair("Host", "localhost"), request_headers[0]);
470 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), request_headers[1]); 339 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), request_headers[1]);
471 EXPECT_EQ(HeaderKeyValuePair("Pragma", "no-cache"), request_headers[2]); 340 EXPECT_EQ(HeaderKeyValuePair("Pragma", "no-cache"), request_headers[2]);
472 EXPECT_EQ(HeaderKeyValuePair("Cache-Control", "no-cache"), 341 EXPECT_EQ(HeaderKeyValuePair("Cache-Control", "no-cache"),
473 request_headers[3]); 342 request_headers[3]);
474 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), request_headers[4]); 343 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), request_headers[4]);
475 EXPECT_EQ(HeaderKeyValuePair("Origin", "http://localhost"), 344 EXPECT_EQ(HeaderKeyValuePair("Origin", "http://localhost"),
476 request_headers[5]); 345 request_headers[5]);
477 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Version", "13"), 346 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Version", "13"),
478 request_headers[6]); 347 request_headers[6]);
479 EXPECT_EQ(HeaderKeyValuePair("User-Agent", ""), request_headers[7]); 348 EXPECT_EQ(HeaderKeyValuePair("User-Agent", ""), request_headers[7]);
480 EXPECT_EQ(HeaderKeyValuePair("Accept-Encoding", "gzip, deflate"), 349 EXPECT_EQ(HeaderKeyValuePair("Accept-Encoding", "gzip, deflate"),
481 request_headers[8]); 350 request_headers[8]);
482 EXPECT_EQ(HeaderKeyValuePair("Accept-Language", "en-us,fr"), 351 EXPECT_EQ(HeaderKeyValuePair("Accept-Language", "en-us,fr"),
483 request_headers[9]); 352 request_headers[9]);
484 EXPECT_EQ("Sec-WebSocket-Key", request_headers[10].first); 353 EXPECT_EQ("Sec-WebSocket-Key", request_headers[10].first);
485 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Extensions", 354 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Extensions",
486 "permessage-deflate; client_max_window_bits"), 355 "permessage-deflate; client_max_window_bits"),
487 request_headers[11]); 356 request_headers[11]);
488 357
489 std::vector<HeaderKeyValuePair> response_headers = 358 std::vector<HeaderKeyValuePair> response_headers =
490 ToVector(*response_info_->headers.get()); 359 ResponseHeadersToVector(*response_info_->headers.get());
491 ASSERT_EQ(6u, response_headers.size()); 360 ASSERT_EQ(6u, response_headers.size());
492 // Sort the headers for ease of verification. 361 // Sort the headers for ease of verification.
493 std::sort(response_headers.begin(), response_headers.end()); 362 std::sort(response_headers.begin(), response_headers.end());
494 363
495 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), response_headers[0]); 364 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), response_headers[0]);
496 EXPECT_EQ("Sec-WebSocket-Accept", response_headers[1].first); 365 EXPECT_EQ("Sec-WebSocket-Accept", response_headers[1].first);
497 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), response_headers[2]); 366 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), response_headers[2]);
498 EXPECT_EQ(HeaderKeyValuePair("foo", "bar, baz"), response_headers[3]); 367 EXPECT_EQ(HeaderKeyValuePair("foo", "bar, baz"), response_headers[3]);
499 EXPECT_EQ(HeaderKeyValuePair("hoge", "fuga"), response_headers[4]); 368 EXPECT_EQ(HeaderKeyValuePair("hoge", "fuga"), response_headers[4]);
500 EXPECT_EQ(HeaderKeyValuePair("hoge", "piyo"), response_headers[5]); 369 EXPECT_EQ(HeaderKeyValuePair("hoge", "piyo"), response_headers[5]);
501 } 370 }
502 371
503 // Confirm that the stream isn't established until the message loop runs. 372 // Confirm that the stream isn't established until the message loop runs.
504 TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) { 373 TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) {
505 CreateAndConnectStandard("ws://localhost/", "localhost", "/", 374 CreateAndConnectStandard("ws://localhost/", "localhost", "/",
506 NoSubProtocols(), "http://localhost", "", ""); 375 NoSubProtocols(), "http://localhost", "", "");
507 EXPECT_FALSE(has_failed()); 376 EXPECT_FALSE(has_failed());
508 EXPECT_FALSE(stream_); 377 EXPECT_FALSE(stream_);
509 } 378 }
510 379
511 // Check the path is used. 380 // Check the path is used.
512 TEST_F(WebSocketStreamCreateTest, PathIsUsed) { 381 TEST_F(WebSocketStreamCreateTest, PathIsUsed) {
513 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", 382 CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
514 "/testing_path", NoSubProtocols(), 383 "/testing_path", NoSubProtocols(),
515 "http://localhost", "", ""); 384 "http://localhost", "", "");
516 RunUntilIdle(); 385 WaitUntilConnectDone();
517 EXPECT_FALSE(has_failed()); 386 EXPECT_FALSE(has_failed());
518 EXPECT_TRUE(stream_); 387 EXPECT_TRUE(stream_);
519 } 388 }
520 389
521 // Check that the origin is used. 390 // Check that the origin is used.
522 TEST_F(WebSocketStreamCreateTest, OriginIsUsed) { 391 TEST_F(WebSocketStreamCreateTest, OriginIsUsed) {
523 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", 392 CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
524 "/testing_path", NoSubProtocols(), 393 "/testing_path", NoSubProtocols(),
525 "http://google.com", "", ""); 394 "http://google.com", "", "");
526 RunUntilIdle(); 395 WaitUntilConnectDone();
527 EXPECT_FALSE(has_failed()); 396 EXPECT_FALSE(has_failed());
528 EXPECT_TRUE(stream_); 397 EXPECT_TRUE(stream_);
529 } 398 }
530 399
531 // Check that sub-protocols are sent and parsed. 400 // Check that sub-protocols are sent and parsed.
532 TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) { 401 TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) {
533 std::vector<std::string> sub_protocols; 402 std::vector<std::string> sub_protocols;
534 sub_protocols.push_back("chatv11.chromium.org"); 403 sub_protocols.push_back("chatv11.chromium.org");
535 sub_protocols.push_back("chatv20.chromium.org"); 404 sub_protocols.push_back("chatv20.chromium.org");
536 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", 405 CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
537 "/testing_path", sub_protocols, "http://google.com", 406 "/testing_path", sub_protocols, "http://google.com",
538 "Sec-WebSocket-Protocol: chatv11.chromium.org, " 407 "Sec-WebSocket-Protocol: chatv11.chromium.org, "
539 "chatv20.chromium.org\r\n", 408 "chatv20.chromium.org\r\n",
540 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); 409 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n");
541 RunUntilIdle(); 410 WaitUntilConnectDone();
542 EXPECT_TRUE(stream_); 411 EXPECT_TRUE(stream_);
543 EXPECT_FALSE(has_failed()); 412 EXPECT_FALSE(has_failed());
544 EXPECT_EQ("chatv20.chromium.org", stream_->GetSubProtocol()); 413 EXPECT_EQ("chatv20.chromium.org", stream_->GetSubProtocol());
545 } 414 }
546 415
547 // Unsolicited sub-protocols are rejected. 416 // Unsolicited sub-protocols are rejected.
548 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { 417 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) {
549 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", 418 CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
550 "/testing_path", NoSubProtocols(), 419 "/testing_path", NoSubProtocols(),
551 "http://google.com", "", 420 "http://google.com", "",
552 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); 421 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n");
553 RunUntilIdle(); 422 WaitUntilConnectDone();
554 EXPECT_FALSE(stream_); 423 EXPECT_FALSE(stream_);
555 EXPECT_TRUE(has_failed()); 424 EXPECT_TRUE(has_failed());
556 EXPECT_EQ("Error during WebSocket handshake: " 425 EXPECT_EQ("Error during WebSocket handshake: "
557 "Response must not include 'Sec-WebSocket-Protocol' header " 426 "Response must not include 'Sec-WebSocket-Protocol' header "
558 "if not present in request: chatv20.chromium.org", 427 "if not present in request: chatv20.chromium.org",
559 failure_message()); 428 failure_message());
560 } 429 }
561 430
562 // Missing sub-protocol response is rejected. 431 // Missing sub-protocol response is rejected.
563 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { 432 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) {
564 std::vector<std::string> sub_protocols; 433 std::vector<std::string> sub_protocols;
565 sub_protocols.push_back("chat.example.com"); 434 sub_protocols.push_back("chat.example.com");
566 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", 435 CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
567 "/testing_path", sub_protocols, "http://localhost", 436 "/testing_path", sub_protocols, "http://localhost",
568 "Sec-WebSocket-Protocol: chat.example.com\r\n", ""); 437 "Sec-WebSocket-Protocol: chat.example.com\r\n", "");
569 RunUntilIdle(); 438 WaitUntilConnectDone();
570 EXPECT_FALSE(stream_); 439 EXPECT_FALSE(stream_);
571 EXPECT_TRUE(has_failed()); 440 EXPECT_TRUE(has_failed());
572 EXPECT_EQ("Error during WebSocket handshake: " 441 EXPECT_EQ("Error during WebSocket handshake: "
573 "Sent non-empty 'Sec-WebSocket-Protocol' header " 442 "Sent non-empty 'Sec-WebSocket-Protocol' header "
574 "but no response was received", 443 "but no response was received",
575 failure_message()); 444 failure_message());
576 } 445 }
577 446
578 // Only one sub-protocol can be accepted. 447 // Only one sub-protocol can be accepted.
579 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { 448 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) {
580 std::vector<std::string> sub_protocols; 449 std::vector<std::string> sub_protocols;
581 sub_protocols.push_back("chatv11.chromium.org"); 450 sub_protocols.push_back("chatv11.chromium.org");
582 sub_protocols.push_back("chatv20.chromium.org"); 451 sub_protocols.push_back("chatv20.chromium.org");
583 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", 452 CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
584 "/testing_path", sub_protocols, "http://google.com", 453 "/testing_path", sub_protocols, "http://google.com",
585 "Sec-WebSocket-Protocol: chatv11.chromium.org, " 454 "Sec-WebSocket-Protocol: chatv11.chromium.org, "
586 "chatv20.chromium.org\r\n", 455 "chatv20.chromium.org\r\n",
587 "Sec-WebSocket-Protocol: chatv11.chromium.org, " 456 "Sec-WebSocket-Protocol: chatv11.chromium.org, "
588 "chatv20.chromium.org\r\n"); 457 "chatv20.chromium.org\r\n");
589 RunUntilIdle(); 458 WaitUntilConnectDone();
590 EXPECT_FALSE(stream_); 459 EXPECT_FALSE(stream_);
591 EXPECT_TRUE(has_failed()); 460 EXPECT_TRUE(has_failed());
592 EXPECT_EQ("Error during WebSocket handshake: " 461 EXPECT_EQ("Error during WebSocket handshake: "
593 "'Sec-WebSocket-Protocol' header must not appear " 462 "'Sec-WebSocket-Protocol' header must not appear "
594 "more than once in a response", 463 "more than once in a response",
595 failure_message()); 464 failure_message());
596 } 465 }
597 466
598 // Unmatched sub-protocol should be rejected. 467 // Unmatched sub-protocol should be rejected.
599 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { 468 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) {
600 std::vector<std::string> sub_protocols; 469 std::vector<std::string> sub_protocols;
601 sub_protocols.push_back("chatv11.chromium.org"); 470 sub_protocols.push_back("chatv11.chromium.org");
602 sub_protocols.push_back("chatv20.chromium.org"); 471 sub_protocols.push_back("chatv20.chromium.org");
603 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", 472 CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
604 "/testing_path", sub_protocols, "http://google.com", 473 "/testing_path", sub_protocols, "http://google.com",
605 "Sec-WebSocket-Protocol: chatv11.chromium.org, " 474 "Sec-WebSocket-Protocol: chatv11.chromium.org, "
606 "chatv20.chromium.org\r\n", 475 "chatv20.chromium.org\r\n",
607 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); 476 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n");
608 RunUntilIdle(); 477 WaitUntilConnectDone();
609 EXPECT_FALSE(stream_); 478 EXPECT_FALSE(stream_);
610 EXPECT_TRUE(has_failed()); 479 EXPECT_TRUE(has_failed());
611 EXPECT_EQ("Error during WebSocket handshake: " 480 EXPECT_EQ("Error during WebSocket handshake: "
612 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " 481 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' "
613 "in response does not match any of sent values", 482 "in response does not match any of sent values",
614 failure_message()); 483 failure_message());
615 } 484 }
616 485
617 // permessage-deflate extension basic success case. 486 // permessage-deflate extension basic success case.
618 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateSuccess) { 487 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateSuccess) {
(...skipping 17 matching lines...) Expand all
636 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) { 505 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) {
637 CreateAndConnectCustomResponse( 506 CreateAndConnectCustomResponse(
638 "ws://localhost/testing_path", "localhost", "/testing_path", 507 "ws://localhost/testing_path", "localhost", "/testing_path",
639 NoSubProtocols(), "http://localhost", "", 508 NoSubProtocols(), "http://localhost", "",
640 WebSocketStandardResponse( 509 WebSocketStandardResponse(
641 "Sec-WebSocket-Extensions: permessage-deflate\r\n") + 510 "Sec-WebSocket-Extensions: permessage-deflate\r\n") +
642 std::string( 511 std::string(
643 "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) 512 "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes)
644 "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed 513 "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed
645 9)); 514 9));
646 RunUntilIdle(); 515 WaitUntilConnectDone();
647 516
648 ASSERT_TRUE(stream_); 517 ASSERT_TRUE(stream_);
649 ScopedVector<WebSocketFrame> frames; 518 ScopedVector<WebSocketFrame> frames;
650 CompletionCallback callback; 519 CompletionCallback callback;
651 ASSERT_EQ(OK, stream_->ReadFrames(&frames, callback)); 520 ASSERT_EQ(OK, stream_->ReadFrames(&frames, callback));
652 ASSERT_EQ(1U, frames.size()); 521 ASSERT_EQ(1U, frames.size());
653 ASSERT_EQ(5U, frames[0]->header.payload_length); 522 ASSERT_EQ(5U, frames[0]->header.payload_length);
654 EXPECT_EQ("Hello", std::string(frames[0]->data->data(), 5)); 523 EXPECT_EQ("Hello", std::string(frames[0]->data->data(), 5));
655 } 524 }
656 525
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 682
814 // TODO(ricea): Check that WebSocketDeflateStream is initialised with the 683 // TODO(ricea): Check that WebSocketDeflateStream is initialised with the
815 // arguments from the server. This is difficult because the data written to the 684 // arguments from the server. This is difficult because the data written to the
816 // socket is randomly masked. 685 // socket is randomly masked.
817 686
818 // Additional Sec-WebSocket-Accept headers should be rejected. 687 // Additional Sec-WebSocket-Accept headers should be rejected.
819 TEST_F(WebSocketStreamCreateTest, DoubleAccept) { 688 TEST_F(WebSocketStreamCreateTest, DoubleAccept) {
820 CreateAndConnectStandard( 689 CreateAndConnectStandard(
821 "ws://localhost/", "localhost", "/", NoSubProtocols(), "http://localhost", 690 "ws://localhost/", "localhost", "/", NoSubProtocols(), "http://localhost",
822 "", "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); 691 "", "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n");
823 RunUntilIdle(); 692 WaitUntilConnectDone();
824 EXPECT_FALSE(stream_); 693 EXPECT_FALSE(stream_);
825 EXPECT_TRUE(has_failed()); 694 EXPECT_TRUE(has_failed());
826 EXPECT_EQ("Error during WebSocket handshake: " 695 EXPECT_EQ("Error during WebSocket handshake: "
827 "'Sec-WebSocket-Accept' header must not appear " 696 "'Sec-WebSocket-Accept' header must not appear "
828 "more than once in a response", 697 "more than once in a response",
829 failure_message()); 698 failure_message());
830 } 699 }
831 700
832 // Response code 200 must be rejected. 701 // Response code 200 must be rejected.
833 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { 702 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) {
834 static const char kInvalidStatusCodeResponse[] = 703 static const char kInvalidStatusCodeResponse[] =
835 "HTTP/1.1 200 OK\r\n" 704 "HTTP/1.1 200 OK\r\n"
836 "Upgrade: websocket\r\n" 705 "Upgrade: websocket\r\n"
837 "Connection: Upgrade\r\n" 706 "Connection: Upgrade\r\n"
838 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 707 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
839 "\r\n"; 708 "\r\n";
840 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", 709 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
841 NoSubProtocols(), "http://localhost", "", 710 NoSubProtocols(), "http://localhost", "",
842 kInvalidStatusCodeResponse); 711 kInvalidStatusCodeResponse);
843 RunUntilIdle(); 712 WaitUntilConnectDone();
844 EXPECT_TRUE(has_failed()); 713 EXPECT_TRUE(has_failed());
845 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", 714 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200",
846 failure_message()); 715 failure_message());
847 } 716 }
848 717
849 // Redirects are not followed (according to the WHATWG WebSocket API, which 718 // Redirects are not followed (according to the WHATWG WebSocket API, which
850 // overrides RFC6455 for browser applications). 719 // overrides RFC6455 for browser applications).
851 TEST_F(WebSocketStreamCreateTest, RedirectsRejected) { 720 TEST_F(WebSocketStreamCreateTest, RedirectsRejected) {
852 static const char kRedirectResponse[] = 721 static const char kRedirectResponse[] =
853 "HTTP/1.1 302 Moved Temporarily\r\n" 722 "HTTP/1.1 302 Moved Temporarily\r\n"
854 "Content-Type: text/html\r\n" 723 "Content-Type: text/html\r\n"
855 "Content-Length: 34\r\n" 724 "Content-Length: 34\r\n"
856 "Connection: keep-alive\r\n" 725 "Connection: keep-alive\r\n"
857 "Location: ws://localhost/other\r\n" 726 "Location: ws://localhost/other\r\n"
858 "\r\n" 727 "\r\n"
859 "<title>Moved</title><h1>Moved</h1>"; 728 "<title>Moved</title><h1>Moved</h1>";
860 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", 729 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
861 NoSubProtocols(), "http://localhost", "", 730 NoSubProtocols(), "http://localhost", "",
862 kRedirectResponse); 731 kRedirectResponse);
863 RunUntilIdle(); 732 WaitUntilConnectDone();
864 EXPECT_TRUE(has_failed()); 733 EXPECT_TRUE(has_failed());
865 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302", 734 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302",
866 failure_message()); 735 failure_message());
867 } 736 }
868 737
869 // Malformed responses should be rejected. HttpStreamParser will accept just 738 // Malformed responses should be rejected. HttpStreamParser will accept just
870 // about any garbage in the middle of the headers. To make it give up, the junk 739 // about any garbage in the middle of the headers. To make it give up, the junk
871 // has to be at the start of the response. Even then, it just gets treated as an 740 // has to be at the start of the response. Even then, it just gets treated as an
872 // HTTP/0.9 response. 741 // HTTP/0.9 response.
873 TEST_F(WebSocketStreamCreateTest, MalformedResponse) { 742 TEST_F(WebSocketStreamCreateTest, MalformedResponse) {
874 static const char kMalformedResponse[] = 743 static const char kMalformedResponse[] =
875 "220 mx.google.com ESMTP\r\n" 744 "220 mx.google.com ESMTP\r\n"
876 "HTTP/1.1 101 OK\r\n" 745 "HTTP/1.1 101 OK\r\n"
877 "Upgrade: websocket\r\n" 746 "Upgrade: websocket\r\n"
878 "Connection: Upgrade\r\n" 747 "Connection: Upgrade\r\n"
879 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 748 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
880 "\r\n"; 749 "\r\n";
881 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", 750 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
882 NoSubProtocols(), "http://localhost", "", 751 NoSubProtocols(), "http://localhost", "",
883 kMalformedResponse); 752 kMalformedResponse);
884 RunUntilIdle(); 753 WaitUntilConnectDone();
885 EXPECT_TRUE(has_failed()); 754 EXPECT_TRUE(has_failed());
886 EXPECT_EQ("Error during WebSocket handshake: Invalid status line", 755 EXPECT_EQ("Error during WebSocket handshake: Invalid status line",
887 failure_message()); 756 failure_message());
888 } 757 }
889 758
890 // Upgrade header must be present. 759 // Upgrade header must be present.
891 TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) { 760 TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) {
892 static const char kMissingUpgradeResponse[] = 761 static const char kMissingUpgradeResponse[] =
893 "HTTP/1.1 101 Switching Protocols\r\n" 762 "HTTP/1.1 101 Switching Protocols\r\n"
894 "Connection: Upgrade\r\n" 763 "Connection: Upgrade\r\n"
895 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 764 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
896 "\r\n"; 765 "\r\n";
897 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", 766 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
898 NoSubProtocols(), "http://localhost", "", 767 NoSubProtocols(), "http://localhost", "",
899 kMissingUpgradeResponse); 768 kMissingUpgradeResponse);
900 RunUntilIdle(); 769 WaitUntilConnectDone();
901 EXPECT_TRUE(has_failed()); 770 EXPECT_TRUE(has_failed());
902 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", 771 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing",
903 failure_message()); 772 failure_message());
904 } 773 }
905 774
906 // There must only be one upgrade header. 775 // There must only be one upgrade header.
907 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { 776 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) {
908 CreateAndConnectStandard("ws://localhost/", "localhost", "/", 777 CreateAndConnectStandard("ws://localhost/", "localhost", "/",
909 NoSubProtocols(), "http://localhost", "", 778 NoSubProtocols(), "http://localhost", "",
910 "Upgrade: HTTP/2.0\r\n"); 779 "Upgrade: HTTP/2.0\r\n");
911 RunUntilIdle(); 780 WaitUntilConnectDone();
912 EXPECT_TRUE(has_failed()); 781 EXPECT_TRUE(has_failed());
913 EXPECT_EQ("Error during WebSocket handshake: " 782 EXPECT_EQ("Error during WebSocket handshake: "
914 "'Upgrade' header must not appear more than once in a response", 783 "'Upgrade' header must not appear more than once in a response",
915 failure_message()); 784 failure_message());
916 } 785 }
917 786
918 // There must only be one correct upgrade header. 787 // There must only be one correct upgrade header.
919 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { 788 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) {
920 static const char kMissingUpgradeResponse[] = 789 static const char kMissingUpgradeResponse[] =
921 "HTTP/1.1 101 Switching Protocols\r\n" 790 "HTTP/1.1 101 Switching Protocols\r\n"
922 "Connection: Upgrade\r\n" 791 "Connection: Upgrade\r\n"
923 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 792 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
924 "Upgrade: hogefuga\r\n" 793 "Upgrade: hogefuga\r\n"
925 "\r\n"; 794 "\r\n";
926 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", 795 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
927 NoSubProtocols(), "http://localhost", "", 796 NoSubProtocols(), "http://localhost", "",
928 kMissingUpgradeResponse); 797 kMissingUpgradeResponse);
929 RunUntilIdle(); 798 WaitUntilConnectDone();
930 EXPECT_TRUE(has_failed()); 799 EXPECT_TRUE(has_failed());
931 EXPECT_EQ("Error during WebSocket handshake: " 800 EXPECT_EQ("Error during WebSocket handshake: "
932 "'Upgrade' header value is not 'WebSocket': hogefuga", 801 "'Upgrade' header value is not 'WebSocket': hogefuga",
933 failure_message()); 802 failure_message());
934 } 803 }
935 804
936 // Connection header must be present. 805 // Connection header must be present.
937 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { 806 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) {
938 static const char kMissingConnectionResponse[] = 807 static const char kMissingConnectionResponse[] =
939 "HTTP/1.1 101 Switching Protocols\r\n" 808 "HTTP/1.1 101 Switching Protocols\r\n"
940 "Upgrade: websocket\r\n" 809 "Upgrade: websocket\r\n"
941 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 810 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
942 "\r\n"; 811 "\r\n";
943 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", 812 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
944 NoSubProtocols(), "http://localhost", "", 813 NoSubProtocols(), "http://localhost", "",
945 kMissingConnectionResponse); 814 kMissingConnectionResponse);
946 RunUntilIdle(); 815 WaitUntilConnectDone();
947 EXPECT_TRUE(has_failed()); 816 EXPECT_TRUE(has_failed());
948 EXPECT_EQ("Error during WebSocket handshake: " 817 EXPECT_EQ("Error during WebSocket handshake: "
949 "'Connection' header is missing", 818 "'Connection' header is missing",
950 failure_message()); 819 failure_message());
951 } 820 }
952 821
953 // Connection header must contain "Upgrade". 822 // Connection header must contain "Upgrade".
954 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { 823 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) {
955 static const char kMissingConnectionResponse[] = 824 static const char kMissingConnectionResponse[] =
956 "HTTP/1.1 101 Switching Protocols\r\n" 825 "HTTP/1.1 101 Switching Protocols\r\n"
957 "Upgrade: websocket\r\n" 826 "Upgrade: websocket\r\n"
958 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 827 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
959 "Connection: hogefuga\r\n" 828 "Connection: hogefuga\r\n"
960 "\r\n"; 829 "\r\n";
961 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", 830 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
962 NoSubProtocols(), "http://localhost", "", 831 NoSubProtocols(), "http://localhost", "",
963 kMissingConnectionResponse); 832 kMissingConnectionResponse);
964 RunUntilIdle(); 833 WaitUntilConnectDone();
965 EXPECT_TRUE(has_failed()); 834 EXPECT_TRUE(has_failed());
966 EXPECT_EQ("Error during WebSocket handshake: " 835 EXPECT_EQ("Error during WebSocket handshake: "
967 "'Connection' header value must contain 'Upgrade'", 836 "'Connection' header value must contain 'Upgrade'",
968 failure_message()); 837 failure_message());
969 } 838 }
970 839
971 // Connection header is permitted to contain other tokens. 840 // Connection header is permitted to contain other tokens.
972 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { 841 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) {
973 static const char kAdditionalConnectionTokenResponse[] = 842 static const char kAdditionalConnectionTokenResponse[] =
974 "HTTP/1.1 101 Switching Protocols\r\n" 843 "HTTP/1.1 101 Switching Protocols\r\n"
975 "Upgrade: websocket\r\n" 844 "Upgrade: websocket\r\n"
976 "Connection: Upgrade, Keep-Alive\r\n" 845 "Connection: Upgrade, Keep-Alive\r\n"
977 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 846 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
978 "\r\n"; 847 "\r\n";
979 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", 848 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
980 NoSubProtocols(), "http://localhost", "", 849 NoSubProtocols(), "http://localhost", "",
981 kAdditionalConnectionTokenResponse); 850 kAdditionalConnectionTokenResponse);
982 RunUntilIdle(); 851 WaitUntilConnectDone();
983 EXPECT_FALSE(has_failed()); 852 EXPECT_FALSE(has_failed());
984 EXPECT_TRUE(stream_); 853 EXPECT_TRUE(stream_);
985 } 854 }
986 855
987 // Sec-WebSocket-Accept header must be present. 856 // Sec-WebSocket-Accept header must be present.
988 TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) { 857 TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) {
989 static const char kMissingAcceptResponse[] = 858 static const char kMissingAcceptResponse[] =
990 "HTTP/1.1 101 Switching Protocols\r\n" 859 "HTTP/1.1 101 Switching Protocols\r\n"
991 "Upgrade: websocket\r\n" 860 "Upgrade: websocket\r\n"
992 "Connection: Upgrade\r\n" 861 "Connection: Upgrade\r\n"
993 "\r\n"; 862 "\r\n";
994 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", 863 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
995 NoSubProtocols(), "http://localhost", "", 864 NoSubProtocols(), "http://localhost", "",
996 kMissingAcceptResponse); 865 kMissingAcceptResponse);
997 RunUntilIdle(); 866 WaitUntilConnectDone();
998 EXPECT_TRUE(has_failed()); 867 EXPECT_TRUE(has_failed());
999 EXPECT_EQ("Error during WebSocket handshake: " 868 EXPECT_EQ("Error during WebSocket handshake: "
1000 "'Sec-WebSocket-Accept' header is missing", 869 "'Sec-WebSocket-Accept' header is missing",
1001 failure_message()); 870 failure_message());
1002 } 871 }
1003 872
1004 // Sec-WebSocket-Accept header must match the key that was sent. 873 // Sec-WebSocket-Accept header must match the key that was sent.
1005 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { 874 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) {
1006 static const char kIncorrectAcceptResponse[] = 875 static const char kIncorrectAcceptResponse[] =
1007 "HTTP/1.1 101 Switching Protocols\r\n" 876 "HTTP/1.1 101 Switching Protocols\r\n"
1008 "Upgrade: websocket\r\n" 877 "Upgrade: websocket\r\n"
1009 "Connection: Upgrade\r\n" 878 "Connection: Upgrade\r\n"
1010 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" 879 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n"
1011 "\r\n"; 880 "\r\n";
1012 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", 881 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
1013 NoSubProtocols(), "http://localhost", "", 882 NoSubProtocols(), "http://localhost", "",
1014 kIncorrectAcceptResponse); 883 kIncorrectAcceptResponse);
1015 RunUntilIdle(); 884 WaitUntilConnectDone();
1016 EXPECT_TRUE(has_failed()); 885 EXPECT_TRUE(has_failed());
1017 EXPECT_EQ("Error during WebSocket handshake: " 886 EXPECT_EQ("Error during WebSocket handshake: "
1018 "Incorrect 'Sec-WebSocket-Accept' header value", 887 "Incorrect 'Sec-WebSocket-Accept' header value",
1019 failure_message()); 888 failure_message());
1020 } 889 }
1021 890
1022 // Cancellation works. 891 // Cancellation works.
1023 TEST_F(WebSocketStreamCreateTest, Cancellation) { 892 TEST_F(WebSocketStreamCreateTest, Cancellation) {
1024 CreateAndConnectStandard("ws://localhost/", "localhost", "/", 893 CreateAndConnectStandard("ws://localhost/", "localhost", "/",
1025 NoSubProtocols(), "http://localhost", "", ""); 894 NoSubProtocols(), "http://localhost", "", "");
1026 stream_request_.reset(); 895 stream_request_.reset();
1027 RunUntilIdle(); 896 // WaitUntilConnectDone doesn't work in this case.
897 base::RunLoop().RunUntilIdle();
1028 EXPECT_FALSE(has_failed()); 898 EXPECT_FALSE(has_failed());
1029 EXPECT_FALSE(stream_); 899 EXPECT_FALSE(stream_);
1030 EXPECT_FALSE(request_info_); 900 EXPECT_FALSE(request_info_);
1031 EXPECT_FALSE(response_info_); 901 EXPECT_FALSE(response_info_);
1032 } 902 }
1033 903
1034 // Connect failure must look just like negotiation failure. 904 // Connect failure must look just like negotiation failure.
1035 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { 905 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) {
1036 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); 906 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData());
1037 socket_data->set_connect_data( 907 socket_data->set_connect_data(
1038 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); 908 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1039 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), 909 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
1040 "http://localhost", socket_data.Pass()); 910 "http://localhost", socket_data.Pass());
1041 RunUntilIdle(); 911 WaitUntilConnectDone();
1042 EXPECT_TRUE(has_failed()); 912 EXPECT_TRUE(has_failed());
1043 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", 913 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED",
1044 failure_message()); 914 failure_message());
1045 EXPECT_FALSE(request_info_); 915 EXPECT_FALSE(request_info_);
1046 EXPECT_FALSE(response_info_); 916 EXPECT_FALSE(response_info_);
1047 } 917 }
1048 918
1049 // Connect timeout must look just like any other failure. 919 // Connect timeout must look just like any other failure.
1050 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { 920 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) {
1051 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); 921 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData());
1052 socket_data->set_connect_data( 922 socket_data->set_connect_data(
1053 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); 923 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT));
1054 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), 924 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
1055 "http://localhost", socket_data.Pass()); 925 "http://localhost", socket_data.Pass());
1056 RunUntilIdle(); 926 WaitUntilConnectDone();
1057 EXPECT_TRUE(has_failed()); 927 EXPECT_TRUE(has_failed());
1058 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", 928 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT",
1059 failure_message()); 929 failure_message());
1060 } 930 }
1061 931
1062 // The server doesn't respond to the opening handshake. 932 // The server doesn't respond to the opening handshake.
1063 TEST_F(WebSocketStreamCreateTest, HandshakeTimeout) { 933 TEST_F(WebSocketStreamCreateTest, HandshakeTimeout) {
1064 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); 934 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData());
1065 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); 935 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
1066 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); 936 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false));
1067 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); 937 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr();
1068 CreateAndConnectRawExpectations("ws://localhost/", 938 CreateAndConnectRawExpectations("ws://localhost/",
1069 NoSubProtocols(), 939 NoSubProtocols(),
1070 "http://localhost", 940 "http://localhost",
1071 socket_data.Pass(), 941 socket_data.Pass(),
1072 timer.Pass()); 942 timer.Pass());
1073 EXPECT_FALSE(has_failed()); 943 EXPECT_FALSE(has_failed());
1074 ASSERT_TRUE(weak_timer.get()); 944 ASSERT_TRUE(weak_timer.get());
1075 EXPECT_TRUE(weak_timer->IsRunning()); 945 EXPECT_TRUE(weak_timer->IsRunning());
1076 946
1077 weak_timer->Fire(); 947 weak_timer->Fire();
1078 RunUntilIdle(); 948 WaitUntilConnectDone();
1079 949
1080 EXPECT_TRUE(has_failed()); 950 EXPECT_TRUE(has_failed());
1081 EXPECT_EQ("WebSocket opening handshake timed out", failure_message()); 951 EXPECT_EQ("WebSocket opening handshake timed out", failure_message());
1082 ASSERT_TRUE(weak_timer.get()); 952 ASSERT_TRUE(weak_timer.get());
1083 EXPECT_FALSE(weak_timer->IsRunning()); 953 EXPECT_FALSE(weak_timer->IsRunning());
1084 } 954 }
1085 955
1086 // When the connection establishes the timer should be stopped. 956 // When the connection establishes the timer should be stopped.
1087 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) { 957 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) {
1088 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); 958 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false));
1089 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); 959 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr();
1090 960
1091 CreateAndConnectStandard("ws://localhost/", "localhost", "/", 961 CreateAndConnectStandard("ws://localhost/", "localhost", "/",
1092 NoSubProtocols(), "http://localhost", "", "", 962 NoSubProtocols(), "http://localhost", "", "",
1093 timer.Pass()); 963 timer.Pass());
1094 ASSERT_TRUE(weak_timer); 964 ASSERT_TRUE(weak_timer);
1095 EXPECT_TRUE(weak_timer->IsRunning()); 965 EXPECT_TRUE(weak_timer->IsRunning());
1096 966
1097 RunUntilIdle(); 967 WaitUntilConnectDone();
1098 EXPECT_FALSE(has_failed()); 968 EXPECT_FALSE(has_failed());
1099 EXPECT_TRUE(stream_); 969 EXPECT_TRUE(stream_);
1100 ASSERT_TRUE(weak_timer); 970 ASSERT_TRUE(weak_timer);
1101 EXPECT_FALSE(weak_timer->IsRunning()); 971 EXPECT_FALSE(weak_timer->IsRunning());
1102 } 972 }
1103 973
1104 // When the connection fails the timer should be stopped. 974 // When the connection fails the timer should be stopped.
1105 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnFailure) { 975 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnFailure) {
1106 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); 976 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData());
1107 socket_data->set_connect_data( 977 socket_data->set_connect_data(
1108 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); 978 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
1109 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); 979 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false));
1110 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); 980 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr();
1111 CreateAndConnectRawExpectations("ws://localhost/", 981 CreateAndConnectRawExpectations("ws://localhost/",
1112 NoSubProtocols(), 982 NoSubProtocols(),
1113 "http://localhost", 983 "http://localhost",
1114 socket_data.Pass(), 984 socket_data.Pass(),
1115 timer.Pass()); 985 timer.Pass());
1116 ASSERT_TRUE(weak_timer.get()); 986 ASSERT_TRUE(weak_timer.get());
1117 EXPECT_TRUE(weak_timer->IsRunning()); 987 EXPECT_TRUE(weak_timer->IsRunning());
1118 988
1119 RunUntilIdle(); 989 WaitUntilConnectDone();
1120 EXPECT_TRUE(has_failed()); 990 EXPECT_TRUE(has_failed());
1121 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", 991 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED",
1122 failure_message()); 992 failure_message());
1123 ASSERT_TRUE(weak_timer.get()); 993 ASSERT_TRUE(weak_timer.get());
1124 EXPECT_FALSE(weak_timer->IsRunning()); 994 EXPECT_FALSE(weak_timer->IsRunning());
1125 } 995 }
1126 996
1127 // Cancellation during connect works. 997 // Cancellation during connect works.
1128 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { 998 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) {
1129 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); 999 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData());
1130 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); 1000 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
1131 CreateAndConnectRawExpectations("ws://localhost/", 1001 CreateAndConnectRawExpectations("ws://localhost/",
1132 NoSubProtocols(), 1002 NoSubProtocols(),
1133 "http://localhost", 1003 "http://localhost",
1134 socket_data.Pass()); 1004 socket_data.Pass());
1135 stream_request_.reset(); 1005 stream_request_.reset();
1136 RunUntilIdle(); 1006 // WaitUntilConnectDone doesn't work in this case.
1007 base::RunLoop().RunUntilIdle();
1137 EXPECT_FALSE(has_failed()); 1008 EXPECT_FALSE(has_failed());
1138 EXPECT_FALSE(stream_); 1009 EXPECT_FALSE(stream_);
1139 } 1010 }
1140 1011
1141 // Cancellation during write of the request headers works. 1012 // Cancellation during write of the request headers works.
1142 TEST_F(WebSocketStreamCreateTest, CancellationDuringWrite) { 1013 TEST_F(WebSocketStreamCreateTest, CancellationDuringWrite) {
1143 // We seem to need at least two operations in order to use SetStop(). 1014 // We seem to need at least two operations in order to use SetStop().
1144 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/"), 1015 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/"),
1145 MockWrite(ASYNC, 1, "1.1\r\n")}; 1016 MockWrite(ASYNC, 1, "1.1\r\n")};
1146 // We keep a copy of the pointer so that we can call RunFor() on it later. 1017 // We keep a copy of the pointer so that we can call RunFor() on it later.
1147 DeterministicSocketData* socket_data( 1018 DeterministicSocketData* socket_data(
1148 new DeterministicSocketData(NULL, 0, writes, arraysize(writes))); 1019 new DeterministicSocketData(NULL, 0, writes, arraysize(writes)));
1149 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); 1020 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
1150 socket_data->SetStop(1); 1021 socket_data->SetStop(1);
1151 CreateAndConnectRawExpectations("ws://localhost/", 1022 CreateAndConnectRawExpectations("ws://localhost/",
1152 NoSubProtocols(), 1023 NoSubProtocols(),
1153 "http://localhost", 1024 "http://localhost",
1154 make_scoped_ptr(socket_data)); 1025 make_scoped_ptr(socket_data));
1155 socket_data->Run(); 1026 socket_data->Run();
1156 stream_request_.reset(); 1027 stream_request_.reset();
1157 RunUntilIdle(); 1028 // WaitUntilConnectDone doesn't work in this case.
1029 base::RunLoop().RunUntilIdle();
1158 EXPECT_FALSE(has_failed()); 1030 EXPECT_FALSE(has_failed());
1159 EXPECT_FALSE(stream_); 1031 EXPECT_FALSE(stream_);
1160 EXPECT_TRUE(request_info_); 1032 EXPECT_TRUE(request_info_);
1161 EXPECT_FALSE(response_info_); 1033 EXPECT_FALSE(response_info_);
1162 } 1034 }
1163 1035
1164 // Cancellation during read of the response headers works. 1036 // Cancellation during read of the response headers works.
1165 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { 1037 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) {
1166 std::string request = 1038 std::string request =
1167 WebSocketStandardRequest("/", "localhost", "http://localhost", ""); 1039 WebSocketStandardRequest("/", "localhost", "http://localhost", "");
1168 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; 1040 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())};
1169 MockRead reads[] = { 1041 MockRead reads[] = {
1170 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"), 1042 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"),
1171 }; 1043 };
1172 scoped_ptr<DeterministicSocketData> socket_data( 1044 scoped_ptr<DeterministicSocketData> socket_data(
1173 BuildSocketData(reads, writes)); 1045 BuildSocketData(reads, writes));
1174 socket_data->SetStop(1); 1046 socket_data->SetStop(1);
1175 DeterministicSocketData* socket_data_raw_ptr = socket_data.get(); 1047 DeterministicSocketData* socket_data_raw_ptr = socket_data.get();
1176 CreateAndConnectRawExpectations("ws://localhost/", 1048 CreateAndConnectRawExpectations("ws://localhost/",
1177 NoSubProtocols(), 1049 NoSubProtocols(),
1178 "http://localhost", 1050 "http://localhost",
1179 socket_data.Pass()); 1051 socket_data.Pass());
1180 socket_data_raw_ptr->Run(); 1052 socket_data_raw_ptr->Run();
1181 stream_request_.reset(); 1053 stream_request_.reset();
1182 RunUntilIdle(); 1054 // WaitUntilConnectDone doesn't work in this case.
1055 base::RunLoop().RunUntilIdle();
1183 EXPECT_FALSE(has_failed()); 1056 EXPECT_FALSE(has_failed());
1184 EXPECT_FALSE(stream_); 1057 EXPECT_FALSE(stream_);
1185 EXPECT_TRUE(request_info_); 1058 EXPECT_TRUE(request_info_);
1186 EXPECT_FALSE(response_info_); 1059 EXPECT_FALSE(response_info_);
1187 } 1060 }
1188 1061
1189 // Over-size response headers (> 256KB) should not cause a crash. This is a 1062 // Over-size response headers (> 256KB) should not cause a crash. This is a
1190 // regression test for crbug.com/339456. It is based on the layout test 1063 // regression test for crbug.com/339456. It is based on the layout test
1191 // "cookie-flood.html". 1064 // "cookie-flood.html".
1192 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { 1065 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) {
1193 std::string set_cookie_headers; 1066 std::string set_cookie_headers;
1194 set_cookie_headers.reserve(45 * 10000); 1067 set_cookie_headers.reserve(45 * 10000);
1195 for (int i = 0; i < 10000; ++i) { 1068 for (int i = 0; i < 10000; ++i) {
1196 set_cookie_headers += 1069 set_cookie_headers +=
1197 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); 1070 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i);
1198 } 1071 }
1199 CreateAndConnectStandard("ws://localhost/", "localhost", "/", 1072 CreateAndConnectStandard("ws://localhost/", "localhost", "/",
1200 NoSubProtocols(), "http://localhost", "", 1073 NoSubProtocols(), "http://localhost", "",
1201 set_cookie_headers); 1074 set_cookie_headers);
1202 RunUntilIdle(); 1075 WaitUntilConnectDone();
1203 EXPECT_TRUE(has_failed()); 1076 EXPECT_TRUE(has_failed());
1204 EXPECT_FALSE(response_info_); 1077 EXPECT_FALSE(response_info_);
1205 } 1078 }
1206 1079
1207 // If the remote host closes the connection without sending headers, we should 1080 // If the remote host closes the connection without sending headers, we should
1208 // log the console message "Connection closed before receiving a handshake 1081 // log the console message "Connection closed before receiving a handshake
1209 // response". 1082 // response".
1210 TEST_F(WebSocketStreamCreateTest, NoResponse) { 1083 TEST_F(WebSocketStreamCreateTest, NoResponse) {
1211 std::string request = 1084 std::string request =
1212 WebSocketStandardRequest("/", "localhost", "http://localhost", ""); 1085 WebSocketStandardRequest("/", "localhost", "http://localhost", "");
(...skipping 18 matching lines...) Expand all
1231 ssl_data_.push_back( 1104 ssl_data_.push_back(
1232 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); 1105 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID));
1233 ssl_data_[0]->cert = 1106 ssl_data_[0]->cert =
1234 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); 1107 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
1235 ASSERT_TRUE(ssl_data_[0]->cert.get()); 1108 ASSERT_TRUE(ssl_data_[0]->cert.get());
1236 scoped_ptr<DeterministicSocketData> raw_socket_data(BuildNullSocketData()); 1109 scoped_ptr<DeterministicSocketData> raw_socket_data(BuildNullSocketData());
1237 CreateAndConnectRawExpectations("wss://localhost/", 1110 CreateAndConnectRawExpectations("wss://localhost/",
1238 NoSubProtocols(), 1111 NoSubProtocols(),
1239 "http://localhost", 1112 "http://localhost",
1240 raw_socket_data.Pass()); 1113 raw_socket_data.Pass());
1241 RunUntilIdle(); 1114 // WaitUntilConnectDone doesn't work in this case.
1115 base::RunLoop().RunUntilIdle();
1242 EXPECT_FALSE(has_failed()); 1116 EXPECT_FALSE(has_failed());
1243 ASSERT_TRUE(ssl_error_callbacks_); 1117 ASSERT_TRUE(ssl_error_callbacks_);
1244 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID, 1118 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID,
1245 &ssl_info_); 1119 &ssl_info_);
1246 RunUntilIdle(); 1120 WaitUntilConnectDone();
1247 EXPECT_TRUE(has_failed()); 1121 EXPECT_TRUE(has_failed());
1248 } 1122 }
1249 1123
1250 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { 1124 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) {
1251 scoped_ptr<SSLSocketDataProvider> ssl_data( 1125 scoped_ptr<SSLSocketDataProvider> ssl_data(
1252 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); 1126 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID));
1253 ssl_data->cert = 1127 ssl_data->cert =
1254 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); 1128 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
1255 ASSERT_TRUE(ssl_data->cert.get()); 1129 ASSERT_TRUE(ssl_data->cert.get());
1256 ssl_data_.push_back(ssl_data.release()); 1130 ssl_data_.push_back(ssl_data.release());
1257 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); 1131 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK));
1258 ssl_data_.push_back(ssl_data.release()); 1132 ssl_data_.push_back(ssl_data.release());
1259 url_request_context_host_.AddRawExpectations(BuildNullSocketData()); 1133 url_request_context_host_.AddRawExpectations(BuildNullSocketData());
1260 CreateAndConnectStandard("wss://localhost/", "localhost", "/", 1134 CreateAndConnectStandard("wss://localhost/", "localhost", "/",
1261 NoSubProtocols(), "http://localhost", "", ""); 1135 NoSubProtocols(), "http://localhost", "", "");
1262 RunUntilIdle(); 1136 // WaitUntilConnectDone doesn't work in this case.
1137 base::RunLoop().RunUntilIdle();
1263 ASSERT_TRUE(ssl_error_callbacks_); 1138 ASSERT_TRUE(ssl_error_callbacks_);
1264 ssl_error_callbacks_->ContinueSSLRequest(); 1139 ssl_error_callbacks_->ContinueSSLRequest();
1265 RunUntilIdle(); 1140 WaitUntilConnectDone();
1266 EXPECT_FALSE(has_failed()); 1141 EXPECT_FALSE(has_failed());
1267 EXPECT_TRUE(stream_); 1142 EXPECT_TRUE(stream_);
1268 } 1143 }
1269 1144
1270 // If the server requests authorisation, but we have no credentials, the 1145 // If the server requests authorisation, but we have no credentials, the
1271 // connection should fail cleanly. 1146 // connection should fail cleanly.
1272 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) { 1147 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) {
1273 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", 1148 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
1274 NoSubProtocols(), "http://localhost", "", 1149 NoSubProtocols(), "http://localhost", "",
1275 kUnauthorizedResponse); 1150 kUnauthorizedResponse);
1276 RunUntilIdle(); 1151 WaitUntilConnectDone();
1277 EXPECT_TRUE(has_failed()); 1152 EXPECT_TRUE(has_failed());
1278 EXPECT_EQ("HTTP Authentication failed; no valid credentials available", 1153 EXPECT_EQ("HTTP Authentication failed; no valid credentials available",
1279 failure_message()); 1154 failure_message());
1280 EXPECT_TRUE(response_info_); 1155 EXPECT_TRUE(response_info_);
1281 } 1156 }
1282 1157
1283 TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) { 1158 TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) {
1284 CreateAndConnectAuthHandshake("ws://foo:bar@localhost/", 1159 CreateAndConnectAuthHandshake("ws://foo:bar@localhost/",
1285 "Zm9vOmJhcg==", 1160 "Zm9vOmJhcg==",
1286 WebSocketStandardResponse(std::string())); 1161 WebSocketStandardResponse(std::string()));
1287 RunUntilIdle(); 1162 WaitUntilConnectDone();
1288 EXPECT_FALSE(has_failed()); 1163 EXPECT_FALSE(has_failed());
1289 EXPECT_TRUE(stream_); 1164 EXPECT_TRUE(stream_);
1290 ASSERT_TRUE(response_info_); 1165 ASSERT_TRUE(response_info_);
1291 EXPECT_EQ(101, response_info_->status_code); 1166 EXPECT_EQ(101, response_info_->status_code);
1292 } 1167 }
1293 1168
1294 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureIncorrectPasswordInUrl) { 1169 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureIncorrectPasswordInUrl) {
1295 CreateAndConnectAuthHandshake( 1170 CreateAndConnectAuthHandshake(
1296 "ws://foo:baz@localhost/", "Zm9vOmJheg==", kUnauthorizedResponse); 1171 "ws://foo:baz@localhost/", "Zm9vOmJheg==", kUnauthorizedResponse);
1297 RunUntilIdle(); 1172 WaitUntilConnectDone();
1298 EXPECT_TRUE(has_failed()); 1173 EXPECT_TRUE(has_failed());
1299 EXPECT_TRUE(response_info_); 1174 EXPECT_TRUE(response_info_);
1300 } 1175 }
1301 1176
1302 // Digest auth has the same connection semantics as Basic auth, so we can 1177 // Digest auth has the same connection semantics as Basic auth, so we can
1303 // generally assume that whatever works for Basic auth will also work for 1178 // generally assume that whatever works for Basic auth will also work for
1304 // Digest. There's just one test here, to confirm that it works at all. 1179 // Digest. There's just one test here, to confirm that it works at all.
1305 TEST_F(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) { 1180 TEST_F(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) {
1306 AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse)); 1181 AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse));
1307 1182
1308 CreateAndConnectRawExpectations( 1183 CreateAndConnectRawExpectations(
1309 "ws://FooBar:pass@localhost/", 1184 "ws://FooBar:pass@localhost/",
1310 NoSubProtocols(), 1185 NoSubProtocols(),
1311 "http://localhost", 1186 "http://localhost",
1312 helper_.BuildSocketData2(kAuthorizedRequest, 1187 helper_.BuildSocketData2(kAuthorizedRequest,
1313 WebSocketStandardResponse(std::string()))); 1188 WebSocketStandardResponse(std::string())));
1314 RunUntilIdle(); 1189 WaitUntilConnectDone();
1315 EXPECT_FALSE(has_failed()); 1190 EXPECT_FALSE(has_failed());
1316 EXPECT_TRUE(stream_); 1191 EXPECT_TRUE(stream_);
1317 ASSERT_TRUE(response_info_); 1192 ASSERT_TRUE(response_info_);
1318 EXPECT_EQ(101, response_info_->status_code); 1193 EXPECT_EQ(101, response_info_->status_code);
1319 } 1194 }
1320 1195
1321 TEST_F(WebSocketStreamCreateUMATest, Incomplete) { 1196 TEST_F(WebSocketStreamCreateUMATest, Incomplete) {
1322 const std::string name("Net.WebSocket.HandshakeResult"); 1197 const std::string name("Net.WebSocket.HandshakeResult");
1323 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); 1198 scoped_ptr<base::HistogramSamples> original(GetSamples(name));
1324 1199
(...skipping 16 matching lines...) Expand all
1341 1216
1342 TEST_F(WebSocketStreamCreateUMATest, Connected) { 1217 TEST_F(WebSocketStreamCreateUMATest, Connected) {
1343 const std::string name("Net.WebSocket.HandshakeResult"); 1218 const std::string name("Net.WebSocket.HandshakeResult");
1344 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); 1219 scoped_ptr<base::HistogramSamples> original(GetSamples(name));
1345 1220
1346 { 1221 {
1347 StreamCreation creation; 1222 StreamCreation creation;
1348 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", 1223 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/",
1349 creation.NoSubProtocols(), 1224 creation.NoSubProtocols(),
1350 "http://localhost", "", ""); 1225 "http://localhost", "", "");
1351 creation.RunUntilIdle(); 1226 creation.WaitUntilConnectDone();
1352 } 1227 }
1353 1228
1354 scoped_ptr<base::HistogramSamples> samples(GetSamples(name)); 1229 scoped_ptr<base::HistogramSamples> samples(GetSamples(name));
1355 ASSERT_TRUE(samples); 1230 ASSERT_TRUE(samples);
1356 if (original) { 1231 if (original) {
1357 samples->Subtract(*original); // Cancel the original values. 1232 samples->Subtract(*original); // Cancel the original values.
1358 } 1233 }
1359 EXPECT_EQ(0, samples->GetCount(INCOMPLETE)); 1234 EXPECT_EQ(0, samples->GetCount(INCOMPLETE));
1360 EXPECT_EQ(1, samples->GetCount(CONNECTED)); 1235 EXPECT_EQ(1, samples->GetCount(CONNECTED));
1361 EXPECT_EQ(0, samples->GetCount(FAILED)); 1236 EXPECT_EQ(0, samples->GetCount(FAILED));
1362 } 1237 }
1363 1238
1364 TEST_F(WebSocketStreamCreateUMATest, Failed) { 1239 TEST_F(WebSocketStreamCreateUMATest, Failed) {
1365 const std::string name("Net.WebSocket.HandshakeResult"); 1240 const std::string name("Net.WebSocket.HandshakeResult");
1366 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); 1241 scoped_ptr<base::HistogramSamples> original(GetSamples(name));
1367 1242
1368 { 1243 {
1369 StreamCreation creation; 1244 StreamCreation creation;
1370 static const char kInvalidStatusCodeResponse[] = 1245 static const char kInvalidStatusCodeResponse[] =
1371 "HTTP/1.1 200 OK\r\n" 1246 "HTTP/1.1 200 OK\r\n"
1372 "Upgrade: websocket\r\n" 1247 "Upgrade: websocket\r\n"
1373 "Connection: Upgrade\r\n" 1248 "Connection: Upgrade\r\n"
1374 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 1249 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
1375 "\r\n"; 1250 "\r\n";
1376 creation.CreateAndConnectCustomResponse( 1251 creation.CreateAndConnectCustomResponse(
1377 "ws://localhost/", "localhost", "/", creation.NoSubProtocols(), 1252 "ws://localhost/", "localhost", "/", creation.NoSubProtocols(),
1378 "http://localhost", "", kInvalidStatusCodeResponse); 1253 "http://localhost", "", kInvalidStatusCodeResponse);
1379 creation.RunUntilIdle(); 1254 creation.WaitUntilConnectDone();
1380 } 1255 }
1381 1256
1382 scoped_ptr<base::HistogramSamples> samples(GetSamples(name)); 1257 scoped_ptr<base::HistogramSamples> samples(GetSamples(name));
1383 ASSERT_TRUE(samples); 1258 ASSERT_TRUE(samples);
1384 if (original) { 1259 if (original) {
1385 samples->Subtract(*original); // Cancel the original values. 1260 samples->Subtract(*original); // Cancel the original values.
1386 } 1261 }
1387 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); 1262 EXPECT_EQ(1, samples->GetCount(INCOMPLETE));
1388 EXPECT_EQ(0, samples->GetCount(CONNECTED)); 1263 EXPECT_EQ(0, samples->GetCount(CONNECTED));
1389 EXPECT_EQ(0, samples->GetCount(FAILED)); 1264 EXPECT_EQ(0, samples->GetCount(FAILED));
(...skipping 12 matching lines...) Expand all
1402 MockRead reads[] = { 1277 MockRead reads[] = {
1403 MockRead(SYNCHRONOUS, 1, kTruncatedResponse), 1278 MockRead(SYNCHRONOUS, 1, kTruncatedResponse),
1404 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 2), 1279 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 2),
1405 }; 1280 };
1406 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, request.c_str())}; 1281 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, request.c_str())};
1407 scoped_ptr<DeterministicSocketData> socket_data( 1282 scoped_ptr<DeterministicSocketData> socket_data(
1408 BuildSocketData(reads, writes)); 1283 BuildSocketData(reads, writes));
1409 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); 1284 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
1410 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), 1285 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
1411 "http://localhost", socket_data.Pass()); 1286 "http://localhost", socket_data.Pass());
1412 RunUntilIdle(); 1287 WaitUntilConnectDone();
1413 EXPECT_TRUE(has_failed()); 1288 EXPECT_TRUE(has_failed());
1414 } 1289 }
1415 1290
1416 TEST_F(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) { 1291 TEST_F(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) {
1417 static const char kConnectRequest[] = 1292 static const char kConnectRequest[] =
1418 "CONNECT localhost:80 HTTP/1.1\r\n" 1293 "CONNECT localhost:80 HTTP/1.1\r\n"
1419 "Host: localhost\r\n" 1294 "Host: localhost\r\n"
1420 "Proxy-Connection: keep-alive\r\n" 1295 "Proxy-Connection: keep-alive\r\n"
1421 "\r\n"; 1296 "\r\n";
1422 1297
1423 static const char kProxyResponse[] = 1298 static const char kProxyResponse[] =
1424 "HTTP/1.1 403 Forbidden\r\n" 1299 "HTTP/1.1 403 Forbidden\r\n"
1425 "Content-Type: text/html\r\n" 1300 "Content-Type: text/html\r\n"
1426 "Content-Length: 9\r\n" 1301 "Content-Length: 9\r\n"
1427 "Connection: keep-alive\r\n" 1302 "Connection: keep-alive\r\n"
1428 "\r\n" 1303 "\r\n"
1429 "Forbidden"; 1304 "Forbidden";
1430 1305
1431 MockRead reads[] = {MockRead(SYNCHRONOUS, 1, kProxyResponse)}; 1306 MockRead reads[] = {MockRead(SYNCHRONOUS, 1, kProxyResponse)};
1432 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, kConnectRequest)}; 1307 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, kConnectRequest)};
1433 scoped_ptr<DeterministicSocketData> socket_data( 1308 scoped_ptr<DeterministicSocketData> socket_data(
1434 BuildSocketData(reads, writes)); 1309 BuildSocketData(reads, writes));
1435 url_request_context_host_.SetProxyConfig("https=proxy:8000"); 1310 url_request_context_host_.SetProxyConfig("https=proxy:8000");
1436 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), 1311 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
1437 "http://localhost", socket_data.Pass()); 1312 "http://localhost", socket_data.Pass());
1438 RunUntilIdle(); 1313 WaitUntilConnectDone();
1439 EXPECT_TRUE(has_failed()); 1314 EXPECT_TRUE(has_failed());
1440 EXPECT_EQ("Establishing a tunnel via proxy server failed.", 1315 EXPECT_EQ("Establishing a tunnel via proxy server failed.",
1441 failure_message()); 1316 failure_message());
1442 } 1317 }
1443 1318
1444 } // namespace 1319 } // namespace
1445 } // namespace net 1320 } // namespace net
OLDNEW
« no previous file with comments | « net/websockets/websocket_stream_create_test_base.cc ('k') | net/websockets/websocket_test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698