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

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

Powered by Google App Engine
This is Rietveld 408576698