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_job.h" | 5 #include "net/websockets/websocket_job.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 // MockHostResolver resolves all hosts to 127.0.0.1; however, when we create | 385 // MockHostResolver resolves all hosts to 127.0.0.1; however, when we create |
386 // a WebSocketJob purely to block another one in a throttling test, we don't | 386 // a WebSocketJob purely to block another one in a throttling test, we don't |
387 // perform a real connect. In that case, the following address is used | 387 // perform a real connect. In that case, the following address is used |
388 // instead. | 388 // instead. |
389 IPAddressNumber ip; | 389 IPAddressNumber ip; |
390 ParseIPLiteralToNumber("127.0.0.1", &ip); | 390 ParseIPLiteralToNumber("127.0.0.1", &ip); |
391 websocket_->addresses_ = AddressList::CreateFromIPAddress(ip, 80); | 391 websocket_->addresses_ = AddressList::CreateFromIPAddress(ip, 80); |
392 } | 392 } |
393 void SkipToConnecting() { | 393 void SkipToConnecting() { |
394 websocket_->state_ = WebSocketJob::CONNECTING; | 394 websocket_->state_ = WebSocketJob::CONNECTING; |
395 WebSocketThrottle::GetInstance()->PutInQueue(websocket_.get()); | 395 ASSERT_TRUE(WebSocketThrottle::GetInstance()->PutInQueue(websocket_.get())); |
396 } | 396 } |
397 WebSocketJob::State GetWebSocketJobState() { | 397 WebSocketJob::State GetWebSocketJobState() { |
398 return websocket_->state_; | 398 return websocket_->state_; |
399 } | 399 } |
400 void CloseWebSocketJob() { | 400 void CloseWebSocketJob() { |
401 if (websocket_->socket_.get()) { | 401 if (websocket_->socket_.get()) { |
402 websocket_->socket_->DetachDelegate(); | 402 websocket_->socket_->DetachDelegate(); |
403 WebSocketThrottle::GetInstance()->RemoveFromQueue(websocket_.get()); | 403 WebSocketThrottle::GetInstance()->RemoveFromQueue(websocket_.get()); |
404 } | 404 } |
405 websocket_->state_ = WebSocketJob::CLOSED; | 405 websocket_->state_ = WebSocketJob::CLOSED; |
(...skipping 19 matching lines...) Expand all Loading... |
425 } | 425 } |
426 | 426 |
427 void TestSimpleHandshake(); | 427 void TestSimpleHandshake(); |
428 void TestSlowHandshake(); | 428 void TestSlowHandshake(); |
429 void TestHandshakeWithCookie(); | 429 void TestHandshakeWithCookie(); |
430 void TestHandshakeWithCookieButNotAllowed(); | 430 void TestHandshakeWithCookieButNotAllowed(); |
431 void TestHSTSUpgrade(); | 431 void TestHSTSUpgrade(); |
432 void TestInvalidSendData(); | 432 void TestInvalidSendData(); |
433 void TestConnectByWebSocket(ThrottlingOption throttling); | 433 void TestConnectByWebSocket(ThrottlingOption throttling); |
434 void TestConnectBySpdy(SpdyOption spdy, ThrottlingOption throttling); | 434 void TestConnectBySpdy(SpdyOption spdy, ThrottlingOption throttling); |
| 435 void TestThrottlingLimit(); |
435 | 436 |
436 SpdyWebSocketTestUtil spdy_util_; | 437 SpdyWebSocketTestUtil spdy_util_; |
437 StreamType stream_type_; | 438 StreamType stream_type_; |
438 scoped_refptr<MockCookieStore> cookie_store_; | 439 scoped_refptr<MockCookieStore> cookie_store_; |
439 scoped_ptr<MockURLRequestContext> context_; | 440 scoped_ptr<MockURLRequestContext> context_; |
440 scoped_refptr<WebSocketJob> websocket_; | 441 scoped_refptr<WebSocketJob> websocket_; |
441 scoped_refptr<SocketStream> socket_; | 442 scoped_refptr<SocketStream> socket_; |
442 scoped_ptr<MockClientSocketFactory> socket_factory_; | 443 scoped_ptr<MockClientSocketFactory> socket_factory_; |
443 scoped_ptr<OrderedSocketData> data_; | 444 scoped_ptr<OrderedSocketData> data_; |
444 TestCompletionCallback sync_test_callback_; | 445 TestCompletionCallback sync_test_callback_; |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 base::Bind(&WebSocketJobTest::DoSendData, base::Unretained(test))); | 815 base::Bind(&WebSocketJobTest::DoSendData, base::Unretained(test))); |
815 delegate.SetOnClose( | 816 delegate.SetOnClose( |
816 base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test))); | 817 base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test))); |
817 InitWebSocketJob(url, &delegate, STREAM_SOCKET); | 818 InitWebSocketJob(url, &delegate, STREAM_SOCKET); |
818 | 819 |
819 scoped_refptr<WebSocketJob> block_websocket; | 820 scoped_refptr<WebSocketJob> block_websocket; |
820 if (throttling == THROTTLING_ON) { | 821 if (throttling == THROTTLING_ON) { |
821 // Create former WebSocket object which obstructs the latter one. | 822 // Create former WebSocket object which obstructs the latter one. |
822 block_websocket = new WebSocketJob(NULL); | 823 block_websocket = new WebSocketJob(NULL); |
823 block_websocket->addresses_ = AddressList(websocket_->address_list()); | 824 block_websocket->addresses_ = AddressList(websocket_->address_list()); |
824 WebSocketThrottle::GetInstance()->PutInQueue(block_websocket.get()); | 825 ASSERT_TRUE( |
| 826 WebSocketThrottle::GetInstance()->PutInQueue(block_websocket.get())); |
825 } | 827 } |
826 | 828 |
827 websocket_->Connect(); | 829 websocket_->Connect(); |
828 | 830 |
829 if (throttling == THROTTLING_ON) { | 831 if (throttling == THROTTLING_ON) { |
830 EXPECT_EQ(OK, WaitForResult()); | 832 EXPECT_EQ(OK, WaitForResult()); |
831 EXPECT_TRUE(websocket_->IsWaiting()); | 833 EXPECT_TRUE(websocket_->IsWaiting()); |
832 | 834 |
833 // Remove the former WebSocket object from throttling queue to unblock the | 835 // Remove the former WebSocket object from throttling queue to unblock the |
834 // latter. | 836 // latter. |
| 837 block_websocket->state_ = WebSocketJob::CLOSED; |
835 WebSocketThrottle::GetInstance()->RemoveFromQueue(block_websocket.get()); | 838 WebSocketThrottle::GetInstance()->RemoveFromQueue(block_websocket.get()); |
836 block_websocket->state_ = WebSocketJob::CLOSED; | |
837 block_websocket = NULL; | 839 block_websocket = NULL; |
838 WebSocketThrottle::GetInstance()->WakeupSocketIfNecessary(); | |
839 } | 840 } |
840 | 841 |
841 EXPECT_EQ(OK, WaitForResult()); | 842 EXPECT_EQ(OK, WaitForResult()); |
842 EXPECT_TRUE(data_->at_read_eof()); | 843 EXPECT_TRUE(data_->at_read_eof()); |
843 EXPECT_TRUE(data_->at_write_eof()); | 844 EXPECT_TRUE(data_->at_write_eof()); |
844 EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState()); | 845 EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState()); |
845 } | 846 } |
846 | 847 |
847 void WebSocketJobTest::TestConnectBySpdy( | 848 void WebSocketJobTest::TestConnectBySpdy( |
848 SpdyOption spdy, ThrottlingOption throttling) { | 849 SpdyOption spdy, ThrottlingOption throttling) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 base::Bind(&WebSocketJobTest::DoSendData, base::Unretained(test))); | 944 base::Bind(&WebSocketJobTest::DoSendData, base::Unretained(test))); |
944 delegate.SetOnClose( | 945 delegate.SetOnClose( |
945 base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test))); | 946 base::Bind(&WebSocketJobTest::DoSync, base::Unretained(test))); |
946 InitWebSocketJob(url, &delegate, STREAM_SPDY_WEBSOCKET); | 947 InitWebSocketJob(url, &delegate, STREAM_SPDY_WEBSOCKET); |
947 | 948 |
948 scoped_refptr<WebSocketJob> block_websocket; | 949 scoped_refptr<WebSocketJob> block_websocket; |
949 if (throttling == THROTTLING_ON) { | 950 if (throttling == THROTTLING_ON) { |
950 // Create former WebSocket object which obstructs the latter one. | 951 // Create former WebSocket object which obstructs the latter one. |
951 block_websocket = new WebSocketJob(NULL); | 952 block_websocket = new WebSocketJob(NULL); |
952 block_websocket->addresses_ = AddressList(websocket_->address_list()); | 953 block_websocket->addresses_ = AddressList(websocket_->address_list()); |
953 WebSocketThrottle::GetInstance()->PutInQueue(block_websocket.get()); | 954 ASSERT_TRUE( |
| 955 WebSocketThrottle::GetInstance()->PutInQueue(block_websocket.get())); |
954 } | 956 } |
955 | 957 |
956 websocket_->Connect(); | 958 websocket_->Connect(); |
957 | 959 |
958 if (throttling == THROTTLING_ON) { | 960 if (throttling == THROTTLING_ON) { |
959 EXPECT_EQ(OK, WaitForResult()); | 961 EXPECT_EQ(OK, WaitForResult()); |
960 EXPECT_TRUE(websocket_->IsWaiting()); | 962 EXPECT_TRUE(websocket_->IsWaiting()); |
961 | 963 |
962 // Remove the former WebSocket object from throttling queue to unblock the | 964 // Remove the former WebSocket object from throttling queue to unblock the |
963 // latter. | 965 // latter. |
| 966 block_websocket->state_ = WebSocketJob::CLOSED; |
964 WebSocketThrottle::GetInstance()->RemoveFromQueue(block_websocket.get()); | 967 WebSocketThrottle::GetInstance()->RemoveFromQueue(block_websocket.get()); |
965 block_websocket->state_ = WebSocketJob::CLOSED; | |
966 block_websocket = NULL; | 968 block_websocket = NULL; |
967 WebSocketThrottle::GetInstance()->WakeupSocketIfNecessary(); | |
968 } | 969 } |
969 | 970 |
970 EXPECT_EQ(OK, WaitForResult()); | 971 EXPECT_EQ(OK, WaitForResult()); |
971 EXPECT_TRUE(data_->at_read_eof()); | 972 EXPECT_TRUE(data_->at_read_eof()); |
972 EXPECT_TRUE(data_->at_write_eof()); | 973 EXPECT_TRUE(data_->at_write_eof()); |
973 EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState()); | 974 EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState()); |
974 } | 975 } |
975 | 976 |
| 977 void WebSocketJobTest::TestThrottlingLimit() { |
| 978 std::vector<scoped_refptr<WebSocketJob> > jobs; |
| 979 const int kMaxWebSocketJobsThrottled = 1024; |
| 980 IPAddressNumber ip; |
| 981 ParseIPLiteralToNumber("127.0.0.1", &ip); |
| 982 for (int i = 0; i < kMaxWebSocketJobsThrottled + 1; ++i) { |
| 983 scoped_refptr<WebSocketJob> job = new WebSocketJob(NULL); |
| 984 job->addresses_ = AddressList(AddressList::CreateFromIPAddress(ip, 80)); |
| 985 if (i >= kMaxWebSocketJobsThrottled) |
| 986 EXPECT_FALSE(WebSocketThrottle::GetInstance()->PutInQueue(job)); |
| 987 else |
| 988 EXPECT_TRUE(WebSocketThrottle::GetInstance()->PutInQueue(job)); |
| 989 jobs.push_back(job); |
| 990 } |
| 991 |
| 992 // Close the jobs in reverse order. Otherwise, We need to make them prepared |
| 993 // for Wakeup call. |
| 994 for (std::vector<scoped_refptr<WebSocketJob> >::reverse_iterator iter = |
| 995 jobs.rbegin(); |
| 996 iter != jobs.rend(); |
| 997 ++iter) { |
| 998 WebSocketJob* job = (*iter).get(); |
| 999 job->state_ = WebSocketJob::CLOSED; |
| 1000 WebSocketThrottle::GetInstance()->RemoveFromQueue(job); |
| 1001 } |
| 1002 } |
| 1003 |
976 // Execute tests in both spdy-disabled mode and spdy-enabled mode. | 1004 // Execute tests in both spdy-disabled mode and spdy-enabled mode. |
977 TEST_P(WebSocketJobTest, SimpleHandshake) { | 1005 TEST_P(WebSocketJobTest, SimpleHandshake) { |
978 WebSocketJob::set_websocket_over_spdy_enabled(false); | 1006 WebSocketJob::set_websocket_over_spdy_enabled(false); |
979 TestSimpleHandshake(); | 1007 TestSimpleHandshake(); |
980 } | 1008 } |
981 | 1009 |
982 TEST_P(WebSocketJobTest, SlowHandshake) { | 1010 TEST_P(WebSocketJobTest, SlowHandshake) { |
983 WebSocketJob::set_websocket_over_spdy_enabled(false); | 1011 WebSocketJob::set_websocket_over_spdy_enabled(false); |
984 TestSlowHandshake(); | 1012 TestSlowHandshake(); |
985 } | 1013 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1052 TEST_P(WebSocketJobTest, ConnectBySpdySpdyEnabled) { | 1080 TEST_P(WebSocketJobTest, ConnectBySpdySpdyEnabled) { |
1053 WebSocketJob::set_websocket_over_spdy_enabled(true); | 1081 WebSocketJob::set_websocket_over_spdy_enabled(true); |
1054 TestConnectBySpdy(SPDY_ON, THROTTLING_OFF); | 1082 TestConnectBySpdy(SPDY_ON, THROTTLING_OFF); |
1055 } | 1083 } |
1056 | 1084 |
1057 TEST_P(WebSocketJobTest, ThrottlingWebSocket) { | 1085 TEST_P(WebSocketJobTest, ThrottlingWebSocket) { |
1058 WebSocketJob::set_websocket_over_spdy_enabled(false); | 1086 WebSocketJob::set_websocket_over_spdy_enabled(false); |
1059 TestConnectByWebSocket(THROTTLING_ON); | 1087 TestConnectByWebSocket(THROTTLING_ON); |
1060 } | 1088 } |
1061 | 1089 |
| 1090 TEST_P(WebSocketJobTest, ThrottlingMaxNumberOfThrottledJobLimit) { |
| 1091 TestThrottlingLimit(); |
| 1092 } |
| 1093 |
1062 TEST_P(WebSocketJobTest, ThrottlingWebSocketSpdyEnabled) { | 1094 TEST_P(WebSocketJobTest, ThrottlingWebSocketSpdyEnabled) { |
1063 WebSocketJob::set_websocket_over_spdy_enabled(true); | 1095 WebSocketJob::set_websocket_over_spdy_enabled(true); |
1064 TestConnectByWebSocket(THROTTLING_ON); | 1096 TestConnectByWebSocket(THROTTLING_ON); |
1065 } | 1097 } |
1066 | 1098 |
1067 TEST_P(WebSocketJobTest, ThrottlingSpdy) { | 1099 TEST_P(WebSocketJobTest, ThrottlingSpdy) { |
1068 WebSocketJob::set_websocket_over_spdy_enabled(false); | 1100 WebSocketJob::set_websocket_over_spdy_enabled(false); |
1069 TestConnectBySpdy(SPDY_OFF, THROTTLING_ON); | 1101 TestConnectBySpdy(SPDY_OFF, THROTTLING_ON); |
1070 } | 1102 } |
1071 | 1103 |
1072 TEST_P(WebSocketJobTest, ThrottlingSpdySpdyEnabled) { | 1104 TEST_P(WebSocketJobTest, ThrottlingSpdySpdyEnabled) { |
1073 WebSocketJob::set_websocket_over_spdy_enabled(true); | 1105 WebSocketJob::set_websocket_over_spdy_enabled(true); |
1074 TestConnectBySpdy(SPDY_ON, THROTTLING_ON); | 1106 TestConnectBySpdy(SPDY_ON, THROTTLING_ON); |
1075 } | 1107 } |
1076 | 1108 |
1077 // TODO(toyoshim): Add tests to verify throttling, SPDY stream limitation. | 1109 // TODO(toyoshim): Add tests to verify throttling, SPDY stream limitation. |
1078 // TODO(toyoshim,yutak): Add tests to verify closing handshake. | 1110 // TODO(toyoshim,yutak): Add tests to verify closing handshake. |
1079 } // namespace net | 1111 } // namespace net |
OLD | NEW |