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