OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/http/http_pipelined_host_pool.h" | 5 #include "net/http/http_pipelined_host_pool.h" |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
9 #include "net/http/http_pipelined_host.h" | 9 #include "net/http/http_pipelined_host.h" |
10 #include "net/http/http_pipelined_host_capability.h" | 10 #include "net/http/http_pipelined_host_capability.h" |
11 #include "net/http/http_server_properties_impl.h" | 11 #include "net/http/http_server_properties_impl.h" |
12 #include "net/proxy/proxy_info.h" | 12 #include "net/proxy/proxy_info.h" |
13 #include "net/ssl/ssl_config_service.h" | 13 #include "net/ssl/ssl_config_service.h" |
14 #include "testing/gmock/include/gmock/gmock.h" | 14 #include "testing/gmock/include/gmock/gmock.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
16 | 16 |
17 using testing::_; | 17 using testing::_; |
18 using testing::Ref; | 18 using testing::Ref; |
19 using testing::Return; | 19 using testing::Return; |
20 using testing::ReturnNull; | 20 using testing::ReturnNull; |
21 | 21 |
22 namespace net { | 22 namespace net { |
23 | 23 |
24 namespace { | 24 namespace { |
25 | 25 |
26 ClientSocketHandle* kDummyConnection = | 26 ClientSocketHandle* kDummyConnection = |
27 reinterpret_cast<ClientSocketHandle*>(188); | 27 reinterpret_cast<ClientSocketHandle*>(188); |
28 HttpPipelinedStream* kDummyStream = | 28 HttpPipelinedStream* kDummyStream = reinterpret_cast<HttpPipelinedStream*>(99); |
29 reinterpret_cast<HttpPipelinedStream*>(99); | |
30 | 29 |
31 class MockPoolDelegate : public HttpPipelinedHostPool::Delegate { | 30 class MockPoolDelegate : public HttpPipelinedHostPool::Delegate { |
32 public: | 31 public: |
33 MOCK_METHOD1(OnHttpPipelinedHostHasAdditionalCapacity, | 32 MOCK_METHOD1(OnHttpPipelinedHostHasAdditionalCapacity, |
34 void(HttpPipelinedHost* host)); | 33 void(HttpPipelinedHost* host)); |
35 }; | 34 }; |
36 | 35 |
37 class MockHostFactory : public HttpPipelinedHost::Factory { | 36 class MockHostFactory : public HttpPipelinedHost::Factory { |
38 public: | 37 public: |
39 MOCK_METHOD5(CreateNewHost, HttpPipelinedHost*( | 38 MOCK_METHOD5(CreateNewHost, |
40 HttpPipelinedHost::Delegate* delegate, | 39 HttpPipelinedHost*(HttpPipelinedHost::Delegate* delegate, |
41 const HttpPipelinedHost::Key& key, | 40 const HttpPipelinedHost::Key& key, |
42 HttpPipelinedConnection::Factory* factory, | 41 HttpPipelinedConnection::Factory* factory, |
43 HttpPipelinedHostCapability capability, | 42 HttpPipelinedHostCapability capability, |
44 bool force_pipelining)); | 43 bool force_pipelining)); |
45 }; | 44 }; |
46 | 45 |
47 class MockHost : public HttpPipelinedHost { | 46 class MockHost : public HttpPipelinedHost { |
48 public: | 47 public: |
49 MockHost(const Key& key) | 48 MockHost(const Key& key) : key_(key) {} |
50 : key_(key) { | |
51 } | |
52 | 49 |
53 MOCK_METHOD6(CreateStreamOnNewPipeline, HttpPipelinedStream*( | 50 MOCK_METHOD6(CreateStreamOnNewPipeline, |
54 ClientSocketHandle* connection, | 51 HttpPipelinedStream*(ClientSocketHandle* connection, |
55 const SSLConfig& used_ssl_config, | 52 const SSLConfig& used_ssl_config, |
56 const ProxyInfo& used_proxy_info, | 53 const ProxyInfo& used_proxy_info, |
57 const BoundNetLog& net_log, | 54 const BoundNetLog& net_log, |
58 bool was_npn_negotiated, | 55 bool was_npn_negotiated, |
59 NextProto protocol_negotiated)); | 56 NextProto protocol_negotiated)); |
60 MOCK_METHOD0(CreateStreamOnExistingPipeline, HttpPipelinedStream*()); | 57 MOCK_METHOD0(CreateStreamOnExistingPipeline, HttpPipelinedStream*()); |
61 MOCK_CONST_METHOD0(IsExistingPipelineAvailable, bool()); | 58 MOCK_CONST_METHOD0(IsExistingPipelineAvailable, bool()); |
62 MOCK_CONST_METHOD0(PipelineInfoToValue, base::Value*()); | 59 MOCK_CONST_METHOD0(PipelineInfoToValue, base::Value*()); |
63 | 60 |
64 virtual const Key& GetKey() const OVERRIDE { return key_; } | 61 virtual const Key& GetKey() const OVERRIDE { return key_; } |
65 | 62 |
66 private: | 63 private: |
67 Key key_; | 64 Key key_; |
68 }; | 65 }; |
69 | 66 |
70 class HttpPipelinedHostPoolTest : public testing::Test { | 67 class HttpPipelinedHostPoolTest : public testing::Test { |
71 public: | 68 public: |
72 HttpPipelinedHostPoolTest() | 69 HttpPipelinedHostPoolTest() |
73 : key_(HostPortPair("host", 123)), | 70 : key_(HostPortPair("host", 123)), |
74 factory_(new MockHostFactory), // Owned by pool_. | 71 factory_(new MockHostFactory), // Owned by pool_. |
75 host_(new MockHost(key_)), // Owned by pool_. | 72 host_(new MockHost(key_)), // Owned by pool_. |
76 http_server_properties_(new HttpServerPropertiesImpl()), | 73 http_server_properties_(new HttpServerPropertiesImpl()), |
77 pool_(new HttpPipelinedHostPool( | 74 pool_(new HttpPipelinedHostPool(&delegate_, |
78 &delegate_, factory_, | 75 factory_, |
79 http_server_properties_->GetWeakPtr(), false)), | 76 http_server_properties_->GetWeakPtr(), |
| 77 false)), |
80 was_npn_negotiated_(false), | 78 was_npn_negotiated_(false), |
81 protocol_negotiated_(kProtoUnknown) { | 79 protocol_negotiated_(kProtoUnknown) {} |
82 } | |
83 | 80 |
84 void CreateDummyStream(const HttpPipelinedHost::Key& key, | 81 void CreateDummyStream(const HttpPipelinedHost::Key& key, |
85 ClientSocketHandle* connection, | 82 ClientSocketHandle* connection, |
86 HttpPipelinedStream* stream, | 83 HttpPipelinedStream* stream, |
87 MockHost* host) { | 84 MockHost* host) { |
88 EXPECT_CALL(*host, CreateStreamOnNewPipeline(connection, | 85 EXPECT_CALL(*host, |
89 Ref(ssl_config_), | 86 CreateStreamOnNewPipeline(connection, |
90 Ref(proxy_info_), | 87 Ref(ssl_config_), |
91 Ref(net_log_), | 88 Ref(proxy_info_), |
92 was_npn_negotiated_, | 89 Ref(net_log_), |
93 protocol_negotiated_)) | 90 was_npn_negotiated_, |
| 91 protocol_negotiated_)) |
94 .Times(1) | 92 .Times(1) |
95 .WillOnce(Return(stream)); | 93 .WillOnce(Return(stream)); |
96 EXPECT_EQ(stream, | 94 EXPECT_EQ(stream, |
97 pool_->CreateStreamOnNewPipeline(key, connection, | 95 pool_->CreateStreamOnNewPipeline(key, |
98 ssl_config_, proxy_info_, | 96 connection, |
99 net_log_, was_npn_negotiated_, | 97 ssl_config_, |
| 98 proxy_info_, |
| 99 net_log_, |
| 100 was_npn_negotiated_, |
100 protocol_negotiated_)); | 101 protocol_negotiated_)); |
101 } | 102 } |
102 | 103 |
103 MockHost* CreateDummyHost(const HttpPipelinedHost::Key& key) { | 104 MockHost* CreateDummyHost(const HttpPipelinedHost::Key& key) { |
104 MockHost* mock_host = new MockHost(key); | 105 MockHost* mock_host = new MockHost(key); |
105 EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(key), _, | 106 EXPECT_CALL( |
106 PIPELINE_UNKNOWN, false)) | 107 *factory_, |
| 108 CreateNewHost(pool_.get(), Ref(key), _, PIPELINE_UNKNOWN, false)) |
107 .Times(1) | 109 .Times(1) |
108 .WillOnce(Return(mock_host)); | 110 .WillOnce(Return(mock_host)); |
109 ClientSocketHandle* dummy_connection = | 111 ClientSocketHandle* dummy_connection = |
110 reinterpret_cast<ClientSocketHandle*>(base::RandUint64()); | 112 reinterpret_cast<ClientSocketHandle*>(base::RandUint64()); |
111 HttpPipelinedStream* dummy_stream = | 113 HttpPipelinedStream* dummy_stream = |
112 reinterpret_cast<HttpPipelinedStream*>(base::RandUint64()); | 114 reinterpret_cast<HttpPipelinedStream*>(base::RandUint64()); |
113 CreateDummyStream(key, dummy_connection, dummy_stream, mock_host); | 115 CreateDummyStream(key, dummy_connection, dummy_stream, mock_host); |
114 return mock_host; | 116 return mock_host; |
115 } | 117 } |
116 | 118 |
117 HttpPipelinedHost::Key key_; | 119 HttpPipelinedHost::Key key_; |
118 MockPoolDelegate delegate_; | 120 MockPoolDelegate delegate_; |
119 MockHostFactory* factory_; | 121 MockHostFactory* factory_; |
120 MockHost* host_; | 122 MockHost* host_; |
121 scoped_ptr<HttpServerPropertiesImpl> http_server_properties_; | 123 scoped_ptr<HttpServerPropertiesImpl> http_server_properties_; |
122 scoped_ptr<HttpPipelinedHostPool> pool_; | 124 scoped_ptr<HttpPipelinedHostPool> pool_; |
123 | 125 |
124 const SSLConfig ssl_config_; | 126 const SSLConfig ssl_config_; |
125 const ProxyInfo proxy_info_; | 127 const ProxyInfo proxy_info_; |
126 const BoundNetLog net_log_; | 128 const BoundNetLog net_log_; |
127 bool was_npn_negotiated_; | 129 bool was_npn_negotiated_; |
128 NextProto protocol_negotiated_; | 130 NextProto protocol_negotiated_; |
129 }; | 131 }; |
130 | 132 |
131 TEST_F(HttpPipelinedHostPoolTest, DefaultUnknown) { | 133 TEST_F(HttpPipelinedHostPoolTest, DefaultUnknown) { |
132 EXPECT_TRUE(pool_->IsKeyEligibleForPipelining(key_)); | 134 EXPECT_TRUE(pool_->IsKeyEligibleForPipelining(key_)); |
133 EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(key_), _, | 135 EXPECT_CALL(*factory_, |
134 PIPELINE_UNKNOWN, false)) | 136 CreateNewHost(pool_.get(), Ref(key_), _, PIPELINE_UNKNOWN, false)) |
135 .Times(1) | 137 .Times(1) |
136 .WillOnce(Return(host_)); | 138 .WillOnce(Return(host_)); |
137 | 139 |
138 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); | 140 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); |
139 pool_->OnHostIdle(host_); | 141 pool_->OnHostIdle(host_); |
140 } | 142 } |
141 | 143 |
142 TEST_F(HttpPipelinedHostPoolTest, RemembersIncapable) { | 144 TEST_F(HttpPipelinedHostPoolTest, RemembersIncapable) { |
143 EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(key_), _, | 145 EXPECT_CALL(*factory_, |
144 PIPELINE_UNKNOWN, false)) | 146 CreateNewHost(pool_.get(), Ref(key_), _, PIPELINE_UNKNOWN, false)) |
145 .Times(1) | 147 .Times(1) |
146 .WillOnce(Return(host_)); | 148 .WillOnce(Return(host_)); |
147 | 149 |
148 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); | 150 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); |
149 pool_->OnHostDeterminedCapability(host_, PIPELINE_INCAPABLE); | 151 pool_->OnHostDeterminedCapability(host_, PIPELINE_INCAPABLE); |
150 pool_->OnHostIdle(host_); | 152 pool_->OnHostIdle(host_); |
151 EXPECT_FALSE(pool_->IsKeyEligibleForPipelining(key_)); | 153 EXPECT_FALSE(pool_->IsKeyEligibleForPipelining(key_)); |
152 EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(key_), _, | 154 EXPECT_CALL( |
153 PIPELINE_INCAPABLE, false)) | 155 *factory_, |
| 156 CreateNewHost(pool_.get(), Ref(key_), _, PIPELINE_INCAPABLE, false)) |
154 .Times(0); | 157 .Times(0); |
155 EXPECT_EQ(NULL, | 158 EXPECT_EQ(NULL, |
156 pool_->CreateStreamOnNewPipeline(key_, kDummyConnection, | 159 pool_->CreateStreamOnNewPipeline(key_, |
157 ssl_config_, proxy_info_, net_log_, | 160 kDummyConnection, |
| 161 ssl_config_, |
| 162 proxy_info_, |
| 163 net_log_, |
158 was_npn_negotiated_, | 164 was_npn_negotiated_, |
159 protocol_negotiated_)); | 165 protocol_negotiated_)); |
160 } | 166 } |
161 | 167 |
162 TEST_F(HttpPipelinedHostPoolTest, RemembersCapable) { | 168 TEST_F(HttpPipelinedHostPoolTest, RemembersCapable) { |
163 EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(key_), _, | 169 EXPECT_CALL(*factory_, |
164 PIPELINE_UNKNOWN, false)) | 170 CreateNewHost(pool_.get(), Ref(key_), _, PIPELINE_UNKNOWN, false)) |
165 .Times(1) | 171 .Times(1) |
166 .WillOnce(Return(host_)); | 172 .WillOnce(Return(host_)); |
167 | 173 |
168 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); | 174 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); |
169 pool_->OnHostDeterminedCapability(host_, PIPELINE_CAPABLE); | 175 pool_->OnHostDeterminedCapability(host_, PIPELINE_CAPABLE); |
170 pool_->OnHostIdle(host_); | 176 pool_->OnHostIdle(host_); |
171 EXPECT_TRUE(pool_->IsKeyEligibleForPipelining(key_)); | 177 EXPECT_TRUE(pool_->IsKeyEligibleForPipelining(key_)); |
172 | 178 |
173 host_ = new MockHost(key_); | 179 host_ = new MockHost(key_); |
174 EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(key_), _, | 180 EXPECT_CALL(*factory_, |
175 PIPELINE_CAPABLE, false)) | 181 CreateNewHost(pool_.get(), Ref(key_), _, PIPELINE_CAPABLE, false)) |
176 .Times(1) | 182 .Times(1) |
177 .WillOnce(Return(host_)); | 183 .WillOnce(Return(host_)); |
178 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); | 184 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); |
179 pool_->OnHostIdle(host_); | 185 pool_->OnHostIdle(host_); |
180 } | 186 } |
181 | 187 |
182 TEST_F(HttpPipelinedHostPoolTest, IncapableIsSticky) { | 188 TEST_F(HttpPipelinedHostPoolTest, IncapableIsSticky) { |
183 EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(key_), _, | 189 EXPECT_CALL(*factory_, |
184 PIPELINE_UNKNOWN, false)) | 190 CreateNewHost(pool_.get(), Ref(key_), _, PIPELINE_UNKNOWN, false)) |
185 .Times(1) | 191 .Times(1) |
186 .WillOnce(Return(host_)); | 192 .WillOnce(Return(host_)); |
187 | 193 |
188 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); | 194 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); |
189 pool_->OnHostDeterminedCapability(host_, PIPELINE_CAPABLE); | 195 pool_->OnHostDeterminedCapability(host_, PIPELINE_CAPABLE); |
190 pool_->OnHostDeterminedCapability(host_, PIPELINE_INCAPABLE); | 196 pool_->OnHostDeterminedCapability(host_, PIPELINE_INCAPABLE); |
191 pool_->OnHostDeterminedCapability(host_, PIPELINE_CAPABLE); | 197 pool_->OnHostDeterminedCapability(host_, PIPELINE_CAPABLE); |
192 pool_->OnHostIdle(host_); | 198 pool_->OnHostIdle(host_); |
193 EXPECT_FALSE(pool_->IsKeyEligibleForPipelining(key_)); | 199 EXPECT_FALSE(pool_->IsKeyEligibleForPipelining(key_)); |
194 } | 200 } |
195 | 201 |
196 TEST_F(HttpPipelinedHostPoolTest, RemainsUnknownWithoutFeedback) { | 202 TEST_F(HttpPipelinedHostPoolTest, RemainsUnknownWithoutFeedback) { |
197 EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(key_), _, | 203 EXPECT_CALL(*factory_, |
198 PIPELINE_UNKNOWN, false)) | 204 CreateNewHost(pool_.get(), Ref(key_), _, PIPELINE_UNKNOWN, false)) |
199 .Times(1) | 205 .Times(1) |
200 .WillOnce(Return(host_)); | 206 .WillOnce(Return(host_)); |
201 | 207 |
202 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); | 208 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); |
203 pool_->OnHostIdle(host_); | 209 pool_->OnHostIdle(host_); |
204 EXPECT_TRUE(pool_->IsKeyEligibleForPipelining(key_)); | 210 EXPECT_TRUE(pool_->IsKeyEligibleForPipelining(key_)); |
205 | 211 |
206 host_ = new MockHost(key_); | 212 host_ = new MockHost(key_); |
207 EXPECT_CALL(*factory_, CreateNewHost(pool_.get(), Ref(key_), _, | 213 EXPECT_CALL(*factory_, |
208 PIPELINE_UNKNOWN, false)) | 214 CreateNewHost(pool_.get(), Ref(key_), _, PIPELINE_UNKNOWN, false)) |
209 .Times(1) | 215 .Times(1) |
210 .WillOnce(Return(host_)); | 216 .WillOnce(Return(host_)); |
211 | 217 |
212 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); | 218 CreateDummyStream(key_, kDummyConnection, kDummyStream, host_); |
213 pool_->OnHostIdle(host_); | 219 pool_->OnHostIdle(host_); |
214 } | 220 } |
215 | 221 |
216 TEST_F(HttpPipelinedHostPoolTest, PopulatesServerProperties) { | 222 TEST_F(HttpPipelinedHostPoolTest, PopulatesServerProperties) { |
217 EXPECT_EQ(PIPELINE_UNKNOWN, | 223 EXPECT_EQ( |
218 http_server_properties_->GetPipelineCapability( | 224 PIPELINE_UNKNOWN, |
219 host_->GetKey().origin())); | 225 http_server_properties_->GetPipelineCapability(host_->GetKey().origin())); |
220 pool_->OnHostDeterminedCapability(host_, PIPELINE_CAPABLE); | 226 pool_->OnHostDeterminedCapability(host_, PIPELINE_CAPABLE); |
221 EXPECT_EQ(PIPELINE_CAPABLE, | 227 EXPECT_EQ( |
222 http_server_properties_->GetPipelineCapability( | 228 PIPELINE_CAPABLE, |
223 host_->GetKey().origin())); | 229 http_server_properties_->GetPipelineCapability(host_->GetKey().origin())); |
224 delete host_; // Must manually delete, because it's never added to |pool_|. | 230 delete host_; // Must manually delete, because it's never added to |pool_|. |
225 } | 231 } |
226 | 232 |
227 TEST_F(HttpPipelinedHostPoolTest, MultipleKeys) { | 233 TEST_F(HttpPipelinedHostPoolTest, MultipleKeys) { |
228 HttpPipelinedHost::Key key1(HostPortPair("host", 123)); | 234 HttpPipelinedHost::Key key1(HostPortPair("host", 123)); |
229 HttpPipelinedHost::Key key2(HostPortPair("host", 456)); | 235 HttpPipelinedHost::Key key2(HostPortPair("host", 456)); |
230 HttpPipelinedHost::Key key3(HostPortPair("other", 456)); | 236 HttpPipelinedHost::Key key3(HostPortPair("other", 456)); |
231 HttpPipelinedHost::Key key4(HostPortPair("other", 789)); | 237 HttpPipelinedHost::Key key4(HostPortPair("other", 789)); |
232 MockHost* host1 = CreateDummyHost(key1); | 238 MockHost* host1 = CreateDummyHost(key1); |
233 MockHost* host2 = CreateDummyHost(key2); | 239 MockHost* host2 = CreateDummyHost(key2); |
234 MockHost* host3 = CreateDummyHost(key3); | 240 MockHost* host3 = CreateDummyHost(key3); |
235 | 241 |
236 EXPECT_CALL(*host1, IsExistingPipelineAvailable()) | 242 EXPECT_CALL(*host1, IsExistingPipelineAvailable()).Times(1).WillOnce( |
237 .Times(1) | 243 Return(true)); |
238 .WillOnce(Return(true)); | |
239 EXPECT_TRUE(pool_->IsExistingPipelineAvailableForKey(key1)); | 244 EXPECT_TRUE(pool_->IsExistingPipelineAvailableForKey(key1)); |
240 | 245 |
241 EXPECT_CALL(*host2, IsExistingPipelineAvailable()) | 246 EXPECT_CALL(*host2, IsExistingPipelineAvailable()).Times(1).WillOnce( |
242 .Times(1) | 247 Return(false)); |
243 .WillOnce(Return(false)); | |
244 EXPECT_FALSE(pool_->IsExistingPipelineAvailableForKey(key2)); | 248 EXPECT_FALSE(pool_->IsExistingPipelineAvailableForKey(key2)); |
245 | 249 |
246 EXPECT_CALL(*host3, IsExistingPipelineAvailable()) | 250 EXPECT_CALL(*host3, IsExistingPipelineAvailable()).Times(1).WillOnce( |
247 .Times(1) | 251 Return(true)); |
248 .WillOnce(Return(true)); | |
249 EXPECT_TRUE(pool_->IsExistingPipelineAvailableForKey(key3)); | 252 EXPECT_TRUE(pool_->IsExistingPipelineAvailableForKey(key3)); |
250 | 253 |
251 EXPECT_FALSE(pool_->IsExistingPipelineAvailableForKey(key4)); | 254 EXPECT_FALSE(pool_->IsExistingPipelineAvailableForKey(key4)); |
252 | 255 |
253 pool_->OnHostIdle(host1); | 256 pool_->OnHostIdle(host1); |
254 pool_->OnHostIdle(host2); | 257 pool_->OnHostIdle(host2); |
255 pool_->OnHostIdle(host3); | 258 pool_->OnHostIdle(host3); |
256 | 259 |
257 delete host_; // Must manually delete, because it's never added to |pool_|. | 260 delete host_; // Must manually delete, because it's never added to |pool_|. |
258 } | 261 } |
259 | 262 |
260 } // anonymous namespace | 263 } // anonymous namespace |
261 | 264 |
262 } // namespace net | 265 } // namespace net |
OLD | NEW |