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