| 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 |