| OLD | NEW |
| 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 stream->SetWebSocketKeyForTesting("dGhlIHNhbXBsZSBub25jZQ=="); | 103 stream->SetWebSocketKeyForTesting("dGhlIHNhbXBsZSBub25jZQ=="); |
| 104 } | 104 } |
| 105 }; | 105 }; |
| 106 | 106 |
| 107 class WebSocketStreamCreateTest : public ::testing::Test { | 107 class WebSocketStreamCreateTest : public ::testing::Test { |
| 108 public: | 108 public: |
| 109 WebSocketStreamCreateTest() : has_failed_(false), ssl_fatal_(false) {} | 109 WebSocketStreamCreateTest() : has_failed_(false), ssl_fatal_(false) {} |
| 110 | 110 |
| 111 void CreateAndConnectCustomResponse( | 111 void CreateAndConnectCustomResponse( |
| 112 const std::string& socket_url, | 112 const std::string& socket_url, |
| 113 const std::string& socket_host, |
| 113 const std::string& socket_path, | 114 const std::string& socket_path, |
| 114 const std::vector<std::string>& sub_protocols, | 115 const std::vector<std::string>& sub_protocols, |
| 115 const std::string& origin, | 116 const std::string& origin, |
| 116 const std::string& extra_request_headers, | 117 const std::string& extra_request_headers, |
| 117 const std::string& response_body, | 118 const std::string& response_body, |
| 118 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { | 119 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { |
| 119 url_request_context_host_.SetExpectations( | 120 url_request_context_host_.SetExpectations( |
| 120 WebSocketStandardRequest(socket_path, origin, extra_request_headers), | 121 WebSocketStandardRequest(socket_path, socket_host, origin, |
| 122 extra_request_headers), |
| 121 response_body); | 123 response_body); |
| 122 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); | 124 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); |
| 123 } | 125 } |
| 124 | 126 |
| 125 // |extra_request_headers| and |extra_response_headers| must end in "\r\n" or | 127 // |extra_request_headers| and |extra_response_headers| must end in "\r\n" or |
| 126 // errors like "Unable to perform synchronous IO while stopped" will occur. | 128 // errors like "Unable to perform synchronous IO while stopped" will occur. |
| 127 void CreateAndConnectStandard(const std::string& socket_url, | 129 void CreateAndConnectStandard( |
| 128 const std::string& socket_path, | 130 const std::string& socket_url, |
| 129 const std::vector<std::string>& sub_protocols, | 131 const std::string& socket_host, |
| 130 const std::string& origin, | 132 const std::string& socket_path, |
| 131 const std::string& extra_request_headers, | 133 const std::vector<std::string>& sub_protocols, |
| 132 const std::string& extra_response_headers, | 134 const std::string& origin, |
| 133 scoped_ptr<base::Timer> timer = | 135 const std::string& extra_request_headers, |
| 134 scoped_ptr<base::Timer>()) { | 136 const std::string& extra_response_headers, |
| 137 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { |
| 135 CreateAndConnectCustomResponse( | 138 CreateAndConnectCustomResponse( |
| 136 socket_url, | 139 socket_url, socket_host, socket_path, sub_protocols, origin, |
| 137 socket_path, | |
| 138 sub_protocols, | |
| 139 origin, | |
| 140 extra_request_headers, | 140 extra_request_headers, |
| 141 WebSocketStandardResponse(extra_response_headers), | 141 WebSocketStandardResponse(extra_response_headers), timer.Pass()); |
| 142 timer.Pass()); | |
| 143 } | 142 } |
| 144 | 143 |
| 145 void CreateAndConnectRawExpectations( | 144 void CreateAndConnectRawExpectations( |
| 146 const std::string& socket_url, | 145 const std::string& socket_url, |
| 147 const std::vector<std::string>& sub_protocols, | 146 const std::vector<std::string>& sub_protocols, |
| 148 const std::string& origin, | 147 const std::string& origin, |
| 149 scoped_ptr<DeterministicSocketData> socket_data, | 148 scoped_ptr<DeterministicSocketData> socket_data, |
| 150 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { | 149 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { |
| 151 AddRawExpectations(socket_data.Pass()); | 150 AddRawExpectations(socket_data.Pass()); |
| 152 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); | 151 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 // There are enough tests of the Sec-WebSocket-Extensions header that they | 253 // There are enough tests of the Sec-WebSocket-Extensions header that they |
| 255 // deserve their own test fixture. | 254 // deserve their own test fixture. |
| 256 class WebSocketStreamCreateExtensionTest : public WebSocketStreamCreateTest { | 255 class WebSocketStreamCreateExtensionTest : public WebSocketStreamCreateTest { |
| 257 public: | 256 public: |
| 258 // Performs a standard connect, with the value of the Sec-WebSocket-Extensions | 257 // Performs a standard connect, with the value of the Sec-WebSocket-Extensions |
| 259 // header in the response set to |extensions_header_value|. Runs the event | 258 // header in the response set to |extensions_header_value|. Runs the event |
| 260 // loop to allow the connect to complete. | 259 // loop to allow the connect to complete. |
| 261 void CreateAndConnectWithExtensions( | 260 void CreateAndConnectWithExtensions( |
| 262 const std::string& extensions_header_value) { | 261 const std::string& extensions_header_value) { |
| 263 CreateAndConnectStandard( | 262 CreateAndConnectStandard( |
| 264 "ws://localhost/testing_path", | 263 "ws://localhost/testing_path", "localhost", "/testing_path", |
| 265 "/testing_path", | 264 NoSubProtocols(), "http://localhost", "", |
| 266 NoSubProtocols(), | |
| 267 "http://localhost", | |
| 268 "", | |
| 269 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); | 265 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); |
| 270 RunUntilIdle(); | 266 RunUntilIdle(); |
| 271 } | 267 } |
| 272 }; | 268 }; |
| 273 | 269 |
| 274 // Common code to construct expectations for authentication tests that receive | 270 // Common code to construct expectations for authentication tests that receive |
| 275 // the auth challenge on one connection and then create a second connection to | 271 // the auth challenge on one connection and then create a second connection to |
| 276 // send the authenticated request on. | 272 // send the authenticated request on. |
| 277 class CommonAuthTestHelper { | 273 class CommonAuthTestHelper { |
| 278 public: | 274 public: |
| 279 CommonAuthTestHelper() : reads1_(), writes1_(), reads2_(), writes2_() {} | 275 CommonAuthTestHelper() : reads1_(), writes1_(), reads2_(), writes2_() {} |
| 280 | 276 |
| 281 scoped_ptr<DeterministicSocketData> BuildSocketData1( | 277 scoped_ptr<DeterministicSocketData> BuildSocketData1( |
| 282 const std::string& response) { | 278 const std::string& response) { |
| 283 request1_ = WebSocketStandardRequest("/", "http://localhost", ""); | 279 request1_ = |
| 280 WebSocketStandardRequest("/", "localhost", "http://localhost", ""); |
| 284 writes1_[0] = MockWrite(SYNCHRONOUS, 0, request1_.c_str()); | 281 writes1_[0] = MockWrite(SYNCHRONOUS, 0, request1_.c_str()); |
| 285 response1_ = response; | 282 response1_ = response; |
| 286 reads1_[0] = MockRead(SYNCHRONOUS, 1, response1_.c_str()); | 283 reads1_[0] = MockRead(SYNCHRONOUS, 1, response1_.c_str()); |
| 287 reads1_[1] = MockRead(SYNCHRONOUS, OK, 2); // Close connection | 284 reads1_[1] = MockRead(SYNCHRONOUS, OK, 2); // Close connection |
| 288 | 285 |
| 289 return BuildSocketData(reads1_, writes1_); | 286 return BuildSocketData(reads1_, writes1_); |
| 290 } | 287 } |
| 291 | 288 |
| 292 scoped_ptr<DeterministicSocketData> BuildSocketData2( | 289 scoped_ptr<DeterministicSocketData> BuildSocketData2( |
| 293 const std::string& request, | 290 const std::string& request, |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 scoped_ptr<base::HistogramSamples> GetSamples(const std::string& name) { | 411 scoped_ptr<base::HistogramSamples> GetSamples(const std::string& name) { |
| 415 base::HistogramBase* histogram = | 412 base::HistogramBase* histogram = |
| 416 base::StatisticsRecorder::FindHistogram(name); | 413 base::StatisticsRecorder::FindHistogram(name); |
| 417 return histogram ? histogram->SnapshotSamples() | 414 return histogram ? histogram->SnapshotSamples() |
| 418 : scoped_ptr<base::HistogramSamples>(); | 415 : scoped_ptr<base::HistogramSamples>(); |
| 419 } | 416 } |
| 420 }; | 417 }; |
| 421 | 418 |
| 422 // Confirm that the basic case works as expected. | 419 // Confirm that the basic case works as expected. |
| 423 TEST_F(WebSocketStreamCreateTest, SimpleSuccess) { | 420 TEST_F(WebSocketStreamCreateTest, SimpleSuccess) { |
| 424 CreateAndConnectStandard( | 421 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 425 "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", ""); | 422 NoSubProtocols(), "http://localhost", "", ""); |
| 426 EXPECT_FALSE(request_info_); | 423 EXPECT_FALSE(request_info_); |
| 427 EXPECT_FALSE(response_info_); | 424 EXPECT_FALSE(response_info_); |
| 428 RunUntilIdle(); | 425 RunUntilIdle(); |
| 429 EXPECT_FALSE(has_failed()); | 426 EXPECT_FALSE(has_failed()); |
| 430 EXPECT_TRUE(stream_); | 427 EXPECT_TRUE(stream_); |
| 431 EXPECT_TRUE(request_info_); | 428 EXPECT_TRUE(request_info_); |
| 432 EXPECT_TRUE(response_info_); | 429 EXPECT_TRUE(response_info_); |
| 433 } | 430 } |
| 434 | 431 |
| 435 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) { | 432 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) { |
| 436 static const char kResponse[] = | 433 static const char kResponse[] = |
| 437 "HTTP/1.1 101 Switching Protocols\r\n" | 434 "HTTP/1.1 101 Switching Protocols\r\n" |
| 438 "Upgrade: websocket\r\n" | 435 "Upgrade: websocket\r\n" |
| 439 "Connection: Upgrade\r\n" | 436 "Connection: Upgrade\r\n" |
| 440 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 437 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 441 "foo: bar, baz\r\n" | 438 "foo: bar, baz\r\n" |
| 442 "hoge: fuga\r\n" | 439 "hoge: fuga\r\n" |
| 443 "hoge: piyo\r\n" | 440 "hoge: piyo\r\n" |
| 444 "\r\n"; | 441 "\r\n"; |
| 445 | 442 |
| 446 CreateAndConnectCustomResponse( | 443 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 447 "ws://localhost/", | 444 NoSubProtocols(), "http://localhost", "", |
| 448 "/", | 445 kResponse); |
| 449 NoSubProtocols(), | |
| 450 "http://localhost", | |
| 451 "", | |
| 452 kResponse); | |
| 453 EXPECT_FALSE(request_info_); | 446 EXPECT_FALSE(request_info_); |
| 454 EXPECT_FALSE(response_info_); | 447 EXPECT_FALSE(response_info_); |
| 455 RunUntilIdle(); | 448 RunUntilIdle(); |
| 456 EXPECT_TRUE(stream_); | 449 EXPECT_TRUE(stream_); |
| 457 ASSERT_TRUE(request_info_); | 450 ASSERT_TRUE(request_info_); |
| 458 ASSERT_TRUE(response_info_); | 451 ASSERT_TRUE(response_info_); |
| 459 std::vector<HeaderKeyValuePair> request_headers = | 452 std::vector<HeaderKeyValuePair> request_headers = |
| 460 ToVector(request_info_->headers); | 453 ToVector(request_info_->headers); |
| 461 // We examine the contents of request_info_ and response_info_ | 454 // We examine the contents of request_info_ and response_info_ |
| 462 // mainly only in this test case. | 455 // mainly only in this test case. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), response_headers[0]); | 487 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), response_headers[0]); |
| 495 EXPECT_EQ("Sec-WebSocket-Accept", response_headers[1].first); | 488 EXPECT_EQ("Sec-WebSocket-Accept", response_headers[1].first); |
| 496 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), response_headers[2]); | 489 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), response_headers[2]); |
| 497 EXPECT_EQ(HeaderKeyValuePair("foo", "bar, baz"), response_headers[3]); | 490 EXPECT_EQ(HeaderKeyValuePair("foo", "bar, baz"), response_headers[3]); |
| 498 EXPECT_EQ(HeaderKeyValuePair("hoge", "fuga"), response_headers[4]); | 491 EXPECT_EQ(HeaderKeyValuePair("hoge", "fuga"), response_headers[4]); |
| 499 EXPECT_EQ(HeaderKeyValuePair("hoge", "piyo"), response_headers[5]); | 492 EXPECT_EQ(HeaderKeyValuePair("hoge", "piyo"), response_headers[5]); |
| 500 } | 493 } |
| 501 | 494 |
| 502 // Confirm that the stream isn't established until the message loop runs. | 495 // Confirm that the stream isn't established until the message loop runs. |
| 503 TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) { | 496 TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) { |
| 504 CreateAndConnectStandard( | 497 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 505 "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", ""); | 498 NoSubProtocols(), "http://localhost", "", ""); |
| 506 EXPECT_FALSE(has_failed()); | 499 EXPECT_FALSE(has_failed()); |
| 507 EXPECT_FALSE(stream_); | 500 EXPECT_FALSE(stream_); |
| 508 } | 501 } |
| 509 | 502 |
| 510 // Check the path is used. | 503 // Check the path is used. |
| 511 TEST_F(WebSocketStreamCreateTest, PathIsUsed) { | 504 TEST_F(WebSocketStreamCreateTest, PathIsUsed) { |
| 512 CreateAndConnectStandard("ws://localhost/testing_path", | 505 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 513 "/testing_path", | 506 "/testing_path", NoSubProtocols(), |
| 514 NoSubProtocols(), | 507 "http://localhost", "", ""); |
| 515 "http://localhost", | |
| 516 "", | |
| 517 ""); | |
| 518 RunUntilIdle(); | 508 RunUntilIdle(); |
| 519 EXPECT_FALSE(has_failed()); | 509 EXPECT_FALSE(has_failed()); |
| 520 EXPECT_TRUE(stream_); | 510 EXPECT_TRUE(stream_); |
| 521 } | 511 } |
| 522 | 512 |
| 523 // Check that the origin is used. | 513 // Check that the origin is used. |
| 524 TEST_F(WebSocketStreamCreateTest, OriginIsUsed) { | 514 TEST_F(WebSocketStreamCreateTest, OriginIsUsed) { |
| 525 CreateAndConnectStandard("ws://localhost/testing_path", | 515 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 526 "/testing_path", | 516 "/testing_path", NoSubProtocols(), |
| 527 NoSubProtocols(), | 517 "http://google.com", "", ""); |
| 528 "http://google.com", | |
| 529 "", | |
| 530 ""); | |
| 531 RunUntilIdle(); | 518 RunUntilIdle(); |
| 532 EXPECT_FALSE(has_failed()); | 519 EXPECT_FALSE(has_failed()); |
| 533 EXPECT_TRUE(stream_); | 520 EXPECT_TRUE(stream_); |
| 534 } | 521 } |
| 535 | 522 |
| 536 // Check that sub-protocols are sent and parsed. | 523 // Check that sub-protocols are sent and parsed. |
| 537 TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) { | 524 TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) { |
| 538 std::vector<std::string> sub_protocols; | 525 std::vector<std::string> sub_protocols; |
| 539 sub_protocols.push_back("chatv11.chromium.org"); | 526 sub_protocols.push_back("chatv11.chromium.org"); |
| 540 sub_protocols.push_back("chatv20.chromium.org"); | 527 sub_protocols.push_back("chatv20.chromium.org"); |
| 541 CreateAndConnectStandard("ws://localhost/testing_path", | 528 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 542 "/testing_path", | 529 "/testing_path", sub_protocols, "http://google.com", |
| 543 sub_protocols, | |
| 544 "http://google.com", | |
| 545 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 530 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
| 546 "chatv20.chromium.org\r\n", | 531 "chatv20.chromium.org\r\n", |
| 547 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); | 532 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); |
| 548 RunUntilIdle(); | 533 RunUntilIdle(); |
| 549 EXPECT_TRUE(stream_); | 534 EXPECT_TRUE(stream_); |
| 550 EXPECT_FALSE(has_failed()); | 535 EXPECT_FALSE(has_failed()); |
| 551 EXPECT_EQ("chatv20.chromium.org", stream_->GetSubProtocol()); | 536 EXPECT_EQ("chatv20.chromium.org", stream_->GetSubProtocol()); |
| 552 } | 537 } |
| 553 | 538 |
| 554 // Unsolicited sub-protocols are rejected. | 539 // Unsolicited sub-protocols are rejected. |
| 555 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { | 540 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { |
| 556 CreateAndConnectStandard("ws://localhost/testing_path", | 541 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 557 "/testing_path", | 542 "/testing_path", NoSubProtocols(), |
| 558 NoSubProtocols(), | 543 "http://google.com", "", |
| 559 "http://google.com", | |
| 560 "", | |
| 561 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); | 544 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); |
| 562 RunUntilIdle(); | 545 RunUntilIdle(); |
| 563 EXPECT_FALSE(stream_); | 546 EXPECT_FALSE(stream_); |
| 564 EXPECT_TRUE(has_failed()); | 547 EXPECT_TRUE(has_failed()); |
| 565 EXPECT_EQ("Error during WebSocket handshake: " | 548 EXPECT_EQ("Error during WebSocket handshake: " |
| 566 "Response must not include 'Sec-WebSocket-Protocol' header " | 549 "Response must not include 'Sec-WebSocket-Protocol' header " |
| 567 "if not present in request: chatv20.chromium.org", | 550 "if not present in request: chatv20.chromium.org", |
| 568 failure_message()); | 551 failure_message()); |
| 569 } | 552 } |
| 570 | 553 |
| 571 // Missing sub-protocol response is rejected. | 554 // Missing sub-protocol response is rejected. |
| 572 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { | 555 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { |
| 573 std::vector<std::string> sub_protocols; | 556 std::vector<std::string> sub_protocols; |
| 574 sub_protocols.push_back("chat.example.com"); | 557 sub_protocols.push_back("chat.example.com"); |
| 575 CreateAndConnectStandard("ws://localhost/testing_path", | 558 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 576 "/testing_path", | 559 "/testing_path", sub_protocols, "http://localhost", |
| 577 sub_protocols, | 560 "Sec-WebSocket-Protocol: chat.example.com\r\n", ""); |
| 578 "http://localhost", | |
| 579 "Sec-WebSocket-Protocol: chat.example.com\r\n", | |
| 580 ""); | |
| 581 RunUntilIdle(); | 561 RunUntilIdle(); |
| 582 EXPECT_FALSE(stream_); | 562 EXPECT_FALSE(stream_); |
| 583 EXPECT_TRUE(has_failed()); | 563 EXPECT_TRUE(has_failed()); |
| 584 EXPECT_EQ("Error during WebSocket handshake: " | 564 EXPECT_EQ("Error during WebSocket handshake: " |
| 585 "Sent non-empty 'Sec-WebSocket-Protocol' header " | 565 "Sent non-empty 'Sec-WebSocket-Protocol' header " |
| 586 "but no response was received", | 566 "but no response was received", |
| 587 failure_message()); | 567 failure_message()); |
| 588 } | 568 } |
| 589 | 569 |
| 590 // Only one sub-protocol can be accepted. | 570 // Only one sub-protocol can be accepted. |
| 591 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { | 571 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { |
| 592 std::vector<std::string> sub_protocols; | 572 std::vector<std::string> sub_protocols; |
| 593 sub_protocols.push_back("chatv11.chromium.org"); | 573 sub_protocols.push_back("chatv11.chromium.org"); |
| 594 sub_protocols.push_back("chatv20.chromium.org"); | 574 sub_protocols.push_back("chatv20.chromium.org"); |
| 595 CreateAndConnectStandard("ws://localhost/testing_path", | 575 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 596 "/testing_path", | 576 "/testing_path", sub_protocols, "http://google.com", |
| 597 sub_protocols, | |
| 598 "http://google.com", | |
| 599 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 577 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
| 600 "chatv20.chromium.org\r\n", | 578 "chatv20.chromium.org\r\n", |
| 601 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 579 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
| 602 "chatv20.chromium.org\r\n"); | 580 "chatv20.chromium.org\r\n"); |
| 603 RunUntilIdle(); | 581 RunUntilIdle(); |
| 604 EXPECT_FALSE(stream_); | 582 EXPECT_FALSE(stream_); |
| 605 EXPECT_TRUE(has_failed()); | 583 EXPECT_TRUE(has_failed()); |
| 606 EXPECT_EQ("Error during WebSocket handshake: " | 584 EXPECT_EQ("Error during WebSocket handshake: " |
| 607 "'Sec-WebSocket-Protocol' header must not appear " | 585 "'Sec-WebSocket-Protocol' header must not appear " |
| 608 "more than once in a response", | 586 "more than once in a response", |
| 609 failure_message()); | 587 failure_message()); |
| 610 } | 588 } |
| 611 | 589 |
| 612 // Unmatched sub-protocol should be rejected. | 590 // Unmatched sub-protocol should be rejected. |
| 613 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { | 591 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { |
| 614 std::vector<std::string> sub_protocols; | 592 std::vector<std::string> sub_protocols; |
| 615 sub_protocols.push_back("chatv11.chromium.org"); | 593 sub_protocols.push_back("chatv11.chromium.org"); |
| 616 sub_protocols.push_back("chatv20.chromium.org"); | 594 sub_protocols.push_back("chatv20.chromium.org"); |
| 617 CreateAndConnectStandard("ws://localhost/testing_path", | 595 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 618 "/testing_path", | 596 "/testing_path", sub_protocols, "http://google.com", |
| 619 sub_protocols, | |
| 620 "http://google.com", | |
| 621 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 597 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
| 622 "chatv20.chromium.org\r\n", | 598 "chatv20.chromium.org\r\n", |
| 623 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); | 599 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); |
| 624 RunUntilIdle(); | 600 RunUntilIdle(); |
| 625 EXPECT_FALSE(stream_); | 601 EXPECT_FALSE(stream_); |
| 626 EXPECT_TRUE(has_failed()); | 602 EXPECT_TRUE(has_failed()); |
| 627 EXPECT_EQ("Error during WebSocket handshake: " | 603 EXPECT_EQ("Error during WebSocket handshake: " |
| 628 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " | 604 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " |
| 629 "in response does not match any of sent values", | 605 "in response does not match any of sent values", |
| 630 failure_message()); | 606 failure_message()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 644 "server_max_window_bits=11; client_max_window_bits=13; " | 620 "server_max_window_bits=11; client_max_window_bits=13; " |
| 645 "server_no_context_takeover"); | 621 "server_no_context_takeover"); |
| 646 EXPECT_TRUE(stream_); | 622 EXPECT_TRUE(stream_); |
| 647 EXPECT_FALSE(has_failed()); | 623 EXPECT_FALSE(has_failed()); |
| 648 } | 624 } |
| 649 | 625 |
| 650 // Verify that incoming messages are actually decompressed with | 626 // Verify that incoming messages are actually decompressed with |
| 651 // permessage-deflate enabled. | 627 // permessage-deflate enabled. |
| 652 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) { | 628 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) { |
| 653 CreateAndConnectCustomResponse( | 629 CreateAndConnectCustomResponse( |
| 654 "ws://localhost/testing_path", | 630 "ws://localhost/testing_path", "localhost", "/testing_path", |
| 655 "/testing_path", | 631 NoSubProtocols(), "http://localhost", "", |
| 656 NoSubProtocols(), | |
| 657 "http://localhost", | |
| 658 "", | |
| 659 WebSocketStandardResponse( | 632 WebSocketStandardResponse( |
| 660 "Sec-WebSocket-Extensions: permessage-deflate\r\n") + | 633 "Sec-WebSocket-Extensions: permessage-deflate\r\n") + |
| 661 std::string( | 634 std::string( |
| 662 "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) | 635 "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) |
| 663 "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed | 636 "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed |
| 664 9)); | 637 9)); |
| 665 RunUntilIdle(); | 638 RunUntilIdle(); |
| 666 | 639 |
| 667 ASSERT_TRUE(stream_); | 640 ASSERT_TRUE(stream_); |
| 668 ScopedVector<WebSocketFrame> frames; | 641 ScopedVector<WebSocketFrame> frames; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 failure_message()); | 803 failure_message()); |
| 831 } | 804 } |
| 832 | 805 |
| 833 // TODO(ricea): Check that WebSocketDeflateStream is initialised with the | 806 // TODO(ricea): Check that WebSocketDeflateStream is initialised with the |
| 834 // arguments from the server. This is difficult because the data written to the | 807 // arguments from the server. This is difficult because the data written to the |
| 835 // socket is randomly masked. | 808 // socket is randomly masked. |
| 836 | 809 |
| 837 // Additional Sec-WebSocket-Accept headers should be rejected. | 810 // Additional Sec-WebSocket-Accept headers should be rejected. |
| 838 TEST_F(WebSocketStreamCreateTest, DoubleAccept) { | 811 TEST_F(WebSocketStreamCreateTest, DoubleAccept) { |
| 839 CreateAndConnectStandard( | 812 CreateAndConnectStandard( |
| 840 "ws://localhost/", | 813 "ws://localhost/", "localhost", "/", NoSubProtocols(), "http://localhost", |
| 841 "/", | 814 "", "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); |
| 842 NoSubProtocols(), | |
| 843 "http://localhost", | |
| 844 "", | |
| 845 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); | |
| 846 RunUntilIdle(); | 815 RunUntilIdle(); |
| 847 EXPECT_FALSE(stream_); | 816 EXPECT_FALSE(stream_); |
| 848 EXPECT_TRUE(has_failed()); | 817 EXPECT_TRUE(has_failed()); |
| 849 EXPECT_EQ("Error during WebSocket handshake: " | 818 EXPECT_EQ("Error during WebSocket handshake: " |
| 850 "'Sec-WebSocket-Accept' header must not appear " | 819 "'Sec-WebSocket-Accept' header must not appear " |
| 851 "more than once in a response", | 820 "more than once in a response", |
| 852 failure_message()); | 821 failure_message()); |
| 853 } | 822 } |
| 854 | 823 |
| 855 // Response code 200 must be rejected. | 824 // Response code 200 must be rejected. |
| 856 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { | 825 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { |
| 857 static const char kInvalidStatusCodeResponse[] = | 826 static const char kInvalidStatusCodeResponse[] = |
| 858 "HTTP/1.1 200 OK\r\n" | 827 "HTTP/1.1 200 OK\r\n" |
| 859 "Upgrade: websocket\r\n" | 828 "Upgrade: websocket\r\n" |
| 860 "Connection: Upgrade\r\n" | 829 "Connection: Upgrade\r\n" |
| 861 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 830 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 862 "\r\n"; | 831 "\r\n"; |
| 863 CreateAndConnectCustomResponse("ws://localhost/", | 832 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 864 "/", | 833 NoSubProtocols(), "http://localhost", "", |
| 865 NoSubProtocols(), | |
| 866 "http://localhost", | |
| 867 "", | |
| 868 kInvalidStatusCodeResponse); | 834 kInvalidStatusCodeResponse); |
| 869 RunUntilIdle(); | 835 RunUntilIdle(); |
| 870 EXPECT_TRUE(has_failed()); | 836 EXPECT_TRUE(has_failed()); |
| 871 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", | 837 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", |
| 872 failure_message()); | 838 failure_message()); |
| 873 } | 839 } |
| 874 | 840 |
| 875 // Redirects are not followed (according to the WHATWG WebSocket API, which | 841 // Redirects are not followed (according to the WHATWG WebSocket API, which |
| 876 // overrides RFC6455 for browser applications). | 842 // overrides RFC6455 for browser applications). |
| 877 TEST_F(WebSocketStreamCreateTest, RedirectsRejected) { | 843 TEST_F(WebSocketStreamCreateTest, RedirectsRejected) { |
| 878 static const char kRedirectResponse[] = | 844 static const char kRedirectResponse[] = |
| 879 "HTTP/1.1 302 Moved Temporarily\r\n" | 845 "HTTP/1.1 302 Moved Temporarily\r\n" |
| 880 "Content-Type: text/html\r\n" | 846 "Content-Type: text/html\r\n" |
| 881 "Content-Length: 34\r\n" | 847 "Content-Length: 34\r\n" |
| 882 "Connection: keep-alive\r\n" | 848 "Connection: keep-alive\r\n" |
| 883 "Location: ws://localhost/other\r\n" | 849 "Location: ws://localhost/other\r\n" |
| 884 "\r\n" | 850 "\r\n" |
| 885 "<title>Moved</title><h1>Moved</h1>"; | 851 "<title>Moved</title><h1>Moved</h1>"; |
| 886 CreateAndConnectCustomResponse("ws://localhost/", | 852 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 887 "/", | 853 NoSubProtocols(), "http://localhost", "", |
| 888 NoSubProtocols(), | |
| 889 "http://localhost", | |
| 890 "", | |
| 891 kRedirectResponse); | 854 kRedirectResponse); |
| 892 RunUntilIdle(); | 855 RunUntilIdle(); |
| 893 EXPECT_TRUE(has_failed()); | 856 EXPECT_TRUE(has_failed()); |
| 894 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302", | 857 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302", |
| 895 failure_message()); | 858 failure_message()); |
| 896 } | 859 } |
| 897 | 860 |
| 898 // Malformed responses should be rejected. HttpStreamParser will accept just | 861 // Malformed responses should be rejected. HttpStreamParser will accept just |
| 899 // about any garbage in the middle of the headers. To make it give up, the junk | 862 // about any garbage in the middle of the headers. To make it give up, the junk |
| 900 // has to be at the start of the response. Even then, it just gets treated as an | 863 // has to be at the start of the response. Even then, it just gets treated as an |
| 901 // HTTP/0.9 response. | 864 // HTTP/0.9 response. |
| 902 TEST_F(WebSocketStreamCreateTest, MalformedResponse) { | 865 TEST_F(WebSocketStreamCreateTest, MalformedResponse) { |
| 903 static const char kMalformedResponse[] = | 866 static const char kMalformedResponse[] = |
| 904 "220 mx.google.com ESMTP\r\n" | 867 "220 mx.google.com ESMTP\r\n" |
| 905 "HTTP/1.1 101 OK\r\n" | 868 "HTTP/1.1 101 OK\r\n" |
| 906 "Upgrade: websocket\r\n" | 869 "Upgrade: websocket\r\n" |
| 907 "Connection: Upgrade\r\n" | 870 "Connection: Upgrade\r\n" |
| 908 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 871 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 909 "\r\n"; | 872 "\r\n"; |
| 910 CreateAndConnectCustomResponse("ws://localhost/", | 873 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 911 "/", | 874 NoSubProtocols(), "http://localhost", "", |
| 912 NoSubProtocols(), | |
| 913 "http://localhost", | |
| 914 "", | |
| 915 kMalformedResponse); | 875 kMalformedResponse); |
| 916 RunUntilIdle(); | 876 RunUntilIdle(); |
| 917 EXPECT_TRUE(has_failed()); | 877 EXPECT_TRUE(has_failed()); |
| 918 EXPECT_EQ("Error during WebSocket handshake: Invalid status line", | 878 EXPECT_EQ("Error during WebSocket handshake: Invalid status line", |
| 919 failure_message()); | 879 failure_message()); |
| 920 } | 880 } |
| 921 | 881 |
| 922 // Upgrade header must be present. | 882 // Upgrade header must be present. |
| 923 TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) { | 883 TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) { |
| 924 static const char kMissingUpgradeResponse[] = | 884 static const char kMissingUpgradeResponse[] = |
| 925 "HTTP/1.1 101 Switching Protocols\r\n" | 885 "HTTP/1.1 101 Switching Protocols\r\n" |
| 926 "Connection: Upgrade\r\n" | 886 "Connection: Upgrade\r\n" |
| 927 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 887 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 928 "\r\n"; | 888 "\r\n"; |
| 929 CreateAndConnectCustomResponse("ws://localhost/", | 889 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 930 "/", | 890 NoSubProtocols(), "http://localhost", "", |
| 931 NoSubProtocols(), | |
| 932 "http://localhost", | |
| 933 "", | |
| 934 kMissingUpgradeResponse); | 891 kMissingUpgradeResponse); |
| 935 RunUntilIdle(); | 892 RunUntilIdle(); |
| 936 EXPECT_TRUE(has_failed()); | 893 EXPECT_TRUE(has_failed()); |
| 937 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", | 894 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", |
| 938 failure_message()); | 895 failure_message()); |
| 939 } | 896 } |
| 940 | 897 |
| 941 // There must only be one upgrade header. | 898 // There must only be one upgrade header. |
| 942 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { | 899 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { |
| 943 CreateAndConnectStandard( | 900 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 944 "ws://localhost/", | 901 NoSubProtocols(), "http://localhost", "", |
| 945 "/", | 902 "Upgrade: HTTP/2.0\r\n"); |
| 946 NoSubProtocols(), | |
| 947 "http://localhost", | |
| 948 "", "Upgrade: HTTP/2.0\r\n"); | |
| 949 RunUntilIdle(); | 903 RunUntilIdle(); |
| 950 EXPECT_TRUE(has_failed()); | 904 EXPECT_TRUE(has_failed()); |
| 951 EXPECT_EQ("Error during WebSocket handshake: " | 905 EXPECT_EQ("Error during WebSocket handshake: " |
| 952 "'Upgrade' header must not appear more than once in a response", | 906 "'Upgrade' header must not appear more than once in a response", |
| 953 failure_message()); | 907 failure_message()); |
| 954 } | 908 } |
| 955 | 909 |
| 956 // There must only be one correct upgrade header. | 910 // There must only be one correct upgrade header. |
| 957 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { | 911 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { |
| 958 static const char kMissingUpgradeResponse[] = | 912 static const char kMissingUpgradeResponse[] = |
| 959 "HTTP/1.1 101 Switching Protocols\r\n" | 913 "HTTP/1.1 101 Switching Protocols\r\n" |
| 960 "Connection: Upgrade\r\n" | 914 "Connection: Upgrade\r\n" |
| 961 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 915 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 962 "Upgrade: hogefuga\r\n" | 916 "Upgrade: hogefuga\r\n" |
| 963 "\r\n"; | 917 "\r\n"; |
| 964 CreateAndConnectCustomResponse("ws://localhost/", | 918 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 965 "/", | 919 NoSubProtocols(), "http://localhost", "", |
| 966 NoSubProtocols(), | |
| 967 "http://localhost", | |
| 968 "", | |
| 969 kMissingUpgradeResponse); | 920 kMissingUpgradeResponse); |
| 970 RunUntilIdle(); | 921 RunUntilIdle(); |
| 971 EXPECT_TRUE(has_failed()); | 922 EXPECT_TRUE(has_failed()); |
| 972 EXPECT_EQ("Error during WebSocket handshake: " | 923 EXPECT_EQ("Error during WebSocket handshake: " |
| 973 "'Upgrade' header value is not 'WebSocket': hogefuga", | 924 "'Upgrade' header value is not 'WebSocket': hogefuga", |
| 974 failure_message()); | 925 failure_message()); |
| 975 } | 926 } |
| 976 | 927 |
| 977 // Connection header must be present. | 928 // Connection header must be present. |
| 978 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { | 929 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { |
| 979 static const char kMissingConnectionResponse[] = | 930 static const char kMissingConnectionResponse[] = |
| 980 "HTTP/1.1 101 Switching Protocols\r\n" | 931 "HTTP/1.1 101 Switching Protocols\r\n" |
| 981 "Upgrade: websocket\r\n" | 932 "Upgrade: websocket\r\n" |
| 982 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 933 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 983 "\r\n"; | 934 "\r\n"; |
| 984 CreateAndConnectCustomResponse("ws://localhost/", | 935 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 985 "/", | 936 NoSubProtocols(), "http://localhost", "", |
| 986 NoSubProtocols(), | |
| 987 "http://localhost", | |
| 988 "", | |
| 989 kMissingConnectionResponse); | 937 kMissingConnectionResponse); |
| 990 RunUntilIdle(); | 938 RunUntilIdle(); |
| 991 EXPECT_TRUE(has_failed()); | 939 EXPECT_TRUE(has_failed()); |
| 992 EXPECT_EQ("Error during WebSocket handshake: " | 940 EXPECT_EQ("Error during WebSocket handshake: " |
| 993 "'Connection' header is missing", | 941 "'Connection' header is missing", |
| 994 failure_message()); | 942 failure_message()); |
| 995 } | 943 } |
| 996 | 944 |
| 997 // Connection header must contain "Upgrade". | 945 // Connection header must contain "Upgrade". |
| 998 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { | 946 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { |
| 999 static const char kMissingConnectionResponse[] = | 947 static const char kMissingConnectionResponse[] = |
| 1000 "HTTP/1.1 101 Switching Protocols\r\n" | 948 "HTTP/1.1 101 Switching Protocols\r\n" |
| 1001 "Upgrade: websocket\r\n" | 949 "Upgrade: websocket\r\n" |
| 1002 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 950 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 1003 "Connection: hogefuga\r\n" | 951 "Connection: hogefuga\r\n" |
| 1004 "\r\n"; | 952 "\r\n"; |
| 1005 CreateAndConnectCustomResponse("ws://localhost/", | 953 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 1006 "/", | 954 NoSubProtocols(), "http://localhost", "", |
| 1007 NoSubProtocols(), | |
| 1008 "http://localhost", | |
| 1009 "", | |
| 1010 kMissingConnectionResponse); | 955 kMissingConnectionResponse); |
| 1011 RunUntilIdle(); | 956 RunUntilIdle(); |
| 1012 EXPECT_TRUE(has_failed()); | 957 EXPECT_TRUE(has_failed()); |
| 1013 EXPECT_EQ("Error during WebSocket handshake: " | 958 EXPECT_EQ("Error during WebSocket handshake: " |
| 1014 "'Connection' header value must contain 'Upgrade'", | 959 "'Connection' header value must contain 'Upgrade'", |
| 1015 failure_message()); | 960 failure_message()); |
| 1016 } | 961 } |
| 1017 | 962 |
| 1018 // Connection header is permitted to contain other tokens. | 963 // Connection header is permitted to contain other tokens. |
| 1019 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { | 964 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { |
| 1020 static const char kAdditionalConnectionTokenResponse[] = | 965 static const char kAdditionalConnectionTokenResponse[] = |
| 1021 "HTTP/1.1 101 Switching Protocols\r\n" | 966 "HTTP/1.1 101 Switching Protocols\r\n" |
| 1022 "Upgrade: websocket\r\n" | 967 "Upgrade: websocket\r\n" |
| 1023 "Connection: Upgrade, Keep-Alive\r\n" | 968 "Connection: Upgrade, Keep-Alive\r\n" |
| 1024 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 969 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 1025 "\r\n"; | 970 "\r\n"; |
| 1026 CreateAndConnectCustomResponse("ws://localhost/", | 971 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 1027 "/", | 972 NoSubProtocols(), "http://localhost", "", |
| 1028 NoSubProtocols(), | |
| 1029 "http://localhost", | |
| 1030 "", | |
| 1031 kAdditionalConnectionTokenResponse); | 973 kAdditionalConnectionTokenResponse); |
| 1032 RunUntilIdle(); | 974 RunUntilIdle(); |
| 1033 EXPECT_FALSE(has_failed()); | 975 EXPECT_FALSE(has_failed()); |
| 1034 EXPECT_TRUE(stream_); | 976 EXPECT_TRUE(stream_); |
| 1035 } | 977 } |
| 1036 | 978 |
| 1037 // Sec-WebSocket-Accept header must be present. | 979 // Sec-WebSocket-Accept header must be present. |
| 1038 TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) { | 980 TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) { |
| 1039 static const char kMissingAcceptResponse[] = | 981 static const char kMissingAcceptResponse[] = |
| 1040 "HTTP/1.1 101 Switching Protocols\r\n" | 982 "HTTP/1.1 101 Switching Protocols\r\n" |
| 1041 "Upgrade: websocket\r\n" | 983 "Upgrade: websocket\r\n" |
| 1042 "Connection: Upgrade\r\n" | 984 "Connection: Upgrade\r\n" |
| 1043 "\r\n"; | 985 "\r\n"; |
| 1044 CreateAndConnectCustomResponse("ws://localhost/", | 986 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 1045 "/", | 987 NoSubProtocols(), "http://localhost", "", |
| 1046 NoSubProtocols(), | |
| 1047 "http://localhost", | |
| 1048 "", | |
| 1049 kMissingAcceptResponse); | 988 kMissingAcceptResponse); |
| 1050 RunUntilIdle(); | 989 RunUntilIdle(); |
| 1051 EXPECT_TRUE(has_failed()); | 990 EXPECT_TRUE(has_failed()); |
| 1052 EXPECT_EQ("Error during WebSocket handshake: " | 991 EXPECT_EQ("Error during WebSocket handshake: " |
| 1053 "'Sec-WebSocket-Accept' header is missing", | 992 "'Sec-WebSocket-Accept' header is missing", |
| 1054 failure_message()); | 993 failure_message()); |
| 1055 } | 994 } |
| 1056 | 995 |
| 1057 // Sec-WebSocket-Accept header must match the key that was sent. | 996 // Sec-WebSocket-Accept header must match the key that was sent. |
| 1058 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { | 997 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { |
| 1059 static const char kIncorrectAcceptResponse[] = | 998 static const char kIncorrectAcceptResponse[] = |
| 1060 "HTTP/1.1 101 Switching Protocols\r\n" | 999 "HTTP/1.1 101 Switching Protocols\r\n" |
| 1061 "Upgrade: websocket\r\n" | 1000 "Upgrade: websocket\r\n" |
| 1062 "Connection: Upgrade\r\n" | 1001 "Connection: Upgrade\r\n" |
| 1063 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" | 1002 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" |
| 1064 "\r\n"; | 1003 "\r\n"; |
| 1065 CreateAndConnectCustomResponse("ws://localhost/", | 1004 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 1066 "/", | 1005 NoSubProtocols(), "http://localhost", "", |
| 1067 NoSubProtocols(), | |
| 1068 "http://localhost", | |
| 1069 "", | |
| 1070 kIncorrectAcceptResponse); | 1006 kIncorrectAcceptResponse); |
| 1071 RunUntilIdle(); | 1007 RunUntilIdle(); |
| 1072 EXPECT_TRUE(has_failed()); | 1008 EXPECT_TRUE(has_failed()); |
| 1073 EXPECT_EQ("Error during WebSocket handshake: " | 1009 EXPECT_EQ("Error during WebSocket handshake: " |
| 1074 "Incorrect 'Sec-WebSocket-Accept' header value", | 1010 "Incorrect 'Sec-WebSocket-Accept' header value", |
| 1075 failure_message()); | 1011 failure_message()); |
| 1076 } | 1012 } |
| 1077 | 1013 |
| 1078 // Cancellation works. | 1014 // Cancellation works. |
| 1079 TEST_F(WebSocketStreamCreateTest, Cancellation) { | 1015 TEST_F(WebSocketStreamCreateTest, Cancellation) { |
| 1080 CreateAndConnectStandard( | 1016 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 1081 "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", ""); | 1017 NoSubProtocols(), "http://localhost", "", ""); |
| 1082 stream_request_.reset(); | 1018 stream_request_.reset(); |
| 1083 RunUntilIdle(); | 1019 RunUntilIdle(); |
| 1084 EXPECT_FALSE(has_failed()); | 1020 EXPECT_FALSE(has_failed()); |
| 1085 EXPECT_FALSE(stream_); | 1021 EXPECT_FALSE(stream_); |
| 1086 EXPECT_FALSE(request_info_); | 1022 EXPECT_FALSE(request_info_); |
| 1087 EXPECT_FALSE(response_info_); | 1023 EXPECT_FALSE(response_info_); |
| 1088 } | 1024 } |
| 1089 | 1025 |
| 1090 // Connect failure must look just like negotiation failure. | 1026 // Connect failure must look just like negotiation failure. |
| 1091 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { | 1027 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1137 EXPECT_EQ("WebSocket opening handshake timed out", failure_message()); | 1073 EXPECT_EQ("WebSocket opening handshake timed out", failure_message()); |
| 1138 ASSERT_TRUE(weak_timer.get()); | 1074 ASSERT_TRUE(weak_timer.get()); |
| 1139 EXPECT_FALSE(weak_timer->IsRunning()); | 1075 EXPECT_FALSE(weak_timer->IsRunning()); |
| 1140 } | 1076 } |
| 1141 | 1077 |
| 1142 // When the connection establishes the timer should be stopped. | 1078 // When the connection establishes the timer should be stopped. |
| 1143 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) { | 1079 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) { |
| 1144 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); | 1080 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
| 1145 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); | 1081 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
| 1146 | 1082 |
| 1147 CreateAndConnectStandard("ws://localhost/", | 1083 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 1148 "/", | 1084 NoSubProtocols(), "http://localhost", "", "", |
| 1149 NoSubProtocols(), | |
| 1150 "http://localhost", | |
| 1151 "", | |
| 1152 "", | |
| 1153 timer.Pass()); | 1085 timer.Pass()); |
| 1154 ASSERT_TRUE(weak_timer); | 1086 ASSERT_TRUE(weak_timer); |
| 1155 EXPECT_TRUE(weak_timer->IsRunning()); | 1087 EXPECT_TRUE(weak_timer->IsRunning()); |
| 1156 | 1088 |
| 1157 RunUntilIdle(); | 1089 RunUntilIdle(); |
| 1158 EXPECT_FALSE(has_failed()); | 1090 EXPECT_FALSE(has_failed()); |
| 1159 EXPECT_TRUE(stream_); | 1091 EXPECT_TRUE(stream_); |
| 1160 ASSERT_TRUE(weak_timer); | 1092 ASSERT_TRUE(weak_timer); |
| 1161 EXPECT_FALSE(weak_timer->IsRunning()); | 1093 EXPECT_FALSE(weak_timer->IsRunning()); |
| 1162 } | 1094 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1216 stream_request_.reset(); | 1148 stream_request_.reset(); |
| 1217 RunUntilIdle(); | 1149 RunUntilIdle(); |
| 1218 EXPECT_FALSE(has_failed()); | 1150 EXPECT_FALSE(has_failed()); |
| 1219 EXPECT_FALSE(stream_); | 1151 EXPECT_FALSE(stream_); |
| 1220 EXPECT_TRUE(request_info_); | 1152 EXPECT_TRUE(request_info_); |
| 1221 EXPECT_FALSE(response_info_); | 1153 EXPECT_FALSE(response_info_); |
| 1222 } | 1154 } |
| 1223 | 1155 |
| 1224 // Cancellation during read of the response headers works. | 1156 // Cancellation during read of the response headers works. |
| 1225 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { | 1157 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { |
| 1226 std::string request = WebSocketStandardRequest("/", "http://localhost", ""); | 1158 std::string request = |
| 1159 WebSocketStandardRequest("/", "localhost", "http://localhost", ""); |
| 1227 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; | 1160 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; |
| 1228 MockRead reads[] = { | 1161 MockRead reads[] = { |
| 1229 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"), | 1162 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"), |
| 1230 }; | 1163 }; |
| 1231 scoped_ptr<DeterministicSocketData> socket_data( | 1164 scoped_ptr<DeterministicSocketData> socket_data( |
| 1232 BuildSocketData(reads, writes)); | 1165 BuildSocketData(reads, writes)); |
| 1233 socket_data->SetStop(1); | 1166 socket_data->SetStop(1); |
| 1234 DeterministicSocketData* socket_data_raw_ptr = socket_data.get(); | 1167 DeterministicSocketData* socket_data_raw_ptr = socket_data.get(); |
| 1235 CreateAndConnectRawExpectations("ws://localhost/", | 1168 CreateAndConnectRawExpectations("ws://localhost/", |
| 1236 NoSubProtocols(), | 1169 NoSubProtocols(), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1248 // Over-size response headers (> 256KB) should not cause a crash. This is a | 1181 // Over-size response headers (> 256KB) should not cause a crash. This is a |
| 1249 // regression test for crbug.com/339456. It is based on the layout test | 1182 // regression test for crbug.com/339456. It is based on the layout test |
| 1250 // "cookie-flood.html". | 1183 // "cookie-flood.html". |
| 1251 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { | 1184 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { |
| 1252 std::string set_cookie_headers; | 1185 std::string set_cookie_headers; |
| 1253 set_cookie_headers.reserve(45 * 10000); | 1186 set_cookie_headers.reserve(45 * 10000); |
| 1254 for (int i = 0; i < 10000; ++i) { | 1187 for (int i = 0; i < 10000; ++i) { |
| 1255 set_cookie_headers += | 1188 set_cookie_headers += |
| 1256 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); | 1189 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); |
| 1257 } | 1190 } |
| 1258 CreateAndConnectStandard("ws://localhost/", "/", NoSubProtocols(), | 1191 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 1259 "http://localhost", "", set_cookie_headers); | 1192 NoSubProtocols(), "http://localhost", "", |
| 1193 set_cookie_headers); |
| 1260 RunUntilIdle(); | 1194 RunUntilIdle(); |
| 1261 EXPECT_TRUE(has_failed()); | 1195 EXPECT_TRUE(has_failed()); |
| 1262 EXPECT_FALSE(response_info_); | 1196 EXPECT_FALSE(response_info_); |
| 1263 } | 1197 } |
| 1264 | 1198 |
| 1265 // If the remote host closes the connection without sending headers, we should | 1199 // If the remote host closes the connection without sending headers, we should |
| 1266 // log the console message "Connection closed before receiving a handshake | 1200 // log the console message "Connection closed before receiving a handshake |
| 1267 // response". | 1201 // response". |
| 1268 TEST_F(WebSocketStreamCreateTest, NoResponse) { | 1202 TEST_F(WebSocketStreamCreateTest, NoResponse) { |
| 1269 std::string request = WebSocketStandardRequest("/", "http://localhost", ""); | 1203 std::string request = |
| 1204 WebSocketStandardRequest("/", "localhost", "http://localhost", ""); |
| 1270 MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)}; | 1205 MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)}; |
| 1271 MockRead reads[] = {MockRead(ASYNC, 0, 1)}; | 1206 MockRead reads[] = {MockRead(ASYNC, 0, 1)}; |
| 1272 scoped_ptr<DeterministicSocketData> socket_data( | 1207 scoped_ptr<DeterministicSocketData> socket_data( |
| 1273 BuildSocketData(reads, writes)); | 1208 BuildSocketData(reads, writes)); |
| 1274 DeterministicSocketData* socket_data_raw_ptr = socket_data.get(); | 1209 DeterministicSocketData* socket_data_raw_ptr = socket_data.get(); |
| 1275 CreateAndConnectRawExpectations("ws://localhost/", | 1210 CreateAndConnectRawExpectations("ws://localhost/", |
| 1276 NoSubProtocols(), | 1211 NoSubProtocols(), |
| 1277 "http://localhost", | 1212 "http://localhost", |
| 1278 socket_data.Pass()); | 1213 socket_data.Pass()); |
| 1279 socket_data_raw_ptr->RunFor(2); | 1214 socket_data_raw_ptr->RunFor(2); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1307 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { | 1242 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { |
| 1308 scoped_ptr<SSLSocketDataProvider> ssl_data( | 1243 scoped_ptr<SSLSocketDataProvider> ssl_data( |
| 1309 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); | 1244 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); |
| 1310 ssl_data->cert = | 1245 ssl_data->cert = |
| 1311 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); | 1246 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); |
| 1312 ASSERT_TRUE(ssl_data->cert.get()); | 1247 ASSERT_TRUE(ssl_data->cert.get()); |
| 1313 ssl_data_.push_back(ssl_data.release()); | 1248 ssl_data_.push_back(ssl_data.release()); |
| 1314 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); | 1249 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); |
| 1315 ssl_data_.push_back(ssl_data.release()); | 1250 ssl_data_.push_back(ssl_data.release()); |
| 1316 url_request_context_host_.AddRawExpectations(BuildNullSocketData()); | 1251 url_request_context_host_.AddRawExpectations(BuildNullSocketData()); |
| 1317 CreateAndConnectStandard( | 1252 CreateAndConnectStandard("wss://localhost/", "localhost", "/", |
| 1318 "wss://localhost/", "/", NoSubProtocols(), "http://localhost", "", ""); | 1253 NoSubProtocols(), "http://localhost", "", ""); |
| 1319 RunUntilIdle(); | 1254 RunUntilIdle(); |
| 1320 ASSERT_TRUE(ssl_error_callbacks_); | 1255 ASSERT_TRUE(ssl_error_callbacks_); |
| 1321 ssl_error_callbacks_->ContinueSSLRequest(); | 1256 ssl_error_callbacks_->ContinueSSLRequest(); |
| 1322 RunUntilIdle(); | 1257 RunUntilIdle(); |
| 1323 EXPECT_FALSE(has_failed()); | 1258 EXPECT_FALSE(has_failed()); |
| 1324 EXPECT_TRUE(stream_); | 1259 EXPECT_TRUE(stream_); |
| 1325 } | 1260 } |
| 1326 | 1261 |
| 1327 // If the server requests authorisation, but we have no credentials, the | 1262 // If the server requests authorisation, but we have no credentials, the |
| 1328 // connection should fail cleanly. | 1263 // connection should fail cleanly. |
| 1329 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) { | 1264 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) { |
| 1330 CreateAndConnectCustomResponse("ws://localhost/", | 1265 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 1331 "/", | 1266 NoSubProtocols(), "http://localhost", "", |
| 1332 NoSubProtocols(), | |
| 1333 "http://localhost", | |
| 1334 "", | |
| 1335 kUnauthorizedResponse); | 1267 kUnauthorizedResponse); |
| 1336 RunUntilIdle(); | 1268 RunUntilIdle(); |
| 1337 EXPECT_TRUE(has_failed()); | 1269 EXPECT_TRUE(has_failed()); |
| 1338 EXPECT_EQ("HTTP Authentication failed; no valid credentials available", | 1270 EXPECT_EQ("HTTP Authentication failed; no valid credentials available", |
| 1339 failure_message()); | 1271 failure_message()); |
| 1340 EXPECT_TRUE(response_info_); | 1272 EXPECT_TRUE(response_info_); |
| 1341 } | 1273 } |
| 1342 | 1274 |
| 1343 TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) { | 1275 TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) { |
| 1344 CreateAndConnectAuthHandshake("ws://foo:bar@localhost/", | 1276 CreateAndConnectAuthHandshake("ws://foo:bar@localhost/", |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1377 ASSERT_TRUE(response_info_); | 1309 ASSERT_TRUE(response_info_); |
| 1378 EXPECT_EQ(101, response_info_->status_code); | 1310 EXPECT_EQ(101, response_info_->status_code); |
| 1379 } | 1311 } |
| 1380 | 1312 |
| 1381 TEST_F(WebSocketStreamCreateUMATest, Incomplete) { | 1313 TEST_F(WebSocketStreamCreateUMATest, Incomplete) { |
| 1382 const std::string name("Net.WebSocket.HandshakeResult"); | 1314 const std::string name("Net.WebSocket.HandshakeResult"); |
| 1383 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); | 1315 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); |
| 1384 | 1316 |
| 1385 { | 1317 { |
| 1386 StreamCreation creation; | 1318 StreamCreation creation; |
| 1387 creation.CreateAndConnectStandard("ws://localhost/", | 1319 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 1388 "/", | |
| 1389 creation.NoSubProtocols(), | 1320 creation.NoSubProtocols(), |
| 1390 "http://localhost", | 1321 "http://localhost", "", ""); |
| 1391 "", | |
| 1392 ""); | |
| 1393 } | 1322 } |
| 1394 | 1323 |
| 1395 scoped_ptr<base::HistogramSamples> samples(GetSamples(name)); | 1324 scoped_ptr<base::HistogramSamples> samples(GetSamples(name)); |
| 1396 ASSERT_TRUE(samples); | 1325 ASSERT_TRUE(samples); |
| 1397 if (original) { | 1326 if (original) { |
| 1398 samples->Subtract(*original); // Cancel the original values. | 1327 samples->Subtract(*original); // Cancel the original values. |
| 1399 } | 1328 } |
| 1400 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); | 1329 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); |
| 1401 EXPECT_EQ(0, samples->GetCount(CONNECTED)); | 1330 EXPECT_EQ(0, samples->GetCount(CONNECTED)); |
| 1402 EXPECT_EQ(0, samples->GetCount(FAILED)); | 1331 EXPECT_EQ(0, samples->GetCount(FAILED)); |
| 1403 } | 1332 } |
| 1404 | 1333 |
| 1405 TEST_F(WebSocketStreamCreateUMATest, Connected) { | 1334 TEST_F(WebSocketStreamCreateUMATest, Connected) { |
| 1406 const std::string name("Net.WebSocket.HandshakeResult"); | 1335 const std::string name("Net.WebSocket.HandshakeResult"); |
| 1407 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); | 1336 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); |
| 1408 | 1337 |
| 1409 { | 1338 { |
| 1410 StreamCreation creation; | 1339 StreamCreation creation; |
| 1411 creation.CreateAndConnectStandard("ws://localhost/", | 1340 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 1412 "/", | |
| 1413 creation.NoSubProtocols(), | 1341 creation.NoSubProtocols(), |
| 1414 "http://localhost", | 1342 "http://localhost", "", ""); |
| 1415 "", | |
| 1416 ""); | |
| 1417 creation.RunUntilIdle(); | 1343 creation.RunUntilIdle(); |
| 1418 } | 1344 } |
| 1419 | 1345 |
| 1420 scoped_ptr<base::HistogramSamples> samples(GetSamples(name)); | 1346 scoped_ptr<base::HistogramSamples> samples(GetSamples(name)); |
| 1421 ASSERT_TRUE(samples); | 1347 ASSERT_TRUE(samples); |
| 1422 if (original) { | 1348 if (original) { |
| 1423 samples->Subtract(*original); // Cancel the original values. | 1349 samples->Subtract(*original); // Cancel the original values. |
| 1424 } | 1350 } |
| 1425 EXPECT_EQ(0, samples->GetCount(INCOMPLETE)); | 1351 EXPECT_EQ(0, samples->GetCount(INCOMPLETE)); |
| 1426 EXPECT_EQ(1, samples->GetCount(CONNECTED)); | 1352 EXPECT_EQ(1, samples->GetCount(CONNECTED)); |
| 1427 EXPECT_EQ(0, samples->GetCount(FAILED)); | 1353 EXPECT_EQ(0, samples->GetCount(FAILED)); |
| 1428 } | 1354 } |
| 1429 | 1355 |
| 1430 TEST_F(WebSocketStreamCreateUMATest, Failed) { | 1356 TEST_F(WebSocketStreamCreateUMATest, Failed) { |
| 1431 const std::string name("Net.WebSocket.HandshakeResult"); | 1357 const std::string name("Net.WebSocket.HandshakeResult"); |
| 1432 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); | 1358 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); |
| 1433 | 1359 |
| 1434 { | 1360 { |
| 1435 StreamCreation creation; | 1361 StreamCreation creation; |
| 1436 static const char kInvalidStatusCodeResponse[] = | 1362 static const char kInvalidStatusCodeResponse[] = |
| 1437 "HTTP/1.1 200 OK\r\n" | 1363 "HTTP/1.1 200 OK\r\n" |
| 1438 "Upgrade: websocket\r\n" | 1364 "Upgrade: websocket\r\n" |
| 1439 "Connection: Upgrade\r\n" | 1365 "Connection: Upgrade\r\n" |
| 1440 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 1366 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 1441 "\r\n"; | 1367 "\r\n"; |
| 1442 creation.CreateAndConnectCustomResponse("ws://localhost/", | 1368 creation.CreateAndConnectCustomResponse( |
| 1443 "/", | 1369 "ws://localhost/", "localhost", "/", creation.NoSubProtocols(), |
| 1444 creation.NoSubProtocols(), | 1370 "http://localhost", "", kInvalidStatusCodeResponse); |
| 1445 "http://localhost", | |
| 1446 "", | |
| 1447 kInvalidStatusCodeResponse); | |
| 1448 creation.RunUntilIdle(); | 1371 creation.RunUntilIdle(); |
| 1449 } | 1372 } |
| 1450 | 1373 |
| 1451 scoped_ptr<base::HistogramSamples> samples(GetSamples(name)); | 1374 scoped_ptr<base::HistogramSamples> samples(GetSamples(name)); |
| 1452 ASSERT_TRUE(samples); | 1375 ASSERT_TRUE(samples); |
| 1453 if (original) { | 1376 if (original) { |
| 1454 samples->Subtract(*original); // Cancel the original values. | 1377 samples->Subtract(*original); // Cancel the original values. |
| 1455 } | 1378 } |
| 1456 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); | 1379 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); |
| 1457 EXPECT_EQ(0, samples->GetCount(CONNECTED)); | 1380 EXPECT_EQ(0, samples->GetCount(CONNECTED)); |
| 1458 EXPECT_EQ(0, samples->GetCount(FAILED)); | 1381 EXPECT_EQ(0, samples->GetCount(FAILED)); |
| 1459 } | 1382 } |
| 1460 | 1383 |
| 1461 } // namespace | 1384 } // namespace |
| 1462 } // namespace net | 1385 } // namespace net |
| OLD | NEW |