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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 return scoped_ptr<WebSocketStream>(); | 104 return scoped_ptr<WebSocketStream>(); |
104 } | 105 } |
105 | 106 |
106 private: | 107 private: |
107 const StreamType type_; | 108 const StreamType type_; |
108 }; | 109 }; |
109 | 110 |
110 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete. | 111 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete. |
111 class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl { | 112 class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl { |
112 public: | 113 public: |
113 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session, | 114 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session) |
114 bool for_websockets) | 115 : HttpStreamFactoryImpl(session, false), |
115 : HttpStreamFactoryImpl(session, for_websockets), | |
116 preconnect_done_(false), | 116 preconnect_done_(false), |
117 waiting_for_preconnect_(false) {} | 117 waiting_for_preconnect_(false) {} |
118 | 118 |
119 | |
120 void WaitForPreconnects() { | 119 void WaitForPreconnects() { |
121 while (!preconnect_done_) { | 120 while (!preconnect_done_) { |
122 waiting_for_preconnect_ = true; | 121 waiting_for_preconnect_ = true; |
123 base::MessageLoop::current()->Run(); | 122 base::MessageLoop::current()->Run(); |
124 waiting_for_preconnect_ = false; | 123 waiting_for_preconnect_ = false; |
125 } | 124 } |
126 } | 125 } |
127 | 126 |
128 private: | 127 private: |
129 // HttpStreamFactoryImpl methods. | 128 // HttpStreamFactoryImpl methods. |
130 void OnPreconnectsCompleteInternal() override { | 129 void OnPreconnectsCompleteInternal() override { |
131 preconnect_done_ = true; | 130 preconnect_done_ = true; |
132 if (waiting_for_preconnect_) | 131 if (waiting_for_preconnect_) |
133 base::MessageLoop::current()->QuitWhenIdle(); | 132 base::MessageLoop::current()->QuitWhenIdle(); |
134 } | 133 } |
135 | 134 |
136 bool preconnect_done_; | 135 bool preconnect_done_; |
137 bool waiting_for_preconnect_; | 136 bool waiting_for_preconnect_; |
138 }; | 137 }; |
139 | 138 |
140 class StreamRequestWaiter : public HttpStreamRequest::Delegate { | 139 class StreamRequestWaiter : public HttpStreamRequest::Delegate { |
141 public: | 140 public: |
142 StreamRequestWaiter() | 141 StreamRequestWaiter() |
143 : waiting_for_stream_(false), | 142 : waiting_for_stream_(false), stream_done_(false), error_status_(OK) {} |
144 stream_done_(false) {} | |
145 | 143 |
146 // HttpStreamRequest::Delegate | 144 // HttpStreamRequest::Delegate |
147 | 145 |
148 void OnStreamReady(const SSLConfig& used_ssl_config, | 146 void OnStreamReady(const SSLConfig& used_ssl_config, |
149 const ProxyInfo& used_proxy_info, | 147 const ProxyInfo& used_proxy_info, |
150 HttpStream* stream) override { | 148 HttpStream* stream) override { |
151 stream_done_ = true; | 149 stream_done_ = true; |
152 if (waiting_for_stream_) | 150 if (waiting_for_stream_) |
153 base::MessageLoop::current()->QuitWhenIdle(); | 151 base::MessageLoop::current()->QuitWhenIdle(); |
154 stream_.reset(stream); | 152 stream_.reset(stream); |
155 used_ssl_config_ = used_ssl_config; | 153 used_ssl_config_ = used_ssl_config; |
156 used_proxy_info_ = used_proxy_info; | 154 used_proxy_info_ = used_proxy_info; |
157 } | 155 } |
158 | 156 |
159 void OnWebSocketHandshakeStreamReady( | 157 void OnWebSocketHandshakeStreamReady( |
160 const SSLConfig& used_ssl_config, | 158 const SSLConfig& used_ssl_config, |
161 const ProxyInfo& used_proxy_info, | 159 const ProxyInfo& used_proxy_info, |
162 WebSocketHandshakeStreamBase* stream) override { | 160 WebSocketHandshakeStreamBase* stream) override { |
163 stream_done_ = true; | 161 stream_done_ = true; |
164 if (waiting_for_stream_) | 162 if (waiting_for_stream_) |
165 base::MessageLoop::current()->QuitWhenIdle(); | 163 base::MessageLoop::current()->QuitWhenIdle(); |
166 websocket_stream_.reset(stream); | 164 websocket_stream_.reset(stream); |
167 used_ssl_config_ = used_ssl_config; | 165 used_ssl_config_ = used_ssl_config; |
168 used_proxy_info_ = used_proxy_info; | 166 used_proxy_info_ = used_proxy_info; |
169 } | 167 } |
170 | 168 |
| 169 void OnBidirectionalStreamJobReady(const SSLConfig& used_ssl_config, |
| 170 const ProxyInfo& used_proxy_info, |
| 171 BidirectionalStreamJob* stream) override { |
| 172 stream_done_ = true; |
| 173 if (waiting_for_stream_) |
| 174 base::MessageLoop::current()->QuitWhenIdle(); |
| 175 bidirectional_stream_job_.reset(stream); |
| 176 used_ssl_config_ = used_ssl_config; |
| 177 used_proxy_info_ = used_proxy_info; |
| 178 } |
| 179 |
171 void OnStreamFailed(int status, | 180 void OnStreamFailed(int status, |
172 const SSLConfig& used_ssl_config, | 181 const SSLConfig& used_ssl_config, |
173 SSLFailureState ssl_failure_state) override {} | 182 SSLFailureState ssl_failure_state) override { |
| 183 stream_done_ = true; |
| 184 if (waiting_for_stream_) |
| 185 base::MessageLoop::current()->QuitWhenIdle(); |
| 186 used_ssl_config_ = used_ssl_config; |
| 187 error_status_ = status; |
| 188 } |
174 | 189 |
175 void OnCertificateError(int status, | 190 void OnCertificateError(int status, |
176 const SSLConfig& used_ssl_config, | 191 const SSLConfig& used_ssl_config, |
177 const SSLInfo& ssl_info) override {} | 192 const SSLInfo& ssl_info) override {} |
178 | 193 |
179 void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response, | 194 void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response, |
180 const SSLConfig& used_ssl_config, | 195 const SSLConfig& used_ssl_config, |
181 const ProxyInfo& used_proxy_info, | 196 const ProxyInfo& used_proxy_info, |
182 HttpAuthController* auth_controller) override {} | 197 HttpAuthController* auth_controller) override {} |
183 | 198 |
(...skipping 22 matching lines...) Expand all Loading... |
206 } | 221 } |
207 | 222 |
208 HttpStream* stream() { | 223 HttpStream* stream() { |
209 return stream_.get(); | 224 return stream_.get(); |
210 } | 225 } |
211 | 226 |
212 MockWebSocketHandshakeStream* websocket_stream() { | 227 MockWebSocketHandshakeStream* websocket_stream() { |
213 return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get()); | 228 return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get()); |
214 } | 229 } |
215 | 230 |
| 231 BidirectionalStreamJob* bidirectional_stream_job() { |
| 232 return bidirectional_stream_job_.get(); |
| 233 } |
| 234 |
216 bool stream_done() const { return stream_done_; } | 235 bool stream_done() const { return stream_done_; } |
| 236 int error_status() const { return error_status_; } |
217 | 237 |
218 private: | 238 private: |
219 bool waiting_for_stream_; | 239 bool waiting_for_stream_; |
220 bool stream_done_; | 240 bool stream_done_; |
221 scoped_ptr<HttpStream> stream_; | 241 scoped_ptr<HttpStream> stream_; |
222 scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_; | 242 scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_; |
| 243 scoped_ptr<BidirectionalStreamJob> bidirectional_stream_job_; |
223 SSLConfig used_ssl_config_; | 244 SSLConfig used_ssl_config_; |
224 ProxyInfo used_proxy_info_; | 245 ProxyInfo used_proxy_info_; |
| 246 int error_status_; |
225 | 247 |
226 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter); | 248 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter); |
227 }; | 249 }; |
228 | 250 |
229 class WebSocketSpdyHandshakeStream : public MockWebSocketHandshakeStream { | 251 class WebSocketSpdyHandshakeStream : public MockWebSocketHandshakeStream { |
230 public: | 252 public: |
231 explicit WebSocketSpdyHandshakeStream( | 253 explicit WebSocketSpdyHandshakeStream( |
232 const base::WeakPtr<SpdySession>& spdy_session) | 254 const base::WeakPtr<SpdySession>& spdy_session) |
233 : MockWebSocketHandshakeStream(kStreamTypeSpdy), | 255 : MockWebSocketHandshakeStream(kStreamTypeSpdy), |
234 spdy_session_(spdy_session) {} | 256 spdy_session_(spdy_session) {} |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 { 2, false }, | 308 { 2, false }, |
287 { 1, true}, | 309 { 1, true}, |
288 { 2, true}, | 310 { 2, true}, |
289 }; | 311 }; |
290 | 312 |
291 void PreconnectHelperForURL(int num_streams, | 313 void PreconnectHelperForURL(int num_streams, |
292 const GURL& url, | 314 const GURL& url, |
293 HttpNetworkSession* session) { | 315 HttpNetworkSession* session) { |
294 HttpNetworkSessionPeer peer(session); | 316 HttpNetworkSessionPeer peer(session); |
295 MockHttpStreamFactoryImplForPreconnect* mock_factory = | 317 MockHttpStreamFactoryImplForPreconnect* mock_factory = |
296 new MockHttpStreamFactoryImplForPreconnect(session, false); | 318 new MockHttpStreamFactoryImplForPreconnect(session); |
297 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory)); | 319 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory)); |
298 SSLConfig ssl_config; | 320 SSLConfig ssl_config; |
299 session->ssl_config_service()->GetSSLConfig(&ssl_config); | 321 session->ssl_config_service()->GetSSLConfig(&ssl_config); |
300 | 322 |
301 HttpRequestInfo request; | 323 HttpRequestInfo request; |
302 request.method = "GET"; | 324 request.method = "GET"; |
303 request.url = url; | 325 request.url = url; |
304 request.load_flags = 0; | 326 request.load_flags = 0; |
305 | 327 |
306 session->http_stream_factory()->PreconnectStreams(num_streams, request, | 328 session->http_stream_factory()->PreconnectStreams(num_streams, request, |
(...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 EXPECT_EQ(1, GetSocketPoolGroupCount( | 1258 EXPECT_EQ(1, GetSocketPoolGroupCount( |
1237 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); | 1259 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); |
1238 EXPECT_EQ(0, GetSocketPoolGroupCount( | 1260 EXPECT_EQ(0, GetSocketPoolGroupCount( |
1239 session->GetTransportSocketPool( | 1261 session->GetTransportSocketPool( |
1240 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); | 1262 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); |
1241 EXPECT_EQ(0, GetSocketPoolGroupCount( | 1263 EXPECT_EQ(0, GetSocketPoolGroupCount( |
1242 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); | 1264 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); |
1243 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); | 1265 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); |
1244 } | 1266 } |
1245 | 1267 |
| 1268 TEST_P(HttpStreamFactoryTest, RequestBidirectionalStreamJob) { |
| 1269 SpdySessionDependencies session_deps(GetParam(), |
| 1270 ProxyService::CreateDirect()); |
| 1271 |
| 1272 MockRead mock_read(ASYNC, OK); |
| 1273 SequencedSocketData socket_data(&mock_read, 1, nullptr, 0); |
| 1274 socket_data.set_connect_data(MockConnect(ASYNC, OK)); |
| 1275 session_deps.socket_factory->AddSocketDataProvider(&socket_data); |
| 1276 |
| 1277 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); |
| 1278 ssl_socket_data.SetNextProto(GetParam()); |
| 1279 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); |
| 1280 |
| 1281 HostPortPair host_port_pair("www.google.com", 443); |
| 1282 scoped_ptr<HttpNetworkSession> session( |
| 1283 SpdySessionDependencies::SpdyCreateSession(&session_deps)); |
| 1284 |
| 1285 // Now request a stream. |
| 1286 HttpRequestInfo request_info; |
| 1287 request_info.method = "GET"; |
| 1288 request_info.url = GURL("https://www.google.com"); |
| 1289 request_info.load_flags = 0; |
| 1290 |
| 1291 SSLConfig ssl_config; |
| 1292 StreamRequestWaiter waiter; |
| 1293 scoped_ptr<HttpStreamRequest> request( |
| 1294 session->http_stream_factory()->RequestBidirectionalStreamJob( |
| 1295 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, |
| 1296 BoundNetLog())); |
| 1297 waiter.WaitForStream(); |
| 1298 EXPECT_TRUE(waiter.stream_done()); |
| 1299 EXPECT_FALSE(waiter.websocket_stream()); |
| 1300 ASSERT_FALSE(waiter.stream()); |
| 1301 ASSERT_TRUE(waiter.bidirectional_stream_job()); |
| 1302 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( |
| 1303 HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| 1304 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( |
| 1305 HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| 1306 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( |
| 1307 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); |
| 1308 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( |
| 1309 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); |
| 1310 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); |
| 1311 ASSERT_EQ(0u, |
| 1312 static_cast<HttpStreamFactoryImpl*>(session->http_stream_factory()) |
| 1313 ->num_orphaned_jobs()); |
| 1314 } |
| 1315 |
| 1316 TEST_P(HttpStreamFactoryTest, RequestBidirectionalStreamJobFailure) { |
| 1317 SpdySessionDependencies session_deps(GetParam(), |
| 1318 ProxyService::CreateDirect()); |
| 1319 |
| 1320 MockRead mock_read(ASYNC, OK); |
| 1321 SequencedSocketData socket_data(&mock_read, 1, nullptr, 0); |
| 1322 socket_data.set_connect_data(MockConnect(ASYNC, OK)); |
| 1323 session_deps.socket_factory->AddSocketDataProvider(&socket_data); |
| 1324 |
| 1325 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); |
| 1326 |
| 1327 // If HTTP/1 is used, BidirectionalStreamJob should not be obtained. |
| 1328 ssl_socket_data.SetNextProto(kProtoHTTP11); |
| 1329 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); |
| 1330 |
| 1331 HostPortPair host_port_pair("www.google.com", 443); |
| 1332 scoped_ptr<HttpNetworkSession> session( |
| 1333 SpdySessionDependencies::SpdyCreateSession(&session_deps)); |
| 1334 |
| 1335 // Now request a stream. |
| 1336 HttpRequestInfo request_info; |
| 1337 request_info.method = "GET"; |
| 1338 request_info.url = GURL("https://www.google.com"); |
| 1339 request_info.load_flags = 0; |
| 1340 |
| 1341 SSLConfig ssl_config; |
| 1342 StreamRequestWaiter waiter; |
| 1343 scoped_ptr<HttpStreamRequest> request( |
| 1344 session->http_stream_factory()->RequestBidirectionalStreamJob( |
| 1345 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, |
| 1346 BoundNetLog())); |
| 1347 waiter.WaitForStream(); |
| 1348 EXPECT_TRUE(waiter.stream_done()); |
| 1349 ASSERT_EQ(ERR_FAILED, waiter.error_status()); |
| 1350 EXPECT_FALSE(waiter.websocket_stream()); |
| 1351 ASSERT_FALSE(waiter.stream()); |
| 1352 ASSERT_FALSE(waiter.bidirectional_stream_job()); |
| 1353 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( |
| 1354 HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| 1355 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( |
| 1356 HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| 1357 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( |
| 1358 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); |
| 1359 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( |
| 1360 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); |
| 1361 ASSERT_EQ(0u, |
| 1362 static_cast<HttpStreamFactoryImpl*>(session->http_stream_factory()) |
| 1363 ->num_orphaned_jobs()); |
| 1364 } |
| 1365 |
1246 // TODO(ricea): This test can be removed once the new WebSocket stack supports | 1366 // TODO(ricea): This test can be removed once the new WebSocket stack supports |
1247 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to | 1367 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to |
1248 // use plain SSL. | 1368 // use plain SSL. |
1249 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) { | 1369 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) { |
1250 SpdySessionDependencies session_deps(GetParam(), | 1370 SpdySessionDependencies session_deps(GetParam(), |
1251 ProxyService::CreateDirect()); | 1371 ProxyService::CreateDirect()); |
1252 | 1372 |
1253 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); | 1373 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); |
1254 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0); | 1374 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0); |
1255 socket_data.set_connect_data(MockConnect(ASYNC, OK)); | 1375 socket_data.set_connect_data(MockConnect(ASYNC, OK)); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1440 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); | 1560 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); |
1441 | 1561 |
1442 // Make sure there is no orphaned job. it is already canceled. | 1562 // Make sure there is no orphaned job. it is already canceled. |
1443 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>( | 1563 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>( |
1444 session->http_stream_factory_for_websocket())->num_orphaned_jobs()); | 1564 session->http_stream_factory_for_websocket())->num_orphaned_jobs()); |
1445 } | 1565 } |
1446 | 1566 |
1447 } // namespace | 1567 } // namespace |
1448 | 1568 |
1449 } // namespace net | 1569 } // namespace net |
OLD | NEW |