| 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 stream_.reset(); | 85 stream_.reset(); |
| 86 base::RunLoop().RunUntilIdle(); | 86 base::RunLoop().RunUntilIdle(); |
| 87 } | 87 } |
| 88 | 88 |
| 89 void CreateAndConnectCustomResponse( | 89 void CreateAndConnectCustomResponse( |
| 90 const std::string& socket_url, | 90 const std::string& socket_url, |
| 91 const std::string& socket_host, | 91 const std::string& socket_host, |
| 92 const std::string& socket_path, | 92 const std::string& socket_path, |
| 93 const std::vector<std::string>& sub_protocols, | 93 const std::vector<std::string>& sub_protocols, |
| 94 const url::Origin& origin, | 94 const url::Origin& origin, |
| 95 const std::string& send_additional_request_headers, |
| 95 const std::string& extra_request_headers, | 96 const std::string& extra_request_headers, |
| 96 const std::string& response_body, | 97 const std::string& response_body, |
| 97 std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { | 98 std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { |
| 98 url_request_context_host_.SetExpectations( | 99 url_request_context_host_.SetExpectations( |
| 99 WebSocketStandardRequest(socket_path, socket_host, origin, | 100 WebSocketStandardRequest(socket_path, socket_host, origin, |
| 100 extra_request_headers), | 101 extra_request_headers), |
| 101 response_body); | 102 response_body); |
| 102 CreateAndConnectStream(socket_url, sub_protocols, origin, std::move(timer)); | 103 CreateAndConnectStream(socket_url, sub_protocols, origin, |
| 104 send_additional_request_headers, std::move(timer)); |
| 103 } | 105 } |
| 104 | 106 |
| 105 // |extra_request_headers| and |extra_response_headers| must end in "\r\n" or | 107 // |extra_request_headers| and |extra_response_headers| must end in "\r\n" or |
| 106 // errors like "Unable to perform synchronous IO while stopped" will occur. | 108 // errors like "Unable to perform synchronous IO while stopped" will occur. |
| 107 void CreateAndConnectStandard( | 109 void CreateAndConnectStandard( |
| 108 const std::string& socket_url, | 110 const std::string& socket_url, |
| 109 const std::string& socket_host, | 111 const std::string& socket_host, |
| 110 const std::string& socket_path, | 112 const std::string& socket_path, |
| 111 const std::vector<std::string>& sub_protocols, | 113 const std::vector<std::string>& sub_protocols, |
| 112 const url::Origin& origin, | 114 const url::Origin& origin, |
| 115 const std::string& send_additional_request_headers, |
| 113 const std::string& extra_request_headers, | 116 const std::string& extra_request_headers, |
| 114 const std::string& extra_response_headers, | 117 const std::string& extra_response_headers, |
| 115 std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { | 118 std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { |
| 116 CreateAndConnectCustomResponse( | 119 CreateAndConnectCustomResponse( |
| 117 socket_url, socket_host, socket_path, sub_protocols, origin, | 120 socket_url, socket_host, socket_path, sub_protocols, origin, |
| 118 extra_request_headers, | 121 send_additional_request_headers, extra_request_headers, |
| 119 WebSocketStandardResponse(extra_response_headers), std::move(timer)); | 122 WebSocketStandardResponse(extra_response_headers), std::move(timer)); |
| 120 } | 123 } |
| 121 | 124 |
| 122 void CreateAndConnectRawExpectations( | 125 void CreateAndConnectRawExpectations( |
| 123 const std::string& socket_url, | 126 const std::string& socket_url, |
| 124 const std::vector<std::string>& sub_protocols, | 127 const std::vector<std::string>& sub_protocols, |
| 125 const url::Origin& origin, | 128 const url::Origin& origin, |
| 129 const std::string& send_additional_request_headers, |
| 126 std::unique_ptr<SequencedSocketData> socket_data, | 130 std::unique_ptr<SequencedSocketData> socket_data, |
| 127 std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { | 131 std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { |
| 128 AddRawExpectations(std::move(socket_data)); | 132 AddRawExpectations(std::move(socket_data)); |
| 129 CreateAndConnectStream(socket_url, sub_protocols, origin, std::move(timer)); | 133 CreateAndConnectStream(socket_url, sub_protocols, origin, |
| 134 send_additional_request_headers, std::move(timer)); |
| 130 } | 135 } |
| 131 | 136 |
| 132 // Add additional raw expectations for sockets created before the final one. | 137 // Add additional raw expectations for sockets created before the final one. |
| 133 void AddRawExpectations(std::unique_ptr<SequencedSocketData> socket_data) { | 138 void AddRawExpectations(std::unique_ptr<SequencedSocketData> socket_data) { |
| 134 url_request_context_host_.AddRawExpectations(std::move(socket_data)); | 139 url_request_context_host_.AddRawExpectations(std::move(socket_data)); |
| 135 } | 140 } |
| 136 }; | 141 }; |
| 137 | 142 |
| 138 // There are enough tests of the Sec-WebSocket-Extensions header that they | 143 // There are enough tests of the Sec-WebSocket-Extensions header that they |
| 139 // deserve their own test fixture. | 144 // deserve their own test fixture. |
| 140 class WebSocketStreamCreateExtensionTest : public WebSocketStreamCreateTest { | 145 class WebSocketStreamCreateExtensionTest : public WebSocketStreamCreateTest { |
| 141 public: | 146 public: |
| 142 // Performs a standard connect, with the value of the Sec-WebSocket-Extensions | 147 // Performs a standard connect, with the value of the Sec-WebSocket-Extensions |
| 143 // header in the response set to |extensions_header_value|. Runs the event | 148 // header in the response set to |extensions_header_value|. Runs the event |
| 144 // loop to allow the connect to complete. | 149 // loop to allow the connect to complete. |
| 145 void CreateAndConnectWithExtensions( | 150 void CreateAndConnectWithExtensions( |
| 146 const std::string& extensions_header_value) { | 151 const std::string& extensions_header_value) { |
| 147 CreateAndConnectStandard( | 152 CreateAndConnectStandard( |
| 148 "ws://localhost/testing_path", "localhost", "/testing_path", | 153 "ws://localhost/testing_path", "localhost", "/testing_path", |
| 149 NoSubProtocols(), LocalhostOrigin(), "", | 154 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 150 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); | 155 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); |
| 151 WaitUntilConnectDone(); | 156 WaitUntilConnectDone(); |
| 152 } | 157 } |
| 153 }; | 158 }; |
| 154 | 159 |
| 155 // Common code to construct expectations for authentication tests that receive | 160 // Common code to construct expectations for authentication tests that receive |
| 156 // the auth challenge on one connection and then create a second connection to | 161 // the auth challenge on one connection and then create a second connection to |
| 157 // send the authenticated request on. | 162 // send the authenticated request on. |
| 158 class CommonAuthTestHelper { | 163 class CommonAuthTestHelper { |
| 159 public: | 164 public: |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 "User-Agent:\r\n" | 222 "User-Agent:\r\n" |
| 218 "Accept-Encoding: gzip, deflate\r\n" | 223 "Accept-Encoding: gzip, deflate\r\n" |
| 219 "Accept-Language: en-us,fr\r\n" | 224 "Accept-Language: en-us,fr\r\n" |
| 220 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | 225 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" |
| 221 "Sec-WebSocket-Extensions: permessage-deflate; " | 226 "Sec-WebSocket-Extensions: permessage-deflate; " |
| 222 "client_max_window_bits\r\n" | 227 "client_max_window_bits\r\n" |
| 223 "\r\n"; | 228 "\r\n"; |
| 224 const std::string request = | 229 const std::string request = |
| 225 base::StringPrintf(request2format, base64_user_pass.c_str()); | 230 base::StringPrintf(request2format, base64_user_pass.c_str()); |
| 226 CreateAndConnectRawExpectations( | 231 CreateAndConnectRawExpectations( |
| 227 url, NoSubProtocols(), LocalhostOrigin(), | 232 url, NoSubProtocols(), LocalhostOrigin(), "", |
| 228 helper_.BuildSocketData2(request, response2)); | 233 helper_.BuildSocketData2(request, response2)); |
| 229 } | 234 } |
| 230 | 235 |
| 231 static const char kUnauthorizedResponse[]; | 236 static const char kUnauthorizedResponse[]; |
| 232 | 237 |
| 233 CommonAuthTestHelper helper_; | 238 CommonAuthTestHelper helper_; |
| 234 }; | 239 }; |
| 235 | 240 |
| 236 class WebSocketStreamCreateDigestAuthTest : public WebSocketStreamCreateTest { | 241 class WebSocketStreamCreateDigestAuthTest : public WebSocketStreamCreateTest { |
| 237 protected: | 242 protected: |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 base::HistogramBase* histogram = | 300 base::HistogramBase* histogram = |
| 296 base::StatisticsRecorder::FindHistogram(name); | 301 base::StatisticsRecorder::FindHistogram(name); |
| 297 return histogram ? histogram->SnapshotSamples() | 302 return histogram ? histogram->SnapshotSamples() |
| 298 : std::unique_ptr<base::HistogramSamples>(); | 303 : std::unique_ptr<base::HistogramSamples>(); |
| 299 } | 304 } |
| 300 }; | 305 }; |
| 301 | 306 |
| 302 // Confirm that the basic case works as expected. | 307 // Confirm that the basic case works as expected. |
| 303 TEST_F(WebSocketStreamCreateTest, SimpleSuccess) { | 308 TEST_F(WebSocketStreamCreateTest, SimpleSuccess) { |
| 304 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 309 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 305 NoSubProtocols(), LocalhostOrigin(), "", ""); | 310 NoSubProtocols(), LocalhostOrigin(), "", "", ""); |
| 306 EXPECT_FALSE(request_info_); | 311 EXPECT_FALSE(request_info_); |
| 307 EXPECT_FALSE(response_info_); | 312 EXPECT_FALSE(response_info_); |
| 308 WaitUntilConnectDone(); | 313 WaitUntilConnectDone(); |
| 309 EXPECT_FALSE(has_failed()); | 314 EXPECT_FALSE(has_failed()); |
| 310 EXPECT_TRUE(stream_); | 315 EXPECT_TRUE(stream_); |
| 311 EXPECT_TRUE(request_info_); | 316 EXPECT_TRUE(request_info_); |
| 312 EXPECT_TRUE(response_info_); | 317 EXPECT_TRUE(response_info_); |
| 313 } | 318 } |
| 314 | 319 |
| 315 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) { | 320 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) { |
| 316 static const char kResponse[] = | 321 static const char kResponse[] = |
| 317 "HTTP/1.1 101 Switching Protocols\r\n" | 322 "HTTP/1.1 101 Switching Protocols\r\n" |
| 318 "Upgrade: websocket\r\n" | 323 "Upgrade: websocket\r\n" |
| 319 "Connection: Upgrade\r\n" | 324 "Connection: Upgrade\r\n" |
| 320 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 325 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 321 "foo: bar, baz\r\n" | 326 "foo: bar, baz\r\n" |
| 322 "hoge: fuga\r\n" | 327 "hoge: fuga\r\n" |
| 323 "hoge: piyo\r\n" | 328 "hoge: piyo\r\n" |
| 324 "\r\n"; | 329 "\r\n"; |
| 325 | 330 |
| 326 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 331 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 327 NoSubProtocols(), LocalhostOrigin(), "", | 332 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 328 kResponse); | 333 kResponse); |
| 329 EXPECT_FALSE(request_info_); | 334 EXPECT_FALSE(request_info_); |
| 330 EXPECT_FALSE(response_info_); | 335 EXPECT_FALSE(response_info_); |
| 331 WaitUntilConnectDone(); | 336 WaitUntilConnectDone(); |
| 332 EXPECT_TRUE(stream_); | 337 EXPECT_TRUE(stream_); |
| 333 ASSERT_TRUE(request_info_); | 338 ASSERT_TRUE(request_info_); |
| 334 ASSERT_TRUE(response_info_); | 339 ASSERT_TRUE(response_info_); |
| 335 std::vector<HeaderKeyValuePair> request_headers = | 340 std::vector<HeaderKeyValuePair> request_headers = |
| 336 RequestHeadersToVector(request_info_->headers); | 341 RequestHeadersToVector(request_info_->headers); |
| 337 // We examine the contents of request_info_ and response_info_ | 342 // We examine the contents of request_info_ and response_info_ |
| (...skipping 30 matching lines...) Expand all Loading... |
| 368 std::sort(response_headers.begin(), response_headers.end()); | 373 std::sort(response_headers.begin(), response_headers.end()); |
| 369 | 374 |
| 370 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), response_headers[0]); | 375 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), response_headers[0]); |
| 371 EXPECT_EQ("Sec-WebSocket-Accept", response_headers[1].first); | 376 EXPECT_EQ("Sec-WebSocket-Accept", response_headers[1].first); |
| 372 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), response_headers[2]); | 377 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), response_headers[2]); |
| 373 EXPECT_EQ(HeaderKeyValuePair("foo", "bar, baz"), response_headers[3]); | 378 EXPECT_EQ(HeaderKeyValuePair("foo", "bar, baz"), response_headers[3]); |
| 374 EXPECT_EQ(HeaderKeyValuePair("hoge", "fuga"), response_headers[4]); | 379 EXPECT_EQ(HeaderKeyValuePair("hoge", "fuga"), response_headers[4]); |
| 375 EXPECT_EQ(HeaderKeyValuePair("hoge", "piyo"), response_headers[5]); | 380 EXPECT_EQ(HeaderKeyValuePair("hoge", "piyo"), response_headers[5]); |
| 376 } | 381 } |
| 377 | 382 |
| 383 // Confirms that request headers are overriden/added after handshake |
| 384 TEST_F(WebSocketStreamCreateTest, HandshakeOverrideHeaders) { |
| 385 static const char kResponse[] = |
| 386 "HTTP/1.1 101 Switching Protocols\r\n" |
| 387 "Upgrade: websocket\r\n" |
| 388 "Connection: Upgrade\r\n" |
| 389 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 390 "foo: bar, baz\r\n" |
| 391 "hoge: fuga\r\n" |
| 392 "hoge: piyo\r\n" |
| 393 "\r\n"; |
| 394 url_request_context_host_.SetExpectations( |
| 395 base::StringPrintf("GET / HTTP/1.1\r\n" |
| 396 "Host: localhost\r\n" |
| 397 "Connection: Upgrade\r\n" |
| 398 "Pragma: no-cache\r\n" |
| 399 "Cache-Control: no-cache\r\n" |
| 400 "Upgrade: websocket\r\n" |
| 401 "Origin: %s\r\n" |
| 402 "Sec-WebSocket-Version: 13\r\n" |
| 403 "User-Agent: OveRrIde\r\n" |
| 404 "rAnDomHeader: foobar\r\n" |
| 405 "Accept-Encoding: gzip, deflate\r\n" |
| 406 "Accept-Language: en-us,fr\r\n" |
| 407 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" |
| 408 "Sec-WebSocket-Extensions: permessage-deflate; " |
| 409 "client_max_window_bits\r\n" |
| 410 "\r\n", |
| 411 LocalhostOrigin().Serialize().c_str()), |
| 412 kResponse); |
| 413 CreateAndConnectStream("ws://localhost/", NoSubProtocols(), LocalhostOrigin(), |
| 414 "User-Agent: OveRrIde\r\n" // Tests overrite header |
| 415 "rAnDomHeader: foobar", // Tests adding new header |
| 416 std::unique_ptr<base::Timer>()); |
| 417 |
| 418 EXPECT_FALSE(request_info_); |
| 419 EXPECT_FALSE(response_info_); |
| 420 WaitUntilConnectDone(); |
| 421 EXPECT_TRUE(stream_); |
| 422 ASSERT_TRUE(request_info_); |
| 423 ASSERT_TRUE(response_info_); |
| 424 |
| 425 std::vector<HeaderKeyValuePair> request_headers = |
| 426 RequestHeadersToVector(request_info_->headers); |
| 427 EXPECT_EQ(HeaderKeyValuePair("User-Agent", "OveRrIde"), request_headers[7]); |
| 428 EXPECT_EQ(HeaderKeyValuePair("rAnDomHeader", "foobar"), request_headers[8]); |
| 429 } |
| 430 |
| 378 // Confirm that the stream isn't established until the message loop runs. | 431 // Confirm that the stream isn't established until the message loop runs. |
| 379 TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) { | 432 TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) { |
| 380 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 433 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 381 NoSubProtocols(), LocalhostOrigin(), "", ""); | 434 NoSubProtocols(), LocalhostOrigin(), "", "", ""); |
| 382 EXPECT_FALSE(has_failed()); | 435 EXPECT_FALSE(has_failed()); |
| 383 EXPECT_FALSE(stream_); | 436 EXPECT_FALSE(stream_); |
| 384 } | 437 } |
| 385 | 438 |
| 386 // Check the path is used. | 439 // Check the path is used. |
| 387 TEST_F(WebSocketStreamCreateTest, PathIsUsed) { | 440 TEST_F(WebSocketStreamCreateTest, PathIsUsed) { |
| 388 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 441 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 389 "/testing_path", NoSubProtocols(), LocalhostOrigin(), | 442 "/testing_path", NoSubProtocols(), LocalhostOrigin(), |
| 390 "", ""); | 443 "", "", ""); |
| 391 WaitUntilConnectDone(); | 444 WaitUntilConnectDone(); |
| 392 EXPECT_FALSE(has_failed()); | 445 EXPECT_FALSE(has_failed()); |
| 393 EXPECT_TRUE(stream_); | 446 EXPECT_TRUE(stream_); |
| 394 } | 447 } |
| 395 | 448 |
| 396 // Check that the origin is used. | 449 // Check that the origin is used. |
| 397 TEST_F(WebSocketStreamCreateTest, OriginIsUsed) { | 450 TEST_F(WebSocketStreamCreateTest, OriginIsUsed) { |
| 398 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 451 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 399 "/testing_path", NoSubProtocols(), GoogleOrigin(), | 452 "/testing_path", NoSubProtocols(), GoogleOrigin(), |
| 400 "", ""); | 453 "", "", ""); |
| 401 WaitUntilConnectDone(); | 454 WaitUntilConnectDone(); |
| 402 EXPECT_FALSE(has_failed()); | 455 EXPECT_FALSE(has_failed()); |
| 403 EXPECT_TRUE(stream_); | 456 EXPECT_TRUE(stream_); |
| 404 } | 457 } |
| 405 | 458 |
| 406 // Check that sub-protocols are sent and parsed. | 459 // Check that sub-protocols are sent and parsed. |
| 407 TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) { | 460 TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) { |
| 408 std::vector<std::string> sub_protocols; | 461 std::vector<std::string> sub_protocols; |
| 409 sub_protocols.push_back("chatv11.chromium.org"); | 462 sub_protocols.push_back("chatv11.chromium.org"); |
| 410 sub_protocols.push_back("chatv20.chromium.org"); | 463 sub_protocols.push_back("chatv20.chromium.org"); |
| 411 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 464 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 412 "/testing_path", sub_protocols, GoogleOrigin(), | 465 "/testing_path", sub_protocols, GoogleOrigin(), "", |
| 413 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 466 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
| 414 "chatv20.chromium.org\r\n", | 467 "chatv20.chromium.org\r\n", |
| 415 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); | 468 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); |
| 416 WaitUntilConnectDone(); | 469 WaitUntilConnectDone(); |
| 417 EXPECT_TRUE(stream_); | 470 EXPECT_TRUE(stream_); |
| 418 EXPECT_FALSE(has_failed()); | 471 EXPECT_FALSE(has_failed()); |
| 419 EXPECT_EQ("chatv20.chromium.org", stream_->GetSubProtocol()); | 472 EXPECT_EQ("chatv20.chromium.org", stream_->GetSubProtocol()); |
| 420 } | 473 } |
| 421 | 474 |
| 422 // Unsolicited sub-protocols are rejected. | 475 // Unsolicited sub-protocols are rejected. |
| 423 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { | 476 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { |
| 424 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 477 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 425 "/testing_path", NoSubProtocols(), GoogleOrigin(), | 478 "/testing_path", NoSubProtocols(), GoogleOrigin(), |
| 426 "", | 479 "", "", |
| 427 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); | 480 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); |
| 428 WaitUntilConnectDone(); | 481 WaitUntilConnectDone(); |
| 429 EXPECT_FALSE(stream_); | 482 EXPECT_FALSE(stream_); |
| 430 EXPECT_TRUE(has_failed()); | 483 EXPECT_TRUE(has_failed()); |
| 431 EXPECT_EQ("Error during WebSocket handshake: " | 484 EXPECT_EQ("Error during WebSocket handshake: " |
| 432 "Response must not include 'Sec-WebSocket-Protocol' header " | 485 "Response must not include 'Sec-WebSocket-Protocol' header " |
| 433 "if not present in request: chatv20.chromium.org", | 486 "if not present in request: chatv20.chromium.org", |
| 434 failure_message()); | 487 failure_message()); |
| 435 } | 488 } |
| 436 | 489 |
| 437 // Missing sub-protocol response is rejected. | 490 // Missing sub-protocol response is rejected. |
| 438 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { | 491 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { |
| 439 std::vector<std::string> sub_protocols; | 492 std::vector<std::string> sub_protocols; |
| 440 sub_protocols.push_back("chat.example.com"); | 493 sub_protocols.push_back("chat.example.com"); |
| 441 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 494 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 442 "/testing_path", sub_protocols, LocalhostOrigin(), | 495 "/testing_path", sub_protocols, LocalhostOrigin(), |
| 443 "Sec-WebSocket-Protocol: chat.example.com\r\n", ""); | 496 "", "Sec-WebSocket-Protocol: chat.example.com\r\n", |
| 497 ""); |
| 444 WaitUntilConnectDone(); | 498 WaitUntilConnectDone(); |
| 445 EXPECT_FALSE(stream_); | 499 EXPECT_FALSE(stream_); |
| 446 EXPECT_TRUE(has_failed()); | 500 EXPECT_TRUE(has_failed()); |
| 447 EXPECT_EQ("Error during WebSocket handshake: " | 501 EXPECT_EQ("Error during WebSocket handshake: " |
| 448 "Sent non-empty 'Sec-WebSocket-Protocol' header " | 502 "Sent non-empty 'Sec-WebSocket-Protocol' header " |
| 449 "but no response was received", | 503 "but no response was received", |
| 450 failure_message()); | 504 failure_message()); |
| 451 } | 505 } |
| 452 | 506 |
| 453 // Only one sub-protocol can be accepted. | 507 // Only one sub-protocol can be accepted. |
| 454 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { | 508 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { |
| 455 std::vector<std::string> sub_protocols; | 509 std::vector<std::string> sub_protocols; |
| 456 sub_protocols.push_back("chatv11.chromium.org"); | 510 sub_protocols.push_back("chatv11.chromium.org"); |
| 457 sub_protocols.push_back("chatv20.chromium.org"); | 511 sub_protocols.push_back("chatv20.chromium.org"); |
| 458 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 512 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 459 "/testing_path", sub_protocols, GoogleOrigin(), | 513 "/testing_path", sub_protocols, GoogleOrigin(), "", |
| 460 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 514 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
| 461 "chatv20.chromium.org\r\n", | 515 "chatv20.chromium.org\r\n", |
| 462 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 516 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
| 463 "chatv20.chromium.org\r\n"); | 517 "chatv20.chromium.org\r\n"); |
| 464 WaitUntilConnectDone(); | 518 WaitUntilConnectDone(); |
| 465 EXPECT_FALSE(stream_); | 519 EXPECT_FALSE(stream_); |
| 466 EXPECT_TRUE(has_failed()); | 520 EXPECT_TRUE(has_failed()); |
| 467 EXPECT_EQ("Error during WebSocket handshake: " | 521 EXPECT_EQ("Error during WebSocket handshake: " |
| 468 "'Sec-WebSocket-Protocol' header must not appear " | 522 "'Sec-WebSocket-Protocol' header must not appear " |
| 469 "more than once in a response", | 523 "more than once in a response", |
| 470 failure_message()); | 524 failure_message()); |
| 471 } | 525 } |
| 472 | 526 |
| 473 // Unmatched sub-protocol should be rejected. | 527 // Unmatched sub-protocol should be rejected. |
| 474 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { | 528 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { |
| 475 std::vector<std::string> sub_protocols; | 529 std::vector<std::string> sub_protocols; |
| 476 sub_protocols.push_back("chatv11.chromium.org"); | 530 sub_protocols.push_back("chatv11.chromium.org"); |
| 477 sub_protocols.push_back("chatv20.chromium.org"); | 531 sub_protocols.push_back("chatv20.chromium.org"); |
| 478 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 532 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 479 "/testing_path", sub_protocols, GoogleOrigin(), | 533 "/testing_path", sub_protocols, GoogleOrigin(), "", |
| 480 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 534 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
| 481 "chatv20.chromium.org\r\n", | 535 "chatv20.chromium.org\r\n", |
| 482 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); | 536 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); |
| 483 WaitUntilConnectDone(); | 537 WaitUntilConnectDone(); |
| 484 EXPECT_FALSE(stream_); | 538 EXPECT_FALSE(stream_); |
| 485 EXPECT_TRUE(has_failed()); | 539 EXPECT_TRUE(has_failed()); |
| 486 EXPECT_EQ("Error during WebSocket handshake: " | 540 EXPECT_EQ("Error during WebSocket handshake: " |
| 487 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " | 541 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " |
| 488 "in response does not match any of sent values", | 542 "in response does not match any of sent values", |
| 489 failure_message()); | 543 failure_message()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 504 "server_no_context_takeover"); | 558 "server_no_context_takeover"); |
| 505 EXPECT_TRUE(stream_); | 559 EXPECT_TRUE(stream_); |
| 506 EXPECT_FALSE(has_failed()); | 560 EXPECT_FALSE(has_failed()); |
| 507 } | 561 } |
| 508 | 562 |
| 509 // Verify that incoming messages are actually decompressed with | 563 // Verify that incoming messages are actually decompressed with |
| 510 // permessage-deflate enabled. | 564 // permessage-deflate enabled. |
| 511 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) { | 565 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) { |
| 512 CreateAndConnectCustomResponse( | 566 CreateAndConnectCustomResponse( |
| 513 "ws://localhost/testing_path", "localhost", "/testing_path", | 567 "ws://localhost/testing_path", "localhost", "/testing_path", |
| 514 NoSubProtocols(), LocalhostOrigin(), "", | 568 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 515 WebSocketStandardResponse( | 569 WebSocketStandardResponse( |
| 516 "Sec-WebSocket-Extensions: permessage-deflate\r\n") + | 570 "Sec-WebSocket-Extensions: permessage-deflate\r\n") + |
| 517 std::string( | 571 std::string( |
| 518 "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) | 572 "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) |
| 519 "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed | 573 "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed |
| 520 9)); | 574 9)); |
| 521 WaitUntilConnectDone(); | 575 WaitUntilConnectDone(); |
| 522 | 576 |
| 523 ASSERT_TRUE(stream_); | 577 ASSERT_TRUE(stream_); |
| 524 std::vector<std::unique_ptr<WebSocketFrame>> frames; | 578 std::vector<std::unique_ptr<WebSocketFrame>> frames; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 // websocket_deflate_parameters_test.cc. | 633 // websocket_deflate_parameters_test.cc. |
| 580 | 634 |
| 581 // TODO(ricea): Check that WebSocketDeflateStream is initialised with the | 635 // TODO(ricea): Check that WebSocketDeflateStream is initialised with the |
| 582 // arguments from the server. This is difficult because the data written to the | 636 // arguments from the server. This is difficult because the data written to the |
| 583 // socket is randomly masked. | 637 // socket is randomly masked. |
| 584 | 638 |
| 585 // Additional Sec-WebSocket-Accept headers should be rejected. | 639 // Additional Sec-WebSocket-Accept headers should be rejected. |
| 586 TEST_F(WebSocketStreamCreateTest, DoubleAccept) { | 640 TEST_F(WebSocketStreamCreateTest, DoubleAccept) { |
| 587 CreateAndConnectStandard( | 641 CreateAndConnectStandard( |
| 588 "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(), | 642 "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(), |
| 589 "", "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); | 643 "", "", "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); |
| 590 WaitUntilConnectDone(); | 644 WaitUntilConnectDone(); |
| 591 EXPECT_FALSE(stream_); | 645 EXPECT_FALSE(stream_); |
| 592 EXPECT_TRUE(has_failed()); | 646 EXPECT_TRUE(has_failed()); |
| 593 EXPECT_EQ("Error during WebSocket handshake: " | 647 EXPECT_EQ("Error during WebSocket handshake: " |
| 594 "'Sec-WebSocket-Accept' header must not appear " | 648 "'Sec-WebSocket-Accept' header must not appear " |
| 595 "more than once in a response", | 649 "more than once in a response", |
| 596 failure_message()); | 650 failure_message()); |
| 597 } | 651 } |
| 598 | 652 |
| 599 // Response code 200 must be rejected. | 653 // Response code 200 must be rejected. |
| 600 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { | 654 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { |
| 601 static const char kInvalidStatusCodeResponse[] = | 655 static const char kInvalidStatusCodeResponse[] = |
| 602 "HTTP/1.1 200 OK\r\n" | 656 "HTTP/1.1 200 OK\r\n" |
| 603 "Upgrade: websocket\r\n" | 657 "Upgrade: websocket\r\n" |
| 604 "Connection: Upgrade\r\n" | 658 "Connection: Upgrade\r\n" |
| 605 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 659 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 606 "\r\n"; | 660 "\r\n"; |
| 607 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 661 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 608 NoSubProtocols(), LocalhostOrigin(), "", | 662 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 609 kInvalidStatusCodeResponse); | 663 kInvalidStatusCodeResponse); |
| 610 WaitUntilConnectDone(); | 664 WaitUntilConnectDone(); |
| 611 EXPECT_TRUE(has_failed()); | 665 EXPECT_TRUE(has_failed()); |
| 612 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", | 666 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", |
| 613 failure_message()); | 667 failure_message()); |
| 614 } | 668 } |
| 615 | 669 |
| 616 // Redirects are not followed (according to the WHATWG WebSocket API, which | 670 // Redirects are not followed (according to the WHATWG WebSocket API, which |
| 617 // overrides RFC6455 for browser applications). | 671 // overrides RFC6455 for browser applications). |
| 618 TEST_F(WebSocketStreamCreateTest, RedirectsRejected) { | 672 TEST_F(WebSocketStreamCreateTest, RedirectsRejected) { |
| 619 static const char kRedirectResponse[] = | 673 static const char kRedirectResponse[] = |
| 620 "HTTP/1.1 302 Moved Temporarily\r\n" | 674 "HTTP/1.1 302 Moved Temporarily\r\n" |
| 621 "Content-Type: text/html\r\n" | 675 "Content-Type: text/html\r\n" |
| 622 "Content-Length: 34\r\n" | 676 "Content-Length: 34\r\n" |
| 623 "Connection: keep-alive\r\n" | 677 "Connection: keep-alive\r\n" |
| 624 "Location: ws://localhost/other\r\n" | 678 "Location: ws://localhost/other\r\n" |
| 625 "\r\n" | 679 "\r\n" |
| 626 "<title>Moved</title><h1>Moved</h1>"; | 680 "<title>Moved</title><h1>Moved</h1>"; |
| 627 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 681 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 628 NoSubProtocols(), LocalhostOrigin(), "", | 682 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 629 kRedirectResponse); | 683 kRedirectResponse); |
| 630 WaitUntilConnectDone(); | 684 WaitUntilConnectDone(); |
| 631 EXPECT_TRUE(has_failed()); | 685 EXPECT_TRUE(has_failed()); |
| 632 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302", | 686 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302", |
| 633 failure_message()); | 687 failure_message()); |
| 634 } | 688 } |
| 635 | 689 |
| 636 // Malformed responses should be rejected. HttpStreamParser will accept just | 690 // Malformed responses should be rejected. HttpStreamParser will accept just |
| 637 // about any garbage in the middle of the headers. To make it give up, the junk | 691 // about any garbage in the middle of the headers. To make it give up, the junk |
| 638 // has to be at the start of the response. Even then, it just gets treated as an | 692 // has to be at the start of the response. Even then, it just gets treated as an |
| 639 // HTTP/0.9 response. | 693 // HTTP/0.9 response. |
| 640 TEST_F(WebSocketStreamCreateTest, MalformedResponse) { | 694 TEST_F(WebSocketStreamCreateTest, MalformedResponse) { |
| 641 static const char kMalformedResponse[] = | 695 static const char kMalformedResponse[] = |
| 642 "220 mx.google.com ESMTP\r\n" | 696 "220 mx.google.com ESMTP\r\n" |
| 643 "HTTP/1.1 101 OK\r\n" | 697 "HTTP/1.1 101 OK\r\n" |
| 644 "Upgrade: websocket\r\n" | 698 "Upgrade: websocket\r\n" |
| 645 "Connection: Upgrade\r\n" | 699 "Connection: Upgrade\r\n" |
| 646 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 700 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 647 "\r\n"; | 701 "\r\n"; |
| 648 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 702 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 649 NoSubProtocols(), LocalhostOrigin(), "", | 703 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 650 kMalformedResponse); | 704 kMalformedResponse); |
| 651 WaitUntilConnectDone(); | 705 WaitUntilConnectDone(); |
| 652 EXPECT_TRUE(has_failed()); | 706 EXPECT_TRUE(has_failed()); |
| 653 EXPECT_EQ("Error during WebSocket handshake: Invalid status line", | 707 EXPECT_EQ("Error during WebSocket handshake: Invalid status line", |
| 654 failure_message()); | 708 failure_message()); |
| 655 } | 709 } |
| 656 | 710 |
| 657 // Upgrade header must be present. | 711 // Upgrade header must be present. |
| 658 TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) { | 712 TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) { |
| 659 static const char kMissingUpgradeResponse[] = | 713 static const char kMissingUpgradeResponse[] = |
| 660 "HTTP/1.1 101 Switching Protocols\r\n" | 714 "HTTP/1.1 101 Switching Protocols\r\n" |
| 661 "Connection: Upgrade\r\n" | 715 "Connection: Upgrade\r\n" |
| 662 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 716 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 663 "\r\n"; | 717 "\r\n"; |
| 664 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 718 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 665 NoSubProtocols(), LocalhostOrigin(), "", | 719 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 666 kMissingUpgradeResponse); | 720 kMissingUpgradeResponse); |
| 667 WaitUntilConnectDone(); | 721 WaitUntilConnectDone(); |
| 668 EXPECT_TRUE(has_failed()); | 722 EXPECT_TRUE(has_failed()); |
| 669 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", | 723 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", |
| 670 failure_message()); | 724 failure_message()); |
| 671 } | 725 } |
| 672 | 726 |
| 673 // There must only be one upgrade header. | 727 // There must only be one upgrade header. |
| 674 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { | 728 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { |
| 675 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 729 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 676 NoSubProtocols(), LocalhostOrigin(), "", | 730 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 677 "Upgrade: HTTP/2.0\r\n"); | 731 "Upgrade: HTTP/2.0\r\n"); |
| 678 WaitUntilConnectDone(); | 732 WaitUntilConnectDone(); |
| 679 EXPECT_TRUE(has_failed()); | 733 EXPECT_TRUE(has_failed()); |
| 680 EXPECT_EQ("Error during WebSocket handshake: " | 734 EXPECT_EQ("Error during WebSocket handshake: " |
| 681 "'Upgrade' header must not appear more than once in a response", | 735 "'Upgrade' header must not appear more than once in a response", |
| 682 failure_message()); | 736 failure_message()); |
| 683 } | 737 } |
| 684 | 738 |
| 685 // There must only be one correct upgrade header. | 739 // There must only be one correct upgrade header. |
| 686 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { | 740 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { |
| 687 static const char kMissingUpgradeResponse[] = | 741 static const char kMissingUpgradeResponse[] = |
| 688 "HTTP/1.1 101 Switching Protocols\r\n" | 742 "HTTP/1.1 101 Switching Protocols\r\n" |
| 689 "Connection: Upgrade\r\n" | 743 "Connection: Upgrade\r\n" |
| 690 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 744 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 691 "Upgrade: hogefuga\r\n" | 745 "Upgrade: hogefuga\r\n" |
| 692 "\r\n"; | 746 "\r\n"; |
| 693 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 747 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 694 NoSubProtocols(), LocalhostOrigin(), "", | 748 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 695 kMissingUpgradeResponse); | 749 kMissingUpgradeResponse); |
| 696 WaitUntilConnectDone(); | 750 WaitUntilConnectDone(); |
| 697 EXPECT_TRUE(has_failed()); | 751 EXPECT_TRUE(has_failed()); |
| 698 EXPECT_EQ("Error during WebSocket handshake: " | 752 EXPECT_EQ("Error during WebSocket handshake: " |
| 699 "'Upgrade' header value is not 'WebSocket': hogefuga", | 753 "'Upgrade' header value is not 'WebSocket': hogefuga", |
| 700 failure_message()); | 754 failure_message()); |
| 701 } | 755 } |
| 702 | 756 |
| 703 // Connection header must be present. | 757 // Connection header must be present. |
| 704 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { | 758 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { |
| 705 static const char kMissingConnectionResponse[] = | 759 static const char kMissingConnectionResponse[] = |
| 706 "HTTP/1.1 101 Switching Protocols\r\n" | 760 "HTTP/1.1 101 Switching Protocols\r\n" |
| 707 "Upgrade: websocket\r\n" | 761 "Upgrade: websocket\r\n" |
| 708 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 762 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 709 "\r\n"; | 763 "\r\n"; |
| 710 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 764 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 711 NoSubProtocols(), LocalhostOrigin(), "", | 765 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 712 kMissingConnectionResponse); | 766 kMissingConnectionResponse); |
| 713 WaitUntilConnectDone(); | 767 WaitUntilConnectDone(); |
| 714 EXPECT_TRUE(has_failed()); | 768 EXPECT_TRUE(has_failed()); |
| 715 EXPECT_EQ("Error during WebSocket handshake: " | 769 EXPECT_EQ("Error during WebSocket handshake: " |
| 716 "'Connection' header is missing", | 770 "'Connection' header is missing", |
| 717 failure_message()); | 771 failure_message()); |
| 718 } | 772 } |
| 719 | 773 |
| 720 // Connection header must contain "Upgrade". | 774 // Connection header must contain "Upgrade". |
| 721 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { | 775 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { |
| 722 static const char kMissingConnectionResponse[] = | 776 static const char kMissingConnectionResponse[] = |
| 723 "HTTP/1.1 101 Switching Protocols\r\n" | 777 "HTTP/1.1 101 Switching Protocols\r\n" |
| 724 "Upgrade: websocket\r\n" | 778 "Upgrade: websocket\r\n" |
| 725 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 779 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 726 "Connection: hogefuga\r\n" | 780 "Connection: hogefuga\r\n" |
| 727 "\r\n"; | 781 "\r\n"; |
| 728 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 782 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 729 NoSubProtocols(), LocalhostOrigin(), "", | 783 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 730 kMissingConnectionResponse); | 784 kMissingConnectionResponse); |
| 731 WaitUntilConnectDone(); | 785 WaitUntilConnectDone(); |
| 732 EXPECT_TRUE(has_failed()); | 786 EXPECT_TRUE(has_failed()); |
| 733 EXPECT_EQ("Error during WebSocket handshake: " | 787 EXPECT_EQ("Error during WebSocket handshake: " |
| 734 "'Connection' header value must contain 'Upgrade'", | 788 "'Connection' header value must contain 'Upgrade'", |
| 735 failure_message()); | 789 failure_message()); |
| 736 } | 790 } |
| 737 | 791 |
| 738 // Connection header is permitted to contain other tokens. | 792 // Connection header is permitted to contain other tokens. |
| 739 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { | 793 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { |
| 740 static const char kAdditionalConnectionTokenResponse[] = | 794 static const char kAdditionalConnectionTokenResponse[] = |
| 741 "HTTP/1.1 101 Switching Protocols\r\n" | 795 "HTTP/1.1 101 Switching Protocols\r\n" |
| 742 "Upgrade: websocket\r\n" | 796 "Upgrade: websocket\r\n" |
| 743 "Connection: Upgrade, Keep-Alive\r\n" | 797 "Connection: Upgrade, Keep-Alive\r\n" |
| 744 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 798 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 745 "\r\n"; | 799 "\r\n"; |
| 746 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 800 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 747 NoSubProtocols(), LocalhostOrigin(), "", | 801 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 748 kAdditionalConnectionTokenResponse); | 802 kAdditionalConnectionTokenResponse); |
| 749 WaitUntilConnectDone(); | 803 WaitUntilConnectDone(); |
| 750 EXPECT_FALSE(has_failed()); | 804 EXPECT_FALSE(has_failed()); |
| 751 EXPECT_TRUE(stream_); | 805 EXPECT_TRUE(stream_); |
| 752 } | 806 } |
| 753 | 807 |
| 754 // Sec-WebSocket-Accept header must be present. | 808 // Sec-WebSocket-Accept header must be present. |
| 755 TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) { | 809 TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) { |
| 756 static const char kMissingAcceptResponse[] = | 810 static const char kMissingAcceptResponse[] = |
| 757 "HTTP/1.1 101 Switching Protocols\r\n" | 811 "HTTP/1.1 101 Switching Protocols\r\n" |
| 758 "Upgrade: websocket\r\n" | 812 "Upgrade: websocket\r\n" |
| 759 "Connection: Upgrade\r\n" | 813 "Connection: Upgrade\r\n" |
| 760 "\r\n"; | 814 "\r\n"; |
| 761 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 815 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 762 NoSubProtocols(), LocalhostOrigin(), "", | 816 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 763 kMissingAcceptResponse); | 817 kMissingAcceptResponse); |
| 764 WaitUntilConnectDone(); | 818 WaitUntilConnectDone(); |
| 765 EXPECT_TRUE(has_failed()); | 819 EXPECT_TRUE(has_failed()); |
| 766 EXPECT_EQ("Error during WebSocket handshake: " | 820 EXPECT_EQ("Error during WebSocket handshake: " |
| 767 "'Sec-WebSocket-Accept' header is missing", | 821 "'Sec-WebSocket-Accept' header is missing", |
| 768 failure_message()); | 822 failure_message()); |
| 769 } | 823 } |
| 770 | 824 |
| 771 // Sec-WebSocket-Accept header must match the key that was sent. | 825 // Sec-WebSocket-Accept header must match the key that was sent. |
| 772 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { | 826 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { |
| 773 static const char kIncorrectAcceptResponse[] = | 827 static const char kIncorrectAcceptResponse[] = |
| 774 "HTTP/1.1 101 Switching Protocols\r\n" | 828 "HTTP/1.1 101 Switching Protocols\r\n" |
| 775 "Upgrade: websocket\r\n" | 829 "Upgrade: websocket\r\n" |
| 776 "Connection: Upgrade\r\n" | 830 "Connection: Upgrade\r\n" |
| 777 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" | 831 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" |
| 778 "\r\n"; | 832 "\r\n"; |
| 779 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 833 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 780 NoSubProtocols(), LocalhostOrigin(), "", | 834 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 781 kIncorrectAcceptResponse); | 835 kIncorrectAcceptResponse); |
| 782 WaitUntilConnectDone(); | 836 WaitUntilConnectDone(); |
| 783 EXPECT_TRUE(has_failed()); | 837 EXPECT_TRUE(has_failed()); |
| 784 EXPECT_EQ("Error during WebSocket handshake: " | 838 EXPECT_EQ("Error during WebSocket handshake: " |
| 785 "Incorrect 'Sec-WebSocket-Accept' header value", | 839 "Incorrect 'Sec-WebSocket-Accept' header value", |
| 786 failure_message()); | 840 failure_message()); |
| 787 } | 841 } |
| 788 | 842 |
| 789 // Cancellation works. | 843 // Cancellation works. |
| 790 TEST_F(WebSocketStreamCreateTest, Cancellation) { | 844 TEST_F(WebSocketStreamCreateTest, Cancellation) { |
| 791 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 845 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 792 NoSubProtocols(), LocalhostOrigin(), "", ""); | 846 NoSubProtocols(), LocalhostOrigin(), "", "", ""); |
| 793 stream_request_.reset(); | 847 stream_request_.reset(); |
| 794 // WaitUntilConnectDone doesn't work in this case. | 848 // WaitUntilConnectDone doesn't work in this case. |
| 795 base::RunLoop().RunUntilIdle(); | 849 base::RunLoop().RunUntilIdle(); |
| 796 EXPECT_FALSE(has_failed()); | 850 EXPECT_FALSE(has_failed()); |
| 797 EXPECT_FALSE(stream_); | 851 EXPECT_FALSE(stream_); |
| 798 EXPECT_FALSE(request_info_); | 852 EXPECT_FALSE(request_info_); |
| 799 EXPECT_FALSE(response_info_); | 853 EXPECT_FALSE(response_info_); |
| 800 } | 854 } |
| 801 | 855 |
| 802 // Connect failure must look just like negotiation failure. | 856 // Connect failure must look just like negotiation failure. |
| 803 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { | 857 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { |
| 804 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); | 858 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); |
| 805 socket_data->set_connect_data( | 859 socket_data->set_connect_data( |
| 806 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); | 860 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); |
| 807 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 861 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 808 LocalhostOrigin(), std::move(socket_data)); | 862 LocalhostOrigin(), "", |
| 863 std::move(socket_data)); |
| 809 WaitUntilConnectDone(); | 864 WaitUntilConnectDone(); |
| 810 EXPECT_TRUE(has_failed()); | 865 EXPECT_TRUE(has_failed()); |
| 811 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", | 866 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", |
| 812 failure_message()); | 867 failure_message()); |
| 813 EXPECT_FALSE(request_info_); | 868 EXPECT_FALSE(request_info_); |
| 814 EXPECT_FALSE(response_info_); | 869 EXPECT_FALSE(response_info_); |
| 815 } | 870 } |
| 816 | 871 |
| 817 // Connect timeout must look just like any other failure. | 872 // Connect timeout must look just like any other failure. |
| 818 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { | 873 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { |
| 819 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); | 874 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); |
| 820 socket_data->set_connect_data( | 875 socket_data->set_connect_data( |
| 821 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); | 876 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); |
| 822 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 877 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 823 LocalhostOrigin(), std::move(socket_data)); | 878 LocalhostOrigin(), "", |
| 879 std::move(socket_data)); |
| 824 WaitUntilConnectDone(); | 880 WaitUntilConnectDone(); |
| 825 EXPECT_TRUE(has_failed()); | 881 EXPECT_TRUE(has_failed()); |
| 826 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", | 882 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", |
| 827 failure_message()); | 883 failure_message()); |
| 828 } | 884 } |
| 829 | 885 |
| 830 // The server doesn't respond to the opening handshake. | 886 // The server doesn't respond to the opening handshake. |
| 831 TEST_F(WebSocketStreamCreateTest, HandshakeTimeout) { | 887 TEST_F(WebSocketStreamCreateTest, HandshakeTimeout) { |
| 832 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); | 888 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); |
| 833 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); | 889 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); |
| 834 std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); | 890 std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
| 835 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); | 891 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
| 836 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 892 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 837 LocalhostOrigin(), std::move(socket_data), | 893 LocalhostOrigin(), "", std::move(socket_data), |
| 838 std::move(timer)); | 894 std::move(timer)); |
| 839 EXPECT_FALSE(has_failed()); | 895 EXPECT_FALSE(has_failed()); |
| 840 ASSERT_TRUE(weak_timer.get()); | 896 ASSERT_TRUE(weak_timer.get()); |
| 841 EXPECT_TRUE(weak_timer->IsRunning()); | 897 EXPECT_TRUE(weak_timer->IsRunning()); |
| 842 | 898 |
| 843 weak_timer->Fire(); | 899 weak_timer->Fire(); |
| 844 WaitUntilConnectDone(); | 900 WaitUntilConnectDone(); |
| 845 | 901 |
| 846 EXPECT_TRUE(has_failed()); | 902 EXPECT_TRUE(has_failed()); |
| 847 EXPECT_EQ("WebSocket opening handshake timed out", failure_message()); | 903 EXPECT_EQ("WebSocket opening handshake timed out", failure_message()); |
| 848 ASSERT_TRUE(weak_timer.get()); | 904 ASSERT_TRUE(weak_timer.get()); |
| 849 EXPECT_FALSE(weak_timer->IsRunning()); | 905 EXPECT_FALSE(weak_timer->IsRunning()); |
| 850 } | 906 } |
| 851 | 907 |
| 852 // When the connection establishes the timer should be stopped. | 908 // When the connection establishes the timer should be stopped. |
| 853 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) { | 909 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) { |
| 854 std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); | 910 std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
| 855 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); | 911 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
| 856 | 912 |
| 857 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 913 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 858 NoSubProtocols(), LocalhostOrigin(), "", "", | 914 NoSubProtocols(), LocalhostOrigin(), "", "", "", |
| 859 std::move(timer)); | 915 std::move(timer)); |
| 860 ASSERT_TRUE(weak_timer); | 916 ASSERT_TRUE(weak_timer); |
| 861 EXPECT_TRUE(weak_timer->IsRunning()); | 917 EXPECT_TRUE(weak_timer->IsRunning()); |
| 862 | 918 |
| 863 WaitUntilConnectDone(); | 919 WaitUntilConnectDone(); |
| 864 EXPECT_FALSE(has_failed()); | 920 EXPECT_FALSE(has_failed()); |
| 865 EXPECT_TRUE(stream_); | 921 EXPECT_TRUE(stream_); |
| 866 ASSERT_TRUE(weak_timer); | 922 ASSERT_TRUE(weak_timer); |
| 867 EXPECT_FALSE(weak_timer->IsRunning()); | 923 EXPECT_FALSE(weak_timer->IsRunning()); |
| 868 } | 924 } |
| 869 | 925 |
| 870 // When the connection fails the timer should be stopped. | 926 // When the connection fails the timer should be stopped. |
| 871 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnFailure) { | 927 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnFailure) { |
| 872 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); | 928 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); |
| 873 socket_data->set_connect_data( | 929 socket_data->set_connect_data( |
| 874 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); | 930 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); |
| 875 std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); | 931 std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
| 876 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); | 932 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
| 877 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 933 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 878 LocalhostOrigin(), std::move(socket_data), | 934 LocalhostOrigin(), "", std::move(socket_data), |
| 879 std::move(timer)); | 935 std::move(timer)); |
| 880 ASSERT_TRUE(weak_timer.get()); | 936 ASSERT_TRUE(weak_timer.get()); |
| 881 EXPECT_TRUE(weak_timer->IsRunning()); | 937 EXPECT_TRUE(weak_timer->IsRunning()); |
| 882 | 938 |
| 883 WaitUntilConnectDone(); | 939 WaitUntilConnectDone(); |
| 884 EXPECT_TRUE(has_failed()); | 940 EXPECT_TRUE(has_failed()); |
| 885 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", | 941 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", |
| 886 failure_message()); | 942 failure_message()); |
| 887 ASSERT_TRUE(weak_timer.get()); | 943 ASSERT_TRUE(weak_timer.get()); |
| 888 EXPECT_FALSE(weak_timer->IsRunning()); | 944 EXPECT_FALSE(weak_timer->IsRunning()); |
| 889 } | 945 } |
| 890 | 946 |
| 891 // Cancellation during connect works. | 947 // Cancellation during connect works. |
| 892 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { | 948 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { |
| 893 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); | 949 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); |
| 894 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); | 950 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); |
| 895 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 951 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 896 LocalhostOrigin(), std::move(socket_data)); | 952 LocalhostOrigin(), "", |
| 953 std::move(socket_data)); |
| 897 stream_request_.reset(); | 954 stream_request_.reset(); |
| 898 // WaitUntilConnectDone doesn't work in this case. | 955 // WaitUntilConnectDone doesn't work in this case. |
| 899 base::RunLoop().RunUntilIdle(); | 956 base::RunLoop().RunUntilIdle(); |
| 900 EXPECT_FALSE(has_failed()); | 957 EXPECT_FALSE(has_failed()); |
| 901 EXPECT_FALSE(stream_); | 958 EXPECT_FALSE(stream_); |
| 902 } | 959 } |
| 903 | 960 |
| 904 // Cancellation during write of the request headers works. | 961 // Cancellation during write of the request headers works. |
| 905 TEST_F(WebSocketStreamCreateTest, CancellationDuringWrite) { | 962 TEST_F(WebSocketStreamCreateTest, CancellationDuringWrite) { |
| 906 // First write never completes. | 963 // First write never completes. |
| 907 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 0)}; | 964 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 0)}; |
| 908 SequencedSocketData* socket_data( | 965 SequencedSocketData* socket_data( |
| 909 new SequencedSocketData(NULL, 0, writes, arraysize(writes))); | 966 new SequencedSocketData(NULL, 0, writes, arraysize(writes))); |
| 910 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 967 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
| 911 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 968 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 912 LocalhostOrigin(), | 969 LocalhostOrigin(), "", |
| 913 base::WrapUnique(socket_data)); | 970 base::WrapUnique(socket_data)); |
| 914 base::RunLoop().RunUntilIdle(); | 971 base::RunLoop().RunUntilIdle(); |
| 915 EXPECT_TRUE(socket_data->AllWriteDataConsumed()); | 972 EXPECT_TRUE(socket_data->AllWriteDataConsumed()); |
| 916 stream_request_.reset(); | 973 stream_request_.reset(); |
| 917 // WaitUntilConnectDone doesn't work in this case. | 974 // WaitUntilConnectDone doesn't work in this case. |
| 918 base::RunLoop().RunUntilIdle(); | 975 base::RunLoop().RunUntilIdle(); |
| 919 EXPECT_FALSE(has_failed()); | 976 EXPECT_FALSE(has_failed()); |
| 920 EXPECT_FALSE(stream_); | 977 EXPECT_FALSE(stream_); |
| 921 EXPECT_TRUE(request_info_); | 978 EXPECT_TRUE(request_info_); |
| 922 EXPECT_FALSE(response_info_); | 979 EXPECT_FALSE(response_info_); |
| 923 } | 980 } |
| 924 | 981 |
| 925 // Cancellation during read of the response headers works. | 982 // Cancellation during read of the response headers works. |
| 926 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { | 983 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { |
| 927 std::string request = | 984 std::string request = |
| 928 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), ""); | 985 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), ""); |
| 929 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; | 986 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; |
| 930 MockRead reads[] = { | 987 MockRead reads[] = { |
| 931 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1), | 988 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1), |
| 932 }; | 989 }; |
| 933 std::unique_ptr<SequencedSocketData> socket_data( | 990 std::unique_ptr<SequencedSocketData> socket_data( |
| 934 BuildSocketData(reads, writes)); | 991 BuildSocketData(reads, writes)); |
| 935 SequencedSocketData* socket_data_raw_ptr = socket_data.get(); | 992 SequencedSocketData* socket_data_raw_ptr = socket_data.get(); |
| 936 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 993 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 937 LocalhostOrigin(), std::move(socket_data)); | 994 LocalhostOrigin(), "", |
| 995 std::move(socket_data)); |
| 938 base::RunLoop().RunUntilIdle(); | 996 base::RunLoop().RunUntilIdle(); |
| 939 EXPECT_TRUE(socket_data_raw_ptr->AllReadDataConsumed()); | 997 EXPECT_TRUE(socket_data_raw_ptr->AllReadDataConsumed()); |
| 940 stream_request_.reset(); | 998 stream_request_.reset(); |
| 941 // WaitUntilConnectDone doesn't work in this case. | 999 // WaitUntilConnectDone doesn't work in this case. |
| 942 base::RunLoop().RunUntilIdle(); | 1000 base::RunLoop().RunUntilIdle(); |
| 943 EXPECT_FALSE(has_failed()); | 1001 EXPECT_FALSE(has_failed()); |
| 944 EXPECT_FALSE(stream_); | 1002 EXPECT_FALSE(stream_); |
| 945 EXPECT_TRUE(request_info_); | 1003 EXPECT_TRUE(request_info_); |
| 946 EXPECT_FALSE(response_info_); | 1004 EXPECT_FALSE(response_info_); |
| 947 } | 1005 } |
| 948 | 1006 |
| 949 // Over-size response headers (> 256KB) should not cause a crash. This is a | 1007 // Over-size response headers (> 256KB) should not cause a crash. This is a |
| 950 // regression test for crbug.com/339456. It is based on the layout test | 1008 // regression test for crbug.com/339456. It is based on the layout test |
| 951 // "cookie-flood.html". | 1009 // "cookie-flood.html". |
| 952 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { | 1010 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { |
| 953 std::string set_cookie_headers; | 1011 std::string set_cookie_headers; |
| 954 set_cookie_headers.reserve(45 * 10000); | 1012 set_cookie_headers.reserve(45 * 10000); |
| 955 for (int i = 0; i < 10000; ++i) { | 1013 for (int i = 0; i < 10000; ++i) { |
| 956 set_cookie_headers += | 1014 set_cookie_headers += |
| 957 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); | 1015 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); |
| 958 } | 1016 } |
| 959 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 1017 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 960 NoSubProtocols(), LocalhostOrigin(), "", | 1018 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 961 set_cookie_headers); | 1019 set_cookie_headers); |
| 962 WaitUntilConnectDone(); | 1020 WaitUntilConnectDone(); |
| 963 EXPECT_TRUE(has_failed()); | 1021 EXPECT_TRUE(has_failed()); |
| 964 EXPECT_FALSE(response_info_); | 1022 EXPECT_FALSE(response_info_); |
| 965 } | 1023 } |
| 966 | 1024 |
| 967 // If the remote host closes the connection without sending headers, we should | 1025 // If the remote host closes the connection without sending headers, we should |
| 968 // log the console message "Connection closed before receiving a handshake | 1026 // log the console message "Connection closed before receiving a handshake |
| 969 // response". | 1027 // response". |
| 970 TEST_F(WebSocketStreamCreateTest, NoResponse) { | 1028 TEST_F(WebSocketStreamCreateTest, NoResponse) { |
| 971 std::string request = | 1029 std::string request = |
| 972 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), ""); | 1030 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), ""); |
| 973 MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)}; | 1031 MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)}; |
| 974 MockRead reads[] = {MockRead(ASYNC, 0, 1)}; | 1032 MockRead reads[] = {MockRead(ASYNC, 0, 1)}; |
| 975 std::unique_ptr<SequencedSocketData> socket_data( | 1033 std::unique_ptr<SequencedSocketData> socket_data( |
| 976 BuildSocketData(reads, writes)); | 1034 BuildSocketData(reads, writes)); |
| 977 SequencedSocketData* socket_data_raw_ptr = socket_data.get(); | 1035 SequencedSocketData* socket_data_raw_ptr = socket_data.get(); |
| 978 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 1036 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 979 LocalhostOrigin(), std::move(socket_data)); | 1037 LocalhostOrigin(), "", |
| 1038 std::move(socket_data)); |
| 980 base::RunLoop().RunUntilIdle(); | 1039 base::RunLoop().RunUntilIdle(); |
| 981 EXPECT_TRUE(socket_data_raw_ptr->AllReadDataConsumed()); | 1040 EXPECT_TRUE(socket_data_raw_ptr->AllReadDataConsumed()); |
| 982 EXPECT_TRUE(has_failed()); | 1041 EXPECT_TRUE(has_failed()); |
| 983 EXPECT_FALSE(stream_); | 1042 EXPECT_FALSE(stream_); |
| 984 EXPECT_FALSE(response_info_); | 1043 EXPECT_FALSE(response_info_); |
| 985 EXPECT_EQ("Connection closed before receiving a handshake response", | 1044 EXPECT_EQ("Connection closed before receiving a handshake response", |
| 986 failure_message()); | 1045 failure_message()); |
| 987 } | 1046 } |
| 988 | 1047 |
| 989 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateFailure) { | 1048 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateFailure) { |
| 990 ssl_data_.push_back(base::WrapUnique( | 1049 ssl_data_.push_back(base::WrapUnique( |
| 991 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID))); | 1050 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID))); |
| 992 ssl_data_[0]->cert = | 1051 ssl_data_[0]->cert = |
| 993 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); | 1052 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); |
| 994 ASSERT_TRUE(ssl_data_[0]->cert.get()); | 1053 ASSERT_TRUE(ssl_data_[0]->cert.get()); |
| 995 std::unique_ptr<SequencedSocketData> raw_socket_data(BuildNullSocketData()); | 1054 std::unique_ptr<SequencedSocketData> raw_socket_data(BuildNullSocketData()); |
| 996 CreateAndConnectRawExpectations("wss://localhost/", NoSubProtocols(), | 1055 CreateAndConnectRawExpectations("wss://localhost/", NoSubProtocols(), |
| 997 LocalhostOrigin(), | 1056 LocalhostOrigin(), "", |
| 998 std::move(raw_socket_data)); | 1057 std::move(raw_socket_data)); |
| 999 // WaitUntilConnectDone doesn't work in this case. | 1058 // WaitUntilConnectDone doesn't work in this case. |
| 1000 base::RunLoop().RunUntilIdle(); | 1059 base::RunLoop().RunUntilIdle(); |
| 1001 EXPECT_FALSE(has_failed()); | 1060 EXPECT_FALSE(has_failed()); |
| 1002 ASSERT_TRUE(ssl_error_callbacks_); | 1061 ASSERT_TRUE(ssl_error_callbacks_); |
| 1003 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID, | 1062 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID, |
| 1004 &ssl_info_); | 1063 &ssl_info_); |
| 1005 WaitUntilConnectDone(); | 1064 WaitUntilConnectDone(); |
| 1006 EXPECT_TRUE(has_failed()); | 1065 EXPECT_TRUE(has_failed()); |
| 1007 } | 1066 } |
| 1008 | 1067 |
| 1009 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { | 1068 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { |
| 1010 std::unique_ptr<SSLSocketDataProvider> ssl_data( | 1069 std::unique_ptr<SSLSocketDataProvider> ssl_data( |
| 1011 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); | 1070 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); |
| 1012 ssl_data->cert = | 1071 ssl_data->cert = |
| 1013 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); | 1072 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); |
| 1014 ASSERT_TRUE(ssl_data->cert.get()); | 1073 ASSERT_TRUE(ssl_data->cert.get()); |
| 1015 ssl_data_.push_back(std::move(ssl_data)); | 1074 ssl_data_.push_back(std::move(ssl_data)); |
| 1016 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); | 1075 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); |
| 1017 ssl_data_.push_back(std::move(ssl_data)); | 1076 ssl_data_.push_back(std::move(ssl_data)); |
| 1018 url_request_context_host_.AddRawExpectations(BuildNullSocketData()); | 1077 url_request_context_host_.AddRawExpectations(BuildNullSocketData()); |
| 1019 CreateAndConnectStandard("wss://localhost/", "localhost", "/", | 1078 CreateAndConnectStandard("wss://localhost/", "localhost", "/", |
| 1020 NoSubProtocols(), LocalhostOrigin(), "", ""); | 1079 NoSubProtocols(), LocalhostOrigin(), "", "", ""); |
| 1021 // WaitUntilConnectDone doesn't work in this case. | 1080 // WaitUntilConnectDone doesn't work in this case. |
| 1022 base::RunLoop().RunUntilIdle(); | 1081 base::RunLoop().RunUntilIdle(); |
| 1023 ASSERT_TRUE(ssl_error_callbacks_); | 1082 ASSERT_TRUE(ssl_error_callbacks_); |
| 1024 ssl_error_callbacks_->ContinueSSLRequest(); | 1083 ssl_error_callbacks_->ContinueSSLRequest(); |
| 1025 WaitUntilConnectDone(); | 1084 WaitUntilConnectDone(); |
| 1026 EXPECT_FALSE(has_failed()); | 1085 EXPECT_FALSE(has_failed()); |
| 1027 EXPECT_TRUE(stream_); | 1086 EXPECT_TRUE(stream_); |
| 1028 } | 1087 } |
| 1029 | 1088 |
| 1030 // If the server requests authorisation, but we have no credentials, the | 1089 // If the server requests authorisation, but we have no credentials, the |
| 1031 // connection should fail cleanly. | 1090 // connection should fail cleanly. |
| 1032 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) { | 1091 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) { |
| 1033 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 1092 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 1034 NoSubProtocols(), LocalhostOrigin(), "", | 1093 NoSubProtocols(), LocalhostOrigin(), "", "", |
| 1035 kUnauthorizedResponse); | 1094 kUnauthorizedResponse); |
| 1036 WaitUntilConnectDone(); | 1095 WaitUntilConnectDone(); |
| 1037 EXPECT_TRUE(has_failed()); | 1096 EXPECT_TRUE(has_failed()); |
| 1038 EXPECT_EQ("HTTP Authentication failed; no valid credentials available", | 1097 EXPECT_EQ("HTTP Authentication failed; no valid credentials available", |
| 1039 failure_message()); | 1098 failure_message()); |
| 1040 EXPECT_TRUE(response_info_); | 1099 EXPECT_TRUE(response_info_); |
| 1041 } | 1100 } |
| 1042 | 1101 |
| 1043 TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) { | 1102 TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) { |
| 1044 CreateAndConnectAuthHandshake("ws://foo:bar@localhost/", | 1103 CreateAndConnectAuthHandshake("ws://foo:bar@localhost/", |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1059 EXPECT_TRUE(response_info_); | 1118 EXPECT_TRUE(response_info_); |
| 1060 } | 1119 } |
| 1061 | 1120 |
| 1062 // Digest auth has the same connection semantics as Basic auth, so we can | 1121 // Digest auth has the same connection semantics as Basic auth, so we can |
| 1063 // generally assume that whatever works for Basic auth will also work for | 1122 // generally assume that whatever works for Basic auth will also work for |
| 1064 // Digest. There's just one test here, to confirm that it works at all. | 1123 // Digest. There's just one test here, to confirm that it works at all. |
| 1065 TEST_F(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) { | 1124 TEST_F(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) { |
| 1066 AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse)); | 1125 AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse)); |
| 1067 | 1126 |
| 1068 CreateAndConnectRawExpectations( | 1127 CreateAndConnectRawExpectations( |
| 1069 "ws://FooBar:pass@localhost/", NoSubProtocols(), LocalhostOrigin(), | 1128 "ws://FooBar:pass@localhost/", NoSubProtocols(), LocalhostOrigin(), "", |
| 1070 helper_.BuildSocketData2(kAuthorizedRequest, | 1129 helper_.BuildSocketData2(kAuthorizedRequest, |
| 1071 WebSocketStandardResponse(std::string()))); | 1130 WebSocketStandardResponse(std::string()))); |
| 1072 WaitUntilConnectDone(); | 1131 WaitUntilConnectDone(); |
| 1073 EXPECT_FALSE(has_failed()); | 1132 EXPECT_FALSE(has_failed()); |
| 1074 EXPECT_TRUE(stream_); | 1133 EXPECT_TRUE(stream_); |
| 1075 ASSERT_TRUE(response_info_); | 1134 ASSERT_TRUE(response_info_); |
| 1076 EXPECT_EQ(101, response_info_->status_code); | 1135 EXPECT_EQ(101, response_info_->status_code); |
| 1077 } | 1136 } |
| 1078 | 1137 |
| 1079 TEST_F(WebSocketStreamCreateUMATest, Incomplete) { | 1138 TEST_F(WebSocketStreamCreateUMATest, Incomplete) { |
| 1080 const std::string name("Net.WebSocket.HandshakeResult"); | 1139 const std::string name("Net.WebSocket.HandshakeResult"); |
| 1081 std::unique_ptr<base::HistogramSamples> original(GetSamples(name)); | 1140 std::unique_ptr<base::HistogramSamples> original(GetSamples(name)); |
| 1082 | 1141 |
| 1083 { | 1142 { |
| 1084 StreamCreation creation; | 1143 StreamCreation creation; |
| 1085 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 1144 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 1086 creation.NoSubProtocols(), | 1145 creation.NoSubProtocols(), |
| 1087 LocalhostOrigin(), "", ""); | 1146 LocalhostOrigin(), "", "", ""); |
| 1088 } | 1147 } |
| 1089 | 1148 |
| 1090 std::unique_ptr<base::HistogramSamples> samples(GetSamples(name)); | 1149 std::unique_ptr<base::HistogramSamples> samples(GetSamples(name)); |
| 1091 ASSERT_TRUE(samples); | 1150 ASSERT_TRUE(samples); |
| 1092 if (original) { | 1151 if (original) { |
| 1093 samples->Subtract(*original); // Cancel the original values. | 1152 samples->Subtract(*original); // Cancel the original values. |
| 1094 } | 1153 } |
| 1095 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); | 1154 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); |
| 1096 EXPECT_EQ(0, samples->GetCount(CONNECTED)); | 1155 EXPECT_EQ(0, samples->GetCount(CONNECTED)); |
| 1097 EXPECT_EQ(0, samples->GetCount(FAILED)); | 1156 EXPECT_EQ(0, samples->GetCount(FAILED)); |
| 1098 } | 1157 } |
| 1099 | 1158 |
| 1100 TEST_F(WebSocketStreamCreateUMATest, Connected) { | 1159 TEST_F(WebSocketStreamCreateUMATest, Connected) { |
| 1101 const std::string name("Net.WebSocket.HandshakeResult"); | 1160 const std::string name("Net.WebSocket.HandshakeResult"); |
| 1102 std::unique_ptr<base::HistogramSamples> original(GetSamples(name)); | 1161 std::unique_ptr<base::HistogramSamples> original(GetSamples(name)); |
| 1103 | 1162 |
| 1104 { | 1163 { |
| 1105 StreamCreation creation; | 1164 StreamCreation creation; |
| 1106 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 1165 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 1107 creation.NoSubProtocols(), | 1166 creation.NoSubProtocols(), |
| 1108 LocalhostOrigin(), "", ""); | 1167 LocalhostOrigin(), "", "", ""); |
| 1109 creation.WaitUntilConnectDone(); | 1168 creation.WaitUntilConnectDone(); |
| 1110 } | 1169 } |
| 1111 | 1170 |
| 1112 std::unique_ptr<base::HistogramSamples> samples(GetSamples(name)); | 1171 std::unique_ptr<base::HistogramSamples> samples(GetSamples(name)); |
| 1113 ASSERT_TRUE(samples); | 1172 ASSERT_TRUE(samples); |
| 1114 if (original) { | 1173 if (original) { |
| 1115 samples->Subtract(*original); // Cancel the original values. | 1174 samples->Subtract(*original); // Cancel the original values. |
| 1116 } | 1175 } |
| 1117 EXPECT_EQ(0, samples->GetCount(INCOMPLETE)); | 1176 EXPECT_EQ(0, samples->GetCount(INCOMPLETE)); |
| 1118 EXPECT_EQ(1, samples->GetCount(CONNECTED)); | 1177 EXPECT_EQ(1, samples->GetCount(CONNECTED)); |
| 1119 EXPECT_EQ(0, samples->GetCount(FAILED)); | 1178 EXPECT_EQ(0, samples->GetCount(FAILED)); |
| 1120 } | 1179 } |
| 1121 | 1180 |
| 1122 TEST_F(WebSocketStreamCreateUMATest, Failed) { | 1181 TEST_F(WebSocketStreamCreateUMATest, Failed) { |
| 1123 const std::string name("Net.WebSocket.HandshakeResult"); | 1182 const std::string name("Net.WebSocket.HandshakeResult"); |
| 1124 std::unique_ptr<base::HistogramSamples> original(GetSamples(name)); | 1183 std::unique_ptr<base::HistogramSamples> original(GetSamples(name)); |
| 1125 | 1184 |
| 1126 { | 1185 { |
| 1127 StreamCreation creation; | 1186 StreamCreation creation; |
| 1128 static const char kInvalidStatusCodeResponse[] = | 1187 static const char kInvalidStatusCodeResponse[] = |
| 1129 "HTTP/1.1 200 OK\r\n" | 1188 "HTTP/1.1 200 OK\r\n" |
| 1130 "Upgrade: websocket\r\n" | 1189 "Upgrade: websocket\r\n" |
| 1131 "Connection: Upgrade\r\n" | 1190 "Connection: Upgrade\r\n" |
| 1132 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 1191 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 1133 "\r\n"; | 1192 "\r\n"; |
| 1134 creation.CreateAndConnectCustomResponse( | 1193 creation.CreateAndConnectCustomResponse( |
| 1135 "ws://localhost/", "localhost", "/", creation.NoSubProtocols(), | 1194 "ws://localhost/", "localhost", "/", creation.NoSubProtocols(), |
| 1136 LocalhostOrigin(), "", kInvalidStatusCodeResponse); | 1195 LocalhostOrigin(), "", "", kInvalidStatusCodeResponse); |
| 1137 creation.WaitUntilConnectDone(); | 1196 creation.WaitUntilConnectDone(); |
| 1138 } | 1197 } |
| 1139 | 1198 |
| 1140 std::unique_ptr<base::HistogramSamples> samples(GetSamples(name)); | 1199 std::unique_ptr<base::HistogramSamples> samples(GetSamples(name)); |
| 1141 ASSERT_TRUE(samples); | 1200 ASSERT_TRUE(samples); |
| 1142 if (original) { | 1201 if (original) { |
| 1143 samples->Subtract(*original); // Cancel the original values. | 1202 samples->Subtract(*original); // Cancel the original values. |
| 1144 } | 1203 } |
| 1145 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); | 1204 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); |
| 1146 EXPECT_EQ(0, samples->GetCount(CONNECTED)); | 1205 EXPECT_EQ(0, samples->GetCount(CONNECTED)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1159 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), ""); | 1218 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), ""); |
| 1160 MockRead reads[] = { | 1219 MockRead reads[] = { |
| 1161 MockRead(SYNCHRONOUS, 1, kTruncatedResponse), | 1220 MockRead(SYNCHRONOUS, 1, kTruncatedResponse), |
| 1162 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 2), | 1221 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 2), |
| 1163 }; | 1222 }; |
| 1164 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, request.c_str())}; | 1223 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, request.c_str())}; |
| 1165 std::unique_ptr<SequencedSocketData> socket_data( | 1224 std::unique_ptr<SequencedSocketData> socket_data( |
| 1166 BuildSocketData(reads, writes)); | 1225 BuildSocketData(reads, writes)); |
| 1167 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 1226 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
| 1168 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 1227 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 1169 LocalhostOrigin(), std::move(socket_data)); | 1228 LocalhostOrigin(), "", |
| 1229 std::move(socket_data)); |
| 1170 WaitUntilConnectDone(); | 1230 WaitUntilConnectDone(); |
| 1171 EXPECT_TRUE(has_failed()); | 1231 EXPECT_TRUE(has_failed()); |
| 1172 } | 1232 } |
| 1173 | 1233 |
| 1174 TEST_F(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) { | 1234 TEST_F(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) { |
| 1175 static const char kConnectRequest[] = | 1235 static const char kConnectRequest[] = |
| 1176 "CONNECT localhost:80 HTTP/1.1\r\n" | 1236 "CONNECT localhost:80 HTTP/1.1\r\n" |
| 1177 "Host: localhost:80\r\n" | 1237 "Host: localhost:80\r\n" |
| 1178 "Proxy-Connection: keep-alive\r\n" | 1238 "Proxy-Connection: keep-alive\r\n" |
| 1179 "\r\n"; | 1239 "\r\n"; |
| 1180 | 1240 |
| 1181 static const char kProxyResponse[] = | 1241 static const char kProxyResponse[] = |
| 1182 "HTTP/1.1 403 Forbidden\r\n" | 1242 "HTTP/1.1 403 Forbidden\r\n" |
| 1183 "Content-Type: text/html\r\n" | 1243 "Content-Type: text/html\r\n" |
| 1184 "Content-Length: 9\r\n" | 1244 "Content-Length: 9\r\n" |
| 1185 "Connection: keep-alive\r\n" | 1245 "Connection: keep-alive\r\n" |
| 1186 "\r\n" | 1246 "\r\n" |
| 1187 "Forbidden"; | 1247 "Forbidden"; |
| 1188 | 1248 |
| 1189 MockRead reads[] = {MockRead(SYNCHRONOUS, 1, kProxyResponse)}; | 1249 MockRead reads[] = {MockRead(SYNCHRONOUS, 1, kProxyResponse)}; |
| 1190 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, kConnectRequest)}; | 1250 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, kConnectRequest)}; |
| 1191 std::unique_ptr<SequencedSocketData> socket_data( | 1251 std::unique_ptr<SequencedSocketData> socket_data( |
| 1192 BuildSocketData(reads, writes)); | 1252 BuildSocketData(reads, writes)); |
| 1193 url_request_context_host_.SetProxyConfig("https=proxy:8000"); | 1253 url_request_context_host_.SetProxyConfig("https=proxy:8000"); |
| 1194 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 1254 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 1195 LocalhostOrigin(), std::move(socket_data)); | 1255 LocalhostOrigin(), "", |
| 1256 std::move(socket_data)); |
| 1196 WaitUntilConnectDone(); | 1257 WaitUntilConnectDone(); |
| 1197 EXPECT_TRUE(has_failed()); | 1258 EXPECT_TRUE(has_failed()); |
| 1198 EXPECT_EQ("Establishing a tunnel via proxy server failed.", | 1259 EXPECT_EQ("Establishing a tunnel via proxy server failed.", |
| 1199 failure_message()); | 1260 failure_message()); |
| 1200 } | 1261 } |
| 1201 | 1262 |
| 1202 } // namespace | 1263 } // namespace |
| 1203 } // namespace net | 1264 } // namespace net |
| OLD | NEW |