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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 // This will break in an obvious way if the type created by | 72 // This will break in an obvious way if the type created by |
73 // CreateBasicStream() changes. | 73 // CreateBasicStream() changes. |
74 static_cast<WebSocketBasicHandshakeStream*>(stream()) | 74 static_cast<WebSocketBasicHandshakeStream*>(stream()) |
75 ->SetWebSocketKeyForTesting("dGhlIHNhbXBsZSBub25jZQ=="); | 75 ->SetWebSocketKeyForTesting("dGhlIHNhbXBsZSBub25jZQ=="); |
76 return stream(); | 76 return stream(); |
77 } | 77 } |
78 }; | 78 }; |
79 | 79 |
80 class WebSocketStreamCreateTest : public ::testing::Test { | 80 class WebSocketStreamCreateTest : public ::testing::Test { |
81 public: | 81 public: |
82 WebSocketStreamCreateTest(): has_failed_(false) {} | 82 WebSocketStreamCreateTest() : has_failed_(false) {} |
83 | 83 |
84 void CreateAndConnectCustomResponse( | 84 void CreateAndConnectCustomResponse( |
85 const std::string& socket_url, | 85 const std::string& socket_url, |
86 const std::string& socket_path, | 86 const std::string& socket_path, |
87 const std::vector<std::string>& sub_protocols, | 87 const std::vector<std::string>& sub_protocols, |
88 const std::string& origin, | 88 const std::string& origin, |
89 const std::string& extra_request_headers, | 89 const std::string& extra_request_headers, |
90 const std::string& response_body) { | 90 const std::string& response_body) { |
91 url_request_context_host_.SetExpectations( | 91 url_request_context_host_.SetExpectations( |
92 WebSocketStandardRequest(socket_path, origin, extra_request_headers), | 92 WebSocketStandardRequest(socket_path, origin, extra_request_headers), |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 static const char kResponse[] = | 250 static const char kResponse[] = |
251 "HTTP/1.1 101 Switching Protocols\r\n" | 251 "HTTP/1.1 101 Switching Protocols\r\n" |
252 "Upgrade: websocket\r\n" | 252 "Upgrade: websocket\r\n" |
253 "Connection: Upgrade\r\n" | 253 "Connection: Upgrade\r\n" |
254 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 254 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
255 "foo: bar, baz\r\n" | 255 "foo: bar, baz\r\n" |
256 "hoge: fuga\r\n" | 256 "hoge: fuga\r\n" |
257 "hoge: piyo\r\n" | 257 "hoge: piyo\r\n" |
258 "\r\n"; | 258 "\r\n"; |
259 | 259 |
260 CreateAndConnectCustomResponse( | 260 CreateAndConnectCustomResponse("ws://localhost/", |
261 "ws://localhost/", | 261 "/", |
262 "/", | 262 NoSubProtocols(), |
263 NoSubProtocols(), | 263 "http://localhost", |
264 "http://localhost", | 264 "", |
265 "", | 265 kResponse); |
266 kResponse); | |
267 EXPECT_FALSE(request_info_); | 266 EXPECT_FALSE(request_info_); |
268 EXPECT_FALSE(response_info_); | 267 EXPECT_FALSE(response_info_); |
269 RunUntilIdle(); | 268 RunUntilIdle(); |
270 EXPECT_TRUE(stream_); | 269 EXPECT_TRUE(stream_); |
271 ASSERT_TRUE(request_info_); | 270 ASSERT_TRUE(request_info_); |
272 ASSERT_TRUE(response_info_); | 271 ASSERT_TRUE(response_info_); |
273 std::vector<HeaderKeyValuePair> request_headers = | 272 std::vector<HeaderKeyValuePair> request_headers = |
274 ToVector(request_info_->headers); | 273 ToVector(request_info_->headers); |
275 // We examine the contents of request_info_ and response_info_ | 274 // We examine the contents of request_info_ and response_info_ |
276 // mainly only in this test case. | 275 // mainly only in this test case. |
(...skipping 10 matching lines...) Expand all Loading... |
287 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), request_headers[4]); | 286 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), request_headers[4]); |
288 EXPECT_EQ(HeaderKeyValuePair("Origin", "http://localhost"), | 287 EXPECT_EQ(HeaderKeyValuePair("Origin", "http://localhost"), |
289 request_headers[5]); | 288 request_headers[5]); |
290 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Version", "13"), | 289 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Version", "13"), |
291 request_headers[6]); | 290 request_headers[6]); |
292 EXPECT_EQ(HeaderKeyValuePair("User-Agent", ""), request_headers[7]); | 291 EXPECT_EQ(HeaderKeyValuePair("User-Agent", ""), request_headers[7]); |
293 EXPECT_EQ(HeaderKeyValuePair("Accept-Encoding", "gzip,deflate"), | 292 EXPECT_EQ(HeaderKeyValuePair("Accept-Encoding", "gzip,deflate"), |
294 request_headers[8]); | 293 request_headers[8]); |
295 EXPECT_EQ(HeaderKeyValuePair("Accept-Language", "en-us,fr"), | 294 EXPECT_EQ(HeaderKeyValuePair("Accept-Language", "en-us,fr"), |
296 request_headers[9]); | 295 request_headers[9]); |
297 EXPECT_EQ("Sec-WebSocket-Key", request_headers[10].first); | 296 EXPECT_EQ("Sec-WebSocket-Key", request_headers[10].first); |
298 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Extensions", | 297 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Extensions", |
299 "permessage-deflate; client_max_window_bits"), | 298 "permessage-deflate; client_max_window_bits"), |
300 request_headers[11]); | 299 request_headers[11]); |
301 | 300 |
302 std::vector<HeaderKeyValuePair> response_headers = | 301 std::vector<HeaderKeyValuePair> response_headers = |
303 ToVector(*response_info_->headers); | 302 ToVector(*response_info_->headers); |
304 ASSERT_EQ(6u, response_headers.size()); | 303 ASSERT_EQ(6u, response_headers.size()); |
305 // Sort the headers for ease of verification. | 304 // Sort the headers for ease of verification. |
306 std::sort(response_headers.begin(), response_headers.end()); | 305 std::sort(response_headers.begin(), response_headers.end()); |
307 | 306 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { | 368 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { |
370 CreateAndConnectStandard("ws://localhost/testing_path", | 369 CreateAndConnectStandard("ws://localhost/testing_path", |
371 "/testing_path", | 370 "/testing_path", |
372 NoSubProtocols(), | 371 NoSubProtocols(), |
373 "http://google.com", | 372 "http://google.com", |
374 "", | 373 "", |
375 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); | 374 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); |
376 RunUntilIdle(); | 375 RunUntilIdle(); |
377 EXPECT_FALSE(stream_); | 376 EXPECT_FALSE(stream_); |
378 EXPECT_TRUE(has_failed()); | 377 EXPECT_TRUE(has_failed()); |
379 EXPECT_EQ("Error during WebSocket handshake: " | 378 EXPECT_EQ( |
380 "Response must not include 'Sec-WebSocket-Protocol' header " | 379 "Error during WebSocket handshake: " |
381 "if not present in request: chatv20.chromium.org", | 380 "Response must not include 'Sec-WebSocket-Protocol' header " |
382 failure_message()); | 381 "if not present in request: chatv20.chromium.org", |
| 382 failure_message()); |
383 } | 383 } |
384 | 384 |
385 // Missing sub-protocol response is rejected. | 385 // Missing sub-protocol response is rejected. |
386 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { | 386 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { |
387 std::vector<std::string> sub_protocols; | 387 std::vector<std::string> sub_protocols; |
388 sub_protocols.push_back("chat.example.com"); | 388 sub_protocols.push_back("chat.example.com"); |
389 CreateAndConnectStandard("ws://localhost/testing_path", | 389 CreateAndConnectStandard("ws://localhost/testing_path", |
390 "/testing_path", | 390 "/testing_path", |
391 sub_protocols, | 391 sub_protocols, |
392 "http://localhost", | 392 "http://localhost", |
393 "Sec-WebSocket-Protocol: chat.example.com\r\n", | 393 "Sec-WebSocket-Protocol: chat.example.com\r\n", |
394 ""); | 394 ""); |
395 RunUntilIdle(); | 395 RunUntilIdle(); |
396 EXPECT_FALSE(stream_); | 396 EXPECT_FALSE(stream_); |
397 EXPECT_TRUE(has_failed()); | 397 EXPECT_TRUE(has_failed()); |
398 EXPECT_EQ("Error during WebSocket handshake: " | 398 EXPECT_EQ( |
399 "Sent non-empty 'Sec-WebSocket-Protocol' header " | 399 "Error during WebSocket handshake: " |
400 "but no response was received", | 400 "Sent non-empty 'Sec-WebSocket-Protocol' header " |
401 failure_message()); | 401 "but no response was received", |
| 402 failure_message()); |
402 } | 403 } |
403 | 404 |
404 // Only one sub-protocol can be accepted. | 405 // Only one sub-protocol can be accepted. |
405 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { | 406 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { |
406 std::vector<std::string> sub_protocols; | 407 std::vector<std::string> sub_protocols; |
407 sub_protocols.push_back("chatv11.chromium.org"); | 408 sub_protocols.push_back("chatv11.chromium.org"); |
408 sub_protocols.push_back("chatv20.chromium.org"); | 409 sub_protocols.push_back("chatv20.chromium.org"); |
409 CreateAndConnectStandard("ws://localhost/testing_path", | 410 CreateAndConnectStandard("ws://localhost/testing_path", |
410 "/testing_path", | 411 "/testing_path", |
411 sub_protocols, | 412 sub_protocols, |
412 "http://google.com", | 413 "http://google.com", |
413 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 414 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
414 "chatv20.chromium.org\r\n", | 415 "chatv20.chromium.org\r\n", |
415 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 416 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
416 "chatv20.chromium.org\r\n"); | 417 "chatv20.chromium.org\r\n"); |
417 RunUntilIdle(); | 418 RunUntilIdle(); |
418 EXPECT_FALSE(stream_); | 419 EXPECT_FALSE(stream_); |
419 EXPECT_TRUE(has_failed()); | 420 EXPECT_TRUE(has_failed()); |
420 EXPECT_EQ("Error during WebSocket handshake: " | 421 EXPECT_EQ( |
421 "'Sec-WebSocket-Protocol' header must not appear " | 422 "Error during WebSocket handshake: " |
422 "more than once in a response", | 423 "'Sec-WebSocket-Protocol' header must not appear " |
423 failure_message()); | 424 "more than once in a response", |
| 425 failure_message()); |
424 } | 426 } |
425 | 427 |
426 // Unmatched sub-protocol should be rejected. | 428 // Unmatched sub-protocol should be rejected. |
427 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { | 429 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { |
428 std::vector<std::string> sub_protocols; | 430 std::vector<std::string> sub_protocols; |
429 sub_protocols.push_back("chatv11.chromium.org"); | 431 sub_protocols.push_back("chatv11.chromium.org"); |
430 sub_protocols.push_back("chatv20.chromium.org"); | 432 sub_protocols.push_back("chatv20.chromium.org"); |
431 CreateAndConnectStandard("ws://localhost/testing_path", | 433 CreateAndConnectStandard("ws://localhost/testing_path", |
432 "/testing_path", | 434 "/testing_path", |
433 sub_protocols, | 435 sub_protocols, |
434 "http://google.com", | 436 "http://google.com", |
435 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 437 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
436 "chatv20.chromium.org\r\n", | 438 "chatv20.chromium.org\r\n", |
437 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); | 439 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); |
438 RunUntilIdle(); | 440 RunUntilIdle(); |
439 EXPECT_FALSE(stream_); | 441 EXPECT_FALSE(stream_); |
440 EXPECT_TRUE(has_failed()); | 442 EXPECT_TRUE(has_failed()); |
441 EXPECT_EQ("Error during WebSocket handshake: " | 443 EXPECT_EQ( |
442 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " | 444 "Error during WebSocket handshake: " |
443 "in response does not match any of sent values", | 445 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " |
444 failure_message()); | 446 "in response does not match any of sent values", |
| 447 failure_message()); |
445 } | 448 } |
446 | 449 |
447 // permessage-deflate extension basic success case. | 450 // permessage-deflate extension basic success case. |
448 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateSuccess) { | 451 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateSuccess) { |
449 CreateAndConnectWithExtensions("permessage-deflate"); | 452 CreateAndConnectWithExtensions("permessage-deflate"); |
450 EXPECT_TRUE(stream_); | 453 EXPECT_TRUE(stream_); |
451 EXPECT_FALSE(has_failed()); | 454 EXPECT_FALSE(has_failed()); |
452 } | 455 } |
453 | 456 |
454 // permessage-deflate extensions success with all parameters. | 457 // permessage-deflate extensions success with all parameters. |
(...skipping 30 matching lines...) Expand all Loading... |
485 ASSERT_EQ(1U, frames.size()); | 488 ASSERT_EQ(1U, frames.size()); |
486 ASSERT_EQ(5U, frames[0]->header.payload_length); | 489 ASSERT_EQ(5U, frames[0]->header.payload_length); |
487 EXPECT_EQ("Hello", std::string(frames[0]->data->data(), 5)); | 490 EXPECT_EQ("Hello", std::string(frames[0]->data->data(), 5)); |
488 } | 491 } |
489 | 492 |
490 // Unknown extension in the response is rejected | 493 // Unknown extension in the response is rejected |
491 TEST_F(WebSocketStreamCreateExtensionTest, UnknownExtension) { | 494 TEST_F(WebSocketStreamCreateExtensionTest, UnknownExtension) { |
492 CreateAndConnectWithExtensions("x-unknown-extension"); | 495 CreateAndConnectWithExtensions("x-unknown-extension"); |
493 EXPECT_FALSE(stream_); | 496 EXPECT_FALSE(stream_); |
494 EXPECT_TRUE(has_failed()); | 497 EXPECT_TRUE(has_failed()); |
495 EXPECT_EQ("Error during WebSocket handshake: " | 498 EXPECT_EQ( |
496 "Found an unsupported extension 'x-unknown-extension' " | 499 "Error during WebSocket handshake: " |
497 "in 'Sec-WebSocket-Extensions' header", | 500 "Found an unsupported extension 'x-unknown-extension' " |
498 failure_message()); | 501 "in 'Sec-WebSocket-Extensions' header", |
| 502 failure_message()); |
499 } | 503 } |
500 | 504 |
501 // Malformed extensions are rejected (this file does not cover all possible | 505 // Malformed extensions are rejected (this file does not cover all possible |
502 // parse failures, as the parser is covered thoroughly by its own unit tests). | 506 // parse failures, as the parser is covered thoroughly by its own unit tests). |
503 TEST_F(WebSocketStreamCreateExtensionTest, MalformedExtension) { | 507 TEST_F(WebSocketStreamCreateExtensionTest, MalformedExtension) { |
504 CreateAndConnectWithExtensions(";"); | 508 CreateAndConnectWithExtensions(";"); |
505 EXPECT_FALSE(stream_); | 509 EXPECT_FALSE(stream_); |
506 EXPECT_TRUE(has_failed()); | 510 EXPECT_TRUE(has_failed()); |
507 EXPECT_EQ( | 511 EXPECT_EQ( |
508 "Error during WebSocket handshake: 'Sec-WebSocket-Extensions' header " | 512 "Error during WebSocket handshake: 'Sec-WebSocket-Extensions' header " |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 CreateAndConnectStandard( | 657 CreateAndConnectStandard( |
654 "ws://localhost/", | 658 "ws://localhost/", |
655 "/", | 659 "/", |
656 NoSubProtocols(), | 660 NoSubProtocols(), |
657 "http://localhost", | 661 "http://localhost", |
658 "", | 662 "", |
659 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); | 663 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); |
660 RunUntilIdle(); | 664 RunUntilIdle(); |
661 EXPECT_FALSE(stream_); | 665 EXPECT_FALSE(stream_); |
662 EXPECT_TRUE(has_failed()); | 666 EXPECT_TRUE(has_failed()); |
663 EXPECT_EQ("Error during WebSocket handshake: " | 667 EXPECT_EQ( |
664 "'Sec-WebSocket-Accept' header must not appear " | 668 "Error during WebSocket handshake: " |
665 "more than once in a response", | 669 "'Sec-WebSocket-Accept' header must not appear " |
666 failure_message()); | 670 "more than once in a response", |
| 671 failure_message()); |
667 } | 672 } |
668 | 673 |
669 // Response code 200 must be rejected. | 674 // Response code 200 must be rejected. |
670 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { | 675 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { |
671 static const char kInvalidStatusCodeResponse[] = | 676 static const char kInvalidStatusCodeResponse[] = |
672 "HTTP/1.1 200 OK\r\n" | 677 "HTTP/1.1 200 OK\r\n" |
673 "Upgrade: websocket\r\n" | 678 "Upgrade: websocket\r\n" |
674 "Connection: Upgrade\r\n" | 679 "Connection: Upgrade\r\n" |
675 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 680 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
676 "\r\n"; | 681 "\r\n"; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 "", | 752 "", |
748 kMissingUpgradeResponse); | 753 kMissingUpgradeResponse); |
749 RunUntilIdle(); | 754 RunUntilIdle(); |
750 EXPECT_TRUE(has_failed()); | 755 EXPECT_TRUE(has_failed()); |
751 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", | 756 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", |
752 failure_message()); | 757 failure_message()); |
753 } | 758 } |
754 | 759 |
755 // There must only be one upgrade header. | 760 // There must only be one upgrade header. |
756 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { | 761 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { |
757 CreateAndConnectStandard( | 762 CreateAndConnectStandard("ws://localhost/", |
758 "ws://localhost/", | 763 "/", |
759 "/", | 764 NoSubProtocols(), |
760 NoSubProtocols(), | 765 "http://localhost", |
761 "http://localhost", | 766 "", |
762 "", "Upgrade: HTTP/2.0\r\n"); | 767 "Upgrade: HTTP/2.0\r\n"); |
763 RunUntilIdle(); | 768 RunUntilIdle(); |
764 EXPECT_TRUE(has_failed()); | 769 EXPECT_TRUE(has_failed()); |
765 EXPECT_EQ("Error during WebSocket handshake: " | 770 EXPECT_EQ( |
766 "'Upgrade' header must not appear more than once in a response", | 771 "Error during WebSocket handshake: " |
767 failure_message()); | 772 "'Upgrade' header must not appear more than once in a response", |
| 773 failure_message()); |
768 } | 774 } |
769 | 775 |
770 // There must only be one correct upgrade header. | 776 // There must only be one correct upgrade header. |
771 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { | 777 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { |
772 static const char kMissingUpgradeResponse[] = | 778 static const char kMissingUpgradeResponse[] = |
773 "HTTP/1.1 101 Switching Protocols\r\n" | 779 "HTTP/1.1 101 Switching Protocols\r\n" |
774 "Connection: Upgrade\r\n" | 780 "Connection: Upgrade\r\n" |
775 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 781 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
776 "Upgrade: hogefuga\r\n" | 782 "Upgrade: hogefuga\r\n" |
777 "\r\n"; | 783 "\r\n"; |
778 CreateAndConnectCustomResponse("ws://localhost/", | 784 CreateAndConnectCustomResponse("ws://localhost/", |
779 "/", | 785 "/", |
780 NoSubProtocols(), | 786 NoSubProtocols(), |
781 "http://localhost", | 787 "http://localhost", |
782 "", | 788 "", |
783 kMissingUpgradeResponse); | 789 kMissingUpgradeResponse); |
784 RunUntilIdle(); | 790 RunUntilIdle(); |
785 EXPECT_TRUE(has_failed()); | 791 EXPECT_TRUE(has_failed()); |
786 EXPECT_EQ("Error during WebSocket handshake: " | 792 EXPECT_EQ( |
787 "'Upgrade' header value is not 'WebSocket': hogefuga", | 793 "Error during WebSocket handshake: " |
788 failure_message()); | 794 "'Upgrade' header value is not 'WebSocket': hogefuga", |
| 795 failure_message()); |
789 } | 796 } |
790 | 797 |
791 // Connection header must be present. | 798 // Connection header must be present. |
792 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { | 799 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { |
793 static const char kMissingConnectionResponse[] = | 800 static const char kMissingConnectionResponse[] = |
794 "HTTP/1.1 101 Switching Protocols\r\n" | 801 "HTTP/1.1 101 Switching Protocols\r\n" |
795 "Upgrade: websocket\r\n" | 802 "Upgrade: websocket\r\n" |
796 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 803 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
797 "\r\n"; | 804 "\r\n"; |
798 CreateAndConnectCustomResponse("ws://localhost/", | 805 CreateAndConnectCustomResponse("ws://localhost/", |
799 "/", | 806 "/", |
800 NoSubProtocols(), | 807 NoSubProtocols(), |
801 "http://localhost", | 808 "http://localhost", |
802 "", | 809 "", |
803 kMissingConnectionResponse); | 810 kMissingConnectionResponse); |
804 RunUntilIdle(); | 811 RunUntilIdle(); |
805 EXPECT_TRUE(has_failed()); | 812 EXPECT_TRUE(has_failed()); |
806 EXPECT_EQ("Error during WebSocket handshake: " | 813 EXPECT_EQ( |
807 "'Connection' header is missing", | 814 "Error during WebSocket handshake: " |
808 failure_message()); | 815 "'Connection' header is missing", |
| 816 failure_message()); |
809 } | 817 } |
810 | 818 |
811 // Connection header must contain "Upgrade". | 819 // Connection header must contain "Upgrade". |
812 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { | 820 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { |
813 static const char kMissingConnectionResponse[] = | 821 static const char kMissingConnectionResponse[] = |
814 "HTTP/1.1 101 Switching Protocols\r\n" | 822 "HTTP/1.1 101 Switching Protocols\r\n" |
815 "Upgrade: websocket\r\n" | 823 "Upgrade: websocket\r\n" |
816 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 824 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
817 "Connection: hogefuga\r\n" | 825 "Connection: hogefuga\r\n" |
818 "\r\n"; | 826 "\r\n"; |
819 CreateAndConnectCustomResponse("ws://localhost/", | 827 CreateAndConnectCustomResponse("ws://localhost/", |
820 "/", | 828 "/", |
821 NoSubProtocols(), | 829 NoSubProtocols(), |
822 "http://localhost", | 830 "http://localhost", |
823 "", | 831 "", |
824 kMissingConnectionResponse); | 832 kMissingConnectionResponse); |
825 RunUntilIdle(); | 833 RunUntilIdle(); |
826 EXPECT_TRUE(has_failed()); | 834 EXPECT_TRUE(has_failed()); |
827 EXPECT_EQ("Error during WebSocket handshake: " | 835 EXPECT_EQ( |
828 "'Connection' header value must contain 'Upgrade'", | 836 "Error during WebSocket handshake: " |
829 failure_message()); | 837 "'Connection' header value must contain 'Upgrade'", |
| 838 failure_message()); |
830 } | 839 } |
831 | 840 |
832 // Connection header is permitted to contain other tokens. | 841 // Connection header is permitted to contain other tokens. |
833 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { | 842 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { |
834 static const char kAdditionalConnectionTokenResponse[] = | 843 static const char kAdditionalConnectionTokenResponse[] = |
835 "HTTP/1.1 101 Switching Protocols\r\n" | 844 "HTTP/1.1 101 Switching Protocols\r\n" |
836 "Upgrade: websocket\r\n" | 845 "Upgrade: websocket\r\n" |
837 "Connection: Upgrade, Keep-Alive\r\n" | 846 "Connection: Upgrade, Keep-Alive\r\n" |
838 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 847 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
839 "\r\n"; | 848 "\r\n"; |
(...skipping 16 matching lines...) Expand all Loading... |
856 "Connection: Upgrade\r\n" | 865 "Connection: Upgrade\r\n" |
857 "\r\n"; | 866 "\r\n"; |
858 CreateAndConnectCustomResponse("ws://localhost/", | 867 CreateAndConnectCustomResponse("ws://localhost/", |
859 "/", | 868 "/", |
860 NoSubProtocols(), | 869 NoSubProtocols(), |
861 "http://localhost", | 870 "http://localhost", |
862 "", | 871 "", |
863 kMissingAcceptResponse); | 872 kMissingAcceptResponse); |
864 RunUntilIdle(); | 873 RunUntilIdle(); |
865 EXPECT_TRUE(has_failed()); | 874 EXPECT_TRUE(has_failed()); |
866 EXPECT_EQ("Error during WebSocket handshake: " | 875 EXPECT_EQ( |
867 "'Sec-WebSocket-Accept' header is missing", | 876 "Error during WebSocket handshake: " |
868 failure_message()); | 877 "'Sec-WebSocket-Accept' header is missing", |
| 878 failure_message()); |
869 } | 879 } |
870 | 880 |
871 // Sec-WebSocket-Accept header must match the key that was sent. | 881 // Sec-WebSocket-Accept header must match the key that was sent. |
872 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { | 882 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { |
873 static const char kIncorrectAcceptResponse[] = | 883 static const char kIncorrectAcceptResponse[] = |
874 "HTTP/1.1 101 Switching Protocols\r\n" | 884 "HTTP/1.1 101 Switching Protocols\r\n" |
875 "Upgrade: websocket\r\n" | 885 "Upgrade: websocket\r\n" |
876 "Connection: Upgrade\r\n" | 886 "Connection: Upgrade\r\n" |
877 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" | 887 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" |
878 "\r\n"; | 888 "\r\n"; |
879 CreateAndConnectCustomResponse("ws://localhost/", | 889 CreateAndConnectCustomResponse("ws://localhost/", |
880 "/", | 890 "/", |
881 NoSubProtocols(), | 891 NoSubProtocols(), |
882 "http://localhost", | 892 "http://localhost", |
883 "", | 893 "", |
884 kIncorrectAcceptResponse); | 894 kIncorrectAcceptResponse); |
885 RunUntilIdle(); | 895 RunUntilIdle(); |
886 EXPECT_TRUE(has_failed()); | 896 EXPECT_TRUE(has_failed()); |
887 EXPECT_EQ("Error during WebSocket handshake: " | 897 EXPECT_EQ( |
888 "Incorrect 'Sec-WebSocket-Accept' header value", | 898 "Error during WebSocket handshake: " |
889 failure_message()); | 899 "Incorrect 'Sec-WebSocket-Accept' header value", |
| 900 failure_message()); |
890 } | 901 } |
891 | 902 |
892 // Cancellation works. | 903 // Cancellation works. |
893 TEST_F(WebSocketStreamCreateTest, Cancellation) { | 904 TEST_F(WebSocketStreamCreateTest, Cancellation) { |
894 CreateAndConnectStandard( | 905 CreateAndConnectStandard( |
895 "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", ""); | 906 "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", ""); |
896 stream_request_.reset(); | 907 stream_request_.reset(); |
897 RunUntilIdle(); | 908 RunUntilIdle(); |
898 EXPECT_FALSE(has_failed()); | 909 EXPECT_FALSE(has_failed()); |
899 EXPECT_FALSE(stream_); | 910 EXPECT_FALSE(stream_); |
900 EXPECT_FALSE(request_info_); | 911 EXPECT_FALSE(request_info_); |
901 EXPECT_FALSE(response_info_); | 912 EXPECT_FALSE(response_info_); |
902 } | 913 } |
903 | 914 |
904 // Connect failure must look just like negotiation failure. | 915 // Connect failure must look just like negotiation failure. |
905 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { | 916 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { |
906 scoped_ptr<DeterministicSocketData> socket_data( | 917 scoped_ptr<DeterministicSocketData> socket_data( |
907 new DeterministicSocketData(NULL, 0, NULL, 0)); | 918 new DeterministicSocketData(NULL, 0, NULL, 0)); |
908 socket_data->set_connect_data( | 919 socket_data->set_connect_data( |
909 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); | 920 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); |
910 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 921 CreateAndConnectRawExpectations("ws://localhost/", |
911 "http://localhost", socket_data.Pass()); | 922 NoSubProtocols(), |
| 923 "http://localhost", |
| 924 socket_data.Pass()); |
912 RunUntilIdle(); | 925 RunUntilIdle(); |
913 EXPECT_TRUE(has_failed()); | 926 EXPECT_TRUE(has_failed()); |
914 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", | 927 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", |
915 failure_message()); | 928 failure_message()); |
916 EXPECT_FALSE(request_info_); | 929 EXPECT_FALSE(request_info_); |
917 EXPECT_FALSE(response_info_); | 930 EXPECT_FALSE(response_info_); |
918 } | 931 } |
919 | 932 |
920 // Connect timeout must look just like any other failure. | 933 // Connect timeout must look just like any other failure. |
921 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { | 934 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { |
922 scoped_ptr<DeterministicSocketData> socket_data( | 935 scoped_ptr<DeterministicSocketData> socket_data( |
923 new DeterministicSocketData(NULL, 0, NULL, 0)); | 936 new DeterministicSocketData(NULL, 0, NULL, 0)); |
924 socket_data->set_connect_data( | 937 socket_data->set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); |
925 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); | 938 CreateAndConnectRawExpectations("ws://localhost/", |
926 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 939 NoSubProtocols(), |
927 "http://localhost", socket_data.Pass()); | 940 "http://localhost", |
| 941 socket_data.Pass()); |
928 RunUntilIdle(); | 942 RunUntilIdle(); |
929 EXPECT_TRUE(has_failed()); | 943 EXPECT_TRUE(has_failed()); |
930 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", | 944 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", |
931 failure_message()); | 945 failure_message()); |
932 } | 946 } |
933 | 947 |
934 // Cancellation during connect works. | 948 // Cancellation during connect works. |
935 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { | 949 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { |
936 scoped_ptr<DeterministicSocketData> socket_data( | 950 scoped_ptr<DeterministicSocketData> socket_data( |
937 new DeterministicSocketData(NULL, 0, NULL, 0)); | 951 new DeterministicSocketData(NULL, 0, NULL, 0)); |
(...skipping 29 matching lines...) Expand all Loading... |
967 EXPECT_FALSE(stream_); | 981 EXPECT_FALSE(stream_); |
968 EXPECT_TRUE(request_info_); | 982 EXPECT_TRUE(request_info_); |
969 EXPECT_FALSE(response_info_); | 983 EXPECT_FALSE(response_info_); |
970 } | 984 } |
971 | 985 |
972 // Cancellation during read of the response headers works. | 986 // Cancellation during read of the response headers works. |
973 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { | 987 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { |
974 std::string request = WebSocketStandardRequest("/", "http://localhost", ""); | 988 std::string request = WebSocketStandardRequest("/", "http://localhost", ""); |
975 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; | 989 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; |
976 MockRead reads[] = { | 990 MockRead reads[] = { |
977 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"), | 991 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"), |
978 }; | 992 }; |
979 DeterministicSocketData* socket_data(new DeterministicSocketData( | 993 DeterministicSocketData* socket_data(new DeterministicSocketData( |
980 reads, arraysize(reads), writes, arraysize(writes))); | 994 reads, arraysize(reads), writes, arraysize(writes))); |
981 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 995 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
982 socket_data->SetStop(1); | 996 socket_data->SetStop(1); |
983 CreateAndConnectRawExpectations("ws://localhost/", | 997 CreateAndConnectRawExpectations("ws://localhost/", |
984 NoSubProtocols(), | 998 NoSubProtocols(), |
985 "http://localhost", | 999 "http://localhost", |
986 make_scoped_ptr(socket_data)); | 1000 make_scoped_ptr(socket_data)); |
987 socket_data->Run(); | 1001 socket_data->Run(); |
988 stream_request_.reset(); | 1002 stream_request_.reset(); |
989 RunUntilIdle(); | 1003 RunUntilIdle(); |
990 EXPECT_FALSE(has_failed()); | 1004 EXPECT_FALSE(has_failed()); |
991 EXPECT_FALSE(stream_); | 1005 EXPECT_FALSE(stream_); |
992 EXPECT_TRUE(request_info_); | 1006 EXPECT_TRUE(request_info_); |
993 EXPECT_FALSE(response_info_); | 1007 EXPECT_FALSE(response_info_); |
994 } | 1008 } |
995 | 1009 |
996 // Over-size response headers (> 256KB) should not cause a crash. This is a | 1010 // Over-size response headers (> 256KB) should not cause a crash. This is a |
997 // regression test for crbug.com/339456. It is based on the layout test | 1011 // regression test for crbug.com/339456. It is based on the layout test |
998 // "cookie-flood.html". | 1012 // "cookie-flood.html". |
999 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { | 1013 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { |
1000 std::string set_cookie_headers; | 1014 std::string set_cookie_headers; |
1001 set_cookie_headers.reserve(45 * 10000); | 1015 set_cookie_headers.reserve(45 * 10000); |
1002 for (int i = 0; i < 10000; ++i) { | 1016 for (int i = 0; i < 10000; ++i) { |
1003 set_cookie_headers += | 1017 set_cookie_headers += |
1004 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); | 1018 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); |
1005 } | 1019 } |
1006 CreateAndConnectStandard("ws://localhost/", "/", NoSubProtocols(), | 1020 CreateAndConnectStandard("ws://localhost/", |
1007 "http://localhost", "", set_cookie_headers); | 1021 "/", |
| 1022 NoSubProtocols(), |
| 1023 "http://localhost", |
| 1024 "", |
| 1025 set_cookie_headers); |
1008 RunUntilIdle(); | 1026 RunUntilIdle(); |
1009 EXPECT_TRUE(has_failed()); | 1027 EXPECT_TRUE(has_failed()); |
1010 EXPECT_FALSE(response_info_); | 1028 EXPECT_FALSE(response_info_); |
1011 } | 1029 } |
1012 | 1030 |
1013 // If the remote host closes the connection without sending headers, we should | 1031 // If the remote host closes the connection without sending headers, we should |
1014 // log the console message "Connection closed before receiving a handshake | 1032 // log the console message "Connection closed before receiving a handshake |
1015 // response". | 1033 // response". |
1016 TEST_F(WebSocketStreamCreateTest, NoResponse) { | 1034 TEST_F(WebSocketStreamCreateTest, NoResponse) { |
1017 std::string request = WebSocketStandardRequest("/", "http://localhost", ""); | 1035 std::string request = WebSocketStandardRequest("/", "http://localhost", ""); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1107 if (original) { | 1125 if (original) { |
1108 samples->Subtract(*original); // Cancel the original values. | 1126 samples->Subtract(*original); // Cancel the original values. |
1109 } | 1127 } |
1110 EXPECT_EQ(0, samples->GetCount(INCOMPLETE)); | 1128 EXPECT_EQ(0, samples->GetCount(INCOMPLETE)); |
1111 EXPECT_EQ(0, samples->GetCount(CONNECTED)); | 1129 EXPECT_EQ(0, samples->GetCount(CONNECTED)); |
1112 EXPECT_EQ(1, samples->GetCount(FAILED)); | 1130 EXPECT_EQ(1, samples->GetCount(FAILED)); |
1113 } | 1131 } |
1114 | 1132 |
1115 } // namespace | 1133 } // namespace |
1116 } // namespace net | 1134 } // namespace net |
OLD | NEW |