OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/socket/client_socket_pool_base.h" | 5 #include "net/socket/client_socket_pool_base.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/platform_thread.h" | 10 #include "base/platform_thread.h" |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 public: | 87 public: |
88 MockClientSocketFactory() : allocation_count_(0) {} | 88 MockClientSocketFactory() : allocation_count_(0) {} |
89 | 89 |
90 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses, | 90 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses, |
91 NetLog* /* net_log */) { | 91 NetLog* /* net_log */) { |
92 allocation_count_++; | 92 allocation_count_++; |
93 return NULL; | 93 return NULL; |
94 } | 94 } |
95 | 95 |
96 virtual SSLClientSocket* CreateSSLClientSocket( | 96 virtual SSLClientSocket* CreateSSLClientSocket( |
97 ClientSocket* transport_socket, | 97 ClientSocketHandle* transport_socket, |
98 const std::string& hostname, | 98 const std::string& hostname, |
99 const SSLConfig& ssl_config) { | 99 const SSLConfig& ssl_config) { |
100 NOTIMPLEMENTED(); | 100 NOTIMPLEMENTED(); |
101 return NULL; | 101 return NULL; |
102 } | 102 } |
103 | 103 |
104 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); } | 104 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); } |
105 void SignalJobs(); | 105 void SignalJobs(); |
106 | 106 |
107 int allocation_count() const { return allocation_count_; } | 107 int allocation_count() const { return allocation_count_; } |
108 | 108 |
109 private: | 109 private: |
110 int allocation_count_; | 110 int allocation_count_; |
111 std::vector<TestConnectJob*> waiting_jobs_; | 111 std::vector<TestConnectJob*> waiting_jobs_; |
112 }; | 112 }; |
113 | 113 |
114 class TestConnectJob : public ConnectJob { | 114 class TestConnectJob : public ConnectJob { |
115 public: | 115 public: |
116 enum JobType { | 116 enum JobType { |
117 kMockJob, | 117 kMockJob, |
118 kMockFailingJob, | 118 kMockFailingJob, |
119 kMockPendingJob, | 119 kMockPendingJob, |
120 kMockPendingFailingJob, | 120 kMockPendingFailingJob, |
121 kMockWaitingJob, | 121 kMockWaitingJob, |
122 kMockAdvancingLoadStateJob, | 122 kMockAdvancingLoadStateJob, |
123 kMockRecoverableJob, | 123 kMockRecoverableJob, |
124 kMockPendingRecoverableJob, | 124 kMockPendingRecoverableJob, |
| 125 kMockAdditionalErrorStateJob, |
| 126 kMockPendingAdditionalErrorStateJob, |
125 }; | 127 }; |
126 | 128 |
127 TestConnectJob(JobType job_type, | 129 TestConnectJob(JobType job_type, |
128 const std::string& group_name, | 130 const std::string& group_name, |
129 const TestClientSocketPoolBase::Request& request, | 131 const TestClientSocketPoolBase::Request& request, |
130 base::TimeDelta timeout_duration, | 132 base::TimeDelta timeout_duration, |
131 ConnectJob::Delegate* delegate, | 133 ConnectJob::Delegate* delegate, |
132 MockClientSocketFactory* client_socket_factory, | 134 MockClientSocketFactory* client_socket_factory, |
133 NetLog* net_log) | 135 NetLog* net_log) |
134 : ConnectJob(group_name, timeout_duration, delegate, | 136 : ConnectJob(group_name, timeout_duration, delegate, |
135 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)), | 137 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)), |
136 job_type_(job_type), | 138 job_type_(job_type), |
137 client_socket_factory_(client_socket_factory), | 139 client_socket_factory_(client_socket_factory), |
138 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 140 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
139 load_state_(LOAD_STATE_IDLE) {} | 141 load_state_(LOAD_STATE_IDLE), |
| 142 store_additional_error_state_(false) {} |
140 | 143 |
141 void Signal() { | 144 void Signal() { |
142 DoConnect(waiting_success_, true /* async */, false /* recoverable */); | 145 DoConnect(waiting_success_, true /* async */, false /* recoverable */); |
143 } | 146 } |
144 | 147 |
145 virtual LoadState GetLoadState() const { return load_state_; } | 148 virtual LoadState GetLoadState() const { return load_state_; } |
146 | 149 |
| 150 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) { |
| 151 if (store_additional_error_state_) { |
| 152 // Set all of the additional error state fields in some way. |
| 153 handle->set_is_ssl_error(true); |
| 154 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders("")); |
| 155 handle->set_tunnel_auth_response_info(headers, NULL); |
| 156 } |
| 157 } |
| 158 |
147 private: | 159 private: |
148 // ConnectJob methods: | 160 // ConnectJob methods: |
149 | 161 |
150 virtual int ConnectInternal() { | 162 virtual int ConnectInternal() { |
151 AddressList ignored; | 163 AddressList ignored; |
152 client_socket_factory_->CreateTCPClientSocket(ignored, NULL); | 164 client_socket_factory_->CreateTCPClientSocket(ignored, NULL); |
153 set_socket(new MockClientSocket()); | 165 set_socket(new MockClientSocket()); |
154 switch (job_type_) { | 166 switch (job_type_) { |
155 case kMockJob: | 167 case kMockJob: |
156 return DoConnect(true /* successful */, false /* sync */, | 168 return DoConnect(true /* successful */, false /* sync */, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 set_load_state(LOAD_STATE_CONNECTING); | 221 set_load_state(LOAD_STATE_CONNECTING); |
210 MessageLoop::current()->PostDelayedTask( | 222 MessageLoop::current()->PostDelayedTask( |
211 FROM_HERE, | 223 FROM_HERE, |
212 method_factory_.NewRunnableMethod( | 224 method_factory_.NewRunnableMethod( |
213 &TestConnectJob::DoConnect, | 225 &TestConnectJob::DoConnect, |
214 false /* error */, | 226 false /* error */, |
215 true /* async */, | 227 true /* async */, |
216 true /* recoverable */), | 228 true /* recoverable */), |
217 2); | 229 2); |
218 return ERR_IO_PENDING; | 230 return ERR_IO_PENDING; |
| 231 case kMockAdditionalErrorStateJob: |
| 232 store_additional_error_state_ = true; |
| 233 return DoConnect(false /* error */, false /* sync */, |
| 234 false /* recoverable */); |
| 235 case kMockPendingAdditionalErrorStateJob: |
| 236 set_load_state(LOAD_STATE_CONNECTING); |
| 237 store_additional_error_state_ = true; |
| 238 MessageLoop::current()->PostDelayedTask( |
| 239 FROM_HERE, |
| 240 method_factory_.NewRunnableMethod( |
| 241 &TestConnectJob::DoConnect, |
| 242 false /* error */, |
| 243 true /* async */, |
| 244 false /* recoverable */), |
| 245 2); |
| 246 return ERR_IO_PENDING; |
219 default: | 247 default: |
220 NOTREACHED(); | 248 NOTREACHED(); |
221 set_socket(NULL); | 249 set_socket(NULL); |
222 return ERR_FAILED; | 250 return ERR_FAILED; |
223 } | 251 } |
224 } | 252 } |
225 | 253 |
226 void set_load_state(LoadState load_state) { load_state_ = load_state; } | 254 void set_load_state(LoadState load_state) { load_state_ = load_state; } |
227 | 255 |
228 int DoConnect(bool succeed, bool was_async, bool recoverable) { | 256 int DoConnect(bool succeed, bool was_async, bool recoverable) { |
(...skipping 27 matching lines...) Expand all Loading... |
256 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState, | 284 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState, |
257 state)); | 285 state)); |
258 } | 286 } |
259 } | 287 } |
260 | 288 |
261 bool waiting_success_; | 289 bool waiting_success_; |
262 const JobType job_type_; | 290 const JobType job_type_; |
263 MockClientSocketFactory* const client_socket_factory_; | 291 MockClientSocketFactory* const client_socket_factory_; |
264 ScopedRunnableMethodFactory<TestConnectJob> method_factory_; | 292 ScopedRunnableMethodFactory<TestConnectJob> method_factory_; |
265 LoadState load_state_; | 293 LoadState load_state_; |
| 294 bool store_additional_error_state_; |
266 | 295 |
267 DISALLOW_COPY_AND_ASSIGN(TestConnectJob); | 296 DISALLOW_COPY_AND_ASSIGN(TestConnectJob); |
268 }; | 297 }; |
269 | 298 |
270 class TestConnectJobFactory | 299 class TestConnectJobFactory |
271 : public TestClientSocketPoolBase::ConnectJobFactory { | 300 : public TestClientSocketPoolBase::ConnectJobFactory { |
272 public: | 301 public: |
273 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory) | 302 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory) |
274 : job_type_(TestConnectJob::kMockJob), | 303 : job_type_(TestConnectJob::kMockJob), |
275 client_socket_factory_(client_socket_factory) {} | 304 client_socket_factory_(client_socket_factory) {} |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 log.entries(), 3, NetLog::TYPE_SOCKET_POOL)); | 611 log.entries(), 3, NetLog::TYPE_SOCKET_POOL)); |
583 } | 612 } |
584 | 613 |
585 TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) { | 614 TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) { |
586 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); | 615 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); |
587 | 616 |
588 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob); | 617 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob); |
589 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | 618 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); |
590 | 619 |
591 TestSocketRequest req(&request_order_, &completion_count_); | 620 TestSocketRequest req(&request_order_, &completion_count_); |
| 621 // Set the additional error state members to ensure that they get cleared. |
| 622 req.handle()->set_is_ssl_error(true); |
| 623 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders("")); |
| 624 req.handle()->set_tunnel_auth_response_info(headers, NULL); |
592 EXPECT_EQ(ERR_CONNECTION_FAILED, req.handle()->Init("a", params_, | 625 EXPECT_EQ(ERR_CONNECTION_FAILED, req.handle()->Init("a", params_, |
593 kDefaultPriority, &req, | 626 kDefaultPriority, &req, |
594 pool_, log.bound())); | 627 pool_, log.bound())); |
595 EXPECT_FALSE(req.handle()->socket()); | 628 EXPECT_FALSE(req.handle()->socket()); |
| 629 EXPECT_FALSE(req.handle()->is_ssl_error()); |
| 630 EXPECT_TRUE(req.handle()->tunnel_auth_response_info().headers.get() == NULL); |
596 | 631 |
597 EXPECT_EQ(3u, log.entries().size()); | 632 EXPECT_EQ(3u, log.entries().size()); |
598 EXPECT_TRUE(LogContainsBeginEvent( | 633 EXPECT_TRUE(LogContainsBeginEvent( |
599 log.entries(), 0, NetLog::TYPE_SOCKET_POOL)); | 634 log.entries(), 0, NetLog::TYPE_SOCKET_POOL)); |
600 EXPECT_TRUE(LogContainsEvent( | 635 EXPECT_TRUE(LogContainsEvent( |
601 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB, | 636 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB, |
602 NetLog::PHASE_NONE)); | 637 NetLog::PHASE_NONE)); |
603 EXPECT_TRUE(LogContainsEndEvent( | 638 EXPECT_TRUE(LogContainsEndEvent( |
604 log.entries(), 2, NetLog::TYPE_SOCKET_POOL)); | 639 log.entries(), 2, NetLog::TYPE_SOCKET_POOL)); |
605 } | 640 } |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1338 log.entries(), 3, NetLog::TYPE_SOCKET_POOL)); | 1373 log.entries(), 3, NetLog::TYPE_SOCKET_POOL)); |
1339 } | 1374 } |
1340 | 1375 |
1341 TEST_F(ClientSocketPoolBaseTest, | 1376 TEST_F(ClientSocketPoolBaseTest, |
1342 InitConnectionAsynchronousFailure) { | 1377 InitConnectionAsynchronousFailure) { |
1343 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); | 1378 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); |
1344 | 1379 |
1345 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob); | 1380 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob); |
1346 TestSocketRequest req(&request_order_, &completion_count_); | 1381 TestSocketRequest req(&request_order_, &completion_count_); |
1347 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | 1382 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); |
| 1383 // Set the additional error state members to ensure that they get cleared. |
| 1384 req.handle()->set_is_ssl_error(true); |
| 1385 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders("")); |
| 1386 req.handle()->set_tunnel_auth_response_info(headers, NULL); |
1348 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority, | 1387 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority, |
1349 &req, pool_, log.bound())); | 1388 &req, pool_, log.bound())); |
1350 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle())); | 1389 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle())); |
1351 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult()); | 1390 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult()); |
| 1391 EXPECT_FALSE(req.handle()->is_ssl_error()); |
| 1392 EXPECT_TRUE(req.handle()->tunnel_auth_response_info().headers.get() == NULL); |
1352 | 1393 |
1353 EXPECT_EQ(3u, log.entries().size()); | 1394 EXPECT_EQ(3u, log.entries().size()); |
1354 EXPECT_TRUE(LogContainsBeginEvent( | 1395 EXPECT_TRUE(LogContainsBeginEvent( |
1355 log.entries(), 0, NetLog::TYPE_SOCKET_POOL)); | 1396 log.entries(), 0, NetLog::TYPE_SOCKET_POOL)); |
1356 EXPECT_TRUE(LogContainsEvent( | 1397 EXPECT_TRUE(LogContainsEvent( |
1357 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB, | 1398 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB, |
1358 NetLog::PHASE_NONE)); | 1399 NetLog::PHASE_NONE)); |
1359 EXPECT_TRUE(LogContainsEndEvent( | 1400 EXPECT_TRUE(LogContainsEndEvent( |
1360 log.entries(), 2, NetLog::TYPE_SOCKET_POOL)); | 1401 log.entries(), 2, NetLog::TYPE_SOCKET_POOL)); |
1361 } | 1402 } |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 TestSocketRequest req(&request_order_, &completion_count_); | 1575 TestSocketRequest req(&request_order_, &completion_count_); |
1535 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority, | 1576 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority, |
1536 &req, pool_, BoundNetLog())); | 1577 &req, pool_, BoundNetLog())); |
1537 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle())); | 1578 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle())); |
1538 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, req.WaitForResult()); | 1579 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, req.WaitForResult()); |
1539 EXPECT_TRUE(req.handle()->is_initialized()); | 1580 EXPECT_TRUE(req.handle()->is_initialized()); |
1540 EXPECT_TRUE(req.handle()->socket()); | 1581 EXPECT_TRUE(req.handle()->socket()); |
1541 req.handle()->Reset(); | 1582 req.handle()->Reset(); |
1542 } | 1583 } |
1543 | 1584 |
| 1585 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) { |
| 1586 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); |
| 1587 connect_job_factory_->set_job_type( |
| 1588 TestConnectJob::kMockAdditionalErrorStateJob); |
| 1589 |
| 1590 TestSocketRequest req(&request_order_, &completion_count_); |
| 1591 EXPECT_EQ(ERR_CONNECTION_FAILED, req.handle()->Init("a", params_, |
| 1592 kDefaultPriority, &req, |
| 1593 pool_, BoundNetLog())); |
| 1594 EXPECT_FALSE(req.handle()->is_initialized()); |
| 1595 EXPECT_FALSE(req.handle()->socket()); |
| 1596 EXPECT_TRUE(req.handle()->is_ssl_error()); |
| 1597 EXPECT_FALSE(req.handle()->tunnel_auth_response_info().headers.get() == NULL); |
| 1598 req.handle()->Reset(); |
| 1599 } |
| 1600 |
| 1601 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) { |
| 1602 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); |
| 1603 |
| 1604 connect_job_factory_->set_job_type( |
| 1605 TestConnectJob::kMockPendingAdditionalErrorStateJob); |
| 1606 TestSocketRequest req(&request_order_, &completion_count_); |
| 1607 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority, |
| 1608 &req, pool_, BoundNetLog())); |
| 1609 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle())); |
| 1610 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult()); |
| 1611 EXPECT_FALSE(req.handle()->is_initialized()); |
| 1612 EXPECT_FALSE(req.handle()->socket()); |
| 1613 EXPECT_TRUE(req.handle()->is_ssl_error()); |
| 1614 EXPECT_FALSE(req.handle()->tunnel_auth_response_info().headers.get() == NULL); |
| 1615 req.handle()->Reset(); |
| 1616 } |
| 1617 |
1544 TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) { | 1618 TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) { |
1545 CreatePoolWithIdleTimeouts( | 1619 CreatePoolWithIdleTimeouts( |
1546 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup, | 1620 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup, |
1547 base::TimeDelta(), // Time out unused sockets immediately. | 1621 base::TimeDelta(), // Time out unused sockets immediately. |
1548 base::TimeDelta::FromDays(1)); // Don't time out used sockets. | 1622 base::TimeDelta::FromDays(1)); // Don't time out used sockets. |
1549 | 1623 |
1550 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); | 1624 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); |
1551 | 1625 |
1552 // Startup two mock pending connect jobs, which will sit in the MessageLoop. | 1626 // Startup two mock pending connect jobs, which will sit in the MessageLoop. |
1553 | 1627 |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1721 EXPECT_EQ(2, GetOrderOfRequest(2)); | 1795 EXPECT_EQ(2, GetOrderOfRequest(2)); |
1722 EXPECT_EQ(3, GetOrderOfRequest(3)); | 1796 EXPECT_EQ(3, GetOrderOfRequest(3)); |
1723 EXPECT_EQ(4, GetOrderOfRequest(4)); | 1797 EXPECT_EQ(4, GetOrderOfRequest(4)); |
1724 | 1798 |
1725 // Make sure we test order of all requests made. | 1799 // Make sure we test order of all requests made. |
1726 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5)); | 1800 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5)); |
1727 } | 1801 } |
1728 | 1802 |
1729 class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > { | 1803 class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > { |
1730 public: | 1804 public: |
1731 explicit TestReleasingSocketRequest(TestClientSocketPool* pool) | 1805 TestReleasingSocketRequest(TestClientSocketPool* pool, int expected_result, |
1732 : pool_(pool) {} | 1806 bool reset_releasing_handle) |
| 1807 : pool_(pool), |
| 1808 expected_result_(expected_result), |
| 1809 reset_releasing_handle_(reset_releasing_handle) {} |
1733 | 1810 |
1734 ClientSocketHandle* handle() { return &handle_; } | 1811 ClientSocketHandle* handle() { return &handle_; } |
1735 | 1812 |
1736 int WaitForResult() { | 1813 int WaitForResult() { |
1737 return callback_.WaitForResult(); | 1814 return callback_.WaitForResult(); |
1738 } | 1815 } |
1739 | 1816 |
1740 virtual void RunWithParams(const Tuple1<int>& params) { | 1817 virtual void RunWithParams(const Tuple1<int>& params) { |
1741 callback_.RunWithParams(params); | 1818 callback_.RunWithParams(params); |
1742 handle_.Reset(); | 1819 if (reset_releasing_handle_) |
| 1820 handle_.Reset(); |
1743 scoped_refptr<TestSocketParams> con_params = new TestSocketParams(); | 1821 scoped_refptr<TestSocketParams> con_params = new TestSocketParams(); |
1744 EXPECT_EQ(ERR_IO_PENDING, handle2_.Init("a", con_params, kDefaultPriority, | 1822 EXPECT_EQ(expected_result_, handle2_.Init("a", con_params, kDefaultPriority, |
1745 &callback2_, pool_, BoundNetLog())); | 1823 &callback2_, pool_, |
| 1824 BoundNetLog())); |
1746 } | 1825 } |
1747 | 1826 |
1748 private: | 1827 private: |
1749 scoped_refptr<TestClientSocketPool> pool_; | 1828 scoped_refptr<TestClientSocketPool> pool_; |
| 1829 int expected_result_; |
| 1830 bool reset_releasing_handle_; |
1750 ClientSocketHandle handle_; | 1831 ClientSocketHandle handle_; |
1751 ClientSocketHandle handle2_; | 1832 ClientSocketHandle handle2_; |
1752 TestCompletionCallback callback_; | 1833 TestCompletionCallback callback_; |
1753 TestCompletionCallback callback2_; | 1834 TestCompletionCallback callback2_; |
1754 }; | 1835 }; |
1755 | 1836 |
| 1837 |
| 1838 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) { |
| 1839 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); |
| 1840 |
| 1841 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority)); |
| 1842 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority)); |
| 1843 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority)); |
| 1844 |
| 1845 EXPECT_EQ(static_cast<int>(requests_.size()), |
| 1846 client_socket_factory_.allocation_count()); |
| 1847 |
| 1848 connect_job_factory_->set_job_type( |
| 1849 TestConnectJob::kMockPendingAdditionalErrorStateJob); |
| 1850 TestReleasingSocketRequest req(pool_.get(), OK, false); |
| 1851 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority, |
| 1852 &req, pool_, BoundNetLog())); |
| 1853 // The next job should complete synchronously |
| 1854 connect_job_factory_->set_job_type(TestConnectJob::kMockJob); |
| 1855 |
| 1856 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult()); |
| 1857 EXPECT_FALSE(req.handle()->is_initialized()); |
| 1858 EXPECT_FALSE(req.handle()->socket()); |
| 1859 EXPECT_TRUE(req.handle()->is_ssl_error()); |
| 1860 EXPECT_FALSE(req.handle()->tunnel_auth_response_info().headers.get() == NULL); |
| 1861 } |
| 1862 |
1756 // http://crbug.com/44724 regression test. | 1863 // http://crbug.com/44724 regression test. |
1757 // We start releasing the pool when we flush on network change. When that | 1864 // We start releasing the pool when we flush on network change. When that |
1758 // happens, the only active references are in the ClientSocketHandles. When a | 1865 // happens, the only active references are in the ClientSocketHandles. When a |
1759 // ConnectJob completes and calls back into the last ClientSocketHandle, that | 1866 // ConnectJob completes and calls back into the last ClientSocketHandle, that |
1760 // callback can release the last reference and delete the pool. After the | 1867 // callback can release the last reference and delete the pool. After the |
1761 // callback finishes, we go back to the stack frame within the now-deleted pool. | 1868 // callback finishes, we go back to the stack frame within the now-deleted pool. |
1762 // Executing any code that refers to members of the now-deleted pool can cause | 1869 // Executing any code that refers to members of the now-deleted pool can cause |
1763 // crashes. | 1870 // crashes. |
1764 TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) { | 1871 TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) { |
1765 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); | 1872 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1979 // Finally, signal the waiting Connect. | 2086 // Finally, signal the waiting Connect. |
1980 client_socket_factory_.SignalJobs(); | 2087 client_socket_factory_.SignalJobs(); |
1981 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a")); | 2088 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a")); |
1982 | 2089 |
1983 MessageLoop::current()->RunAllPending(); | 2090 MessageLoop::current()->RunAllPending(); |
1984 } | 2091 } |
1985 | 2092 |
1986 } // namespace | 2093 } // namespace |
1987 | 2094 |
1988 } // namespace net | 2095 } // namespace net |
OLD | NEW |