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

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

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