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