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

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: Get rid of Delegate::OnClose 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698