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_stream_factory_impl.h" | 5 #include "net/http/http_stream_factory_impl.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
14 #include "net/base/port_util.h" | 14 #include "net/base/port_util.h" |
15 #include "net/base/test_completion_callback.h" | 15 #include "net/base/test_completion_callback.h" |
16 #include "net/cert/mock_cert_verifier.h" | 16 #include "net/cert/mock_cert_verifier.h" |
17 #include "net/dns/mock_host_resolver.h" | 17 #include "net/dns/mock_host_resolver.h" |
| 18 #include "net/http/bidirectional_stream_job.h" |
18 #include "net/http/http_auth_handler_factory.h" | 19 #include "net/http/http_auth_handler_factory.h" |
19 #include "net/http/http_network_session.h" | 20 #include "net/http/http_network_session.h" |
20 #include "net/http/http_network_session_peer.h" | 21 #include "net/http/http_network_session_peer.h" |
21 #include "net/http/http_network_transaction.h" | 22 #include "net/http/http_network_transaction.h" |
22 #include "net/http/http_request_info.h" | 23 #include "net/http/http_request_info.h" |
23 #include "net/http/http_server_properties.h" | 24 #include "net/http/http_server_properties.h" |
24 #include "net/http/http_server_properties_impl.h" | 25 #include "net/http/http_server_properties_impl.h" |
25 #include "net/http/http_stream.h" | 26 #include "net/http/http_stream.h" |
26 #include "net/http/transport_security_state.h" | 27 #include "net/http/transport_security_state.h" |
27 #include "net/log/net_log.h" | 28 #include "net/log/net_log.h" |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 return scoped_ptr<WebSocketStream>(); | 106 return scoped_ptr<WebSocketStream>(); |
106 } | 107 } |
107 | 108 |
108 private: | 109 private: |
109 const StreamType type_; | 110 const StreamType type_; |
110 }; | 111 }; |
111 | 112 |
112 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete. | 113 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete. |
113 class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl { | 114 class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl { |
114 public: | 115 public: |
115 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session, | 116 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session) |
116 bool for_websockets) | 117 : HttpStreamFactoryImpl(session, false), |
117 : HttpStreamFactoryImpl(session, for_websockets), | |
118 preconnect_done_(false), | 118 preconnect_done_(false), |
119 waiting_for_preconnect_(false) {} | 119 waiting_for_preconnect_(false) {} |
120 | 120 |
121 void WaitForPreconnects() { | 121 void WaitForPreconnects() { |
122 while (!preconnect_done_) { | 122 while (!preconnect_done_) { |
123 waiting_for_preconnect_ = true; | 123 waiting_for_preconnect_ = true; |
124 base::MessageLoop::current()->Run(); | 124 base::MessageLoop::current()->Run(); |
125 waiting_for_preconnect_ = false; | 125 waiting_for_preconnect_ = false; |
126 } | 126 } |
127 } | 127 } |
128 | 128 |
129 private: | 129 private: |
130 // HttpStreamFactoryImpl methods. | 130 // HttpStreamFactoryImpl methods. |
131 void OnPreconnectsCompleteInternal() override { | 131 void OnPreconnectsCompleteInternal() override { |
132 preconnect_done_ = true; | 132 preconnect_done_ = true; |
133 if (waiting_for_preconnect_) | 133 if (waiting_for_preconnect_) |
134 base::MessageLoop::current()->QuitWhenIdle(); | 134 base::MessageLoop::current()->QuitWhenIdle(); |
135 } | 135 } |
136 | 136 |
137 bool preconnect_done_; | 137 bool preconnect_done_; |
138 bool waiting_for_preconnect_; | 138 bool waiting_for_preconnect_; |
139 }; | 139 }; |
140 | 140 |
141 class StreamRequestWaiter : public HttpStreamRequest::Delegate { | 141 class StreamRequestWaiter : public HttpStreamRequest::Delegate { |
142 public: | 142 public: |
143 StreamRequestWaiter() | 143 StreamRequestWaiter() |
144 : waiting_for_stream_(false), | 144 : waiting_for_stream_(false), stream_done_(false), error_status_(OK) {} |
145 stream_done_(false) {} | |
146 | 145 |
147 // HttpStreamRequest::Delegate | 146 // HttpStreamRequest::Delegate |
148 | 147 |
149 void OnStreamReady(const SSLConfig& used_ssl_config, | 148 void OnStreamReady(const SSLConfig& used_ssl_config, |
150 const ProxyInfo& used_proxy_info, | 149 const ProxyInfo& used_proxy_info, |
151 HttpStream* stream) override { | 150 HttpStream* stream) override { |
152 stream_done_ = true; | 151 stream_done_ = true; |
153 if (waiting_for_stream_) | 152 if (waiting_for_stream_) |
154 base::MessageLoop::current()->QuitWhenIdle(); | 153 base::MessageLoop::current()->QuitWhenIdle(); |
155 stream_.reset(stream); | 154 stream_.reset(stream); |
156 used_ssl_config_ = used_ssl_config; | 155 used_ssl_config_ = used_ssl_config; |
157 used_proxy_info_ = used_proxy_info; | 156 used_proxy_info_ = used_proxy_info; |
158 } | 157 } |
159 | 158 |
160 void OnWebSocketHandshakeStreamReady( | 159 void OnWebSocketHandshakeStreamReady( |
161 const SSLConfig& used_ssl_config, | 160 const SSLConfig& used_ssl_config, |
162 const ProxyInfo& used_proxy_info, | 161 const ProxyInfo& used_proxy_info, |
163 WebSocketHandshakeStreamBase* stream) override { | 162 WebSocketHandshakeStreamBase* stream) override { |
164 stream_done_ = true; | 163 stream_done_ = true; |
165 if (waiting_for_stream_) | 164 if (waiting_for_stream_) |
166 base::MessageLoop::current()->QuitWhenIdle(); | 165 base::MessageLoop::current()->QuitWhenIdle(); |
167 websocket_stream_.reset(stream); | 166 websocket_stream_.reset(stream); |
168 used_ssl_config_ = used_ssl_config; | 167 used_ssl_config_ = used_ssl_config; |
169 used_proxy_info_ = used_proxy_info; | 168 used_proxy_info_ = used_proxy_info; |
170 } | 169 } |
171 | 170 |
| 171 void OnBidirectionalStreamJobReady(const SSLConfig& used_ssl_config, |
| 172 const ProxyInfo& used_proxy_info, |
| 173 BidirectionalStreamJob* stream) override { |
| 174 stream_done_ = true; |
| 175 if (waiting_for_stream_) |
| 176 base::MessageLoop::current()->QuitWhenIdle(); |
| 177 bidirectional_stream_job_.reset(stream); |
| 178 used_ssl_config_ = used_ssl_config; |
| 179 used_proxy_info_ = used_proxy_info; |
| 180 } |
| 181 |
172 void OnStreamFailed(int status, | 182 void OnStreamFailed(int status, |
173 const SSLConfig& used_ssl_config, | 183 const SSLConfig& used_ssl_config, |
174 SSLFailureState ssl_failure_state) override {} | 184 SSLFailureState ssl_failure_state) override { |
| 185 stream_done_ = true; |
| 186 if (waiting_for_stream_) |
| 187 base::MessageLoop::current()->QuitWhenIdle(); |
| 188 used_ssl_config_ = used_ssl_config; |
| 189 error_status_ = status; |
| 190 } |
175 | 191 |
176 void OnCertificateError(int status, | 192 void OnCertificateError(int status, |
177 const SSLConfig& used_ssl_config, | 193 const SSLConfig& used_ssl_config, |
178 const SSLInfo& ssl_info) override {} | 194 const SSLInfo& ssl_info) override {} |
179 | 195 |
180 void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response, | 196 void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response, |
181 const SSLConfig& used_ssl_config, | 197 const SSLConfig& used_ssl_config, |
182 const ProxyInfo& used_proxy_info, | 198 const ProxyInfo& used_proxy_info, |
183 HttpAuthController* auth_controller) override {} | 199 HttpAuthController* auth_controller) override {} |
184 | 200 |
(...skipping 24 matching lines...) Expand all Loading... |
209 } | 225 } |
210 | 226 |
211 HttpStream* stream() { | 227 HttpStream* stream() { |
212 return stream_.get(); | 228 return stream_.get(); |
213 } | 229 } |
214 | 230 |
215 MockWebSocketHandshakeStream* websocket_stream() { | 231 MockWebSocketHandshakeStream* websocket_stream() { |
216 return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get()); | 232 return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get()); |
217 } | 233 } |
218 | 234 |
| 235 BidirectionalStreamJob* bidirectional_stream_job() { |
| 236 return bidirectional_stream_job_.get(); |
| 237 } |
| 238 |
219 bool stream_done() const { return stream_done_; } | 239 bool stream_done() const { return stream_done_; } |
| 240 int error_status() const { return error_status_; } |
220 | 241 |
221 private: | 242 private: |
222 bool waiting_for_stream_; | 243 bool waiting_for_stream_; |
223 bool stream_done_; | 244 bool stream_done_; |
224 scoped_ptr<HttpStream> stream_; | 245 scoped_ptr<HttpStream> stream_; |
225 scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_; | 246 scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_; |
| 247 scoped_ptr<BidirectionalStreamJob> bidirectional_stream_job_; |
226 SSLConfig used_ssl_config_; | 248 SSLConfig used_ssl_config_; |
227 ProxyInfo used_proxy_info_; | 249 ProxyInfo used_proxy_info_; |
| 250 int error_status_; |
228 | 251 |
229 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter); | 252 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter); |
230 }; | 253 }; |
231 | 254 |
232 class WebSocketSpdyHandshakeStream : public MockWebSocketHandshakeStream { | 255 class WebSocketSpdyHandshakeStream : public MockWebSocketHandshakeStream { |
233 public: | 256 public: |
234 explicit WebSocketSpdyHandshakeStream( | 257 explicit WebSocketSpdyHandshakeStream( |
235 const base::WeakPtr<SpdySession>& spdy_session) | 258 const base::WeakPtr<SpdySession>& spdy_session) |
236 : MockWebSocketHandshakeStream(kStreamTypeSpdy), | 259 : MockWebSocketHandshakeStream(kStreamTypeSpdy), |
237 spdy_session_(spdy_session) {} | 260 spdy_session_(spdy_session) {} |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 { 2, false }, | 312 { 2, false }, |
290 { 1, true}, | 313 { 1, true}, |
291 { 2, true}, | 314 { 2, true}, |
292 }; | 315 }; |
293 | 316 |
294 void PreconnectHelperForURL(int num_streams, | 317 void PreconnectHelperForURL(int num_streams, |
295 const GURL& url, | 318 const GURL& url, |
296 HttpNetworkSession* session) { | 319 HttpNetworkSession* session) { |
297 HttpNetworkSessionPeer peer(session); | 320 HttpNetworkSessionPeer peer(session); |
298 MockHttpStreamFactoryImplForPreconnect* mock_factory = | 321 MockHttpStreamFactoryImplForPreconnect* mock_factory = |
299 new MockHttpStreamFactoryImplForPreconnect(session, false); | 322 new MockHttpStreamFactoryImplForPreconnect(session); |
300 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory)); | 323 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory)); |
301 SSLConfig ssl_config; | 324 SSLConfig ssl_config; |
302 session->ssl_config_service()->GetSSLConfig(&ssl_config); | 325 session->ssl_config_service()->GetSSLConfig(&ssl_config); |
303 | 326 |
304 HttpRequestInfo request; | 327 HttpRequestInfo request; |
305 request.method = "GET"; | 328 request.method = "GET"; |
306 request.url = url; | 329 request.url = url; |
307 request.load_flags = 0; | 330 request.load_flags = 0; |
308 | 331 |
309 session->http_stream_factory()->PreconnectStreams(num_streams, request, | 332 session->http_stream_factory()->PreconnectStreams(num_streams, request, |
(...skipping 1030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1340 EXPECT_EQ(1, GetSocketPoolGroupCount( | 1363 EXPECT_EQ(1, GetSocketPoolGroupCount( |
1341 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); | 1364 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); |
1342 EXPECT_EQ(0, GetSocketPoolGroupCount( | 1365 EXPECT_EQ(0, GetSocketPoolGroupCount( |
1343 session->GetTransportSocketPool( | 1366 session->GetTransportSocketPool( |
1344 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); | 1367 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); |
1345 EXPECT_EQ(0, GetSocketPoolGroupCount( | 1368 EXPECT_EQ(0, GetSocketPoolGroupCount( |
1346 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); | 1369 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); |
1347 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); | 1370 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); |
1348 } | 1371 } |
1349 | 1372 |
| 1373 TEST_P(HttpStreamFactoryTest, RequestBidirectionalStreamJob) { |
| 1374 SpdySessionDependencies session_deps(GetParam(), |
| 1375 ProxyService::CreateDirect()); |
| 1376 |
| 1377 MockRead mock_read(ASYNC, OK); |
| 1378 SequencedSocketData socket_data(&mock_read, 1, nullptr, 0); |
| 1379 socket_data.set_connect_data(MockConnect(ASYNC, OK)); |
| 1380 session_deps.socket_factory->AddSocketDataProvider(&socket_data); |
| 1381 |
| 1382 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); |
| 1383 ssl_socket_data.SetNextProto(GetParam()); |
| 1384 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); |
| 1385 |
| 1386 HostPortPair host_port_pair("www.google.com", 443); |
| 1387 scoped_ptr<HttpNetworkSession> session( |
| 1388 SpdySessionDependencies::SpdyCreateSession(&session_deps)); |
| 1389 |
| 1390 // Now request a stream. |
| 1391 HttpRequestInfo request_info; |
| 1392 request_info.method = "GET"; |
| 1393 request_info.url = GURL("https://www.google.com"); |
| 1394 request_info.load_flags = 0; |
| 1395 |
| 1396 SSLConfig ssl_config; |
| 1397 StreamRequestWaiter waiter; |
| 1398 scoped_ptr<HttpStreamRequest> request( |
| 1399 session->http_stream_factory()->RequestBidirectionalStreamJob( |
| 1400 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, |
| 1401 BoundNetLog())); |
| 1402 waiter.WaitForStream(); |
| 1403 EXPECT_TRUE(waiter.stream_done()); |
| 1404 EXPECT_FALSE(waiter.websocket_stream()); |
| 1405 ASSERT_FALSE(waiter.stream()); |
| 1406 ASSERT_TRUE(waiter.bidirectional_stream_job()); |
| 1407 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( |
| 1408 HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| 1409 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( |
| 1410 HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| 1411 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( |
| 1412 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); |
| 1413 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( |
| 1414 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); |
| 1415 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); |
| 1416 ASSERT_EQ(0u, |
| 1417 static_cast<HttpStreamFactoryImpl*>(session->http_stream_factory()) |
| 1418 ->num_orphaned_jobs()); |
| 1419 } |
| 1420 |
| 1421 TEST_P(HttpStreamFactoryTest, RequestBidirectionalStreamJobFailure) { |
| 1422 SpdySessionDependencies session_deps(GetParam(), |
| 1423 ProxyService::CreateDirect()); |
| 1424 |
| 1425 MockRead mock_read(ASYNC, OK); |
| 1426 SequencedSocketData socket_data(&mock_read, 1, nullptr, 0); |
| 1427 socket_data.set_connect_data(MockConnect(ASYNC, OK)); |
| 1428 session_deps.socket_factory->AddSocketDataProvider(&socket_data); |
| 1429 |
| 1430 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); |
| 1431 |
| 1432 // If HTTP/1 is used, BidirectionalStreamJob should not be obtained. |
| 1433 ssl_socket_data.SetNextProto(kProtoHTTP11); |
| 1434 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); |
| 1435 |
| 1436 HostPortPair host_port_pair("www.google.com", 443); |
| 1437 scoped_ptr<HttpNetworkSession> session( |
| 1438 SpdySessionDependencies::SpdyCreateSession(&session_deps)); |
| 1439 |
| 1440 // Now request a stream. |
| 1441 HttpRequestInfo request_info; |
| 1442 request_info.method = "GET"; |
| 1443 request_info.url = GURL("https://www.google.com"); |
| 1444 request_info.load_flags = 0; |
| 1445 |
| 1446 SSLConfig ssl_config; |
| 1447 StreamRequestWaiter waiter; |
| 1448 scoped_ptr<HttpStreamRequest> request( |
| 1449 session->http_stream_factory()->RequestBidirectionalStreamJob( |
| 1450 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, |
| 1451 BoundNetLog())); |
| 1452 waiter.WaitForStream(); |
| 1453 EXPECT_TRUE(waiter.stream_done()); |
| 1454 ASSERT_EQ(ERR_FAILED, waiter.error_status()); |
| 1455 EXPECT_FALSE(waiter.websocket_stream()); |
| 1456 ASSERT_FALSE(waiter.stream()); |
| 1457 ASSERT_FALSE(waiter.bidirectional_stream_job()); |
| 1458 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( |
| 1459 HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| 1460 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( |
| 1461 HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| 1462 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( |
| 1463 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); |
| 1464 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( |
| 1465 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); |
| 1466 ASSERT_EQ(0u, |
| 1467 static_cast<HttpStreamFactoryImpl*>(session->http_stream_factory()) |
| 1468 ->num_orphaned_jobs()); |
| 1469 } |
| 1470 |
1350 // TODO(ricea): This test can be removed once the new WebSocket stack supports | 1471 // TODO(ricea): This test can be removed once the new WebSocket stack supports |
1351 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to | 1472 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to |
1352 // use plain SSL. | 1473 // use plain SSL. |
1353 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) { | 1474 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) { |
1354 SpdySessionDependencies session_deps(GetParam(), | 1475 SpdySessionDependencies session_deps(GetParam(), |
1355 ProxyService::CreateDirect()); | 1476 ProxyService::CreateDirect()); |
1356 | 1477 |
1357 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); | 1478 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); |
1358 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0); | 1479 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0); |
1359 socket_data.set_connect_data(MockConnect(ASYNC, OK)); | 1480 socket_data.set_connect_data(MockConnect(ASYNC, OK)); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1544 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); | 1665 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); |
1545 | 1666 |
1546 // Make sure there is no orphaned job. it is already canceled. | 1667 // Make sure there is no orphaned job. it is already canceled. |
1547 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>( | 1668 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>( |
1548 session->http_stream_factory_for_websocket())->num_orphaned_jobs()); | 1669 session->http_stream_factory_for_websocket())->num_orphaned_jobs()); |
1549 } | 1670 } |
1550 | 1671 |
1551 } // namespace | 1672 } // namespace |
1552 | 1673 |
1553 } // namespace net | 1674 } // namespace net |
OLD | NEW |