Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: net/http/http_stream_factory_impl_unittest.cc

Issue 1326503003: Added a net::BidirectionalStream to expose a bidirectional streaming interface (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Matt's comments Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698