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