blob: 8f97c3d549210b0c1960047e6d498781054ba662 [file] [log] [blame]
[email protected]7acf98292012-01-28 00:51:551// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]81cdfcd2010-10-16 00:49:002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Xida Chen9bfe0b62018-04-24 19:52:215#include "net/http/http_stream_factory.h"
[email protected]81cdfcd2010-10-16 00:49:006
sclittlebe1ccf62015-09-02 19:40:367#include <stdint.h>
avifceb32f62016-10-07 16:30:528
9#include <memory>
[email protected]81cdfcd2010-10-16 00:49:0010#include <string>
Xida Chen9bfe0b62018-04-24 19:52:2111#include <tuple>
dchengc7eeda422015-12-26 03:56:4812#include <utility>
[email protected]3732cea2013-06-21 06:50:5013#include <vector>
[email protected]81cdfcd2010-10-16 00:49:0014
[email protected]41d64e82013-07-03 22:44:2615#include "base/compiler_specific.h"
aviadef3442016-10-03 18:50:3916#include "base/memory/ptr_util.h"
Matt Menkef09e64c2019-04-23 22:16:2817#include "base/optional.h"
xunjieli2608f9b2016-03-14 13:39:2318#include "base/run_loop.h"
Avi Drissman4365a4782018-12-28 19:26:2419#include "base/stl_util.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4720#include "base/test/metrics/histogram_tester.h"
Matt Menke9b2c3e82019-06-21 19:16:4121#include "base/test/scoped_feature_list.h"
Paul Jensena457017a2018-01-19 23:52:0422#include "build/build_config.h"
Bence Békya25e3f72018-02-13 21:13:3923#include "net/base/completion_once_callback.h"
Matt Menke9b2c3e82019-06-21 19:16:4124#include "net/base/features.h"
Matt Menkefe1f1c8f2019-08-20 17:49:1125#include "net/base/network_isolation_key.h"
eroman9ab64842015-07-21 05:07:5226#include "net/base/port_util.h"
tbansal37e33d52017-01-23 17:02:1527#include "net/base/privacy_mode.h"
Lily Houghton582d4622018-01-22 22:43:4028#include "net/base/proxy_server.h"
[email protected]81cdfcd2010-10-16 00:49:0029#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0430#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2031#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1132#include "net/cert/mock_cert_verifier.h"
rsleevid6de8302016-06-21 01:33:2033#include "net/cert/multi_log_ct_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5334#include "net/dns/mock_host_resolver.h"
xunjieli5749218c2016-03-22 16:43:0635#include "net/http/bidirectional_stream_impl.h"
xunjieli7f655802016-03-18 17:41:0636#include "net/http/bidirectional_stream_request_info.h"
[email protected]81cdfcd2010-10-16 00:49:0037#include "net/http/http_auth_handler_factory.h"
38#include "net/http/http_network_session.h"
39#include "net/http/http_network_session_peer.h"
[email protected]e6d017652013-05-17 18:01:4040#include "net/http/http_network_transaction.h"
Matt Menke0754b5d02019-02-10 21:46:4341#include "net/http/http_proxy_connect_job.h"
[email protected]81cdfcd2010-10-16 00:49:0042#include "net/http/http_request_info.h"
[email protected]3732cea2013-06-21 06:50:5043#include "net/http/http_server_properties.h"
[email protected]96e1933f2011-08-29 16:39:0044#include "net/http/http_stream.h"
[email protected]b1c988b2013-06-13 06:48:1145#include "net/http/transport_security_state.h"
mikecironef22f9812016-10-04 03:40:1946#include "net/log/net_log_with_source.h"
Lily Houghton582d4622018-01-22 22:43:4047#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0348#include "net/proxy_resolution/proxy_resolution_service.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0849#include "net/quic/mock_crypto_client_stream_factory.h"
Victor Vasiliev7752898d2019-11-14 21:30:2250#include "net/quic/mock_quic_context.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0851#include "net/quic/quic_http_utils.h"
52#include "net/quic/quic_stream_factory_peer.h"
53#include "net/quic/quic_test_packet_maker.h"
Ryan Hamilton0d65a8c2019-06-07 00:46:0254#include "net/quic/quic_test_packet_printer.h"
[email protected]3732cea2013-06-21 06:50:5055#include "net/socket/client_socket_handle.h"
Matt Menke12d33db92019-03-26 22:45:4456#include "net/socket/client_socket_pool.h"
Matt Menked6fd2a52019-03-20 06:14:3657#include "net/socket/connect_job.h"
[email protected]a42dbd142011-11-17 16:42:0258#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]3732cea2013-06-21 06:50:5059#include "net/socket/next_proto.h"
Paul Jensen8d6f87ec2018-01-13 00:46:5460#include "net/socket/socket_tag.h"
[email protected]81cdfcd2010-10-16 00:49:0061#include "net/socket/socket_test_util.h"
Matt Menke4b412da2019-01-25 19:31:1262#include "net/socket/socks_connect_job.h"
Matt Menkedf126e0e2019-02-01 22:23:4763#include "net/socket/ssl_connect_job.h"
Matt Menke2170bccb2019-01-16 00:03:2764#include "net/socket/transport_connect_job.h"
Bence Béky94658bf2018-05-11 19:22:5865#include "net/spdy/spdy_session.h"
66#include "net/spdy/spdy_session_pool.h"
67#include "net/spdy/spdy_test_util_common.h"
[email protected]3732cea2013-06-21 06:50:5068#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5769#include "net/ssl/ssl_config_service_defaults.h"
xunjieli2608f9b2016-03-14 13:39:2370#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0171#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4372#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4073#include "net/test/test_with_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5174#include "net/third_party/quiche/src/quic/core/quic_server_id.h"
75#include "net/third_party/quiche/src/quic/core/quic_utils.h"
76#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
77#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
78#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Ramin Halavati3c96c6d2018-03-11 13:29:4479#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menke9aa86262019-08-21 15:52:0780#include "testing/gmock/include/gmock/gmock.h"
81#include "testing/gtest/include/gtest/gtest.h"
Matt Menkefe1f1c8f2019-08-20 17:49:1182#include "url/origin.h"
xunjieli2608f9b2016-03-14 13:39:2383
[email protected]3732cea2013-06-21 06:50:5084// This file can be included from net/http even though
85// it is in net/websockets because it doesn't
86// introduce any link dependency to net/websockets.
[email protected]a9cf2b92013-10-30 12:08:4987#include "net/websockets/websocket_handshake_stream_base.h"
robpercival214763f2016-07-01 23:27:0188
Reilly Grant89a7e512018-01-20 01:57:1689using ::testing::Contains;
90using ::testing::ElementsAre;
91using ::testing::IsEmpty;
92using ::testing::Key;
93using ::testing::SizeIs;
94
robpercival214763f2016-07-01 23:27:0195using net::test::IsError;
96using net::test::IsOk;
97
mikecironef22f9812016-10-04 03:40:1998namespace base {
99class Value;
100class DictionaryValue;
101} // namespace base
102
[email protected]81cdfcd2010-10-16 00:49:00103namespace net {
104
xunjieli5749218c2016-03-22 16:43:06105class BidirectionalStreamImpl;
Bence Békyda280c62018-04-12 15:08:37106class WebSocketEndpointLockManager;
Nico Weber13d106e2015-12-22 21:41:56107
[email protected]81cdfcd2010-10-16 00:49:00108namespace {
109
[email protected]a9cf2b92013-10-30 12:08:49110class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
[email protected]3732cea2013-06-21 06:50:50111 public:
112 enum StreamType {
113 kStreamTypeBasic,
114 kStreamTypeSpdy,
115 };
116
Jeremy Romand54000b22019-07-08 18:40:16117 explicit MockWebSocketHandshakeStream(StreamType type) : type_(type) {}
[email protected]3732cea2013-06-21 06:50:50118
Chris Watkins7a41d3552017-12-01 02:13:27119 ~MockWebSocketHandshakeStream() override = default;
[email protected]3732cea2013-06-21 06:50:50120
Xida Chen9bfe0b62018-04-24 19:52:21121 StreamType type() const { return type_; }
[email protected]3732cea2013-06-21 06:50:50122
yhiranoa7e05bb2014-11-06 05:40:39123 // HttpStream methods
dchengb03027d2014-10-21 12:00:20124 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:27125 bool can_send_early,
dchengb03027d2014-10-21 12:00:20126 RequestPriority priority,
tfarina428341112016-09-22 13:38:20127 const NetLogWithSource& net_log,
Bence Békya25e3f72018-02-13 21:13:39128 CompletionOnceCallback callback) override {
[email protected]693ebf32013-10-23 13:47:01129 return ERR_IO_PENDING;
130 }
dchengb03027d2014-10-21 12:00:20131 int SendRequest(const HttpRequestHeaders& request_headers,
132 HttpResponseInfo* response,
Bence Békya25e3f72018-02-13 21:13:39133 CompletionOnceCallback callback) override {
[email protected]693ebf32013-10-23 13:47:01134 return ERR_IO_PENDING;
135 }
Bence Békya25e3f72018-02-13 21:13:39136 int ReadResponseHeaders(CompletionOnceCallback callback) override {
[email protected]693ebf32013-10-23 13:47:01137 return ERR_IO_PENDING;
138 }
dchengb03027d2014-10-21 12:00:20139 int ReadResponseBody(IOBuffer* buf,
140 int buf_len,
Bence Békya25e3f72018-02-13 21:13:39141 CompletionOnceCallback callback) override {
[email protected]693ebf32013-10-23 13:47:01142 return ERR_IO_PENDING;
143 }
dchengb03027d2014-10-21 12:00:20144 void Close(bool not_reusable) override {}
145 bool IsResponseBodyComplete() const override { return false; }
dchengb03027d2014-10-21 12:00:20146 bool IsConnectionReused() const override { return false; }
147 void SetConnectionReused() override {}
mmenkebd84c392015-09-02 14:12:34148 bool CanReuseConnection() const override { return false; }
sclittle4de1bab92015-09-22 21:28:24149 int64_t GetTotalReceivedBytes() const override { return 0; }
sclittlebe1ccf62015-09-02 19:40:36150 int64_t GetTotalSentBytes() const override { return 0; }
dchengb03027d2014-10-21 12:00:20151 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]693ebf32013-10-23 13:47:01152 return false;
153 }
rchcd379012017-04-12 21:53:32154 bool GetAlternativeService(
155 AlternativeService* alternative_service) const override {
156 return false;
157 }
dchengb03027d2014-10-21 12:00:20158 void GetSSLInfo(SSLInfo* ssl_info) override {}
159 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {}
ttuttled9dbc652015-09-29 20:00:59160 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
dchengb03027d2014-10-21 12:00:20161 void Drain(HttpNetworkSession* session) override {}
zhongyica364fbb2015-12-12 03:39:12162 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
dchengb03027d2014-10-21 12:00:20163 void SetPriority(RequestPriority priority) override {}
yhiranoa7e05bb2014-11-06 05:40:39164 HttpStream* RenewStreamForAuth() override { return nullptr; }
[email protected]693ebf32013-10-23 13:47:01165
danakj1fd259a02016-04-16 03:17:09166 std::unique_ptr<WebSocketStream> Upgrade() override {
167 return std::unique_ptr<WebSocketStream>();
[email protected]a9cf2b92013-10-30 12:08:49168 }
169
Bence Békyca0da432019-01-24 15:03:20170 base::WeakPtr<WebSocketHandshakeStreamBase> GetWeakPtr() override {
171 return weak_ptr_factory_.GetWeakPtr();
172 }
173
[email protected]3732cea2013-06-21 06:50:50174 private:
175 const StreamType type_;
Jeremy Romand54000b22019-07-08 18:40:16176 base::WeakPtrFactory<MockWebSocketHandshakeStream> weak_ptr_factory_{this};
[email protected]3732cea2013-06-21 06:50:50177};
178
Xida Chen9bfe0b62018-04-24 19:52:21179// HttpStreamFactory subclass that can wait until a preconnect is complete.
Bence Békye4c0e3e2018-04-27 00:47:25180class MockHttpStreamFactoryForPreconnect : public HttpStreamFactory {
[email protected]3732cea2013-06-21 06:50:50181 public:
Bence Békye4c0e3e2018-04-27 00:47:25182 explicit MockHttpStreamFactoryForPreconnect(HttpNetworkSession* session)
Xida Chen9bfe0b62018-04-24 19:52:21183 : HttpStreamFactory(session),
[email protected]102e27c2011-02-23 01:01:31184 preconnect_done_(false),
185 waiting_for_preconnect_(false) {}
186
Bence Békye4c0e3e2018-04-27 00:47:25187 ~MockHttpStreamFactoryForPreconnect() override {}
Xida Chen9bfe0b62018-04-24 19:52:21188
[email protected]102e27c2011-02-23 01:01:31189 void WaitForPreconnects() {
190 while (!preconnect_done_) {
191 waiting_for_preconnect_ = true;
Bence Békya55e4322018-04-11 15:17:53192 loop_.Run();
[email protected]102e27c2011-02-23 01:01:31193 waiting_for_preconnect_ = false;
194 }
195 }
196
197 private:
Xida Chen9bfe0b62018-04-24 19:52:21198 // HttpStreamFactory methods.
dchengb03027d2014-10-21 12:00:20199 void OnPreconnectsCompleteInternal() override {
[email protected]102e27c2011-02-23 01:01:31200 preconnect_done_ = true;
201 if (waiting_for_preconnect_)
Bence Békya55e4322018-04-11 15:17:53202 loop_.QuitWhenIdle();
[email protected]102e27c2011-02-23 01:01:31203 }
204
205 bool preconnect_done_;
206 bool waiting_for_preconnect_;
Bence Békya55e4322018-04-11 15:17:53207 base::RunLoop loop_;
[email protected]102e27c2011-02-23 01:01:31208};
209
[email protected]96e1933f2011-08-29 16:39:00210class StreamRequestWaiter : public HttpStreamRequest::Delegate {
211 public:
212 StreamRequestWaiter()
xunjieli11834f02015-12-22 04:27:08213 : waiting_for_stream_(false), stream_done_(false), error_status_(OK) {}
[email protected]96e1933f2011-08-29 16:39:00214
215 // HttpStreamRequest::Delegate
216
dchengb03027d2014-10-21 12:00:20217 void OnStreamReady(const SSLConfig& used_ssl_config,
218 const ProxyInfo& used_proxy_info,
bnc5029f4632017-06-08 16:19:00219 std::unique_ptr<HttpStream> stream) override {
[email protected]96e1933f2011-08-29 16:39:00220 stream_done_ = true;
221 if (waiting_for_stream_)
xunjieli66e35d22017-03-30 22:06:06222 loop_.Quit();
bnc5029f4632017-06-08 16:19:00223 stream_ = std::move(stream);
[email protected]e6d017652013-05-17 18:01:40224 used_ssl_config_ = used_ssl_config;
[email protected]3732cea2013-06-21 06:50:50225 used_proxy_info_ = used_proxy_info;
226 }
227
dchengb03027d2014-10-21 12:00:20228 void OnWebSocketHandshakeStreamReady(
[email protected]a9cf2b92013-10-30 12:08:49229 const SSLConfig& used_ssl_config,
230 const ProxyInfo& used_proxy_info,
bnc5029f4632017-06-08 16:19:00231 std::unique_ptr<WebSocketHandshakeStreamBase> stream) override {
[email protected]3732cea2013-06-21 06:50:50232 stream_done_ = true;
233 if (waiting_for_stream_)
xunjieli66e35d22017-03-30 22:06:06234 loop_.Quit();
bnc5029f4632017-06-08 16:19:00235 websocket_stream_ = std::move(stream);
[email protected]3732cea2013-06-21 06:50:50236 used_ssl_config_ = used_ssl_config;
237 used_proxy_info_ = used_proxy_info;
[email protected]96e1933f2011-08-29 16:39:00238 }
239
xunjieli5749218c2016-03-22 16:43:06240 void OnBidirectionalStreamImplReady(
241 const SSLConfig& used_ssl_config,
242 const ProxyInfo& used_proxy_info,
bnc5029f4632017-06-08 16:19:00243 std::unique_ptr<BidirectionalStreamImpl> stream) override {
xunjieli11834f02015-12-22 04:27:08244 stream_done_ = true;
245 if (waiting_for_stream_)
xunjieli66e35d22017-03-30 22:06:06246 loop_.Quit();
bnc5029f4632017-06-08 16:19:00247 bidirectional_stream_impl_ = std::move(stream);
xunjieli11834f02015-12-22 04:27:08248 used_ssl_config_ = used_ssl_config;
249 used_proxy_info_ = used_proxy_info;
250 }
251
Ryan Hamilton75f197262017-08-17 14:00:07252 void OnStreamFailed(int status,
253 const NetErrorDetails& net_error_details,
Wojciech Dzierżanowskiabdeeaf2019-04-01 20:16:22254 const SSLConfig& used_ssl_config,
255 const ProxyInfo& used_proxy_info) override {
xunjieli11834f02015-12-22 04:27:08256 stream_done_ = true;
257 if (waiting_for_stream_)
xunjieli66e35d22017-03-30 22:06:06258 loop_.Quit();
xunjieli11834f02015-12-22 04:27:08259 used_ssl_config_ = used_ssl_config;
260 error_status_ = status;
261 }
[email protected]96e1933f2011-08-29 16:39:00262
dchengb03027d2014-10-21 12:00:20263 void OnCertificateError(int status,
264 const SSLConfig& used_ssl_config,
265 const SSLInfo& ssl_info) override {}
[email protected]96e1933f2011-08-29 16:39:00266
dchengb03027d2014-10-21 12:00:20267 void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response,
268 const SSLConfig& used_ssl_config,
269 const ProxyInfo& used_proxy_info,
270 HttpAuthController* auth_controller) override {}
[email protected]96e1933f2011-08-29 16:39:00271
dchengb03027d2014-10-21 12:00:20272 void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
273 SSLCertRequestInfo* cert_info) override {}
[email protected]96e1933f2011-08-29 16:39:00274
zhongyi48704c182015-12-07 07:52:02275 void OnQuicBroken() override {}
276
[email protected]96e1933f2011-08-29 16:39:00277 void WaitForStream() {
278 while (!stream_done_) {
279 waiting_for_stream_ = true;
xunjieli66e35d22017-03-30 22:06:06280 loop_.Run();
[email protected]96e1933f2011-08-29 16:39:00281 waiting_for_stream_ = false;
282 }
283 }
284
Xida Chen9bfe0b62018-04-24 19:52:21285 const SSLConfig& used_ssl_config() const { return used_ssl_config_; }
[email protected]e6d017652013-05-17 18:01:40286
Xida Chen9bfe0b62018-04-24 19:52:21287 const ProxyInfo& used_proxy_info() const { return used_proxy_info_; }
[email protected]3732cea2013-06-21 06:50:50288
Xida Chen9bfe0b62018-04-24 19:52:21289 HttpStream* stream() { return stream_.get(); }
[email protected]e6d017652013-05-17 18:01:40290
[email protected]693ebf32013-10-23 13:47:01291 MockWebSocketHandshakeStream* websocket_stream() {
292 return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get());
[email protected]3732cea2013-06-21 06:50:50293 }
294
xunjieli5749218c2016-03-22 16:43:06295 BidirectionalStreamImpl* bidirectional_stream_impl() {
296 return bidirectional_stream_impl_.get();
xunjieli11834f02015-12-22 04:27:08297 }
298
[email protected]3732cea2013-06-21 06:50:50299 bool stream_done() const { return stream_done_; }
xunjieli11834f02015-12-22 04:27:08300 int error_status() const { return error_status_; }
[email protected]e6d017652013-05-17 18:01:40301
[email protected]96e1933f2011-08-29 16:39:00302 private:
303 bool waiting_for_stream_;
304 bool stream_done_;
xunjieli66e35d22017-03-30 22:06:06305 base::RunLoop loop_;
danakj1fd259a02016-04-16 03:17:09306 std::unique_ptr<HttpStream> stream_;
307 std::unique_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
308 std::unique_ptr<BidirectionalStreamImpl> bidirectional_stream_impl_;
[email protected]e6d017652013-05-17 18:01:40309 SSLConfig used_ssl_config_;
[email protected]3732cea2013-06-21 06:50:50310 ProxyInfo used_proxy_info_;
xunjieli11834f02015-12-22 04:27:08311 int error_status_;
[email protected]96e1933f2011-08-29 16:39:00312
313 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter);
314};
315
[email protected]693ebf32013-10-23 13:47:01316class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream {
[email protected]3732cea2013-06-21 06:50:50317 public:
[email protected]7e841a52013-11-22 09:04:21318 explicit WebSocketBasicHandshakeStream(
danakj1fd259a02016-04-16 03:17:09319 std::unique_ptr<ClientSocketHandle> connection)
[email protected]693ebf32013-10-23 13:47:01320 : MockWebSocketHandshakeStream(kStreamTypeBasic),
dchengc7eeda422015-12-26 03:56:48321 connection_(std::move(connection)) {}
[email protected]3732cea2013-06-21 06:50:50322
dchengb03027d2014-10-21 12:00:20323 ~WebSocketBasicHandshakeStream() override {
[email protected]3732cea2013-06-21 06:50:50324 connection_->socket()->Disconnect();
325 }
326
327 ClientSocketHandle* connection() { return connection_.get(); }
328
329 private:
danakj1fd259a02016-04-16 03:17:09330 std::unique_ptr<ClientSocketHandle> connection_;
[email protected]3732cea2013-06-21 06:50:50331};
332
[email protected]467086b2013-11-12 08:19:46333class WebSocketStreamCreateHelper
334 : public WebSocketHandshakeStreamBase::CreateHelper {
[email protected]3732cea2013-06-21 06:50:50335 public:
Chris Watkins7a41d3552017-12-01 02:13:27336 ~WebSocketStreamCreateHelper() override = default;
[email protected]3732cea2013-06-21 06:50:50337
bnc615cf2f2017-05-19 18:53:26338 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:09339 std::unique_ptr<ClientSocketHandle> connection,
Bence Békyda280c62018-04-12 15:08:37340 bool using_proxy,
341 WebSocketEndpointLockManager* websocket_endpoint_lock_manager) override {
Jeremy Roman0579ed62017-08-29 15:56:19342 return std::make_unique<WebSocketBasicHandshakeStream>(
bnc615cf2f2017-05-19 18:53:26343 std::move(connection));
[email protected]3732cea2013-06-21 06:50:50344 }
Bence Béky46bfbc12018-02-22 19:28:20345 std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp2Stream(
346 base::WeakPtr<SpdySession> session) override {
347 NOTREACHED();
348 return nullptr;
349 }
[email protected]3732cea2013-06-21 06:50:50350};
351
[email protected]81cdfcd2010-10-16 00:49:00352struct TestCase {
353 int num_streams;
354 bool ssl;
355};
356
357TestCase kTests[] = {
Xida Chen9bfe0b62018-04-24 19:52:21358 {1, false},
359 {2, false},
360 {1, true},
361 {2, true},
[email protected]81cdfcd2010-10-16 00:49:00362};
363
[email protected]1967b09e2011-12-13 20:34:21364void PreconnectHelperForURL(int num_streams,
365 const GURL& url,
Matt Menke9b2c3e82019-06-21 19:16:41366 NetworkIsolationKey network_isolation_key,
dalyka92863972019-10-14 20:25:58367 bool disable_secure_dns,
[email protected]1967b09e2011-12-13 20:34:21368 HttpNetworkSession* session) {
[email protected]102e27c2011-02-23 01:01:31369 HttpNetworkSessionPeer peer(session);
Bence Békye4c0e3e2018-04-27 00:47:25370 MockHttpStreamFactoryForPreconnect* mock_factory =
371 new MockHttpStreamFactoryForPreconnect(session);
danakj1fd259a02016-04-16 03:17:09372 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(mock_factory));
[email protected]81cdfcd2010-10-16 00:49:00373
374 HttpRequestInfo request;
375 request.method = "GET";
[email protected]1967b09e2011-12-13 20:34:21376 request.url = url;
[email protected]81cdfcd2010-10-16 00:49:00377 request.load_flags = 0;
Matt Menke9b2c3e82019-06-21 19:16:41378 request.network_isolation_key = network_isolation_key;
dalyka92863972019-10-14 20:25:58379 request.disable_secure_dns = disable_secure_dns;
Ramin Halavati216426e2018-03-12 22:13:35380 request.traffic_annotation =
381 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]81cdfcd2010-10-16 00:49:00382
nharper8cdb0fb2016-04-22 21:34:59383 session->http_stream_factory()->PreconnectStreams(num_streams, request);
[email protected]102e27c2011-02-23 01:01:31384 mock_factory->WaitForPreconnects();
bnc2ae6a1f2015-08-17 23:21:18385}
[email protected]81cdfcd2010-10-16 00:49:00386
Xida Chen9bfe0b62018-04-24 19:52:21387void PreconnectHelper(const TestCase& test, HttpNetworkSession* session) {
388 GURL url =
389 test.ssl ? GURL("https://www.google.com") : GURL("http://www.google.com");
dalyka92863972019-10-14 20:25:58390 PreconnectHelperForURL(test.num_streams, url, NetworkIsolationKey(),
391 false /* disable_secure_dns */, session);
bnc2ae6a1f2015-08-17 23:21:18392}
[email protected]1967b09e2011-12-13 20:34:21393
Matt Menkef6edce752019-03-19 17:21:56394ClientSocketPool::GroupId GetGroupId(const TestCase& test) {
395 if (test.ssl) {
dalyk51ab46b2019-10-15 15:14:34396 return ClientSocketPool::GroupId(
397 HostPortPair("www.google.com", 443), ClientSocketPool::SocketType::kSsl,
398 PrivacyMode::PRIVACY_MODE_DISABLED, NetworkIsolationKey(),
399 false /* disable_secure_dns */);
Matt Menkef6edce752019-03-19 17:21:56400 }
dalyk51ab46b2019-10-15 15:14:34401 return ClientSocketPool::GroupId(
402 HostPortPair("www.google.com", 80), ClientSocketPool::SocketType::kHttp,
403 PrivacyMode::PRIVACY_MODE_DISABLED, NetworkIsolationKey(),
404 false /* disable_secure_dns */);
Matt Menke9d5e2c92019-02-05 01:42:23405}
406
Matt Menked6fd2a52019-03-20 06:14:36407class CapturePreconnectsTransportSocketPool : public TransportClientSocketPool {
[email protected]81cdfcd2010-10-16 00:49:00408 public:
Matt Menked6fd2a52019-03-20 06:14:36409 explicit CapturePreconnectsTransportSocketPool(
410 const CommonConnectJobParams* common_connect_job_params)
411 : TransportClientSocketPool(0,
412 0,
413 base::TimeDelta(),
Matt Menkeaafff542019-04-22 22:09:36414 ProxyServer::Direct(),
415 false /* is_for_websockets */,
David Benjamin151ec6b2019-08-02 19:38:52416 common_connect_job_params),
Matt Menked6fd2a52019-03-20 06:14:36417 last_num_streams_(-1) {}
[email protected]81cdfcd2010-10-16 00:49:00418
Xida Chen9bfe0b62018-04-24 19:52:21419 int last_num_streams() const { return last_num_streams_; }
Matt Menkef6edce752019-03-19 17:21:56420 const ClientSocketPool::GroupId& last_group_id() const {
421 return last_group_id_;
422 }
[email protected]81cdfcd2010-10-16 00:49:00423
Matt Menkef6edce752019-03-19 17:21:56424 // Resets |last_num_streams_| and |last_group_id_| default values.
Matt Menke628d624f2019-02-09 00:40:24425 void reset() {
426 last_num_streams_ = -1;
Matt Menkef6edce752019-03-19 17:21:56427 // Group ID that shouldn't match much.
428 last_group_id_ = ClientSocketPool::GroupId(
David Benjamind61bd532019-04-23 21:11:37429 HostPortPair(), ClientSocketPool::SocketType::kSsl,
dalyk51ab46b2019-10-15 15:14:34430 PrivacyMode::PRIVACY_MODE_ENABLED, NetworkIsolationKey(),
431 false /* disable_secure_dns */);
Matt Menke628d624f2019-02-09 00:40:24432 }
tbansal37e33d52017-01-23 17:02:15433
Matt Menke28ac03e2019-02-25 22:25:50434 int RequestSocket(
Matt Menkef6edce752019-03-19 17:21:56435 const ClientSocketPool::GroupId& group_id,
Matt Menkebd12b7e2019-03-25 21:12:03436 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
Matt Menkef09e64c2019-04-23 22:16:28437 const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
Matt Menke28ac03e2019-02-25 22:25:50438 RequestPriority priority,
439 const SocketTag& socket_tag,
440 ClientSocketPool::RespectLimits respect_limits,
441 ClientSocketHandle* handle,
442 CompletionOnceCallback callback,
443 const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback,
444 const NetLogWithSource& net_log) override {
[email protected]81cdfcd2010-10-16 00:49:00445 ADD_FAILURE();
446 return ERR_UNEXPECTED;
447 }
448
Matt Menkebd12b7e2019-03-25 21:12:03449 void RequestSockets(
450 const ClientSocketPool::GroupId& group_id,
451 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
Matt Menkef09e64c2019-04-23 22:16:28452 const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
Matt Menkebd12b7e2019-03-25 21:12:03453 int num_sockets,
454 const NetLogWithSource& net_log) override {
[email protected]81cdfcd2010-10-16 00:49:00455 last_num_streams_ = num_sockets;
Matt Menkef6edce752019-03-19 17:21:56456 last_group_id_ = group_id;
[email protected]81cdfcd2010-10-16 00:49:00457 }
458
Matt Menkef6edce752019-03-19 17:21:56459 void CancelRequest(const ClientSocketPool::GroupId& group_id,
Matt Menke7eb405e2019-04-25 20:48:21460 ClientSocketHandle* handle,
461 bool cancel_connect_job) override {
[email protected]81cdfcd2010-10-16 00:49:00462 ADD_FAILURE();
463 }
Matt Menkef6edce752019-03-19 17:21:56464 void ReleaseSocket(const ClientSocketPool::GroupId& group_id,
danakj1fd259a02016-04-16 03:17:09465 std::unique_ptr<StreamSocket> socket,
Matt Menkebf3c767d2019-04-15 23:28:24466 int64_t generation) override {
[email protected]81cdfcd2010-10-16 00:49:00467 ADD_FAILURE();
468 }
nickd3f30d022015-04-23 10:18:37469 void CloseIdleSockets() override { ADD_FAILURE(); }
470 int IdleSocketCount() const override {
[email protected]81cdfcd2010-10-16 00:49:00471 ADD_FAILURE();
472 return 0;
473 }
Matt Menkef6edce752019-03-19 17:21:56474 size_t IdleSocketCountInGroup(
475 const ClientSocketPool::GroupId& group_id) const override {
[email protected]81cdfcd2010-10-16 00:49:00476 ADD_FAILURE();
477 return 0;
478 }
Matt Menkef6edce752019-03-19 17:21:56479 LoadState GetLoadState(const ClientSocketPool::GroupId& group_id,
nickd3f30d022015-04-23 10:18:37480 const ClientSocketHandle* handle) const override {
[email protected]81cdfcd2010-10-16 00:49:00481 ADD_FAILURE();
482 return LOAD_STATE_IDLE;
483 }
[email protected]81cdfcd2010-10-16 00:49:00484
485 private:
486 int last_num_streams_;
Matt Menkef6edce752019-03-19 17:21:56487 ClientSocketPool::GroupId last_group_id_;
[email protected]81cdfcd2010-10-16 00:49:00488};
489
Gabriel Charette694c3c332019-08-19 14:53:05490using HttpStreamFactoryTest = TestWithTaskEnvironment;
[email protected]41d64e82013-07-03 22:44:26491
Shivani Sharma8ae506c2019-07-21 21:08:27492// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
493// kAppendInitiatingFrameOriginToNetworkIsolationKey.
494
bnca9b9e222016-07-11 20:10:40495TEST_F(HttpStreamFactoryTest, PreconnectDirect) {
Avi Drissman4365a4782018-12-28 19:26:24496 for (size_t i = 0; i < base::size(kTests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:59497 SpdySessionDependencies session_deps(
498 ProxyResolutionService::CreateDirect());
danakj1fd259a02016-04-16 03:17:09499 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:26500 SpdySessionDependencies::SpdyCreateSession(&session_deps));
mmenkee65e7af2015-10-13 17:16:42501 HttpNetworkSessionPeer peer(session.get());
Matt Menked6fd2a52019-03-20 06:14:36502 CommonConnectJobParams common_connect_job_params =
503 session->CreateCommonConnectJobParams();
Matt Menked23ab952019-03-06 00:24:40504 std::unique_ptr<CapturePreconnectsTransportSocketPool>
505 owned_transport_conn_pool =
506 std::make_unique<CapturePreconnectsTransportSocketPool>(
Matt Menked6fd2a52019-03-20 06:14:36507 &common_connect_job_params);
[email protected]ab739042011-04-07 15:22:28508 CapturePreconnectsTransportSocketPool* transport_conn_pool =
Matt Menked23ab952019-03-06 00:24:40509 owned_transport_conn_pool.get();
Jeremy Roman0579ed62017-08-29 15:56:19510 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:40511 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
512 std::move(owned_transport_conn_pool));
dchengc7eeda422015-12-26 03:56:48513 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]90499482013-06-01 00:39:50514 PreconnectHelper(kTests[i], session.get());
Matt Menke9d5e2c92019-02-05 01:42:23515 EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams());
Matt Menkef6edce752019-03-19 17:21:56516 EXPECT_EQ(GetGroupId(kTests[i]), transport_conn_pool->last_group_id());
[email protected]81cdfcd2010-10-16 00:49:00517 }
518}
519
bnca9b9e222016-07-11 20:10:40520TEST_F(HttpStreamFactoryTest, PreconnectHttpProxy) {
Avi Drissman4365a4782018-12-28 19:26:24521 for (size_t i = 0; i < base::size(kTests); ++i) {
Ramin Halavatica8d5252018-03-12 05:33:49522 SpdySessionDependencies session_deps(ProxyResolutionService::CreateFixed(
523 "http_proxy", TRAFFIC_ANNOTATION_FOR_TESTS));
danakj1fd259a02016-04-16 03:17:09524 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:26525 SpdySessionDependencies::SpdyCreateSession(&session_deps));
mmenkee65e7af2015-10-13 17:16:42526 HttpNetworkSessionPeer peer(session.get());
Matt Menkee8648fa2019-01-17 16:47:07527 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
528 HostPortPair("http_proxy", 80));
Matt Menked6fd2a52019-03-20 06:14:36529 CommonConnectJobParams common_connect_job_params =
530 session->CreateCommonConnectJobParams();
Matt Menke0754b5d02019-02-10 21:46:43531 CapturePreconnectsTransportSocketPool* http_proxy_pool =
Matt Menked6fd2a52019-03-20 06:14:36532 new CapturePreconnectsTransportSocketPool(&common_connect_job_params);
Jeremy Roman0579ed62017-08-29 15:56:19533 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:40534 mock_pool_manager->SetSocketPool(proxy_server,
535 base::WrapUnique(http_proxy_pool));
dchengc7eeda422015-12-26 03:56:48536 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]90499482013-06-01 00:39:50537 PreconnectHelper(kTests[i], session.get());
Matt Menkeaade5812019-03-02 13:38:00538 EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams());
Matt Menkef6edce752019-03-19 17:21:56539 EXPECT_EQ(GetGroupId(kTests[i]), http_proxy_pool->last_group_id());
[email protected]81cdfcd2010-10-16 00:49:00540 }
541}
542
bnca9b9e222016-07-11 20:10:40543TEST_F(HttpStreamFactoryTest, PreconnectSocksProxy) {
Avi Drissman4365a4782018-12-28 19:26:24544 for (size_t i = 0; i < base::size(kTests); ++i) {
Ramin Halavatica8d5252018-03-12 05:33:49545 SpdySessionDependencies session_deps(ProxyResolutionService::CreateFixed(
546 "socks4://socks_proxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS));
danakj1fd259a02016-04-16 03:17:09547 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:26548 SpdySessionDependencies::SpdyCreateSession(&session_deps));
mmenkee65e7af2015-10-13 17:16:42549 HttpNetworkSessionPeer peer(session.get());
Matt Menkee8648fa2019-01-17 16:47:07550 ProxyServer proxy_server(ProxyServer::SCHEME_SOCKS4,
551 HostPortPair("socks_proxy", 1080));
Matt Menked6fd2a52019-03-20 06:14:36552 CommonConnectJobParams common_connect_job_params =
553 session->CreateCommonConnectJobParams();
Matt Menke4b412da2019-01-25 19:31:12554 CapturePreconnectsTransportSocketPool* socks_proxy_pool =
Matt Menked6fd2a52019-03-20 06:14:36555 new CapturePreconnectsTransportSocketPool(&common_connect_job_params);
Jeremy Roman0579ed62017-08-29 15:56:19556 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:40557 mock_pool_manager->SetSocketPool(proxy_server,
558 base::WrapUnique(socks_proxy_pool));
dchengc7eeda422015-12-26 03:56:48559 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]90499482013-06-01 00:39:50560 PreconnectHelper(kTests[i], session.get());
Matt Menke628d624f2019-02-09 00:40:24561 EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams());
Matt Menkef6edce752019-03-19 17:21:56562 EXPECT_EQ(GetGroupId(kTests[i]), socks_proxy_pool->last_group_id());
[email protected]81cdfcd2010-10-16 00:49:00563 }
564}
565
bnca9b9e222016-07-11 20:10:40566TEST_F(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
Avi Drissman4365a4782018-12-28 19:26:24567 for (size_t i = 0; i < base::size(kTests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:59568 SpdySessionDependencies session_deps(
569 ProxyResolutionService::CreateDirect());
danakj1fd259a02016-04-16 03:17:09570 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:26571 SpdySessionDependencies::SpdyCreateSession(&session_deps));
mmenkee65e7af2015-10-13 17:16:42572 HttpNetworkSessionPeer peer(session.get());
[email protected]5cffc732011-01-26 03:14:27573
[email protected]41d64e82013-07-03 22:44:26574 // Put a SpdySession in the pool.
[email protected]5cffc732011-01-26 03:14:27575 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:40576 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:11577 PRIVACY_MODE_DISABLED,
dalyk51ab46b2019-10-15 15:14:34578 SpdySessionKey::IsProxySession::kFalse, SocketTag(),
579 NetworkIsolationKey(), false /* disable_secure_dns */);
[email protected]41d64e82013-07-03 22:44:26580 ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key));
[email protected]5cffc732011-01-26 03:14:27581
Matt Menked6fd2a52019-03-20 06:14:36582 CommonConnectJobParams common_connect_job_params =
583 session->CreateCommonConnectJobParams();
Matt Menked23ab952019-03-06 00:24:40584 std::unique_ptr<CapturePreconnectsTransportSocketPool>
585 owned_transport_conn_pool =
586 std::make_unique<CapturePreconnectsTransportSocketPool>(
Matt Menked6fd2a52019-03-20 06:14:36587 &common_connect_job_params);
[email protected]ab739042011-04-07 15:22:28588 CapturePreconnectsTransportSocketPool* transport_conn_pool =
Matt Menked23ab952019-03-06 00:24:40589 owned_transport_conn_pool.get();
Jeremy Roman0579ed62017-08-29 15:56:19590 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:40591 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
592 std::move(owned_transport_conn_pool));
dchengc7eeda422015-12-26 03:56:48593 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]90499482013-06-01 00:39:50594 PreconnectHelper(kTests[i], session.get());
[email protected]5cffc732011-01-26 03:14:27595 // We shouldn't be preconnecting if we have an existing session, which is
596 // the case for https://www.google.com.
597 if (kTests[i].ssl)
Matt Menke9d5e2c92019-02-05 01:42:23598 EXPECT_EQ(-1, transport_conn_pool->last_num_streams());
[email protected]5cffc732011-01-26 03:14:27599 else
Xida Chen9bfe0b62018-04-24 19:52:21600 EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams());
[email protected]5cffc732011-01-26 03:14:27601 }
602}
603
[email protected]1967b09e2011-12-13 20:34:21604// Verify that preconnects to unsafe ports are cancelled before they reach
605// the SocketPool.
bnca9b9e222016-07-11 20:10:40606TEST_F(HttpStreamFactoryTest, PreconnectUnsafePort) {
mmenke2e57b39b2015-06-11 21:08:14607 ASSERT_FALSE(IsPortAllowedForScheme(7, "http"));
[email protected]1967b09e2011-12-13 20:34:21608
Lily Houghton8c2f97d2018-01-22 05:06:59609 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
danakj1fd259a02016-04-16 03:17:09610 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:26611 SpdySessionDependencies::SpdyCreateSession(&session_deps));
mmenkee65e7af2015-10-13 17:16:42612 HttpNetworkSessionPeer peer(session.get());
Matt Menked6fd2a52019-03-20 06:14:36613 CommonConnectJobParams common_connect_job_params =
614 session->CreateCommonConnectJobParams();
Matt Menked23ab952019-03-06 00:24:40615 std::unique_ptr<CapturePreconnectsTransportSocketPool>
616 owned_transport_conn_pool =
617 std::make_unique<CapturePreconnectsTransportSocketPool>(
Matt Menked6fd2a52019-03-20 06:14:36618 &common_connect_job_params);
[email protected]1967b09e2011-12-13 20:34:21619 CapturePreconnectsTransportSocketPool* transport_conn_pool =
Matt Menked23ab952019-03-06 00:24:40620 owned_transport_conn_pool.get();
Jeremy Roman0579ed62017-08-29 15:56:19621 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:40622 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
623 std::move(owned_transport_conn_pool));
dchengc7eeda422015-12-26 03:56:48624 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]1967b09e2011-12-13 20:34:21625
Matt Menke9b2c3e82019-06-21 19:16:41626 PreconnectHelperForURL(1, GURL("http://www.google.com:7"),
dalyka92863972019-10-14 20:25:58627 NetworkIsolationKey(), false /* disable_secure_dns */,
628 session.get());
[email protected]1967b09e2011-12-13 20:34:21629 EXPECT_EQ(-1, transport_conn_pool->last_num_streams());
630}
631
Matt Menke9b2c3e82019-06-21 19:16:41632// Verify that preconnects use the specified NetworkIsolationKey.
633TEST_F(HttpStreamFactoryTest, PreconnectNetworkIsolationKey) {
634 base::test::ScopedFeatureList feature_list;
635 feature_list.InitAndEnableFeature(
636 features::kPartitionConnectionsByNetworkIsolationKey);
637
638 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
639 std::unique_ptr<HttpNetworkSession> session(
640 SpdySessionDependencies::SpdyCreateSession(&session_deps));
641 HttpNetworkSessionPeer peer(session.get());
642 CommonConnectJobParams common_connect_job_params =
643 session->CreateCommonConnectJobParams();
644 std::unique_ptr<CapturePreconnectsTransportSocketPool>
645 owned_transport_conn_pool =
646 std::make_unique<CapturePreconnectsTransportSocketPool>(
647 &common_connect_job_params);
648 CapturePreconnectsTransportSocketPool* transport_conn_pool =
649 owned_transport_conn_pool.get();
650 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
651 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
652 std::move(owned_transport_conn_pool));
653 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
654
655 const GURL kURL("http://foo.test/");
Shivani Sharma8ae506c2019-07-21 21:08:27656 const auto kOriginFoo = url::Origin::Create(GURL("http://foo.test"));
657 const auto kOriginBar = url::Origin::Create(GURL("http://bar.test"));
658 const NetworkIsolationKey kKey1(kOriginFoo, kOriginFoo);
659 const NetworkIsolationKey kKey2(kOriginBar, kOriginBar);
dalyka92863972019-10-14 20:25:58660 PreconnectHelperForURL(1, kURL, kKey1, false /* disable_secure_dns */,
661 session.get());
Matt Menke9b2c3e82019-06-21 19:16:41662 EXPECT_EQ(1, transport_conn_pool->last_num_streams());
663 EXPECT_EQ(kKey1,
664 transport_conn_pool->last_group_id().network_isolation_key());
665
dalyka92863972019-10-14 20:25:58666 PreconnectHelperForURL(2, kURL, kKey2, false /* disable_secure_dns */,
667 session.get());
Matt Menke9b2c3e82019-06-21 19:16:41668 EXPECT_EQ(2, transport_conn_pool->last_num_streams());
669 EXPECT_EQ(kKey2,
670 transport_conn_pool->last_group_id().network_isolation_key());
671}
672
dalyka92863972019-10-14 20:25:58673// Verify that preconnects use the specified disable_secure_dns field.
674TEST_F(HttpStreamFactoryTest, PreconnectDisableSecureDns) {
675 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
676 std::unique_ptr<HttpNetworkSession> session(
677 SpdySessionDependencies::SpdyCreateSession(&session_deps));
678 HttpNetworkSessionPeer peer(session.get());
679 CommonConnectJobParams common_connect_job_params =
680 session->CreateCommonConnectJobParams();
681 std::unique_ptr<CapturePreconnectsTransportSocketPool>
682 owned_transport_conn_pool =
683 std::make_unique<CapturePreconnectsTransportSocketPool>(
684 &common_connect_job_params);
685 CapturePreconnectsTransportSocketPool* transport_conn_pool =
686 owned_transport_conn_pool.get();
687 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
688 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
689 std::move(owned_transport_conn_pool));
690 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
691
692 const GURL kURL("http://foo.test/");
693 const auto kOriginFoo = url::Origin::Create(GURL("http://foo.test"));
694 const auto kOriginBar = url::Origin::Create(GURL("http://bar.test"));
695 PreconnectHelperForURL(1, kURL, NetworkIsolationKey(),
696 false /* disable_secure_dns */, session.get());
697 EXPECT_EQ(1, transport_conn_pool->last_num_streams());
698 EXPECT_FALSE(transport_conn_pool->last_group_id().disable_secure_dns());
699
700 PreconnectHelperForURL(2, kURL, NetworkIsolationKey(),
701 true /* disable_secure_dns */, session.get());
702 EXPECT_EQ(2, transport_conn_pool->last_num_streams());
703 EXPECT_TRUE(transport_conn_pool->last_group_id().disable_secure_dns());
704}
705
bnca9b9e222016-07-11 20:10:40706TEST_F(HttpStreamFactoryTest, JobNotifiesProxy) {
[email protected]96e1933f2011-08-29 16:39:00707 const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT";
[email protected]41d64e82013-07-03 22:44:26708 SpdySessionDependencies session_deps(
Ramin Halavatica8d5252018-03-12 05:33:49709 ProxyResolutionService::CreateFixedFromPacResult(
710 kProxyString, TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]96e1933f2011-08-29 16:39:00711
712 // First connection attempt fails
713 StaticSocketDataProvider socket_data1;
[email protected]d973e99a2012-02-17 21:02:36714 socket_data1.set_connect_data(MockConnect(ASYNC, ERR_ADDRESS_UNREACHABLE));
[email protected]41d64e82013-07-03 22:44:26715 session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
[email protected]96e1933f2011-08-29 16:39:00716
717 // Second connection attempt succeeds
718 StaticSocketDataProvider socket_data2;
[email protected]d973e99a2012-02-17 21:02:36719 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
[email protected]41d64e82013-07-03 22:44:26720 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
[email protected]96e1933f2011-08-29 16:39:00721
danakj1fd259a02016-04-16 03:17:09722 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:26723 SpdySessionDependencies::SpdyCreateSession(&session_deps));
[email protected]96e1933f2011-08-29 16:39:00724
[email protected]3732cea2013-06-21 06:50:50725 // Now request a stream. It should succeed using the second proxy in the
[email protected]96e1933f2011-08-29 16:39:00726 // list.
727 HttpRequestInfo request_info;
728 request_info.method = "GET";
729 request_info.url = GURL("http://www.google.com");
Ramin Halavati216426e2018-03-12 22:13:35730 request_info.traffic_annotation =
731 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]96e1933f2011-08-29 16:39:00732
733 SSLConfig ssl_config;
734 StreamRequestWaiter waiter;
danakj1fd259a02016-04-16 03:17:09735 std::unique_ptr<HttpStreamRequest> request(
[email protected]262eec82013-03-19 21:01:36736 session->http_stream_factory()->RequestStream(
danakj1fd259a02016-04-16 03:17:09737 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:26738 /* enable_ip_based_pooling = */ true,
739 /* enable_alternative_services = */ true, NetLogWithSource()));
[email protected]96e1933f2011-08-29 16:39:00740 waiter.WaitForStream();
741
Lily Houghton8c2f97d2018-01-22 05:06:59742 // The proxy that failed should now be known to the proxy_resolution_service
743 // as bad.
[email protected]96e1933f2011-08-29 16:39:00744 const ProxyRetryInfoMap& retry_info =
Lily Houghton8c2f97d2018-01-22 05:06:59745 session->proxy_resolution_service()->proxy_retry_info();
[email protected]96e1933f2011-08-29 16:39:00746 EXPECT_EQ(1u, retry_info.size());
jdoerrie22a91d8b92018-10-05 08:43:26747 auto iter = retry_info.find("bad:99");
[email protected]96e1933f2011-08-29 16:39:00748 EXPECT_TRUE(iter != retry_info.end());
749}
750
Eric Romanad1fa4c62018-03-29 14:28:48751// This test requests a stream for an https:// URL using an HTTP proxy.
752// The proxy will fail to establish a tunnel via connect, and the resolved
753// proxy list includes a fallback to DIRECT.
754//
755// The expected behavior is that proxy fallback does NOT occur, even though the
756// request might work using the fallback. This is a regression test for
757// https://crbug.com/680837.
758TEST_F(HttpStreamFactoryTest, NoProxyFallbackOnTunnelFail) {
759 const char* kProxyString = "PROXY bad:99; DIRECT";
760 SpdySessionDependencies session_deps(
761 ProxyResolutionService::CreateFixedFromPacResult(
762 kProxyString, TRAFFIC_ANNOTATION_FOR_TESTS));
763
764 // A 404 in response to a CONNECT will trigger
765 // ERR_TUNNEL_CONNECTION_FAILED.
766 MockRead data_reads[] = {
767 MockRead("HTTP/1.1 404 Not Found\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
768 };
769
770 // Simulate a failure during CONNECT to bad:99.
Ryan Sleevib8d7ea02018-05-07 20:01:01771 StaticSocketDataProvider socket_data1(data_reads, base::span<MockWrite>());
Eric Romanad1fa4c62018-03-29 14:28:48772 socket_data1.set_connect_data(MockConnect(SYNCHRONOUS, OK));
773 session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
774
775 std::unique_ptr<HttpNetworkSession> session(
776 SpdySessionDependencies::SpdyCreateSession(&session_deps));
777
778 // Request a stream for an https:// URL. The exact URL doesn't matter for
779 // this test, since it mocks a failure immediately when establishing a
780 // tunnel through the proxy.
781 HttpRequestInfo request_info;
782 request_info.method = "GET";
783 request_info.url = GURL("https://www.google.com");
784 request_info.traffic_annotation =
785 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
786
787 SSLConfig ssl_config;
788 StreamRequestWaiter waiter;
789 std::unique_ptr<HttpStreamRequest> request(
790 session->http_stream_factory()->RequestStream(
791 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
792 /* enable_ip_based_pooling = */ true,
793 /* enable_alternative_services = */ true, NetLogWithSource()));
794 waiter.WaitForStream();
795
796 // The stream should have failed, since the proxy server failed to
797 // establish a tunnel.
798 ASSERT_THAT(waiter.error_status(), IsError(ERR_TUNNEL_CONNECTION_FAILED));
799
800 // The proxy should NOT have been marked as bad.
801 const ProxyRetryInfoMap& retry_info =
802 session->proxy_resolution_service()->proxy_retry_info();
803 EXPECT_EQ(0u, retry_info.size());
804}
805
tbansalc3308d72016-08-27 10:25:04806// List of errors that are used in the tests related to QUIC proxy.
807const int quic_proxy_test_mock_errors[] = {
808 ERR_PROXY_CONNECTION_FAILED,
809 ERR_NAME_NOT_RESOLVED,
tbansalc3308d72016-08-27 10:25:04810 ERR_ADDRESS_UNREACHABLE,
811 ERR_CONNECTION_CLOSED,
812 ERR_CONNECTION_TIMED_OUT,
813 ERR_CONNECTION_RESET,
814 ERR_CONNECTION_REFUSED,
815 ERR_CONNECTION_ABORTED,
816 ERR_TIMED_OUT,
tbansalc3308d72016-08-27 10:25:04817 ERR_SOCKS_CONNECTION_FAILED,
818 ERR_PROXY_CERTIFICATE_INVALID,
819 ERR_QUIC_PROTOCOL_ERROR,
820 ERR_QUIC_HANDSHAKE_FAILED,
821 ERR_SSL_PROTOCOL_ERROR,
822 ERR_MSG_TOO_BIG,
823};
824
825// Tests that a bad QUIC proxy is added to the list of bad proxies.
826TEST_F(HttpStreamFactoryTest, QuicProxyMarkedAsBad) {
Avi Drissman4365a4782018-12-28 19:26:24827 for (size_t i = 0; i < base::size(quic_proxy_test_mock_errors); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:59828 std::unique_ptr<ProxyResolutionService> proxy_resolution_service;
Ramin Halavatica8d5252018-03-12 05:33:49829 proxy_resolution_service = ProxyResolutionService::CreateFixedFromPacResult(
830 "QUIC bad:99; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal53eef7f2015-02-19 01:47:48831
mmenke6ddfbea2017-05-31 21:48:41832 HttpNetworkSession::Params session_params;
833 session_params.enable_quic = true;
834
835 HttpNetworkSession::Context session_context;
Ryan Sleevib8449e02018-07-15 04:31:07836 SSLConfigServiceDefaults ssl_config_service;
Matt Menke609160742019-08-02 18:47:26837 HttpServerProperties http_server_properties;
tbansale05fe062015-02-19 19:49:10838 MockClientSocketFactory socket_factory;
mmenke6ddfbea2017-05-31 21:48:41839 session_context.client_socket_factory = &socket_factory;
tbansale05fe062015-02-19 19:49:10840 MockHostResolver host_resolver;
mmenke6ddfbea2017-05-31 21:48:41841 session_context.host_resolver = &host_resolver;
rsleevid6de8302016-06-21 01:33:20842 MockCertVerifier cert_verifier;
mmenke6ddfbea2017-05-31 21:48:41843 session_context.cert_verifier = &cert_verifier;
tbansale05fe062015-02-19 19:49:10844 TransportSecurityState transport_security_state;
mmenke6ddfbea2017-05-31 21:48:41845 session_context.transport_security_state = &transport_security_state;
rsleevid6de8302016-06-21 01:33:20846 MultiLogCTVerifier ct_verifier;
mmenke6ddfbea2017-05-31 21:48:41847 session_context.cert_transparency_verifier = &ct_verifier;
Ryan Sleevi8a9c9c12018-05-09 02:36:23848 DefaultCTPolicyEnforcer ct_policy_enforcer;
Victor Vasiliev7752898d2019-11-14 21:30:22849 QuicContext quic_context;
mmenke6ddfbea2017-05-31 21:48:41850 session_context.ct_policy_enforcer = &ct_policy_enforcer;
Lily Houghton8c2f97d2018-01-22 05:06:59851 session_context.proxy_resolution_service = proxy_resolution_service.get();
Ryan Sleevib8449e02018-07-15 04:31:07852 session_context.ssl_config_service = &ssl_config_service;
mmenke6ddfbea2017-05-31 21:48:41853 session_context.http_server_properties = &http_server_properties;
Victor Vasiliev7752898d2019-11-14 21:30:22854 session_context.quic_context = &quic_context;
tbansal53eef7f2015-02-19 01:47:48855
mmenke6ddfbea2017-05-31 21:48:41856 auto session =
Jeremy Roman0579ed62017-08-29 15:56:19857 std::make_unique<HttpNetworkSession>(session_params, session_context);
Matt Menkeb566c392019-09-11 23:22:43858 session->quic_stream_factory()
859 ->set_is_quic_known_to_work_on_current_network(true);
tbansal53eef7f2015-02-19 01:47:48860
tbansale05fe062015-02-19 19:49:10861 StaticSocketDataProvider socket_data1;
tbansalc3308d72016-08-27 10:25:04862 socket_data1.set_connect_data(
863 MockConnect(ASYNC, quic_proxy_test_mock_errors[i]));
tbansale05fe062015-02-19 19:49:10864 socket_factory.AddSocketDataProvider(&socket_data1);
tbansal53eef7f2015-02-19 01:47:48865
tbansale05fe062015-02-19 19:49:10866 // Second connection attempt succeeds.
867 StaticSocketDataProvider socket_data2;
868 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
869 socket_factory.AddSocketDataProvider(&socket_data2);
tbansal53eef7f2015-02-19 01:47:48870
tbansale05fe062015-02-19 19:49:10871 // Now request a stream. It should succeed using the second proxy in the
872 // list.
873 HttpRequestInfo request_info;
874 request_info.method = "GET";
875 request_info.url = GURL("http://www.google.com");
Ramin Halavati216426e2018-03-12 22:13:35876 request_info.traffic_annotation =
877 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal53eef7f2015-02-19 01:47:48878
tbansale05fe062015-02-19 19:49:10879 SSLConfig ssl_config;
880 StreamRequestWaiter waiter;
danakj1fd259a02016-04-16 03:17:09881 std::unique_ptr<HttpStreamRequest> request(
tbansale05fe062015-02-19 19:49:10882 session->http_stream_factory()->RequestStream(
883 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:26884 /* enable_ip_based_pooling = */ true,
885 /* enable_alternative_services = */ true, NetLogWithSource()));
tbansale05fe062015-02-19 19:49:10886 waiter.WaitForStream();
tbansal53eef7f2015-02-19 01:47:48887
Lily Houghton8c2f97d2018-01-22 05:06:59888 // The proxy that failed should now be known to the
889 // proxy_resolution_service as bad.
tbansale05fe062015-02-19 19:49:10890 const ProxyRetryInfoMap& retry_info =
Lily Houghton8c2f97d2018-01-22 05:06:59891 session->proxy_resolution_service()->proxy_retry_info();
tbansalc3308d72016-08-27 10:25:04892 EXPECT_EQ(1u, retry_info.size()) << quic_proxy_test_mock_errors[i];
tbansala5268e22015-06-30 02:57:58893 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
tbansale05fe062015-02-19 19:49:10894
jdoerrie22a91d8b92018-10-05 08:43:26895 auto iter = retry_info.find("quic://bad:99");
tbansalc3308d72016-08-27 10:25:04896 EXPECT_TRUE(iter != retry_info.end()) << quic_proxy_test_mock_errors[i];
tbansale05fe062015-02-19 19:49:10897 }
tbansal53eef7f2015-02-19 01:47:48898}
899
xunjieli5749218c2016-03-22 16:43:06900// BidirectionalStreamImpl::Delegate to wait until response headers are
xunjieli2608f9b2016-03-14 13:39:23901// received.
xunjieli5749218c2016-03-22 16:43:06902class TestBidirectionalDelegate : public BidirectionalStreamImpl::Delegate {
xunjieli2608f9b2016-03-14 13:39:23903 public:
904 void WaitUntilDone() { loop_.Run(); }
905
Ryan Hamilton0239aac2018-05-19 00:03:13906 const spdy::SpdyHeaderBlock& response_headers() const {
907 return response_headers_;
908 }
xunjieli2608f9b2016-03-14 13:39:23909
910 private:
xunjielibcb0f86e2016-06-03 00:49:29911 void OnStreamReady(bool request_headers_sent) override {}
Ryan Hamilton0239aac2018-05-19 00:03:13912 void OnHeadersReceived(
913 const spdy::SpdyHeaderBlock& response_headers) override {
bnc94893a72016-06-30 13:45:25914 response_headers_ = response_headers.Clone();
xunjieli2608f9b2016-03-14 13:39:23915 loop_.Quit();
916 }
917 void OnDataRead(int bytes_read) override { NOTREACHED(); }
918 void OnDataSent() override { NOTREACHED(); }
Ryan Hamilton0239aac2018-05-19 00:03:13919 void OnTrailersReceived(const spdy::SpdyHeaderBlock& trailers) override {
xunjieli2608f9b2016-03-14 13:39:23920 NOTREACHED();
921 }
922 void OnFailed(int error) override { NOTREACHED(); }
923 base::RunLoop loop_;
Ryan Hamilton0239aac2018-05-19 00:03:13924 spdy::SpdyHeaderBlock response_headers_;
xunjieli2608f9b2016-03-14 13:39:23925};
926
927// Helper class to encapsulate MockReads and MockWrites for QUIC.
928// Simplify ownership issues and the interaction with the MockSocketFactory.
929class MockQuicData {
930 public:
Ryan Hamilton0d65a8c2019-06-07 00:46:02931 explicit MockQuicData(quic::ParsedQuicVersion version)
932 : packet_number_(0), printer_(version) {}
xunjieli2608f9b2016-03-14 13:39:23933
Chris Watkins7a41d3552017-12-01 02:13:27934 ~MockQuicData() = default;
xunjieli2608f9b2016-03-14 13:39:23935
Ryan Hamilton8d9ee76e2018-05-29 23:52:52936 void AddRead(std::unique_ptr<quic::QuicEncryptedPacket> packet) {
xunjieli2608f9b2016-03-14 13:39:23937 reads_.push_back(
938 MockRead(ASYNC, packet->data(), packet->length(), packet_number_++));
avifceb32f62016-10-07 16:30:52939 packets_.push_back(std::move(packet));
xunjieli2608f9b2016-03-14 13:39:23940 }
941
942 void AddRead(IoMode mode, int rv) {
943 reads_.push_back(MockRead(mode, rv, packet_number_++));
944 }
945
Ryan Hamilton8d9ee76e2018-05-29 23:52:52946 void AddWrite(std::unique_ptr<quic::QuicEncryptedPacket> packet) {
xunjieli2608f9b2016-03-14 13:39:23947 writes_.push_back(MockWrite(SYNCHRONOUS, packet->data(), packet->length(),
948 packet_number_++));
avifceb32f62016-10-07 16:30:52949 packets_.push_back(std::move(packet));
xunjieli2608f9b2016-03-14 13:39:23950 }
951
952 void AddSocketDataToFactory(MockClientSocketFactory* factory) {
Ryan Sleevib8d7ea02018-05-07 20:01:01953 socket_data_ = std::make_unique<SequencedSocketData>(reads_, writes_);
Ryan Hamilton0d65a8c2019-06-07 00:46:02954 socket_data_->set_printer(&printer_);
xunjieli2608f9b2016-03-14 13:39:23955 factory->AddSocketDataProvider(socket_data_.get());
956 }
957
958 private:
Ryan Hamilton8d9ee76e2018-05-29 23:52:52959 std::vector<std::unique_ptr<quic::QuicEncryptedPacket>> packets_;
xunjieli2608f9b2016-03-14 13:39:23960 std::vector<MockWrite> writes_;
961 std::vector<MockRead> reads_;
962 size_t packet_number_;
Ryan Hamilton0d65a8c2019-06-07 00:46:02963 QuicPacketPrinter printer_;
danakj1fd259a02016-04-16 03:17:09964 std::unique_ptr<SequencedSocketData> socket_data_;
xunjieli2608f9b2016-03-14 13:39:23965};
xunjieli2608f9b2016-03-14 13:39:23966
tbansalc3308d72016-08-27 10:25:04967void SetupForQuicAlternativeProxyTest(
mmenke6ddfbea2017-05-31 21:48:41968 HttpNetworkSession::Params* session_params,
969 HttpNetworkSession::Context* session_context,
tbansalc3308d72016-08-27 10:25:04970 MockClientSocketFactory* socket_factory,
Lily Houghton8c2f97d2018-01-22 05:06:59971 ProxyResolutionService* proxy_resolution_service,
tbansalc3308d72016-08-27 10:25:04972 TestProxyDelegate* test_proxy_delegate,
Matt Menke609160742019-08-02 18:47:26973 HttpServerProperties* http_server_properties,
tbansalc3308d72016-08-27 10:25:04974 MockCertVerifier* cert_verifier,
975 CTPolicyEnforcer* ct_policy_enforcer,
976 MultiLogCTVerifier* ct_verifier,
977 SSLConfigServiceDefaults* ssl_config_service,
978 MockHostResolver* host_resolver,
979 TransportSecurityState* transport_security_state,
Victor Vasiliev7752898d2019-11-14 21:30:22980 QuicContext* quic_context,
tbansalc3308d72016-08-27 10:25:04981 bool set_alternative_proxy_server) {
mmenke6ddfbea2017-05-31 21:48:41982 session_params->enable_quic = true;
983
984 session_context->client_socket_factory = socket_factory;
985 session_context->host_resolver = host_resolver;
986 session_context->transport_security_state = transport_security_state;
Lily Houghton8c2f97d2018-01-22 05:06:59987 session_context->proxy_resolution_service = proxy_resolution_service;
mmenke6ddfbea2017-05-31 21:48:41988 session_context->ssl_config_service = ssl_config_service;
989 session_context->http_server_properties = http_server_properties;
990 session_context->cert_verifier = cert_verifier;
991 session_context->ct_policy_enforcer = ct_policy_enforcer;
992 session_context->cert_transparency_verifier = ct_verifier;
Victor Vasiliev7752898d2019-11-14 21:30:22993 session_context->quic_context = quic_context;
tbansalc3308d72016-08-27 10:25:04994
995 if (set_alternative_proxy_server) {
996 test_proxy_delegate->set_alternative_proxy_server(
997 ProxyServer::FromPacString("QUIC badproxy:99"));
998 }
Eric Roman3d8546a2018-09-10 17:00:52999
1000 proxy_resolution_service->SetProxyDelegate(test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:041001}
1002
tbansala5268e22015-06-30 02:57:581003} // namespace
1004
tbansalc3308d72016-08-27 10:25:041005// Tests that a HTTPS proxy that supports QUIC alternative proxy server is
1006// marked as bad if connecting to both the default proxy and the alternative
1007// proxy is unsuccessful.
1008TEST_F(HttpStreamFactoryTest, WithQUICAlternativeProxyMarkedAsBad) {
1009 const bool set_alternative_proxy_server_values[] = {
1010 false, true,
1011 };
1012
1013 for (auto mock_error : quic_proxy_test_mock_errors) {
1014 for (auto set_alternative_proxy_server :
1015 set_alternative_proxy_server_values) {
mmenke6ddfbea2017-05-31 21:48:411016 HttpNetworkSession::Params session_params;
1017 HttpNetworkSession::Context session_context;
tbansalc3308d72016-08-27 10:25:041018 MockClientSocketFactory socket_factory;
Lily Houghton8c2f97d2018-01-22 05:06:591019 std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
1020 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491021 "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT",
1022 TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:041023 TestProxyDelegate test_proxy_delegate;
Matt Menke609160742019-08-02 18:47:261024 HttpServerProperties http_server_properties;
tbansalc3308d72016-08-27 10:25:041025 MockCertVerifier cert_verifier;
Ryan Sleevi8a9c9c12018-05-09 02:36:231026 DefaultCTPolicyEnforcer ct_policy_enforcer;
tbansalc3308d72016-08-27 10:25:041027 MultiLogCTVerifier ct_verifier;
Ryan Sleevib8449e02018-07-15 04:31:071028 SSLConfigServiceDefaults ssl_config_service;
tbansalc3308d72016-08-27 10:25:041029 MockHostResolver host_resolver;
1030 TransportSecurityState transport_security_state;
Victor Vasiliev7752898d2019-11-14 21:30:221031 QuicContext quic_context;
tbansalc3308d72016-08-27 10:25:041032 SetupForQuicAlternativeProxyTest(
mmenke6ddfbea2017-05-31 21:48:411033 &session_params, &session_context, &socket_factory,
Lily Houghton8c2f97d2018-01-22 05:06:591034 proxy_resolution_service.get(), &test_proxy_delegate,
1035 &http_server_properties, &cert_verifier, &ct_policy_enforcer,
Ryan Sleevib8449e02018-07-15 04:31:071036 &ct_verifier, &ssl_config_service, &host_resolver,
Victor Vasiliev7752898d2019-11-14 21:30:221037 &transport_security_state, &quic_context,
1038 set_alternative_proxy_server);
tbansalc3308d72016-08-27 10:25:041039
mmenke6ddfbea2017-05-31 21:48:411040 auto session =
Jeremy Roman0579ed62017-08-29 15:56:191041 std::make_unique<HttpNetworkSession>(session_params, session_context);
tbansalc3308d72016-08-27 10:25:041042
1043 // Before starting the test, verify that there are no proxies marked as
1044 // bad.
Xida Chen9bfe0b62018-04-24 19:52:211045 ASSERT_TRUE(
1046 session->proxy_resolution_service()->proxy_retry_info().empty())
tbansalc3308d72016-08-27 10:25:041047 << mock_error;
1048
1049 StaticSocketDataProvider socket_data_proxy_main_job;
1050 socket_data_proxy_main_job.set_connect_data(
1051 MockConnect(ASYNC, mock_error));
1052 socket_factory.AddSocketDataProvider(&socket_data_proxy_main_job);
1053
1054 StaticSocketDataProvider socket_data_proxy_alternate_job;
1055 if (set_alternative_proxy_server) {
1056 // Mock socket used by the QUIC job.
1057 socket_data_proxy_alternate_job.set_connect_data(
1058 MockConnect(ASYNC, mock_error));
1059 socket_factory.AddSocketDataProvider(&socket_data_proxy_alternate_job);
1060 }
1061
1062 // When retrying the job using the second proxy (badFallback:98),
1063 // alternative job must not be created. So, socket data for only the
1064 // main job is needed.
1065 StaticSocketDataProvider socket_data_proxy_main_job_2;
1066 socket_data_proxy_main_job_2.set_connect_data(
1067 MockConnect(ASYNC, mock_error));
1068 socket_factory.AddSocketDataProvider(&socket_data_proxy_main_job_2);
1069
xunjieli96f2a402017-06-05 17:24:271070 SSLSocketDataProvider ssl_data(ASYNC, OK);
1071
tbansalc3308d72016-08-27 10:25:041072 // First request would use DIRECT, and succeed.
1073 StaticSocketDataProvider socket_data_direct_first_request;
1074 socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK));
1075 socket_factory.AddSocketDataProvider(&socket_data_direct_first_request);
xunjieli96f2a402017-06-05 17:24:271076 socket_factory.AddSSLSocketDataProvider(&ssl_data);
tbansalc3308d72016-08-27 10:25:041077
1078 // Second request would use DIRECT, and succeed.
1079 StaticSocketDataProvider socket_data_direct_second_request;
1080 socket_data_direct_second_request.set_connect_data(
1081 MockConnect(ASYNC, OK));
1082 socket_factory.AddSocketDataProvider(&socket_data_direct_second_request);
xunjieli96f2a402017-06-05 17:24:271083 socket_factory.AddSSLSocketDataProvider(&ssl_data);
tbansalc3308d72016-08-27 10:25:041084
1085 // Now request a stream. It should succeed using the DIRECT.
1086 HttpRequestInfo request_info;
1087 request_info.method = "GET";
1088 request_info.url = GURL("http://www.google.com");
Ramin Halavati216426e2018-03-12 22:13:351089 request_info.traffic_annotation =
1090 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:041091
1092 SSLConfig ssl_config;
1093 StreamRequestWaiter waiter;
1094
1095 EXPECT_EQ(set_alternative_proxy_server,
1096 test_proxy_delegate.alternative_proxy_server().is_quic());
1097
1098 // Start two requests. The first request should consume data from
1099 // |socket_data_proxy_main_job|,
1100 // |socket_data_proxy_alternate_job| and
1101 // |socket_data_direct_first_request|. The second request should consume
1102 // data from |socket_data_direct_second_request|.
1103 for (size_t i = 0; i < 2; ++i) {
1104 std::unique_ptr<HttpStreamRequest> request(
1105 session->http_stream_factory()->RequestStream(
1106 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:261107 /* enable_ip_based_pooling = */ true,
1108 /* enable_alternative_services = */ true, NetLogWithSource()));
tbansalc3308d72016-08-27 10:25:041109 waiter.WaitForStream();
1110
tbansalc3308d72016-08-27 10:25:041111 // Verify that request was fetched without proxy.
1112 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1113
Reilly Grant89a7e512018-01-20 01:57:161114 // The proxies that failed should now be known to the proxy service as
1115 // bad.
1116 const ProxyRetryInfoMap& retry_info =
Lily Houghton8c2f97d2018-01-22 05:06:591117 session->proxy_resolution_service()->proxy_retry_info();
Reilly Grant89a7e512018-01-20 01:57:161118 EXPECT_THAT(retry_info, SizeIs(set_alternative_proxy_server ? 3 : 2));
1119 EXPECT_THAT(retry_info, Contains(Key("https://badproxy:99")));
1120 EXPECT_THAT(retry_info, Contains(Key("https://badfallbackproxy:98")));
tbansalc3308d72016-08-27 10:25:041121
Reilly Grant89a7e512018-01-20 01:57:161122 if (set_alternative_proxy_server)
1123 EXPECT_THAT(retry_info, Contains(Key("quic://badproxy:99")));
tbansalc3308d72016-08-27 10:25:041124 }
1125 }
1126 }
1127}
1128
1129// Tests that a HTTPS proxy that supports QUIC alternative proxy server is
1130// not marked as bad if only the alternative proxy server job fails.
1131TEST_F(HttpStreamFactoryTest, WithQUICAlternativeProxyNotMarkedAsBad) {
1132 for (auto mock_error : quic_proxy_test_mock_errors) {
mmenke6ddfbea2017-05-31 21:48:411133 HttpNetworkSession::Params session_params;
1134 HttpNetworkSession::Context session_context;
tbansalc3308d72016-08-27 10:25:041135 MockClientSocketFactory socket_factory;
Lily Houghton8c2f97d2018-01-22 05:06:591136 std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
1137 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491138 "HTTPS badproxy:99; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:041139 TestProxyDelegate test_proxy_delegate;
Matt Menke609160742019-08-02 18:47:261140 HttpServerProperties http_server_properties;
tbansalc3308d72016-08-27 10:25:041141 MockCertVerifier cert_verifier;
Ryan Sleevi8a9c9c12018-05-09 02:36:231142 DefaultCTPolicyEnforcer ct_policy_enforcer;
tbansalc3308d72016-08-27 10:25:041143 MultiLogCTVerifier ct_verifier;
1144
Ryan Sleevib8449e02018-07-15 04:31:071145 SSLConfigServiceDefaults ssl_config_service;
tbansalc3308d72016-08-27 10:25:041146 MockHostResolver host_resolver;
1147 TransportSecurityState transport_security_state;
Victor Vasiliev7752898d2019-11-14 21:30:221148 QuicContext quic_context;
tbansalc3308d72016-08-27 10:25:041149
1150 SetupForQuicAlternativeProxyTest(
Lily Houghton8c2f97d2018-01-22 05:06:591151 &session_params, &session_context, &socket_factory,
1152 proxy_resolution_service.get(), &test_proxy_delegate,
1153 &http_server_properties, &cert_verifier, &ct_policy_enforcer,
Ryan Sleevib8449e02018-07-15 04:31:071154 &ct_verifier, &ssl_config_service, &host_resolver,
Victor Vasiliev7752898d2019-11-14 21:30:221155 &transport_security_state, &quic_context, true);
tbansalc3308d72016-08-27 10:25:041156
1157 HostPortPair host_port_pair("badproxy", 99);
mmenke6ddfbea2017-05-31 21:48:411158 auto session =
Jeremy Roman0579ed62017-08-29 15:56:191159 std::make_unique<HttpNetworkSession>(session_params, session_context);
tbansalc3308d72016-08-27 10:25:041160
1161 // Before starting the test, verify that there are no proxies marked as
1162 // bad.
Lily Houghton8c2f97d2018-01-22 05:06:591163 ASSERT_TRUE(session->proxy_resolution_service()->proxy_retry_info().empty())
tbansalc3308d72016-08-27 10:25:041164 << mock_error;
1165
1166 StaticSocketDataProvider socket_data_proxy_main_job;
1167 socket_data_proxy_main_job.set_connect_data(MockConnect(ASYNC, mock_error));
1168 socket_factory.AddSocketDataProvider(&socket_data_proxy_main_job);
1169
1170 SSLSocketDataProvider ssl_data(ASYNC, OK);
1171
1172 // Next connection attempt would use HTTPS proxy, and succeed.
1173 StaticSocketDataProvider socket_data_https_first;
1174 socket_data_https_first.set_connect_data(MockConnect(ASYNC, OK));
1175 socket_factory.AddSocketDataProvider(&socket_data_https_first);
1176 socket_factory.AddSSLSocketDataProvider(&ssl_data);
1177
1178 // Next connection attempt would use HTTPS proxy, and succeed.
1179 StaticSocketDataProvider socket_data_https_second;
1180 socket_data_https_second.set_connect_data(MockConnect(ASYNC, OK));
1181 socket_factory.AddSocketDataProvider(&socket_data_https_second);
1182 socket_factory.AddSSLSocketDataProvider(&ssl_data);
1183
1184 // Now request a stream. It should succeed using the second proxy in the
1185 // list.
1186 HttpRequestInfo request_info;
1187 request_info.method = "GET";
1188 request_info.url = GURL("http://www.google.com");
Ramin Halavati216426e2018-03-12 22:13:351189 request_info.traffic_annotation =
1190 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:041191
1192 SSLConfig ssl_config;
1193 StreamRequestWaiter waiter;
1194
Xida Chen9bfe0b62018-04-24 19:52:211195 EXPECT_THAT(session->proxy_resolution_service()->proxy_retry_info(),
1196 IsEmpty());
tbansalc3308d72016-08-27 10:25:041197 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
1198
1199 // Start two requests. The first request should consume data from
1200 // |socket_data_proxy_main_job| and |socket_data_https_first|.
1201 // The second request should consume data from |socket_data_https_second|.
1202 for (size_t i = 0; i < 2; ++i) {
1203 std::unique_ptr<HttpStreamRequest> request(
1204 session->http_stream_factory()->RequestStream(
1205 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:261206 /* enable_ip_based_pooling = */ true,
1207 /* enable_alternative_services = */ true, NetLogWithSource()));
tbansalc3308d72016-08-27 10:25:041208 waiter.WaitForStream();
1209
tbansalc3308d72016-08-27 10:25:041210 // Verify that request was fetched using proxy.
1211 EXPECT_TRUE(waiter.used_proxy_info().is_https());
1212 EXPECT_TRUE(host_port_pair.Equals(
1213 waiter.used_proxy_info().proxy_server().host_port_pair()));
tbansalc3308d72016-08-27 10:25:041214
Reilly Grant89a7e512018-01-20 01:57:161215 // Alternative proxy server should be marked as bad so that it is not
1216 // used for subsequent requests.
Lily Houghton8c2f97d2018-01-22 05:06:591217 EXPECT_THAT(session->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:161218 ElementsAre(Key("quic://badproxy:99")));
tbansalc3308d72016-08-27 10:25:041219 }
1220 }
1221}
1222
bnca9b9e222016-07-11 20:10:401223TEST_F(HttpStreamFactoryTest, UsePreConnectIfNoZeroRTT) {
rtennetid2e74caa2015-12-09 00:51:571224 for (int num_streams = 1; num_streams < 3; ++num_streams) {
1225 GURL url = GURL("https://www.google.com");
1226
Ramin Halavatica8d5252018-03-12 05:33:491227 SpdySessionDependencies session_deps(ProxyResolutionService::CreateFixed(
1228 "http_proxy", TRAFFIC_ANNOTATION_FOR_TESTS));
rtennetid2e74caa2015-12-09 00:51:571229
1230 // Setup params to disable preconnect, but QUIC doesn't 0RTT.
mmenke6ddfbea2017-05-31 21:48:411231 HttpNetworkSession::Params session_params =
rtennetid2e74caa2015-12-09 00:51:571232 SpdySessionDependencies::CreateSessionParams(&session_deps);
mmenke6ddfbea2017-05-31 21:48:411233 session_params.enable_quic = true;
rtennetid2e74caa2015-12-09 00:51:571234
zhongyie537a002017-06-27 16:48:211235 // Set up QUIC as alternative_service.
Matt Menke609160742019-08-02 18:47:261236 HttpServerProperties http_server_properties;
zhongyie537a002017-06-27 16:48:211237 const AlternativeService alternative_service(kProtoQUIC, url.host().c_str(),
1238 url.IntPort());
1239 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1240 HostPortPair host_port_pair(alternative_service.host_port_pair());
1241 url::SchemeHostPort server("https", host_port_pair.host(),
1242 host_port_pair.port());
1243 http_server_properties.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071244 server, NetworkIsolationKey(), alternative_service, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:381245 DefaultSupportedQuicVersions());
zhongyie537a002017-06-27 16:48:211246
mmenke6ddfbea2017-05-31 21:48:411247 HttpNetworkSession::Context session_context =
1248 SpdySessionDependencies::CreateSessionContext(&session_deps);
1249 session_context.http_server_properties = &http_server_properties;
1250
1251 auto session =
Jeremy Roman0579ed62017-08-29 15:56:191252 std::make_unique<HttpNetworkSession>(session_params, session_context);
rtennetid2e74caa2015-12-09 00:51:571253 HttpNetworkSessionPeer peer(session.get());
Matt Menkee8648fa2019-01-17 16:47:071254 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
1255 HostPortPair("http_proxy", 80));
Matt Menked6fd2a52019-03-20 06:14:361256 CommonConnectJobParams common_connect_job_params =
1257 session->CreateCommonConnectJobParams();
Matt Menke0754b5d02019-02-10 21:46:431258 CapturePreconnectsTransportSocketPool* http_proxy_pool =
Matt Menked6fd2a52019-03-20 06:14:361259 new CapturePreconnectsTransportSocketPool(&common_connect_job_params);
Jeremy Roman0579ed62017-08-29 15:56:191260 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:401261 mock_pool_manager->SetSocketPool(proxy_server,
1262 base::WrapUnique(http_proxy_pool));
dchengc7eeda422015-12-26 03:56:481263 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
Matt Menke9b2c3e82019-06-21 19:16:411264 PreconnectHelperForURL(num_streams, url, NetworkIsolationKey(),
dalyka92863972019-10-14 20:25:581265 false /* disable_secure_dns */, session.get());
Matt Menkeaade5812019-03-02 13:38:001266 EXPECT_EQ(num_streams, http_proxy_pool->last_num_streams());
rtennetid2e74caa2015-12-09 00:51:571267 }
1268}
1269
tbansala5268e22015-06-30 02:57:581270namespace {
1271
[email protected]e6d017652013-05-17 18:01:401272// Return count of distinct groups in given socket pool.
1273int GetSocketPoolGroupCount(ClientSocketPool* pool) {
1274 int count = 0;
David Benjamin0c58df52019-08-06 16:59:111275 base::Value dict = pool->GetInfoAsValue("", "");
1276 EXPECT_TRUE(dict.is_dict());
1277 const base::Value* groups = dict.FindDictKey("groups");
1278 if (groups) {
1279 count = groups->DictSize();
[email protected]e6d017652013-05-17 18:01:401280 }
1281 return count;
1282}
mmenkebd84c392015-09-02 14:12:341283
1284// Return count of distinct spdy sessions.
1285int GetSpdySessionCount(HttpNetworkSession* session) {
danakj1fd259a02016-04-16 03:17:091286 std::unique_ptr<base::Value> value(
mmenkebd84c392015-09-02 14:12:341287 session->spdy_session_pool()->SpdySessionPoolInfoToValue());
1288 base::ListValue* session_list;
1289 if (!value || !value->GetAsList(&session_list))
1290 return -1;
1291 return session_list->GetSize();
1292}
1293
Paul Jensena457017a2018-01-19 23:52:041294// Return count of sockets handed out by a given socket pool.
1295int GetHandedOutSocketCount(ClientSocketPool* pool) {
David Benjamin0c58df52019-08-06 16:59:111296 base::Value dict = pool->GetInfoAsValue("", "");
1297 EXPECT_TRUE(dict.is_dict());
1298 return dict.FindIntKey("handed_out_socket_count").value_or(-1);
Paul Jensena457017a2018-01-19 23:52:041299}
Paul Jensen8e3c5d32018-02-19 17:06:331300
Paul Jensen6afc0b42018-02-28 01:14:561301#if defined(OS_ANDROID)
Paul Jensen8e3c5d32018-02-19 17:06:331302// Return count of distinct QUIC sessions.
1303int GetQuicSessionCount(HttpNetworkSession* session) {
1304 std::unique_ptr<base::DictionaryValue> dict(
1305 base::DictionaryValue::From(session->QuicInfoToValue()));
1306 base::ListValue* session_list;
1307 if (!dict->GetList("sessions", &session_list))
1308 return -1;
1309 return session_list->GetSize();
1310}
Paul Jensena457017a2018-01-19 23:52:041311#endif
1312
bnca9b9e222016-07-11 20:10:401313TEST_F(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) {
Lily Houghton8c2f97d2018-01-22 05:06:591314 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
[email protected]e6d017652013-05-17 18:01:401315
rsleevid6de8302016-06-21 01:33:201316 StaticSocketDataProvider socket_data_1;
1317 socket_data_1.set_connect_data(MockConnect(ASYNC, OK));
1318 session_deps.socket_factory->AddSocketDataProvider(&socket_data_1);
1319 StaticSocketDataProvider socket_data_2;
1320 socket_data_2.set_connect_data(MockConnect(ASYNC, OK));
1321 session_deps.socket_factory->AddSocketDataProvider(&socket_data_2);
1322 StaticSocketDataProvider socket_data_3;
1323 socket_data_3.set_connect_data(MockConnect(ASYNC, OK));
1324 session_deps.socket_factory->AddSocketDataProvider(&socket_data_3);
[email protected]e6d017652013-05-17 18:01:401325
rsleevid6de8302016-06-21 01:33:201326 SSLSocketDataProvider ssl_1(ASYNC, OK);
1327 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_1);
1328 SSLSocketDataProvider ssl_2(ASYNC, OK);
1329 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_2);
1330 SSLSocketDataProvider ssl_3(ASYNC, OK);
1331 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_3);
[email protected]e6d017652013-05-17 18:01:401332
danakj1fd259a02016-04-16 03:17:091333 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:261334 SpdySessionDependencies::SpdyCreateSession(&session_deps));
Matt Menke12d33db92019-03-26 22:45:441335 ClientSocketPool* ssl_pool = session->GetSocketPool(
Matt Menked23ab952019-03-06 00:24:401336 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct());
[email protected]e6d017652013-05-17 18:01:401337
1338 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0);
1339
1340 HttpRequestInfo request_info;
1341 request_info.method = "GET";
1342 request_info.url = GURL("https://www.google.com");
1343 request_info.load_flags = 0;
[email protected]314b03992014-04-01 01:28:531344 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
Ramin Halavati216426e2018-03-12 22:13:351345 request_info.traffic_annotation =
1346 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]e6d017652013-05-17 18:01:401347
1348 SSLConfig ssl_config;
1349 StreamRequestWaiter waiter;
1350
danakj1fd259a02016-04-16 03:17:091351 std::unique_ptr<HttpStreamRequest> request1(
[email protected]e6d017652013-05-17 18:01:401352 session->http_stream_factory()->RequestStream(
danakj1fd259a02016-04-16 03:17:091353 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:261354 /* enable_ip_based_pooling = */ true,
1355 /* enable_alternative_services = */ true, NetLogWithSource()));
[email protected]e6d017652013-05-17 18:01:401356 waiter.WaitForStream();
1357
1358 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
1359
danakj1fd259a02016-04-16 03:17:091360 std::unique_ptr<HttpStreamRequest> request2(
[email protected]e6d017652013-05-17 18:01:401361 session->http_stream_factory()->RequestStream(
danakj1fd259a02016-04-16 03:17:091362 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:261363 /* enable_ip_based_pooling = */ true,
1364 /* enable_alternative_services = */ true, NetLogWithSource()));
[email protected]e6d017652013-05-17 18:01:401365 waiter.WaitForStream();
1366
1367 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
1368
[email protected]314b03992014-04-01 01:28:531369 request_info.privacy_mode = PRIVACY_MODE_ENABLED;
danakj1fd259a02016-04-16 03:17:091370 std::unique_ptr<HttpStreamRequest> request3(
[email protected]e6d017652013-05-17 18:01:401371 session->http_stream_factory()->RequestStream(
danakj1fd259a02016-04-16 03:17:091372 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:261373 /* enable_ip_based_pooling = */ true,
1374 /* enable_alternative_services = */ true, NetLogWithSource()));
[email protected]e6d017652013-05-17 18:01:401375 waiter.WaitForStream();
1376
1377 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2);
1378}
1379
dalyka92863972019-10-14 20:25:581380TEST_F(HttpStreamFactoryTest, DisableSecureDnsUsesDifferentSocketPoolGroup) {
1381 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
1382
1383 StaticSocketDataProvider socket_data_1;
1384 socket_data_1.set_connect_data(MockConnect(ASYNC, OK));
1385 session_deps.socket_factory->AddSocketDataProvider(&socket_data_1);
1386 StaticSocketDataProvider socket_data_2;
1387 socket_data_2.set_connect_data(MockConnect(ASYNC, OK));
1388 session_deps.socket_factory->AddSocketDataProvider(&socket_data_2);
1389 StaticSocketDataProvider socket_data_3;
1390 socket_data_3.set_connect_data(MockConnect(ASYNC, OK));
1391 session_deps.socket_factory->AddSocketDataProvider(&socket_data_3);
1392
1393 SSLSocketDataProvider ssl_1(ASYNC, OK);
1394 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_1);
1395 SSLSocketDataProvider ssl_2(ASYNC, OK);
1396 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_2);
1397 SSLSocketDataProvider ssl_3(ASYNC, OK);
1398 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_3);
1399
1400 std::unique_ptr<HttpNetworkSession> session(
1401 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1402 ClientSocketPool* ssl_pool = session->GetSocketPool(
1403 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct());
1404
1405 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0);
1406
1407 HttpRequestInfo request_info;
1408 request_info.method = "GET";
1409 request_info.url = GURL("https://www.google.com");
1410 request_info.load_flags = 0;
1411 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
1412 request_info.traffic_annotation =
1413 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1414 request_info.disable_secure_dns = false;
1415
1416 SSLConfig ssl_config;
1417 StreamRequestWaiter waiter;
1418
1419 std::unique_ptr<HttpStreamRequest> request1(
1420 session->http_stream_factory()->RequestStream(
1421 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
1422 /* enable_ip_based_pooling = */ true,
1423 /* enable_alternative_services = */ true, NetLogWithSource()));
1424 waiter.WaitForStream();
1425
1426 EXPECT_FALSE(
1427 session_deps.host_resolver->last_secure_dns_mode_override().has_value());
1428 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
1429
1430 std::unique_ptr<HttpStreamRequest> request2(
1431 session->http_stream_factory()->RequestStream(
1432 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
1433 /* enable_ip_based_pooling = */ true,
1434 /* enable_alternative_services = */ true, NetLogWithSource()));
1435 waiter.WaitForStream();
1436
1437 EXPECT_FALSE(
1438 session_deps.host_resolver->last_secure_dns_mode_override().has_value());
1439 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
1440
1441 request_info.disable_secure_dns = true;
1442 std::unique_ptr<HttpStreamRequest> request3(
1443 session->http_stream_factory()->RequestStream(
1444 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
1445 /* enable_ip_based_pooling = */ true,
1446 /* enable_alternative_services = */ true, NetLogWithSource()));
1447 waiter.WaitForStream();
1448
1449 EXPECT_EQ(
1450 net::DnsConfig::SecureDnsMode::OFF,
1451 session_deps.host_resolver->last_secure_dns_mode_override().value());
1452 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2);
1453}
1454
bnca9b9e222016-07-11 20:10:401455TEST_F(HttpStreamFactoryTest, GetLoadState) {
Lily Houghton8c2f97d2018-01-22 05:06:591456 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
[email protected]1646c9e12013-05-18 09:30:051457
1458 StaticSocketDataProvider socket_data;
1459 socket_data.set_connect_data(MockConnect(ASYNC, OK));
[email protected]41d64e82013-07-03 22:44:261460 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
[email protected]1646c9e12013-05-18 09:30:051461
danakj1fd259a02016-04-16 03:17:091462 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:261463 SpdySessionDependencies::SpdyCreateSession(&session_deps));
[email protected]1646c9e12013-05-18 09:30:051464
1465 HttpRequestInfo request_info;
1466 request_info.method = "GET";
1467 request_info.url = GURL("http://www.google.com");
Ramin Halavati216426e2018-03-12 22:13:351468 request_info.traffic_annotation =
1469 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1646c9e12013-05-18 09:30:051470
1471 SSLConfig ssl_config;
1472 StreamRequestWaiter waiter;
danakj1fd259a02016-04-16 03:17:091473 std::unique_ptr<HttpStreamRequest> request(
[email protected]1646c9e12013-05-18 09:30:051474 session->http_stream_factory()->RequestStream(
danakj1fd259a02016-04-16 03:17:091475 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:261476 /* enable_ip_based_pooling = */ true,
1477 /* enable_alternative_services = */ true, NetLogWithSource()));
[email protected]1646c9e12013-05-18 09:30:051478
1479 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState());
1480
1481 waiter.WaitForStream();
1482}
1483
bnca9b9e222016-07-11 20:10:401484TEST_F(HttpStreamFactoryTest, RequestHttpStream) {
Lily Houghton8c2f97d2018-01-22 05:06:591485 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
[email protected]3732cea2013-06-21 06:50:501486
1487 StaticSocketDataProvider socket_data;
1488 socket_data.set_connect_data(MockConnect(ASYNC, OK));
[email protected]41d64e82013-07-03 22:44:261489 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
[email protected]3732cea2013-06-21 06:50:501490
danakj1fd259a02016-04-16 03:17:091491 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:261492 SpdySessionDependencies::SpdyCreateSession(&session_deps));
[email protected]3732cea2013-06-21 06:50:501493
1494 // Now request a stream. It should succeed using the second proxy in the
1495 // list.
1496 HttpRequestInfo request_info;
1497 request_info.method = "GET";
1498 request_info.url = GURL("http://www.google.com");
1499 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:351500 request_info.traffic_annotation =
1501 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3732cea2013-06-21 06:50:501502
1503 SSLConfig ssl_config;
1504 StreamRequestWaiter waiter;
danakj1fd259a02016-04-16 03:17:091505 std::unique_ptr<HttpStreamRequest> request(
[email protected]3732cea2013-06-21 06:50:501506 session->http_stream_factory()->RequestStream(
danakj1fd259a02016-04-16 03:17:091507 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:261508 /* enable_ip_based_pooling = */ true,
1509 /* enable_alternative_services = */ true, NetLogWithSource()));
[email protected]3732cea2013-06-21 06:50:501510 waiter.WaitForStream();
1511 EXPECT_TRUE(waiter.stream_done());
yhiranoa7e05bb2014-11-06 05:40:391512 ASSERT_TRUE(nullptr != waiter.stream());
1513 EXPECT_TRUE(nullptr == waiter.websocket_stream());
[email protected]3732cea2013-06-21 06:50:501514
mmenkebd84c392015-09-02 14:12:341515 EXPECT_EQ(0, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:401516 EXPECT_EQ(
1517 1, GetSocketPoolGroupCount(session->GetSocketPool(
1518 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
[email protected]3732cea2013-06-21 06:50:501519 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1520}
1521
Xida Chen9bfe0b62018-04-24 19:52:211522// Test the race of SetPriority versus stream completion where SetPriority may
1523// be called on an HttpStreamFactory::Job after the stream has been created by
1524// the job.
rdsmith29dbad12017-02-17 02:22:181525TEST_F(HttpStreamFactoryTest, ReprioritizeAfterStreamReceived) {
Lily Houghton8c2f97d2018-01-22 05:06:591526 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
Bence Békybcae37092018-06-12 04:18:531527 session_deps.host_resolver->set_synchronous_mode(true);
rdsmith29dbad12017-02-17 02:22:181528
1529 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:011530 StaticSocketDataProvider socket_data(base::make_span(&mock_read, 1),
1531 base::span<MockWrite>());
rdsmith29dbad12017-02-17 02:22:181532 socket_data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1533 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1534
1535 SSLSocketDataProvider ssl_socket_data(SYNCHRONOUS, OK);
1536 ssl_socket_data.next_proto = kProtoHTTP2;
1537 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1538
1539 std::unique_ptr<HttpNetworkSession> session(
1540 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1541
1542 // Now request a stream.
1543 HttpRequestInfo request_info;
1544 request_info.method = "GET";
1545 request_info.url = GURL("https://www.google.com");
1546 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:351547 request_info.traffic_annotation =
1548 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith29dbad12017-02-17 02:22:181549
1550 SSLConfig ssl_config;
1551 StreamRequestWaiter waiter;
1552 EXPECT_EQ(0, GetSpdySessionCount(session.get()));
1553 std::unique_ptr<HttpStreamRequest> request(
1554 session->http_stream_factory()->RequestStream(
1555 request_info, LOWEST, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:261556 /* enable_ip_based_pooling = */ true,
1557 /* enable_alternative_services = */ true, NetLogWithSource()));
rdsmith29dbad12017-02-17 02:22:181558 EXPECT_FALSE(waiter.stream_done());
1559
1560 // Confirm a stream has been created by asserting that a new session
1561 // has been created. (The stream is only created at the SPDY level on
1562 // first write, which happens after the request has returned a stream).
1563 ASSERT_EQ(1, GetSpdySessionCount(session.get()));
1564
1565 // Test to confirm that a SetPriority received after the stream is created
1566 // but before the request returns it does not crash.
1567 request->SetPriority(HIGHEST);
1568
1569 waiter.WaitForStream();
1570 EXPECT_TRUE(waiter.stream_done());
1571 ASSERT_TRUE(waiter.stream());
1572 EXPECT_FALSE(waiter.websocket_stream());
1573}
1574
bnca9b9e222016-07-11 20:10:401575TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
Lily Houghton8c2f97d2018-01-22 05:06:591576 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
[email protected]3732cea2013-06-21 06:50:501577
1578 MockRead mock_read(ASYNC, OK);
Ryan Sleevib8d7ea02018-05-07 20:01:011579 StaticSocketDataProvider socket_data(base::make_span(&mock_read, 1),
1580 base::span<MockWrite>());
[email protected]3732cea2013-06-21 06:50:501581 socket_data.set_connect_data(MockConnect(ASYNC, OK));
[email protected]41d64e82013-07-03 22:44:261582 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
[email protected]3732cea2013-06-21 06:50:501583
1584 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
[email protected]41d64e82013-07-03 22:44:261585 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
[email protected]3732cea2013-06-21 06:50:501586
danakj1fd259a02016-04-16 03:17:091587 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:261588 SpdySessionDependencies::SpdyCreateSession(&session_deps));
[email protected]3732cea2013-06-21 06:50:501589
1590 // Now request a stream.
1591 HttpRequestInfo request_info;
1592 request_info.method = "GET";
1593 request_info.url = GURL("https://www.google.com");
1594 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:351595 request_info.traffic_annotation =
1596 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3732cea2013-06-21 06:50:501597
1598 SSLConfig ssl_config;
1599 StreamRequestWaiter waiter;
danakj1fd259a02016-04-16 03:17:091600 std::unique_ptr<HttpStreamRequest> request(
[email protected]3732cea2013-06-21 06:50:501601 session->http_stream_factory()->RequestStream(
danakj1fd259a02016-04-16 03:17:091602 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:261603 /* enable_ip_based_pooling = */ true,
1604 /* enable_alternative_services = */ true, NetLogWithSource()));
[email protected]3732cea2013-06-21 06:50:501605 waiter.WaitForStream();
1606 EXPECT_TRUE(waiter.stream_done());
yhiranoa7e05bb2014-11-06 05:40:391607 ASSERT_TRUE(nullptr != waiter.stream());
1608 EXPECT_TRUE(nullptr == waiter.websocket_stream());
mmenkebd84c392015-09-02 14:12:341609
1610 EXPECT_EQ(0, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:401611 EXPECT_EQ(
1612 1, GetSocketPoolGroupCount(session->GetSocketPool(
1613 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
[email protected]3732cea2013-06-21 06:50:501614 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1615}
1616
bnca9b9e222016-07-11 20:10:401617TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
Ramin Halavatica8d5252018-03-12 05:33:491618 SpdySessionDependencies session_deps(ProxyResolutionService::CreateFixed(
1619 "myproxy:8888", TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]3732cea2013-06-21 06:50:501620
1621 StaticSocketDataProvider socket_data;
1622 socket_data.set_connect_data(MockConnect(ASYNC, OK));
[email protected]41d64e82013-07-03 22:44:261623 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
[email protected]3732cea2013-06-21 06:50:501624
danakj1fd259a02016-04-16 03:17:091625 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:261626 SpdySessionDependencies::SpdyCreateSession(&session_deps));
[email protected]3732cea2013-06-21 06:50:501627
1628 // Now request a stream. It should succeed using the second proxy in the
1629 // list.
1630 HttpRequestInfo request_info;
1631 request_info.method = "GET";
1632 request_info.url = GURL("http://www.google.com");
1633 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:351634 request_info.traffic_annotation =
1635 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3732cea2013-06-21 06:50:501636
1637 SSLConfig ssl_config;
1638 StreamRequestWaiter waiter;
danakj1fd259a02016-04-16 03:17:091639 std::unique_ptr<HttpStreamRequest> request(
[email protected]3732cea2013-06-21 06:50:501640 session->http_stream_factory()->RequestStream(
danakj1fd259a02016-04-16 03:17:091641 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:261642 /* enable_ip_based_pooling = */ true,
1643 /* enable_alternative_services = */ true, NetLogWithSource()));
[email protected]3732cea2013-06-21 06:50:501644 waiter.WaitForStream();
1645 EXPECT_TRUE(waiter.stream_done());
yhiranoa7e05bb2014-11-06 05:40:391646 ASSERT_TRUE(nullptr != waiter.stream());
1647 EXPECT_TRUE(nullptr == waiter.websocket_stream());
mmenkebd84c392015-09-02 14:12:341648
1649 EXPECT_EQ(0, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:401650 EXPECT_EQ(
1651 0, GetSocketPoolGroupCount(session->GetSocketPool(
1652 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
1653 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPool(
Xida Chen9bfe0b62018-04-24 19:52:211654 HttpNetworkSession::NORMAL_SOCKET_POOL,
Matt Menkee8648fa2019-01-17 16:47:071655 ProxyServer(ProxyServer::SCHEME_HTTP,
1656 HostPortPair("myproxy", 8888)))));
Matt Menked23ab952019-03-06 00:24:401657 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:071658 HttpNetworkSession::NORMAL_SOCKET_POOL,
1659 ProxyServer(ProxyServer::SCHEME_HTTPS,
1660 HostPortPair("myproxy", 8888)))));
Matt Menked23ab952019-03-06 00:24:401661 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPool(
Xida Chen9bfe0b62018-04-24 19:52:211662 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
Matt Menkee8648fa2019-01-17 16:47:071663 ProxyServer(ProxyServer::SCHEME_HTTP,
1664 HostPortPair("myproxy", 8888)))));
[email protected]3732cea2013-06-21 06:50:501665 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1666}
1667
bnca9b9e222016-07-11 20:10:401668TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
Lily Houghton8c2f97d2018-01-22 05:06:591669 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
[email protected]3732cea2013-06-21 06:50:501670
1671 StaticSocketDataProvider socket_data;
1672 socket_data.set_connect_data(MockConnect(ASYNC, OK));
[email protected]41d64e82013-07-03 22:44:261673 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
[email protected]3732cea2013-06-21 06:50:501674
danakj1fd259a02016-04-16 03:17:091675 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:261676 SpdySessionDependencies::SpdyCreateSession(&session_deps));
[email protected]3732cea2013-06-21 06:50:501677
1678 // Now request a stream.
1679 HttpRequestInfo request_info;
1680 request_info.method = "GET";
1681 request_info.url = GURL("ws://www.google.com");
1682 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:351683 request_info.traffic_annotation =
1684 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3732cea2013-06-21 06:50:501685
1686 SSLConfig ssl_config;
1687 StreamRequestWaiter waiter;
[email protected]467086b2013-11-12 08:19:461688 WebSocketStreamCreateHelper create_helper;
danakj1fd259a02016-04-16 03:17:091689 std::unique_ptr<HttpStreamRequest> request(
Bence Béky8cae04e2018-01-15 18:37:061690 session->http_stream_factory()->RequestWebSocketHandshakeStream(
1691 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
1692 &create_helper,
1693 /* enable_ip_based_pooling = */ true,
1694 /* enable_alternative_services = */ true, NetLogWithSource()));
[email protected]3732cea2013-06-21 06:50:501695 waiter.WaitForStream();
1696 EXPECT_TRUE(waiter.stream_done());
yhiranoa7e05bb2014-11-06 05:40:391697 EXPECT_TRUE(nullptr == waiter.stream());
1698 ASSERT_TRUE(nullptr != waiter.websocket_stream());
[email protected]693ebf32013-10-23 13:47:011699 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
[email protected]3732cea2013-06-21 06:50:501700 waiter.websocket_stream()->type());
Matt Menked23ab952019-03-06 00:24:401701 EXPECT_EQ(
1702 0, GetSocketPoolGroupCount(session->GetSocketPool(
1703 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
[email protected]3732cea2013-06-21 06:50:501704 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1705}
1706
bnca9b9e222016-07-11 20:10:401707TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
Lily Houghton8c2f97d2018-01-22 05:06:591708 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
[email protected]3732cea2013-06-21 06:50:501709
1710 MockRead mock_read(ASYNC, OK);
Ryan Sleevib8d7ea02018-05-07 20:01:011711 StaticSocketDataProvider socket_data(base::make_span(&mock_read, 1),
1712 base::span<MockWrite>());
[email protected]3732cea2013-06-21 06:50:501713 socket_data.set_connect_data(MockConnect(ASYNC, OK));
[email protected]41d64e82013-07-03 22:44:261714 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
[email protected]3732cea2013-06-21 06:50:501715
1716 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
[email protected]41d64e82013-07-03 22:44:261717 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
[email protected]3732cea2013-06-21 06:50:501718
danakj1fd259a02016-04-16 03:17:091719 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:261720 SpdySessionDependencies::SpdyCreateSession(&session_deps));
[email protected]3732cea2013-06-21 06:50:501721
1722 // Now request a stream.
1723 HttpRequestInfo request_info;
1724 request_info.method = "GET";
1725 request_info.url = GURL("wss://www.google.com");
1726 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:351727 request_info.traffic_annotation =
1728 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3732cea2013-06-21 06:50:501729
1730 SSLConfig ssl_config;
1731 StreamRequestWaiter waiter;
[email protected]467086b2013-11-12 08:19:461732 WebSocketStreamCreateHelper create_helper;
danakj1fd259a02016-04-16 03:17:091733 std::unique_ptr<HttpStreamRequest> request(
Bence Béky8cae04e2018-01-15 18:37:061734 session->http_stream_factory()->RequestWebSocketHandshakeStream(
1735 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
1736 &create_helper,
1737 /* enable_ip_based_pooling = */ true,
1738 /* enable_alternative_services = */ true, NetLogWithSource()));
[email protected]3732cea2013-06-21 06:50:501739 waiter.WaitForStream();
1740 EXPECT_TRUE(waiter.stream_done());
yhiranoa7e05bb2014-11-06 05:40:391741 EXPECT_TRUE(nullptr == waiter.stream());
1742 ASSERT_TRUE(nullptr != waiter.websocket_stream());
[email protected]693ebf32013-10-23 13:47:011743 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
[email protected]3732cea2013-06-21 06:50:501744 waiter.websocket_stream()->type());
Matt Menked23ab952019-03-06 00:24:401745 EXPECT_EQ(
1746 0, GetSocketPoolGroupCount(session->GetSocketPool(
1747 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
[email protected]3732cea2013-06-21 06:50:501748 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1749}
1750
bnca9b9e222016-07-11 20:10:401751TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
Ramin Halavatica8d5252018-03-12 05:33:491752 SpdySessionDependencies session_deps(ProxyResolutionService::CreateFixed(
1753 "myproxy:8888", TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]3732cea2013-06-21 06:50:501754
Ryan Sleevib8d7ea02018-05-07 20:01:011755 MockRead reads[] = {
1756 MockRead(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n")};
1757 StaticSocketDataProvider socket_data(reads, base::span<MockWrite>());
[email protected]3732cea2013-06-21 06:50:501758 socket_data.set_connect_data(MockConnect(ASYNC, OK));
[email protected]41d64e82013-07-03 22:44:261759 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
[email protected]3732cea2013-06-21 06:50:501760
danakj1fd259a02016-04-16 03:17:091761 std::unique_ptr<HttpNetworkSession> session(
[email protected]41d64e82013-07-03 22:44:261762 SpdySessionDependencies::SpdyCreateSession(&session_deps));
[email protected]3732cea2013-06-21 06:50:501763
1764 // Now request a stream.
1765 HttpRequestInfo request_info;
1766 request_info.method = "GET";
1767 request_info.url = GURL("ws://www.google.com");
1768 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:351769 request_info.traffic_annotation =
1770 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3732cea2013-06-21 06:50:501771
1772 SSLConfig ssl_config;
1773 StreamRequestWaiter waiter;
[email protected]467086b2013-11-12 08:19:461774 WebSocketStreamCreateHelper create_helper;
danakj1fd259a02016-04-16 03:17:091775 std::unique_ptr<HttpStreamRequest> request(
Bence Béky8cae04e2018-01-15 18:37:061776 session->http_stream_factory()->RequestWebSocketHandshakeStream(
1777 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
1778 &create_helper,
1779 /* enable_ip_based_pooling = */ true,
1780 /* enable_alternative_services = */ true, NetLogWithSource()));
[email protected]3732cea2013-06-21 06:50:501781 waiter.WaitForStream();
1782 EXPECT_TRUE(waiter.stream_done());
yhiranoa7e05bb2014-11-06 05:40:391783 EXPECT_TRUE(nullptr == waiter.stream());
1784 ASSERT_TRUE(nullptr != waiter.websocket_stream());
[email protected]693ebf32013-10-23 13:47:011785 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
[email protected]3732cea2013-06-21 06:50:501786 waiter.websocket_stream()->type());
Matt Menked23ab952019-03-06 00:24:401787 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPool(
1788 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1789 ProxyServer::Direct())));
1790 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPool(
Xida Chen9bfe0b62018-04-24 19:52:211791 HttpNetworkSession::NORMAL_SOCKET_POOL,
Matt Menkee8648fa2019-01-17 16:47:071792 ProxyServer(ProxyServer::SCHEME_HTTP,
1793 HostPortPair("myproxy", 8888)))));
Matt Menked23ab952019-03-06 00:24:401794 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPool(
Xida Chen9bfe0b62018-04-24 19:52:211795 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
Matt Menkee8648fa2019-01-17 16:47:071796 ProxyServer(ProxyServer::SCHEME_HTTP,
1797 HostPortPair("myproxy", 8888)))));
[email protected]3732cea2013-06-21 06:50:501798 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1799}
1800
tbansal0844a892016-12-13 16:00:011801TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpsURL) {
Lily Houghton8c2f97d2018-01-22 05:06:591802 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
[email protected]3732cea2013-06-21 06:50:501803
mmenkebd84c392015-09-02 14:12:341804 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:011805 SequencedSocketData socket_data(base::make_span(&mock_read, 1),
1806 base::span<MockWrite>());
[email protected]3732cea2013-06-21 06:50:501807 socket_data.set_connect_data(MockConnect(ASYNC, OK));
mmenke6429ac9b2015-06-05 20:49:061808 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
[email protected]3732cea2013-06-21 06:50:501809
1810 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:361811 ssl_socket_data.next_proto = kProtoHTTP2;
mmenke6429ac9b2015-06-05 20:49:061812 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
[email protected]3732cea2013-06-21 06:50:501813
1814 HostPortPair host_port_pair("www.google.com", 443);
danakj1fd259a02016-04-16 03:17:091815 std::unique_ptr<HttpNetworkSession> session(
mmenke6429ac9b2015-06-05 20:49:061816 SpdySessionDependencies::SpdyCreateSession(&session_deps));
[email protected]3732cea2013-06-21 06:50:501817
1818 // Now request a stream.
1819 HttpRequestInfo request_info;
1820 request_info.method = "GET";
1821 request_info.url = GURL("https://www.google.com");
1822 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:351823 request_info.traffic_annotation =
1824 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3732cea2013-06-21 06:50:501825
1826 SSLConfig ssl_config;
1827 StreamRequestWaiter waiter;
danakj1fd259a02016-04-16 03:17:091828 std::unique_ptr<HttpStreamRequest> request(
[email protected]3732cea2013-06-21 06:50:501829 session->http_stream_factory()->RequestStream(
danakj1fd259a02016-04-16 03:17:091830 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:261831 /* enable_ip_based_pooling = */ true,
1832 /* enable_alternative_services = */ true, NetLogWithSource()));
[email protected]3732cea2013-06-21 06:50:501833 waiter.WaitForStream();
1834 EXPECT_TRUE(waiter.stream_done());
yhiranoa7e05bb2014-11-06 05:40:391835 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1836 ASSERT_TRUE(nullptr != waiter.stream());
mmenkebd84c392015-09-02 14:12:341837
1838 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:401839 EXPECT_EQ(
1840 1, GetSocketPoolGroupCount(session->GetSocketPool(
1841 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
[email protected]3732cea2013-06-21 06:50:501842 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1843}
1844
tbansal0844a892016-12-13 16:00:011845TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpURL) {
1846 url::SchemeHostPort scheme_host_port("http", "myproxy.org", 443);
Jeremy Roman0579ed62017-08-29 15:56:191847 auto session_deps = std::make_unique<SpdySessionDependencies>(
Lily Houghton8c2f97d2018-01-22 05:06:591848 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491849 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS));
Lily Houghton8c2f97d2018-01-22 05:06:591850 std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:491851 ProxyResolutionService::CreateFixedFromPacResult(
1852 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal0844a892016-12-13 16:00:011853
1854 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:011855 SequencedSocketData socket_data(base::make_span(&mock_read, 1),
1856 base::span<MockWrite>());
tbansal0844a892016-12-13 16:00:011857 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1858 session_deps->socket_factory->AddSocketDataProvider(&socket_data);
1859
1860 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1861 ssl_socket_data.next_proto = kProtoHTTP2;
1862 session_deps->socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
Lily Houghton8c2f97d2018-01-22 05:06:591863 session_deps->proxy_resolution_service = std::move(proxy_resolution_service);
tbansal0844a892016-12-13 16:00:011864
1865 std::unique_ptr<HttpNetworkSession> session(
1866 SpdySessionDependencies::SpdyCreateSession(session_deps.get()));
1867
1868 HttpServerProperties* http_server_properties =
1869 session->spdy_session_pool()->http_server_properties();
Matt Menkefe1f1c8f2019-08-20 17:49:111870 EXPECT_FALSE(http_server_properties->GetSupportsSpdy(scheme_host_port,
1871 NetworkIsolationKey()));
tbansal0844a892016-12-13 16:00:011872
1873 // Now request a stream.
1874 HttpRequestInfo request_info;
1875 request_info.method = "GET";
1876 request_info.url = GURL("http://www.google.com");
1877 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:351878 request_info.traffic_annotation =
1879 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal0844a892016-12-13 16:00:011880
1881 SSLConfig ssl_config;
1882 StreamRequestWaiter waiter;
1883 std::unique_ptr<HttpStreamRequest> request(
1884 session->http_stream_factory()->RequestStream(
1885 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:261886 /* enable_ip_based_pooling = */ true,
1887 /* enable_alternative_services = */ true, NetLogWithSource()));
tbansal0844a892016-12-13 16:00:011888 waiter.WaitForStream();
1889 EXPECT_TRUE(waiter.stream_done());
1890 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1891 ASSERT_TRUE(nullptr != waiter.stream());
1892
1893 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:401894 EXPECT_EQ(
1895 0, GetSocketPoolGroupCount(session->GetSocketPool(
1896 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
tbansal0844a892016-12-13 16:00:011897 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
Matt Menkefe1f1c8f2019-08-20 17:49:111898 EXPECT_TRUE(http_server_properties->GetSupportsSpdy(scheme_host_port,
1899 NetworkIsolationKey()));
1900}
1901
1902// Same as above, but checks HttpServerProperties is updated using the correct
1903// NetworkIsolationKey. When/if NetworkIsolationKey is enabled by default, this
1904// should probably be merged into the above test.
1905TEST_F(HttpStreamFactoryTest,
1906 RequestSpdyHttpStreamHttpURLWithNetworkIsolationKey) {
1907 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
1908 const NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
1909 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
1910 const NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
1911
1912 base::test::ScopedFeatureList feature_list;
1913 feature_list.InitAndEnableFeature(
1914 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1915
1916 url::SchemeHostPort scheme_host_port("http", "myproxy.org", 443);
1917 auto session_deps = std::make_unique<SpdySessionDependencies>(
1918 ProxyResolutionService::CreateFixedFromPacResult(
1919 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS));
1920 std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
1921 ProxyResolutionService::CreateFixedFromPacResult(
1922 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
1923
1924 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1925 SequencedSocketData socket_data(base::make_span(&mock_read, 1),
1926 base::span<MockWrite>());
1927 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1928 session_deps->socket_factory->AddSocketDataProvider(&socket_data);
1929
1930 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1931 ssl_socket_data.next_proto = kProtoHTTP2;
1932 session_deps->socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1933 session_deps->proxy_resolution_service = std::move(proxy_resolution_service);
1934
1935 std::unique_ptr<HttpNetworkSession> session(
1936 SpdySessionDependencies::SpdyCreateSession(session_deps.get()));
1937
1938 HttpServerProperties* http_server_properties =
1939 session->spdy_session_pool()->http_server_properties();
1940 EXPECT_FALSE(http_server_properties->GetSupportsSpdy(scheme_host_port,
1941 kNetworkIsolationKey1));
1942
1943 // Now request a stream.
1944 HttpRequestInfo request_info;
1945 request_info.method = "GET";
1946 request_info.url = GURL("http://www.google.com");
1947 request_info.load_flags = 0;
1948 request_info.network_isolation_key = kNetworkIsolationKey1;
1949 request_info.traffic_annotation =
1950 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1951
1952 SSLConfig ssl_config;
1953 StreamRequestWaiter waiter;
1954 std::unique_ptr<HttpStreamRequest> request(
1955 session->http_stream_factory()->RequestStream(
1956 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
1957 /* enable_ip_based_pooling = */ true,
1958 /* enable_alternative_services = */ true, NetLogWithSource()));
1959 waiter.WaitForStream();
1960 EXPECT_TRUE(waiter.stream_done());
1961 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1962 ASSERT_TRUE(nullptr != waiter.stream());
1963
1964 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
1965 EXPECT_EQ(
1966 0, GetSocketPoolGroupCount(session->GetSocketPool(
1967 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
1968 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1969 EXPECT_TRUE(http_server_properties->GetSupportsSpdy(scheme_host_port,
1970 kNetworkIsolationKey1));
1971 // Other NetworkIsolationKeys should not be recorded as supporting SPDY.
1972 EXPECT_FALSE(http_server_properties->GetSupportsSpdy(scheme_host_port,
1973 NetworkIsolationKey()));
1974 EXPECT_FALSE(http_server_properties->GetSupportsSpdy(scheme_host_port,
1975 kNetworkIsolationKey2));
tbansal0844a892016-12-13 16:00:011976}
1977
xunjieli66e35d22017-03-30 22:06:061978// Tests that when a new SpdySession is established, duplicated idle H2 sockets
1979// to the same server are closed.
1980TEST_F(HttpStreamFactoryTest, NewSpdySessionCloseIdleH2Sockets) {
Lily Houghton8c2f97d2018-01-22 05:06:591981 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
xunjieli66e35d22017-03-30 22:06:061982
1983 const int kNumIdleSockets = 4;
1984 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
1985 std::vector<std::unique_ptr<SequencedSocketData>> providers;
1986 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1987 ssl_socket_data.next_proto = kProtoHTTP2;
1988 for (int i = 0; i < kNumIdleSockets; i++) {
Ryan Sleevib8d7ea02018-05-07 20:01:011989 auto provider =
1990 std::make_unique<SequencedSocketData>(reads, base::span<MockWrite>());
xunjieli66e35d22017-03-30 22:06:061991 provider->set_connect_data(MockConnect(ASYNC, OK));
1992 session_deps.socket_factory->AddSocketDataProvider(provider.get());
1993 providers.push_back(std::move(provider));
1994 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1995 }
1996
1997 std::unique_ptr<HttpNetworkSession> session(
1998 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1999
2000 HostPortPair host_port_pair("www.google.com", 443);
2001
2002 // Create some HTTP/2 sockets.
2003 std::vector<std::unique_ptr<ClientSocketHandle>> handles;
2004 for (size_t i = 0; i < kNumIdleSockets; i++) {
Jeremy Roman0579ed62017-08-29 15:56:192005 auto connection = std::make_unique<ClientSocketHandle>();
xunjieli66e35d22017-03-30 22:06:062006 TestCompletionCallback callback;
2007
Matt Menke870e19ab2019-04-23 16:23:032008 scoped_refptr<ClientSocketPool::SocketParams> socket_params =
2009 base::MakeRefCounted<ClientSocketPool::SocketParams>(
Matt Menke870e19ab2019-04-23 16:23:032010 std::make_unique<SSLConfig>() /* ssl_config_for_origin */,
Matt Menke75802252019-05-01 19:23:212011 nullptr /* ssl_config_for_proxy */);
dalyk51ab46b2019-10-15 15:14:342012 ClientSocketPool::GroupId group_id(
2013 host_port_pair, ClientSocketPool::SocketType::kSsl,
2014 PrivacyMode::PRIVACY_MODE_DISABLED, NetworkIsolationKey(),
2015 false /* disable_secure_dns */);
xunjieli66e35d22017-03-30 22:06:062016 int rv = connection->Init(
Matt Menkef09e64c2019-04-23 22:16:282017 group_id, socket_params, base::nullopt /* proxy_annotation_tag */,
2018 MEDIUM, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2019 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
Matt Menked23ab952019-03-06 00:24:402020 session->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
2021 ProxyServer::Direct()),
xunjieli66e35d22017-03-30 22:06:062022 NetLogWithSource());
2023 rv = callback.GetResult(rv);
2024 handles.push_back(std::move(connection));
2025 }
2026
2027 // Releases handles now, and these sockets should go into the socket pool.
2028 handles.clear();
Matt Menked23ab952019-03-06 00:24:402029 EXPECT_EQ(kNumIdleSockets,
2030 session
2031 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
2032 ProxyServer::Direct())
2033 ->IdleSocketCount());
xunjieli66e35d22017-03-30 22:06:062034
2035 // Request two streams at once and make sure they use the same connection.
2036 HttpRequestInfo request_info;
2037 request_info.method = "GET";
2038 request_info.url = GURL("https://www.google.com");
2039 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:352040 request_info.traffic_annotation =
2041 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli66e35d22017-03-30 22:06:062042
2043 SSLConfig ssl_config;
2044 StreamRequestWaiter waiter1;
2045 StreamRequestWaiter waiter2;
2046 std::unique_ptr<HttpStreamRequest> request1(
2047 session->http_stream_factory()->RequestStream(
2048 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter1,
bncaccd4962017-04-06 21:00:262049 /* enable_ip_based_pooling = */ true,
2050 /* enable_alternative_services = */ true, NetLogWithSource()));
xunjieli66e35d22017-03-30 22:06:062051 std::unique_ptr<HttpStreamRequest> request2(
2052 session->http_stream_factory()->RequestStream(
2053 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter2,
bncaccd4962017-04-06 21:00:262054 /* enable_ip_based_pooling = */ true,
2055 /* enable_alternative_services = */ true, NetLogWithSource()));
xunjieli66e35d22017-03-30 22:06:062056 waiter1.WaitForStream();
2057 waiter2.WaitForStream();
2058 EXPECT_TRUE(waiter1.stream_done());
2059 EXPECT_TRUE(waiter2.stream_done());
2060 ASSERT_NE(nullptr, waiter1.stream());
2061 ASSERT_NE(nullptr, waiter2.stream());
2062 ASSERT_NE(waiter1.stream(), waiter2.stream());
2063
2064 // Establishing the SpdySession will close idle H2 sockets.
Matt Menked23ab952019-03-06 00:24:402065 EXPECT_EQ(0, session
2066 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
2067 ProxyServer::Direct())
2068 ->IdleSocketCount());
xunjieli66e35d22017-03-30 22:06:062069 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
2070}
2071
bncdcdaa5f2017-06-12 19:02:462072// Regression test for https://crbug.com/706974.
2073TEST_F(HttpStreamFactoryTest, TwoSpdyConnects) {
Lily Houghton8c2f97d2018-01-22 05:06:592074 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
bncdcdaa5f2017-06-12 19:02:462075
2076 SSLSocketDataProvider ssl_socket_data0(ASYNC, OK);
2077 ssl_socket_data0.next_proto = kProtoHTTP2;
2078 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data0);
2079
2080 MockRead reads0[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
Ryan Sleevib8d7ea02018-05-07 20:01:012081 SequencedSocketData data0(reads0, base::span<MockWrite>());
bncdcdaa5f2017-06-12 19:02:462082 data0.set_connect_data(MockConnect(ASYNC, OK));
2083 session_deps.socket_factory->AddSocketDataProvider(&data0);
2084
2085 SSLSocketDataProvider ssl_socket_data1(ASYNC, OK);
2086 ssl_socket_data1.next_proto = kProtoHTTP2;
2087 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data1);
2088
Ryan Sleevib8d7ea02018-05-07 20:01:012089 SequencedSocketData data1;
bncdcdaa5f2017-06-12 19:02:462090 data1.set_connect_data(MockConnect(ASYNC, OK));
2091 session_deps.socket_factory->AddSocketDataProvider(&data1);
2092
2093 std::unique_ptr<HttpNetworkSession> session =
2094 SpdySessionDependencies::SpdyCreateSession(&session_deps);
2095 HttpRequestInfo request_info;
2096 request_info.method = "GET";
2097 request_info.url = GURL("https://www.google.com");
2098 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:352099 request_info.traffic_annotation =
2100 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncdcdaa5f2017-06-12 19:02:462101 SSLConfig ssl_config;
2102
2103 // Request two streams at once and make sure they use the same connection.
2104 StreamRequestWaiter waiter1;
2105 std::unique_ptr<HttpStreamRequest> request1 =
2106 session->http_stream_factory()->RequestStream(
2107 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter1,
2108 /* enable_ip_based_pooling = */ true,
2109 /* enable_alternative_services = */ true, NetLogWithSource());
2110
2111 StreamRequestWaiter waiter2;
2112 std::unique_ptr<HttpStreamRequest> request2 =
2113 session->http_stream_factory()->RequestStream(
2114 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter2,
2115 /* enable_ip_based_pooling = */ true,
2116 /* enable_alternative_services = */ true, NetLogWithSource());
2117
2118 waiter1.WaitForStream();
2119 waiter2.WaitForStream();
2120
2121 EXPECT_TRUE(waiter1.stream_done());
2122 EXPECT_TRUE(waiter2.stream_done());
2123 ASSERT_NE(nullptr, waiter1.stream());
2124 ASSERT_NE(nullptr, waiter2.stream());
2125 ASSERT_NE(waiter1.stream(), waiter2.stream());
2126
2127 // Establishing the SpdySession will close the extra H2 socket.
Matt Menked23ab952019-03-06 00:24:402128 EXPECT_EQ(0, session
2129 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
2130 ProxyServer::Direct())
2131 ->IdleSocketCount());
bncdcdaa5f2017-06-12 19:02:462132 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
2133 EXPECT_TRUE(data0.AllReadDataConsumed());
2134 EXPECT_TRUE(data1.AllReadDataConsumed());
2135}
2136
bnca9b9e222016-07-11 20:10:402137TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImpl) {
Lily Houghton8c2f97d2018-01-22 05:06:592138 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
xunjieli11834f02015-12-22 04:27:082139
2140 MockRead mock_read(ASYNC, OK);
Ryan Sleevib8d7ea02018-05-07 20:01:012141 SequencedSocketData socket_data(base::make_span(&mock_read, 1),
2142 base::span<MockWrite>());
xunjieli11834f02015-12-22 04:27:082143 socket_data.set_connect_data(MockConnect(ASYNC, OK));
2144 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
2145
2146 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:362147 ssl_socket_data.next_proto = kProtoHTTP2;
xunjieli11834f02015-12-22 04:27:082148 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
2149
danakj1fd259a02016-04-16 03:17:092150 std::unique_ptr<HttpNetworkSession> session(
xunjieli11834f02015-12-22 04:27:082151 SpdySessionDependencies::SpdyCreateSession(&session_deps));
2152
2153 // Now request a stream.
2154 HttpRequestInfo request_info;
2155 request_info.method = "GET";
2156 request_info.url = GURL("https://www.google.com");
2157 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:352158 request_info.traffic_annotation =
2159 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli11834f02015-12-22 04:27:082160
2161 SSLConfig ssl_config;
2162 StreamRequestWaiter waiter;
danakj1fd259a02016-04-16 03:17:092163 std::unique_ptr<HttpStreamRequest> request(
xunjieli5749218c2016-03-22 16:43:062164 session->http_stream_factory()->RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:082165 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:262166 /* enable_ip_based_pooling = */ true,
2167 /* enable_alternative_services = */ true, NetLogWithSource()));
xunjieli11834f02015-12-22 04:27:082168 waiter.WaitForStream();
2169 EXPECT_TRUE(waiter.stream_done());
2170 EXPECT_FALSE(waiter.websocket_stream());
2171 ASSERT_FALSE(waiter.stream());
xunjieli5749218c2016-03-22 16:43:062172 ASSERT_TRUE(waiter.bidirectional_stream_impl());
Matt Menked23ab952019-03-06 00:24:402173 EXPECT_EQ(
2174 1, GetSocketPoolGroupCount(session->GetSocketPool(
2175 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
xunjieli11834f02015-12-22 04:27:082176 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
xunjieli11834f02015-12-22 04:27:082177}
2178
xunjieli2608f9b2016-03-14 13:39:232179class HttpStreamFactoryBidirectionalQuicTest
Gabriel Charette694c3c332019-08-19 14:53:052180 : public TestWithTaskEnvironment,
Yixin Wang079ad542018-01-11 04:06:052181 public ::testing::WithParamInterface<
Nick Harper23290b82019-05-02 00:02:562182 std::tuple<quic::ParsedQuicVersion, bool>> {
xunjieli2608f9b2016-03-14 13:39:232183 protected:
2184 HttpStreamFactoryBidirectionalQuicTest()
bnc3d9035b32016-06-30 18:18:482185 : default_url_(kDefaultUrl),
Yixin Wang079ad542018-01-11 04:06:052186 version_(std::get<0>(GetParam())),
2187 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Victor Vasiliev7752898d2019-11-14 21:30:222188 client_packet_maker_(version_,
2189 quic::QuicUtils::CreateRandomConnectionId(
2190 quic_context_.random_generator()),
2191 quic_context_.clock(),
2192 "www.example.org",
2193 quic::Perspective::IS_CLIENT,
2194 client_headers_include_h2_stream_dependency_),
2195 server_packet_maker_(version_,
2196 quic::QuicUtils::CreateRandomConnectionId(
2197 quic_context_.random_generator()),
2198 quic_context_.clock(),
2199 "www.example.org",
2200 quic::Perspective::IS_SERVER,
2201 false),
Lily Houghton8c2f97d2018-01-22 05:06:592202 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
xunjieli2608f9b2016-03-14 13:39:232203 ssl_config_service_(new SSLConfigServiceDefaults) {
Victor Vasiliev7752898d2019-11-14 21:30:222204 quic_context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
David Schinazi3f7465c2019-07-12 01:57:052205 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
Zhongyi Shi49f8ad2fd2019-12-13 01:20:312206 quic::QuicEnableVersion(version_);
David Schinazi3f7465c2019-07-12 01:57:052207 }
xunjieli2608f9b2016-03-14 13:39:232208 }
2209
bnc525e175a2016-06-20 12:36:402210 void TearDown() override { session_.reset(); }
2211
xunjieli888c29922016-03-18 21:05:092212 // Disable bidirectional stream over QUIC. This should be invoked before
2213 // Initialize().
2214 void DisableQuicBidirectionalStream() {
Victor Vasilieva1e66d72019-12-05 17:55:382215 quic_context_.params()->disable_bidirectional_streams = true;
xunjieli888c29922016-03-18 21:05:092216 }
2217
xunjieli2608f9b2016-03-14 13:39:232218 void Initialize() {
2219 params_.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:382220 quic_context_.params()->supported_versions =
Nick Harper72ade192019-07-17 03:30:422221 quic::test::SupportedVersions(version_);
Victor Vasilieva1e66d72019-12-05 17:55:382222 quic_context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:052223 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:412224
2225 HttpNetworkSession::Context session_context;
2226 session_context.http_server_properties = &http_server_properties_;
Victor Vasiliev7752898d2019-11-14 21:30:222227 session_context.quic_context = &quic_context_;
xunjieli2608f9b2016-03-14 13:39:232228
2229 // Load a certificate that is valid for *.example.org
2230 scoped_refptr<X509Certificate> test_cert(
2231 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
2232 EXPECT_TRUE(test_cert.get());
2233 verify_details_.cert_verify_result.verified_cert = test_cert;
2234 verify_details_.cert_verify_result.is_issued_by_known_root = true;
2235 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
2236 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:272237 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:412238 session_context.cert_verifier = &cert_verifier_;
2239 session_context.quic_crypto_client_stream_factory =
2240 &crypto_client_stream_factory_;
2241 session_context.transport_security_state = &transport_security_state_;
2242 session_context.cert_transparency_verifier = &ct_verifier_;
2243 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
2244 session_context.host_resolver = &host_resolver_;
Lily Houghton8c2f97d2018-01-22 05:06:592245 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:412246 session_context.ssl_config_service = ssl_config_service_.get();
2247 session_context.client_socket_factory = &socket_factory_;
2248 session_.reset(new HttpNetworkSession(params_, session_context));
Matt Menkeb566c392019-09-11 23:22:432249 session_->quic_stream_factory()
2250 ->set_is_quic_known_to_work_on_current_network(true);
xunjieli2608f9b2016-03-14 13:39:232251 }
2252
2253 void AddQuicAlternativeService() {
bnc3472afd2016-11-17 15:27:212254 const AlternativeService alternative_service(kProtoQUIC, "www.example.org",
2255 443);
xunjieli2608f9b2016-03-14 13:39:232256 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:212257 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:072258 url::SchemeHostPort(default_url_), NetworkIsolationKey(),
2259 alternative_service, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:382260 session_->context().quic_context->params()->supported_versions);
Bence Béky6d05ebd2017-05-16 00:09:012261 }
xunjieli2608f9b2016-03-14 13:39:232262
alyssar2adf3ac2016-05-03 17:12:582263 test::QuicTestPacketMaker& client_packet_maker() {
2264 return client_packet_maker_;
2265 }
2266 test::QuicTestPacketMaker& server_packet_maker() {
2267 return server_packet_maker_;
2268 }
xunjieli2608f9b2016-03-14 13:39:232269
Paul Jensen8e3c5d32018-02-19 17:06:332270 MockTaggingClientSocketFactory& socket_factory() { return socket_factory_; }
xunjieli2608f9b2016-03-14 13:39:232271
2272 HttpNetworkSession* session() { return session_.get(); }
2273
bnc3d9035b32016-06-30 18:18:482274 const GURL default_url_;
2275
Fan Yang32c5a112018-12-10 20:06:332276 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:562277 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
2278 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:362279 }
2280
Ryan Hamilton0d65a8c2019-06-07 00:46:022281 quic::ParsedQuicVersion version() const { return version_; }
2282
xunjieli2608f9b2016-03-14 13:39:232283 private:
David Schinazi3f7465c2019-07-12 01:57:052284 QuicFlagSaver saver_;
Nick Harper23290b82019-05-02 00:02:562285 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:052286 const bool client_headers_include_h2_stream_dependency_;
Victor Vasiliev7752898d2019-11-14 21:30:222287 MockQuicContext quic_context_;
alyssar2adf3ac2016-05-03 17:12:582288 test::QuicTestPacketMaker client_packet_maker_;
2289 test::QuicTestPacketMaker server_packet_maker_;
Paul Jensen8e3c5d32018-02-19 17:06:332290 MockTaggingClientSocketFactory socket_factory_;
danakj1fd259a02016-04-16 03:17:092291 std::unique_ptr<HttpNetworkSession> session_;
rsleevid6de8302016-06-21 01:33:202292 MockCertVerifier cert_verifier_;
xunjieli2608f9b2016-03-14 13:39:232293 ProofVerifyDetailsChromium verify_details_;
2294 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Matt Menke609160742019-08-02 18:47:262295 HttpServerProperties http_server_properties_;
xunjieli2608f9b2016-03-14 13:39:232296 TransportSecurityState transport_security_state_;
rsleevid6de8302016-06-21 01:33:202297 MultiLogCTVerifier ct_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:232298 DefaultCTPolicyEnforcer ct_policy_enforcer_;
xunjieli2608f9b2016-03-14 13:39:232299 MockHostResolver host_resolver_;
Lily Houghton8c2f97d2018-01-22 05:06:592300 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
Ryan Sleevib8449e02018-07-15 04:31:072301 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
xunjieli2608f9b2016-03-14 13:39:232302 HttpNetworkSession::Params params_;
2303};
2304
Victor Costan8fb98f6f2019-02-01 17:08:292305INSTANTIATE_TEST_SUITE_P(
Bence Békyce380cb2018-04-26 23:39:552306 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:052307 HttpStreamFactoryBidirectionalQuicTest,
Victor Vasiliev5d6cdc22019-05-28 20:37:432308 ::testing::Combine(::testing::ValuesIn(quic::AllVersionsExcept99()),
Nick Harper23290b82019-05-02 00:02:562309 ::testing::Bool()));
xunjieli2608f9b2016-03-14 13:39:232310
2311TEST_P(HttpStreamFactoryBidirectionalQuicTest,
xunjieli5749218c2016-03-22 16:43:062312 RequestBidirectionalStreamImplQuicAlternative) {
Ryan Hamilton0d65a8c2019-06-07 00:46:022313 MockQuicData mock_quic_data(version());
Ryan Hamilton0239aac2018-05-19 00:03:132314 spdy::SpdyPriority priority =
xunjieli2608f9b2016-03-14 13:39:232315 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2316 size_t spdy_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:232317 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252318 if (VersionUsesHttp3(version().transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232319 mock_quic_data.AddWrite(
2320 client_packet_maker().MakeInitialSettingsPacket(packet_num++));
2321 }
alyssar2adf3ac2016-05-03 17:12:582322 mock_quic_data.AddWrite(client_packet_maker().MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:232323 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:332324 /*should_include_version=*/true,
xunjieli2608f9b2016-03-14 13:39:232325 /*fin=*/true, priority,
alyssar2adf3ac2016-05-03 17:12:582326 client_packet_maker().GetRequestHeaders("GET", "https", "/"),
Ryan Hamilton0d65a8c2019-06-07 00:46:022327 /*parent_stream_id=*/0, &spdy_headers_frame_length));
xunjieli2608f9b2016-03-14 13:39:232328 size_t spdy_response_headers_frame_length;
alyssar2adf3ac2016-05-03 17:12:582329 mock_quic_data.AddRead(server_packet_maker().MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332330 1, GetNthClientInitiatedBidirectionalStreamId(0),
2331 /*should_include_version=*/false,
alyssar2adf3ac2016-05-03 17:12:582332 /*fin=*/true, server_packet_maker().GetResponseHeaders("200"),
xunjieli2608f9b2016-03-14 13:39:232333 &spdy_response_headers_frame_length));
2334 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
2335 mock_quic_data.AddSocketDataToFactory(&socket_factory());
2336
2337 // Add hanging data for http job.
Jeremy Roman0579ed62017-08-29 15:56:192338 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
xunjieli2608f9b2016-03-14 13:39:232339 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
2340 hanging_data->set_connect_data(hanging_connect);
2341 socket_factory().AddSocketDataProvider(hanging_data.get());
2342 SSLSocketDataProvider ssl_data(ASYNC, OK);
2343 socket_factory().AddSSLSocketDataProvider(&ssl_data);
2344
2345 // Set up QUIC as alternative_service.
xunjieli2608f9b2016-03-14 13:39:232346 Initialize();
zhongyie537a002017-06-27 16:48:212347 AddQuicAlternativeService();
xunjieli2608f9b2016-03-14 13:39:232348
2349 // Now request a stream.
2350 SSLConfig ssl_config;
2351 HttpRequestInfo request_info;
2352 request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482353 request_info.url = default_url_;
xunjieli2608f9b2016-03-14 13:39:232354 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:352355 request_info.traffic_annotation =
2356 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli2608f9b2016-03-14 13:39:232357
2358 StreamRequestWaiter waiter;
danakj1fd259a02016-04-16 03:17:092359 std::unique_ptr<HttpStreamRequest> request(
xunjieli5749218c2016-03-22 16:43:062360 session()->http_stream_factory()->RequestBidirectionalStreamImpl(
xunjieli2608f9b2016-03-14 13:39:232361 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:262362 /* enable_ip_based_pooling = */ true,
2363 /* enable_alternative_services = */ true, NetLogWithSource()));
xunjieli2608f9b2016-03-14 13:39:232364
2365 waiter.WaitForStream();
2366 EXPECT_TRUE(waiter.stream_done());
2367 EXPECT_FALSE(waiter.websocket_stream());
2368 ASSERT_FALSE(waiter.stream());
xunjieli5749218c2016-03-22 16:43:062369 ASSERT_TRUE(waiter.bidirectional_stream_impl());
2370 BidirectionalStreamImpl* stream_impl = waiter.bidirectional_stream_impl();
xunjieli2608f9b2016-03-14 13:39:232371
2372 BidirectionalStreamRequestInfo bidi_request_info;
2373 bidi_request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482374 bidi_request_info.url = default_url_;
xunjieli2608f9b2016-03-14 13:39:232375 bidi_request_info.end_stream_on_headers = true;
2376 bidi_request_info.priority = LOWEST;
2377
2378 TestBidirectionalDelegate delegate;
tfarina428341112016-09-22 13:38:202379 stream_impl->Start(&bidi_request_info, NetLogWithSource(),
xunjielibcb0f86e2016-06-03 00:49:292380 /*send_request_headers_automatically=*/true, &delegate,
Ramin Halavati3c96c6d2018-03-11 13:29:442381 nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli2608f9b2016-03-14 13:39:232382 delegate.WaitUntilDone();
2383
Victor Costan9c7302b2018-08-27 16:39:442384 scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<net::IOBuffer>(1);
robpercival214763f2016-07-01 23:27:012385 EXPECT_THAT(stream_impl->ReadData(buffer.get(), 1), IsOk());
bnc401eb922016-10-21 16:49:352386 EXPECT_EQ(kProtoQUIC, stream_impl->GetProtocol());
xunjieli2608f9b2016-03-14 13:39:232387 EXPECT_EQ("200", delegate.response_headers().find(":status")->second);
Matt Menked23ab952019-03-06 00:24:402388 EXPECT_EQ(
2389 0, GetSocketPoolGroupCount(session()->GetSocketPool(
2390 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
xunjieli2608f9b2016-03-14 13:39:232391 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
2392}
2393
xunjieli888c29922016-03-18 21:05:092394// Tests that when QUIC is not enabled for bidirectional streaming, HTTP/2 is
2395// used instead.
2396TEST_P(HttpStreamFactoryBidirectionalQuicTest,
xunjieli5749218c2016-03-22 16:43:062397 RequestBidirectionalStreamImplQuicNotEnabled) {
xunjieli888c29922016-03-18 21:05:092398 // Make the http job fail.
Jeremy Roman0579ed62017-08-29 15:56:192399 auto http_job_data = std::make_unique<StaticSocketDataProvider>();
xunjieli888c29922016-03-18 21:05:092400 MockConnect failed_connect(ASYNC, ERR_CONNECTION_REFUSED);
2401 http_job_data->set_connect_data(failed_connect);
2402 socket_factory().AddSocketDataProvider(http_job_data.get());
2403 SSLSocketDataProvider ssl_data(ASYNC, OK);
2404 socket_factory().AddSSLSocketDataProvider(&ssl_data);
2405
2406 // Set up QUIC as alternative_service.
xunjieli888c29922016-03-18 21:05:092407 DisableQuicBidirectionalStream();
2408 Initialize();
zhongyie537a002017-06-27 16:48:212409 AddQuicAlternativeService();
xunjieli888c29922016-03-18 21:05:092410
2411 // Now request a stream.
2412 SSLConfig ssl_config;
2413 HttpRequestInfo request_info;
2414 request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482415 request_info.url = default_url_;
xunjieli888c29922016-03-18 21:05:092416 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:352417 request_info.traffic_annotation =
2418 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli888c29922016-03-18 21:05:092419
2420 StreamRequestWaiter waiter;
danakj1fd259a02016-04-16 03:17:092421 std::unique_ptr<HttpStreamRequest> request(
xunjieli5749218c2016-03-22 16:43:062422 session()->http_stream_factory()->RequestBidirectionalStreamImpl(
xunjieli888c29922016-03-18 21:05:092423 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:262424 /* enable_ip_based_pooling = */ true,
2425 /* enable_alternative_services = */ true, NetLogWithSource()));
xunjieli888c29922016-03-18 21:05:092426
2427 waiter.WaitForStream();
2428 EXPECT_TRUE(waiter.stream_done());
2429 EXPECT_FALSE(waiter.websocket_stream());
2430 ASSERT_FALSE(waiter.stream());
xunjieli5749218c2016-03-22 16:43:062431 ASSERT_FALSE(waiter.bidirectional_stream_impl());
xunjieli888c29922016-03-18 21:05:092432 // Since the alternative service job is not started, we will get the error
2433 // from the http job.
robpercival214763f2016-07-01 23:27:012434 ASSERT_THAT(waiter.error_status(), IsError(ERR_CONNECTION_REFUSED));
xunjieli888c29922016-03-18 21:05:092435}
2436
2437// Tests that if Http job fails, but Quic job succeeds, we return
2438// BidirectionalStreamQuicImpl.
2439TEST_P(HttpStreamFactoryBidirectionalQuicTest,
xunjieli5749218c2016-03-22 16:43:062440 RequestBidirectionalStreamImplHttpJobFailsQuicJobSucceeds) {
xunjieli888c29922016-03-18 21:05:092441 // Set up Quic data.
Ryan Hamilton0d65a8c2019-06-07 00:46:022442 MockQuicData mock_quic_data(version());
Ryan Hamilton0239aac2018-05-19 00:03:132443 spdy::SpdyPriority priority =
xunjieli888c29922016-03-18 21:05:092444 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2445 size_t spdy_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:232446 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252447 if (VersionUsesHttp3(version().transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232448 mock_quic_data.AddWrite(
2449 client_packet_maker().MakeInitialSettingsPacket(packet_num++));
2450 }
alyssar2adf3ac2016-05-03 17:12:582451 mock_quic_data.AddWrite(client_packet_maker().MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:232452 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:332453 /*should_include_version=*/true,
xunjieli888c29922016-03-18 21:05:092454 /*fin=*/true, priority,
alyssar2adf3ac2016-05-03 17:12:582455 client_packet_maker().GetRequestHeaders("GET", "https", "/"),
Ryan Hamilton0d65a8c2019-06-07 00:46:022456 /*parent_stream_id=*/0, &spdy_headers_frame_length));
xunjieli888c29922016-03-18 21:05:092457 size_t spdy_response_headers_frame_length;
alyssar2adf3ac2016-05-03 17:12:582458 mock_quic_data.AddRead(server_packet_maker().MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332459 1, GetNthClientInitiatedBidirectionalStreamId(0),
2460 /*should_include_version=*/false,
alyssar2adf3ac2016-05-03 17:12:582461 /*fin=*/true, server_packet_maker().GetResponseHeaders("200"),
xunjieli888c29922016-03-18 21:05:092462 &spdy_response_headers_frame_length));
2463 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
2464 mock_quic_data.AddSocketDataToFactory(&socket_factory());
2465
2466 // Make the http job fail.
Jeremy Roman0579ed62017-08-29 15:56:192467 auto http_job_data = std::make_unique<StaticSocketDataProvider>();
xunjieli888c29922016-03-18 21:05:092468 MockConnect failed_connect(ASYNC, ERR_CONNECTION_REFUSED);
2469 http_job_data->set_connect_data(failed_connect);
2470 socket_factory().AddSocketDataProvider(http_job_data.get());
2471 SSLSocketDataProvider ssl_data(ASYNC, OK);
2472 socket_factory().AddSSLSocketDataProvider(&ssl_data);
2473
2474 // Set up QUIC as alternative_service.
xunjieli888c29922016-03-18 21:05:092475 Initialize();
zhongyie537a002017-06-27 16:48:212476 AddQuicAlternativeService();
xunjieli888c29922016-03-18 21:05:092477
2478 // Now request a stream.
2479 SSLConfig ssl_config;
2480 HttpRequestInfo request_info;
2481 request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482482 request_info.url = default_url_;
xunjieli888c29922016-03-18 21:05:092483 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:352484 request_info.traffic_annotation =
2485 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli888c29922016-03-18 21:05:092486
2487 StreamRequestWaiter waiter;
danakj1fd259a02016-04-16 03:17:092488 std::unique_ptr<HttpStreamRequest> request(
xunjieli5749218c2016-03-22 16:43:062489 session()->http_stream_factory()->RequestBidirectionalStreamImpl(
xunjieli888c29922016-03-18 21:05:092490 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:262491 /* enable_ip_based_pooling = */ true,
2492 /* enable_alternative_services = */ true, NetLogWithSource()));
xunjieli888c29922016-03-18 21:05:092493
2494 waiter.WaitForStream();
2495 EXPECT_TRUE(waiter.stream_done());
2496 EXPECT_FALSE(waiter.websocket_stream());
2497 ASSERT_FALSE(waiter.stream());
xunjieli5749218c2016-03-22 16:43:062498 ASSERT_TRUE(waiter.bidirectional_stream_impl());
2499 BidirectionalStreamImpl* stream_impl = waiter.bidirectional_stream_impl();
xunjieli888c29922016-03-18 21:05:092500
2501 BidirectionalStreamRequestInfo bidi_request_info;
2502 bidi_request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482503 bidi_request_info.url = default_url_;
xunjieli888c29922016-03-18 21:05:092504 bidi_request_info.end_stream_on_headers = true;
2505 bidi_request_info.priority = LOWEST;
2506
2507 TestBidirectionalDelegate delegate;
tfarina428341112016-09-22 13:38:202508 stream_impl->Start(&bidi_request_info, NetLogWithSource(),
xunjielibcb0f86e2016-06-03 00:49:292509 /*send_request_headers_automatically=*/true, &delegate,
Ramin Halavati3c96c6d2018-03-11 13:29:442510 nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli888c29922016-03-18 21:05:092511 delegate.WaitUntilDone();
2512
2513 // Make sure the BidirectionalStream negotiated goes through QUIC.
Victor Costan9c7302b2018-08-27 16:39:442514 scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<net::IOBuffer>(1);
robpercival214763f2016-07-01 23:27:012515 EXPECT_THAT(stream_impl->ReadData(buffer.get(), 1), IsOk());
bnc401eb922016-10-21 16:49:352516 EXPECT_EQ(kProtoQUIC, stream_impl->GetProtocol());
xunjieli888c29922016-03-18 21:05:092517 EXPECT_EQ("200", delegate.response_headers().find(":status")->second);
2518 // There is no Http2 socket pool.
Matt Menked23ab952019-03-06 00:24:402519 EXPECT_EQ(
2520 0, GetSocketPoolGroupCount(session()->GetSocketPool(
2521 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
xunjieli888c29922016-03-18 21:05:092522 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
2523}
2524
bnca9b9e222016-07-11 20:10:402525TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImplFailure) {
Lily Houghton8c2f97d2018-01-22 05:06:592526 SpdySessionDependencies session_deps(ProxyResolutionService::CreateDirect());
xunjieli11834f02015-12-22 04:27:082527
2528 MockRead mock_read(ASYNC, OK);
Ryan Sleevib8d7ea02018-05-07 20:01:012529 SequencedSocketData socket_data(base::make_span(&mock_read, 1),
2530 base::span<MockWrite>());
xunjieli11834f02015-12-22 04:27:082531 socket_data.set_connect_data(MockConnect(ASYNC, OK));
2532 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
2533
2534 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
2535
xunjieli5749218c2016-03-22 16:43:062536 // If HTTP/1 is used, BidirectionalStreamImpl should not be obtained.
bnc3cf2a592016-08-11 14:48:362537 ssl_socket_data.next_proto = kProtoHTTP11;
xunjieli11834f02015-12-22 04:27:082538 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
2539
danakj1fd259a02016-04-16 03:17:092540 std::unique_ptr<HttpNetworkSession> session(
xunjieli11834f02015-12-22 04:27:082541 SpdySessionDependencies::SpdyCreateSession(&session_deps));
2542
2543 // Now request a stream.
2544 HttpRequestInfo request_info;
2545 request_info.method = "GET";
2546 request_info.url = GURL("https://www.google.com");
2547 request_info.load_flags = 0;
Ramin Halavati216426e2018-03-12 22:13:352548 request_info.traffic_annotation =
2549 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli11834f02015-12-22 04:27:082550
2551 SSLConfig ssl_config;
2552 StreamRequestWaiter waiter;
danakj1fd259a02016-04-16 03:17:092553 std::unique_ptr<HttpStreamRequest> request(
xunjieli5749218c2016-03-22 16:43:062554 session->http_stream_factory()->RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:082555 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
bncaccd4962017-04-06 21:00:262556 /* enable_ip_based_pooling = */ true,
2557 /* enable_alternative_services = */ true, NetLogWithSource()));
xunjieli11834f02015-12-22 04:27:082558 waiter.WaitForStream();
2559 EXPECT_TRUE(waiter.stream_done());
robpercival214763f2016-07-01 23:27:012560 ASSERT_THAT(waiter.error_status(), IsError(ERR_FAILED));
xunjieli11834f02015-12-22 04:27:082561 EXPECT_FALSE(waiter.websocket_stream());
2562 ASSERT_FALSE(waiter.stream());
xunjieli5749218c2016-03-22 16:43:062563 ASSERT_FALSE(waiter.bidirectional_stream_impl());
Matt Menked23ab952019-03-06 00:24:402564 EXPECT_EQ(
2565 1, GetSocketPoolGroupCount(session->GetSocketPool(
2566 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
xunjieli11834f02015-12-22 04:27:082567}
xunjieli11834f02015-12-22 04:27:082568
Paul Jensena457017a2018-01-19 23:52:042569#if defined(OS_ANDROID)
Bence Békye4c0e3e2018-04-27 00:47:252570// Verify HttpStreamFactory::Job passes socket tag along properly and that
Paul Jensena457017a2018-01-19 23:52:042571// SpdySessions have unique socket tags (e.g. one sessions should not be shared
2572// amongst streams with different socket tags).
2573TEST_F(HttpStreamFactoryTest, Tag) {
2574 SpdySessionDependencies session_deps;
2575 MockTaggingClientSocketFactory* socket_factory =
2576 new MockTaggingClientSocketFactory();
2577 session_deps.socket_factory.reset(socket_factory);
2578
2579 // Prepare for two HTTPS connects.
2580 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:012581 SequencedSocketData socket_data(base::make_span(&mock_read, 1),
2582 base::span<MockWrite>());
Paul Jensena457017a2018-01-19 23:52:042583 socket_data.set_connect_data(MockConnect(ASYNC, OK));
2584 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
2585 MockRead mock_read2(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:012586 SequencedSocketData socket_data2(base::make_span(&mock_read2, 1),
2587 base::span<MockWrite>());
Paul Jensena457017a2018-01-19 23:52:042588 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
2589 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
2590 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
Paul Jensen94cde5f2018-03-01 04:38:132591 ssl_socket_data.ssl_info.cert =
2592 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Paul Jensena457017a2018-01-19 23:52:042593 ssl_socket_data.next_proto = kProtoHTTP2;
2594 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
2595 SSLSocketDataProvider ssl_socket_data2(ASYNC, OK);
Paul Jensen94cde5f2018-03-01 04:38:132596 ssl_socket_data2.ssl_info.cert =
2597 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Paul Jensena457017a2018-01-19 23:52:042598 ssl_socket_data2.next_proto = kProtoHTTP2;
2599 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data2);
2600
Paul Jensena457017a2018-01-19 23:52:042601 std::unique_ptr<HttpNetworkSession> session(
2602 SpdySessionDependencies::SpdyCreateSession(&session_deps));
2603
2604 // Prepare two different tags and corresponding HttpRequestInfos.
2605 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
2606 HttpRequestInfo request_info1;
2607 request_info1.method = "GET";
2608 request_info1.url = GURL("https://example.org");
2609 request_info1.load_flags = 0;
2610 request_info1.socket_tag = tag1;
Ramin Halavati216426e2018-03-12 22:13:352611 request_info1.traffic_annotation =
2612 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Paul Jensena457017a2018-01-19 23:52:042613 SocketTag tag2(getuid(), 0x87654321);
2614 HttpRequestInfo request_info2 = request_info1;
2615 request_info2.socket_tag = tag2;
Ramin Halavati216426e2018-03-12 22:13:352616 request_info2.traffic_annotation =
2617 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Paul Jensena457017a2018-01-19 23:52:042618
Ramin Halavati216426e2018-03-12 22:13:352619 // Verify one stream with one tag results in one session, group and
2620 // socket.
Paul Jensena457017a2018-01-19 23:52:042621 SSLConfig ssl_config;
2622 StreamRequestWaiter waiter1;
2623 std::unique_ptr<HttpStreamRequest> request1(
2624 session->http_stream_factory()->RequestStream(
2625 request_info1, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter1,
2626 /* enable_ip_based_pooling = */ true,
2627 /* enable_alternative_services = */ true, NetLogWithSource()));
2628 waiter1.WaitForStream();
2629 EXPECT_TRUE(waiter1.stream_done());
2630 EXPECT_TRUE(nullptr == waiter1.websocket_stream());
2631 ASSERT_TRUE(nullptr != waiter1.stream());
2632
2633 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:402634 EXPECT_EQ(
2635 1, GetSocketPoolGroupCount(session->GetSocketPool(
2636 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
2637 EXPECT_EQ(
2638 1, GetHandedOutSocketCount(session->GetSocketPool(
2639 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
Paul Jensena457017a2018-01-19 23:52:042640 // Verify socket tagged appropriately.
Paul Jensen8e3c5d32018-02-19 17:06:332641 EXPECT_TRUE(tag1 == socket_factory->GetLastProducedTCPSocket()->tag());
Paul Jensena457017a2018-01-19 23:52:042642 EXPECT_TRUE(
Paul Jensen8e3c5d32018-02-19 17:06:332643 socket_factory->GetLastProducedTCPSocket()->tagged_before_connected());
Paul Jensena457017a2018-01-19 23:52:042644
2645 // Verify one more stream with a different tag results in one more session and
2646 // socket.
2647 StreamRequestWaiter waiter2;
2648 std::unique_ptr<HttpStreamRequest> request2(
2649 session->http_stream_factory()->RequestStream(
2650 request_info2, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter2,
2651 /* enable_ip_based_pooling = */ true,
2652 /* enable_alternative_services = */ true, NetLogWithSource()));
2653 waiter2.WaitForStream();
2654 EXPECT_TRUE(waiter2.stream_done());
2655 EXPECT_TRUE(nullptr == waiter2.websocket_stream());
2656 ASSERT_TRUE(nullptr != waiter2.stream());
2657
2658 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:402659 EXPECT_EQ(
2660 1, GetSocketPoolGroupCount(session->GetSocketPool(
2661 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
2662 EXPECT_EQ(
2663 2, GetHandedOutSocketCount(session->GetSocketPool(
2664 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
Paul Jensena457017a2018-01-19 23:52:042665 // Verify socket tagged appropriately.
Paul Jensen8e3c5d32018-02-19 17:06:332666 EXPECT_TRUE(tag2 == socket_factory->GetLastProducedTCPSocket()->tag());
Paul Jensena457017a2018-01-19 23:52:042667 EXPECT_TRUE(
Paul Jensen8e3c5d32018-02-19 17:06:332668 socket_factory->GetLastProducedTCPSocket()->tagged_before_connected());
Paul Jensena457017a2018-01-19 23:52:042669
2670 // Verify one more stream reusing a tag does not create new sessions, groups
2671 // or sockets.
2672 StreamRequestWaiter waiter3;
2673 std::unique_ptr<HttpStreamRequest> request3(
2674 session->http_stream_factory()->RequestStream(
2675 request_info2, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter3,
2676 /* enable_ip_based_pooling = */ true,
2677 /* enable_alternative_services = */ true, NetLogWithSource()));
2678 waiter3.WaitForStream();
2679 EXPECT_TRUE(waiter3.stream_done());
2680 EXPECT_TRUE(nullptr == waiter3.websocket_stream());
2681 ASSERT_TRUE(nullptr != waiter3.stream());
2682
2683 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:402684 EXPECT_EQ(
2685 1, GetSocketPoolGroupCount(session->GetSocketPool(
2686 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
2687 EXPECT_EQ(
2688 2, GetHandedOutSocketCount(session->GetSocketPool(
2689 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
Paul Jensena457017a2018-01-19 23:52:042690}
Paul Jensen8e3c5d32018-02-19 17:06:332691
Bence Békye4c0e3e2018-04-27 00:47:252692// Verify HttpStreamFactory::Job passes socket tag along properly to QUIC
Paul Jensen8e3c5d32018-02-19 17:06:332693// sessions and that QuicSessions have unique socket tags (e.g. one sessions
2694// should not be shared amongst streams with different socket tags).
2695TEST_P(HttpStreamFactoryBidirectionalQuicTest, Tag) {
2696 // Prepare mock QUIC data for a first session establishment.
Ryan Hamilton0d65a8c2019-06-07 00:46:022697 MockQuicData mock_quic_data(version());
Ryan Hamilton0239aac2018-05-19 00:03:132698 spdy::SpdyPriority priority =
Paul Jensen8e3c5d32018-02-19 17:06:332699 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2700 size_t spdy_headers_frame_length;
Renjie Tangaadb84b2019-08-31 01:00:232701 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252702 if (VersionUsesHttp3(version().transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232703 mock_quic_data.AddWrite(
2704 client_packet_maker().MakeInitialSettingsPacket(packet_num++));
2705 }
Paul Jensen8e3c5d32018-02-19 17:06:332706 mock_quic_data.AddWrite(client_packet_maker().MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:232707 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:332708 /*should_include_version=*/true,
Paul Jensen8e3c5d32018-02-19 17:06:332709 /*fin=*/true, priority,
2710 client_packet_maker().GetRequestHeaders("GET", "https", "/"),
Ryan Hamilton0d65a8c2019-06-07 00:46:022711 /*parent_stream_id=*/0, &spdy_headers_frame_length));
Paul Jensen8e3c5d32018-02-19 17:06:332712 size_t spdy_response_headers_frame_length;
2713 mock_quic_data.AddRead(server_packet_maker().MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332714 1, GetNthClientInitiatedBidirectionalStreamId(0),
2715 /*should_include_version=*/false,
Paul Jensen8e3c5d32018-02-19 17:06:332716 /*fin=*/true, server_packet_maker().GetResponseHeaders("200"),
2717 &spdy_response_headers_frame_length));
2718 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
2719 mock_quic_data.AddSocketDataToFactory(&socket_factory());
2720
2721 // Prepare mock QUIC data for a second session establishment.
Ryan Hamilton0d65a8c2019-06-07 00:46:022722 client_packet_maker().Reset();
2723 MockQuicData mock_quic_data2(version());
Renjie Tangaadb84b2019-08-31 01:00:232724 packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252725 if (VersionUsesHttp3(version().transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232726 mock_quic_data2.AddWrite(
2727 client_packet_maker().MakeInitialSettingsPacket(packet_num++));
2728 }
Paul Jensen8e3c5d32018-02-19 17:06:332729 mock_quic_data2.AddWrite(client_packet_maker().MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:232730 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:332731 /*should_include_version=*/true,
Paul Jensen8e3c5d32018-02-19 17:06:332732 /*fin=*/true, priority,
2733 client_packet_maker().GetRequestHeaders("GET", "https", "/"),
Ryan Hamilton0d65a8c2019-06-07 00:46:022734 /*parent_stream_id=*/0, &spdy_headers_frame_length));
Paul Jensen8e3c5d32018-02-19 17:06:332735 mock_quic_data2.AddRead(server_packet_maker().MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332736 1, GetNthClientInitiatedBidirectionalStreamId(0),
2737 /*should_include_version=*/false,
Paul Jensen8e3c5d32018-02-19 17:06:332738 /*fin=*/true, server_packet_maker().GetResponseHeaders("200"),
2739 &spdy_response_headers_frame_length));
2740 mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
2741 mock_quic_data2.AddSocketDataToFactory(&socket_factory());
2742
2743 // Add hanging data for http job.
2744 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
2745 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
2746 hanging_data->set_connect_data(hanging_connect);
2747 socket_factory().AddSocketDataProvider(hanging_data.get());
2748 SSLSocketDataProvider ssl_data(ASYNC, OK);
2749 socket_factory().AddSSLSocketDataProvider(&ssl_data);
2750
2751 // Set up QUIC as alternative_service.
2752 Initialize();
2753 AddQuicAlternativeService();
2754
2755 // Prepare two different tags and corresponding HttpRequestInfos.
2756 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
2757 HttpRequestInfo request_info1;
2758 request_info1.method = "GET";
2759 request_info1.url = default_url_;
2760 request_info1.load_flags = 0;
2761 request_info1.socket_tag = tag1;
Ramin Halavati216426e2018-03-12 22:13:352762 request_info1.traffic_annotation =
2763 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Paul Jensen8e3c5d32018-02-19 17:06:332764 SocketTag tag2(getuid(), 0x87654321);
2765 HttpRequestInfo request_info2 = request_info1;
2766 request_info2.socket_tag = tag2;
Ramin Halavati216426e2018-03-12 22:13:352767 request_info2.traffic_annotation =
2768 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Paul Jensen8e3c5d32018-02-19 17:06:332769
2770 // Verify one stream with one tag results in one QUIC session.
2771 SSLConfig ssl_config;
2772 StreamRequestWaiter waiter1;
2773 std::unique_ptr<HttpStreamRequest> request1(
2774 session()->http_stream_factory()->RequestStream(
2775 request_info1, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter1,
2776 /* enable_ip_based_pooling = */ true,
2777 /* enable_alternative_services = */ true, NetLogWithSource()));
2778 waiter1.WaitForStream();
2779 EXPECT_TRUE(waiter1.stream_done());
2780 EXPECT_TRUE(nullptr == waiter1.websocket_stream());
2781 ASSERT_TRUE(nullptr != waiter1.stream());
2782 EXPECT_EQ(kProtoQUIC, request1->negotiated_protocol());
2783 EXPECT_EQ(1, GetQuicSessionCount(session()));
2784
2785 // Verify socket tagged appropriately.
2786 EXPECT_TRUE(tag1 == socket_factory().GetLastProducedUDPSocket()->tag());
2787 EXPECT_TRUE(socket_factory()
2788 .GetLastProducedUDPSocket()
2789 ->tagged_before_data_transferred());
2790
2791 // Verify one more stream with a different tag results in one more session and
2792 // socket.
2793 StreamRequestWaiter waiter2;
2794 std::unique_ptr<HttpStreamRequest> request2(
2795 session()->http_stream_factory()->RequestStream(
2796 request_info2, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter2,
2797 /* enable_ip_based_pooling = */ true,
2798 /* enable_alternative_services = */ true, NetLogWithSource()));
2799 waiter2.WaitForStream();
2800 EXPECT_TRUE(waiter2.stream_done());
2801 EXPECT_TRUE(nullptr == waiter2.websocket_stream());
2802 ASSERT_TRUE(nullptr != waiter2.stream());
2803 EXPECT_EQ(kProtoQUIC, request2->negotiated_protocol());
2804 EXPECT_EQ(2, GetQuicSessionCount(session()));
2805
2806 // Verify socket tagged appropriately.
2807 EXPECT_TRUE(tag2 == socket_factory().GetLastProducedUDPSocket()->tag());
2808 EXPECT_TRUE(socket_factory()
2809 .GetLastProducedUDPSocket()
2810 ->tagged_before_data_transferred());
2811
2812 // Verify one more stream reusing a tag does not create new sessions.
2813 StreamRequestWaiter waiter3;
2814 std::unique_ptr<HttpStreamRequest> request3(
2815 session()->http_stream_factory()->RequestStream(
2816 request_info2, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter3,
2817 /* enable_ip_based_pooling = */ true,
2818 /* enable_alternative_services = */ true, NetLogWithSource()));
2819 waiter3.WaitForStream();
2820 EXPECT_TRUE(waiter3.stream_done());
2821 EXPECT_TRUE(nullptr == waiter3.websocket_stream());
2822 ASSERT_TRUE(nullptr != waiter3.stream());
2823 EXPECT_EQ(kProtoQUIC, request3->negotiated_protocol());
2824 EXPECT_EQ(2, GetQuicSessionCount(session()));
2825}
Paul Jensen94cde5f2018-03-01 04:38:132826
2827TEST_F(HttpStreamFactoryTest, ChangeSocketTag) {
2828 SpdySessionDependencies session_deps;
2829 MockTaggingClientSocketFactory* socket_factory =
2830 new MockTaggingClientSocketFactory();
2831 session_deps.socket_factory.reset(socket_factory);
2832
2833 // Prepare for two HTTPS connects.
2834 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:012835 SequencedSocketData socket_data(base::make_span(&mock_read, 1),
2836 base::span<MockWrite>());
Paul Jensen94cde5f2018-03-01 04:38:132837 socket_data.set_connect_data(MockConnect(ASYNC, OK));
2838 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
2839 MockRead mock_read2(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:012840 SequencedSocketData socket_data2(base::make_span(&mock_read2, 1),
2841 base::span<MockWrite>());
Paul Jensen94cde5f2018-03-01 04:38:132842 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
2843 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
2844 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
2845 // Use cert for *.example.org
2846 ssl_socket_data.ssl_info.cert =
2847 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
2848 ssl_socket_data.next_proto = kProtoHTTP2;
2849 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
2850 SSLSocketDataProvider ssl_socket_data2(ASYNC, OK);
2851 // Use cert for *.example.org
2852 ssl_socket_data2.ssl_info.cert =
2853 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
2854 ssl_socket_data2.next_proto = kProtoHTTP2;
2855 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data2);
2856
2857 std::unique_ptr<HttpNetworkSession> session(
2858 SpdySessionDependencies::SpdyCreateSession(&session_deps));
2859
2860 // Prepare two different tags and corresponding HttpRequestInfos.
2861 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
2862 HttpRequestInfo request_info1;
2863 request_info1.method = "GET";
2864 request_info1.url = GURL("https://www.example.org");
2865 request_info1.load_flags = 0;
2866 request_info1.socket_tag = tag1;
Ramin Halavati216426e2018-03-12 22:13:352867 request_info1.traffic_annotation =
2868 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Paul Jensen94cde5f2018-03-01 04:38:132869
2870 SocketTag tag2(getuid(), 0x87654321);
2871 HttpRequestInfo request_info2 = request_info1;
2872 request_info2.socket_tag = tag2;
Ramin Halavati216426e2018-03-12 22:13:352873 request_info2.traffic_annotation =
2874 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Paul Jensen94cde5f2018-03-01 04:38:132875
2876 // Prepare another HttpRequestInfo with tag1 and a different host name.
2877 HttpRequestInfo request_info3 = request_info1;
2878 request_info3.url = GURL("https://foo.example.org");
Ramin Halavati216426e2018-03-12 22:13:352879 request_info3.traffic_annotation =
2880 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Paul Jensen94cde5f2018-03-01 04:38:132881
Ramin Halavati216426e2018-03-12 22:13:352882 // Verify one stream with one tag results in one session, group and
2883 // socket.
Paul Jensen94cde5f2018-03-01 04:38:132884 SSLConfig ssl_config;
2885 StreamRequestWaiter waiter1;
2886 std::unique_ptr<HttpStreamRequest> request1(
2887 session->http_stream_factory()->RequestStream(
2888 request_info1, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter1,
2889 /* enable_ip_based_pooling = */ true,
2890 /* enable_alternative_services = */ true, NetLogWithSource()));
2891 waiter1.WaitForStream();
2892 EXPECT_TRUE(waiter1.stream_done());
2893 EXPECT_FALSE(waiter1.websocket_stream());
2894 ASSERT_TRUE(waiter1.stream());
2895
2896 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:402897 EXPECT_EQ(
2898 1, GetSocketPoolGroupCount(session->GetSocketPool(
2899 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
2900 EXPECT_EQ(
2901 1, GetHandedOutSocketCount(session->GetSocketPool(
2902 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
Paul Jensen94cde5f2018-03-01 04:38:132903 // Verify socket tagged appropriately.
2904 MockTaggingStreamSocket* socket = socket_factory->GetLastProducedTCPSocket();
2905 EXPECT_TRUE(tag1 == socket->tag());
2906 EXPECT_TRUE(socket->tagged_before_connected());
2907
2908 // Verify the socket tag on the first session can be changed.
2909 StreamRequestWaiter waiter2;
2910 std::unique_ptr<HttpStreamRequest> request2(
2911 session->http_stream_factory()->RequestStream(
2912 request_info2, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter2,
2913 /* enable_ip_based_pooling = */ true,
2914 /* enable_alternative_services = */ true, NetLogWithSource()));
2915 waiter2.WaitForStream();
2916 EXPECT_TRUE(waiter2.stream_done());
2917 EXPECT_FALSE(waiter2.websocket_stream());
2918 ASSERT_TRUE(waiter2.stream());
2919 // Verify still have just one session.
2920 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:402921 EXPECT_EQ(
2922 1, GetSocketPoolGroupCount(session->GetSocketPool(
2923 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
2924 EXPECT_EQ(
2925 1, GetHandedOutSocketCount(session->GetSocketPool(
2926 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
Paul Jensen94cde5f2018-03-01 04:38:132927 // Verify no new sockets created.
2928 EXPECT_EQ(socket, socket_factory->GetLastProducedTCPSocket());
2929 // Verify socket tag changed.
2930 EXPECT_TRUE(tag2 == socket->tag());
2931 EXPECT_FALSE(socket->tagged_before_connected());
2932
2933 // Verify attempting to use the first stream fails because the session's
2934 // socket tag has since changed.
2935 TestCompletionCallback callback1;
2936 EXPECT_EQ(ERR_FAILED,
2937 waiter1.stream()->InitializeStream(
2938 &request_info1, /* can_send_early = */ false, DEFAULT_PRIORITY,
2939 NetLogWithSource(), callback1.callback()));
2940
2941 // Verify the socket tag can be changed, this time using an IP alias
2942 // (different host, same IP).
2943 StreamRequestWaiter waiter3;
2944 std::unique_ptr<HttpStreamRequest> request3(
2945 session->http_stream_factory()->RequestStream(
2946 request_info3, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter3,
2947 /* enable_ip_based_pooling = */ true,
2948 /* enable_alternative_services = */ true, NetLogWithSource()));
2949 waiter3.WaitForStream();
2950 EXPECT_TRUE(waiter3.stream_done());
2951 EXPECT_FALSE(waiter3.websocket_stream());
2952 ASSERT_TRUE(waiter3.stream());
2953 // Verify still have just one session.
2954 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:402955 EXPECT_EQ(
2956 1, GetSocketPoolGroupCount(session->GetSocketPool(
2957 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
2958 EXPECT_EQ(
2959 1, GetHandedOutSocketCount(session->GetSocketPool(
2960 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
Paul Jensen94cde5f2018-03-01 04:38:132961 // Verify no new sockets created.
2962 EXPECT_EQ(socket, socket_factory->GetLastProducedTCPSocket());
2963 // Verify socket tag changed.
2964 EXPECT_TRUE(tag1 == socket->tag());
2965 EXPECT_FALSE(socket->tagged_before_connected());
2966
2967 // Initialize the third stream, thus marking the session active, so it cannot
2968 // have its socket tag changed.
2969 TestCompletionCallback callback3;
2970 EXPECT_EQ(OK,
2971 waiter3.stream()->InitializeStream(
2972 &request_info3, /* can_send_early = */ false, DEFAULT_PRIORITY,
2973 NetLogWithSource(), callback3.callback()));
2974
2975 // Verify a new session is created when a request with a different tag is
2976 // started.
2977 StreamRequestWaiter waiter4;
2978 std::unique_ptr<HttpStreamRequest> request4(
2979 session->http_stream_factory()->RequestStream(
2980 request_info2, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter4,
2981 /* enable_ip_based_pooling = */ true,
2982 /* enable_alternative_services = */ true, NetLogWithSource()));
2983 waiter4.WaitForStream();
2984 EXPECT_TRUE(waiter4.stream_done());
2985 EXPECT_FALSE(waiter4.websocket_stream());
2986 ASSERT_TRUE(waiter4.stream());
2987 // Verify we now have two sessions.
2988 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:402989 EXPECT_EQ(
2990 1, GetSocketPoolGroupCount(session->GetSocketPool(
2991 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
2992 EXPECT_EQ(
2993 2, GetHandedOutSocketCount(session->GetSocketPool(
2994 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
Paul Jensen94cde5f2018-03-01 04:38:132995 // Verify a new socket was created.
2996 MockTaggingStreamSocket* socket2 = socket_factory->GetLastProducedTCPSocket();
2997 EXPECT_NE(socket, socket2);
2998 // Verify tag set appropriately.
2999 EXPECT_TRUE(tag2 == socket2->tag());
3000 EXPECT_TRUE(socket2->tagged_before_connected());
3001 // Verify tag on original socket is unchanged.
3002 EXPECT_TRUE(tag1 == socket->tag());
3003
3004 waiter3.stream()->Close(/* not_reusable = */ true);
3005}
Paul Jensenbc4db502019-04-22 12:34:293006
Bence Békycad805862019-04-22 13:27:263007// Regression test for https://crbug.com/954503.
Paul Jensenbc4db502019-04-22 12:34:293008TEST_F(HttpStreamFactoryTest, ChangeSocketTagAvoidOverwrite) {
3009 SpdySessionDependencies session_deps;
3010 MockTaggingClientSocketFactory* socket_factory =
3011 new MockTaggingClientSocketFactory();
3012 session_deps.socket_factory.reset(socket_factory);
3013
3014 // Prepare for two HTTPS connects.
3015 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
3016 SequencedSocketData socket_data(base::make_span(&mock_read, 1),
3017 base::span<MockWrite>());
3018 socket_data.set_connect_data(MockConnect(ASYNC, OK));
3019 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
3020 MockRead mock_read2(SYNCHRONOUS, ERR_IO_PENDING);
3021 SequencedSocketData socket_data2(base::make_span(&mock_read2, 1),
3022 base::span<MockWrite>());
3023 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
3024 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
3025 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
3026 // Use cert for *.example.org
3027 ssl_socket_data.ssl_info.cert =
3028 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
3029 ssl_socket_data.next_proto = kProtoHTTP2;
3030 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
3031 SSLSocketDataProvider ssl_socket_data2(ASYNC, OK);
3032 // Use cert for *.example.org
3033 ssl_socket_data2.ssl_info.cert =
3034 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
3035 ssl_socket_data2.next_proto = kProtoHTTP2;
3036 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data2);
3037
3038 std::unique_ptr<HttpNetworkSession> session(
3039 SpdySessionDependencies::SpdyCreateSession(&session_deps));
3040
3041 // Prepare three different tags and corresponding HttpRequestInfos.
3042 SocketTag tag1(SocketTag::UNSET_UID, 2);
3043 HttpRequestInfo request_info1;
3044 request_info1.method = "GET";
3045 request_info1.url = GURL("https://www.example.org");
3046 request_info1.load_flags = 0;
3047 request_info1.socket_tag = tag1;
3048 request_info1.traffic_annotation =
3049 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3050
3051 SocketTag tag2(SocketTag::UNSET_UID, 1);
3052 HttpRequestInfo request_info2 = request_info1;
3053 request_info2.socket_tag = tag2;
3054
3055 HttpRequestInfo request_info3 = request_info1;
3056 SocketTag tag3(SocketTag::UNSET_UID, 3);
3057 request_info3.socket_tag = tag3;
3058
3059 // Prepare another HttpRequestInfo with tag3 and a different host name.
3060 HttpRequestInfo request_info4 = request_info1;
3061 request_info4.socket_tag = tag3;
3062 request_info4.url = GURL("https://foo.example.org");
3063
3064 // Verify one stream with one tag results in one session, group and
3065 // socket.
3066 SSLConfig ssl_config;
3067 StreamRequestWaiter waiter1;
3068 std::unique_ptr<HttpStreamRequest> request1(
3069 session->http_stream_factory()->RequestStream(
3070 request_info1, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter1,
3071 /* enable_ip_based_pooling = */ true,
3072 /* enable_alternative_services = */ true, NetLogWithSource()));
3073 waiter1.WaitForStream();
3074 EXPECT_TRUE(waiter1.stream_done());
3075 EXPECT_FALSE(waiter1.websocket_stream());
3076 ASSERT_TRUE(waiter1.stream());
3077
3078 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
3079 EXPECT_EQ(
3080 1, GetSocketPoolGroupCount(session->GetSocketPool(
3081 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
3082 EXPECT_EQ(
3083 1, GetHandedOutSocketCount(session->GetSocketPool(
3084 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
3085 // Verify socket tagged appropriately.
3086 MockTaggingStreamSocket* socket = socket_factory->GetLastProducedTCPSocket();
3087 EXPECT_TRUE(tag1 == socket->tag());
3088 EXPECT_TRUE(socket->tagged_before_connected());
3089
3090 // Initialize the first stream, thus marking the session active, so it cannot
3091 // have its socket tag changed and be reused for the second session.
3092 TestCompletionCallback callback1;
3093 EXPECT_EQ(OK,
3094 waiter1.stream()->InitializeStream(
3095 &request_info1, /* can_send_early = */ false, DEFAULT_PRIORITY,
3096 NetLogWithSource(), callback1.callback()));
3097
3098 // Create a second stream with a new tag.
3099 StreamRequestWaiter waiter2;
3100 std::unique_ptr<HttpStreamRequest> request2(
3101 session->http_stream_factory()->RequestStream(
3102 request_info2, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter2,
3103 /* enable_ip_based_pooling = */ true,
3104 /* enable_alternative_services = */ true, NetLogWithSource()));
3105 waiter2.WaitForStream();
3106 EXPECT_TRUE(waiter2.stream_done());
3107 EXPECT_FALSE(waiter2.websocket_stream());
3108 ASSERT_TRUE(waiter2.stream());
3109 // Verify we now have two sessions.
3110 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
3111 EXPECT_EQ(
3112 1, GetSocketPoolGroupCount(session->GetSocketPool(
3113 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
3114 EXPECT_EQ(
3115 2, GetHandedOutSocketCount(session->GetSocketPool(
3116 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
3117 // Verify a new socket was created.
3118 MockTaggingStreamSocket* socket2 = socket_factory->GetLastProducedTCPSocket();
3119 EXPECT_NE(socket, socket2);
3120 // Verify tag set appropriately.
3121 EXPECT_TRUE(tag2 == socket2->tag());
3122 EXPECT_TRUE(socket2->tagged_before_connected());
3123 // Verify tag on original socket is unchanged.
3124 EXPECT_TRUE(tag1 == socket->tag());
3125
3126 // Initialize the second stream, thus marking the session active, so it cannot
3127 // have its socket tag changed and be reused for the third session.
3128 TestCompletionCallback callback2;
3129 EXPECT_EQ(OK,
3130 waiter2.stream()->InitializeStream(
3131 &request_info2, /* can_send_early = */ false, DEFAULT_PRIORITY,
3132 NetLogWithSource(), callback2.callback()));
3133
3134 // Release first stream so first session can be retagged for third request.
3135 waiter1.stream()->Close(/* not_reusable = */ true);
3136
3137 // Verify the first session can be retagged for a third request.
3138 StreamRequestWaiter waiter3;
3139 std::unique_ptr<HttpStreamRequest> request3(
3140 session->http_stream_factory()->RequestStream(
3141 request_info3, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter3,
3142 /* enable_ip_based_pooling = */ true,
3143 /* enable_alternative_services = */ true, NetLogWithSource()));
3144 waiter3.WaitForStream();
3145 EXPECT_TRUE(waiter3.stream_done());
3146 EXPECT_FALSE(waiter3.websocket_stream());
3147 ASSERT_TRUE(waiter3.stream());
3148 // Verify still have two sessions.
3149 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
3150 EXPECT_EQ(
3151 1, GetSocketPoolGroupCount(session->GetSocketPool(
3152 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
3153 EXPECT_EQ(
3154 2, GetHandedOutSocketCount(session->GetSocketPool(
3155 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
3156 // Verify no new sockets created.
3157 EXPECT_EQ(socket2, socket_factory->GetLastProducedTCPSocket());
3158 // Verify socket tag changed.
3159 EXPECT_TRUE(tag3 == socket->tag());
3160 EXPECT_FALSE(socket->tagged_before_connected());
3161
3162 // Release second stream so second session can be retagged for fourth request.
3163 waiter2.stream()->Close(/* not_reusable = */ true);
3164
3165 // Request a stream with a new tag and a different host that aliases existing
3166 // sessions.
3167 StreamRequestWaiter waiter4;
3168 std::unique_ptr<HttpStreamRequest> request4(
3169 session->http_stream_factory()->RequestStream(
3170 request_info4, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter4,
3171 /* enable_ip_based_pooling = */ true,
3172 /* enable_alternative_services = */ true, NetLogWithSource()));
3173 waiter4.WaitForStream();
3174 EXPECT_TRUE(waiter4.stream_done());
3175 EXPECT_FALSE(waiter4.websocket_stream());
3176 ASSERT_TRUE(waiter4.stream());
3177 // Verify no new sockets created.
3178 EXPECT_EQ(socket2, socket_factory->GetLastProducedTCPSocket());
3179}
Paul Jensena457017a2018-01-19 23:52:043180#endif
3181
Paul Jensen6afc0b42018-02-28 01:14:563182// Test that when creating a stream all sessions that alias an IP are tried,
3183// not just one. This is important because there can be multiple sessions
3184// that could satisfy a stream request and they should all be tried.
3185TEST_F(HttpStreamFactoryTest, MultiIPAliases) {
3186 SpdySessionDependencies session_deps;
3187
3188 // Prepare for two HTTPS connects.
3189 MockRead mock_read1(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:013190 SequencedSocketData socket_data1(base::make_span(&mock_read1, 1),
3191 base::span<MockWrite>());
Paul Jensen6afc0b42018-02-28 01:14:563192 socket_data1.set_connect_data(MockConnect(ASYNC, OK));
3193 session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
3194 MockRead mock_read2(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:013195 SequencedSocketData socket_data2(base::make_span(&mock_read2, 1),
3196 base::span<MockWrite>());
Paul Jensen6afc0b42018-02-28 01:14:563197 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
3198 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
3199 SSLSocketDataProvider ssl_socket_data1(ASYNC, OK);
3200 // Load cert for *.example.org
3201 ssl_socket_data1.ssl_info.cert =
3202 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
3203 ssl_socket_data1.next_proto = kProtoHTTP2;
3204 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data1);
3205 SSLSocketDataProvider ssl_socket_data2(ASYNC, OK);
3206 // Load cert for *.example.org
3207 ssl_socket_data2.ssl_info.cert =
3208 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
3209 ssl_socket_data2.next_proto = kProtoHTTP2;
3210 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data2);
3211
Paul Jensen6afc0b42018-02-28 01:14:563212 std::unique_ptr<HttpNetworkSession> session(
3213 SpdySessionDependencies::SpdyCreateSession(&session_deps));
3214
3215 // Create two HttpRequestInfos, differing only in host name.
3216 // Both will resolve to 127.0.0.1 and hence be IP aliases.
3217 HttpRequestInfo request_info1;
3218 request_info1.method = "GET";
3219 request_info1.url = GURL("https://a.example.org");
3220 request_info1.privacy_mode = PRIVACY_MODE_DISABLED;
Ramin Halavati216426e2018-03-12 22:13:353221 request_info1.traffic_annotation =
3222 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Paul Jensen6afc0b42018-02-28 01:14:563223 HttpRequestInfo request_info1_alias = request_info1;
3224 request_info1.url = GURL("https://b.example.org");
3225
3226 // Create two more HttpRequestInfos but with different privacy_mode.
3227 HttpRequestInfo request_info2;
3228 request_info2.method = "GET";
3229 request_info2.url = GURL("https://a.example.org");
3230 request_info2.privacy_mode = PRIVACY_MODE_ENABLED;
Ramin Halavati216426e2018-03-12 22:13:353231 request_info2.traffic_annotation =
3232 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Paul Jensen6afc0b42018-02-28 01:14:563233 HttpRequestInfo request_info2_alias = request_info2;
3234 request_info2.url = GURL("https://b.example.org");
3235
3236 // Open one session.
3237 SSLConfig ssl_config;
3238 StreamRequestWaiter waiter1;
3239 std::unique_ptr<HttpStreamRequest> request1(
3240 session->http_stream_factory()->RequestStream(
3241 request_info1, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter1,
3242 /* enable_ip_based_pooling = */ true,
3243 /* enable_alternative_services = */ true, NetLogWithSource()));
3244 waiter1.WaitForStream();
3245 EXPECT_TRUE(waiter1.stream_done());
3246 EXPECT_FALSE(waiter1.websocket_stream());
3247 ASSERT_TRUE(waiter1.stream());
3248
3249 // Verify just one session created.
3250 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:403251 EXPECT_EQ(
3252 1, GetSocketPoolGroupCount(session->GetSocketPool(
3253 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
3254 EXPECT_EQ(
3255 1, GetHandedOutSocketCount(session->GetSocketPool(
3256 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
Paul Jensen6afc0b42018-02-28 01:14:563257
3258 // Open another session to same IP but with different privacy mode.
3259 StreamRequestWaiter waiter2;
3260 std::unique_ptr<HttpStreamRequest> request2(
3261 session->http_stream_factory()->RequestStream(
3262 request_info2, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter2,
3263 /* enable_ip_based_pooling = */ true,
3264 /* enable_alternative_services = */ true, NetLogWithSource()));
3265 waiter2.WaitForStream();
3266 EXPECT_TRUE(waiter2.stream_done());
3267 EXPECT_FALSE(waiter2.websocket_stream());
3268 ASSERT_TRUE(waiter2.stream());
3269
3270 // Verify two sessions are now open.
3271 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:403272 EXPECT_EQ(
3273 2, GetSocketPoolGroupCount(session->GetSocketPool(
3274 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
3275 EXPECT_EQ(
3276 2, GetHandedOutSocketCount(session->GetSocketPool(
3277 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
Paul Jensen6afc0b42018-02-28 01:14:563278
3279 // Open a third session that IP aliases first session.
3280 StreamRequestWaiter waiter3;
3281 std::unique_ptr<HttpStreamRequest> request3(
3282 session->http_stream_factory()->RequestStream(
3283 request_info1_alias, DEFAULT_PRIORITY, ssl_config, ssl_config,
3284 &waiter3,
3285 /* enable_ip_based_pooling = */ true,
3286 /* enable_alternative_services = */ true, NetLogWithSource()));
3287 waiter3.WaitForStream();
3288 EXPECT_TRUE(waiter3.stream_done());
3289 EXPECT_FALSE(waiter3.websocket_stream());
3290 ASSERT_TRUE(waiter3.stream());
3291
3292 // Verify the session pool reused the first session and no new session is
3293 // created. This will fail unless the session pool supports multiple
3294 // sessions aliasing a single IP.
3295 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:403296 EXPECT_EQ(
3297 2, GetSocketPoolGroupCount(session->GetSocketPool(
3298 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
3299 EXPECT_EQ(
3300 2, GetHandedOutSocketCount(session->GetSocketPool(
3301 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
Paul Jensen6afc0b42018-02-28 01:14:563302
3303 // Open a fourth session that IP aliases the second session.
3304 StreamRequestWaiter waiter4;
3305 std::unique_ptr<HttpStreamRequest> request4(
3306 session->http_stream_factory()->RequestStream(
3307 request_info2_alias, DEFAULT_PRIORITY, ssl_config, ssl_config,
3308 &waiter4,
3309 /* enable_ip_based_pooling = */ true,
3310 /* enable_alternative_services = */ true, NetLogWithSource()));
3311 waiter4.WaitForStream();
3312 EXPECT_TRUE(waiter4.stream_done());
3313 EXPECT_FALSE(waiter4.websocket_stream());
3314 ASSERT_TRUE(waiter4.stream());
3315
3316 // Verify the session pool reused the second session. This will fail unless
3317 // the session pool supports multiple sessions aliasing a single IP.
3318 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
Matt Menked23ab952019-03-06 00:24:403319 EXPECT_EQ(
3320 2, GetSocketPoolGroupCount(session->GetSocketPool(
3321 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
3322 EXPECT_EQ(
3323 2, GetHandedOutSocketCount(session->GetSocketPool(
3324 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct())));
Paul Jensen6afc0b42018-02-28 01:14:563325}
3326
Ryan Hamilton64f21d52019-08-31 07:10:513327class ProcessAlternativeServicesTest : public TestWithTaskEnvironment {
3328 public:
3329 ProcessAlternativeServicesTest() {
3330 session_params_.enable_quic = true;
3331
3332 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
3333 session_context_.host_resolver = &host_resolver_;
3334 session_context_.cert_verifier = &cert_verifier_;
3335 session_context_.transport_security_state = &transport_security_state_;
3336 session_context_.cert_transparency_verifier = &ct_verifier_;
3337 session_context_.client_socket_factory = &socket_factory_;
3338 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
3339 session_context_.ssl_config_service = &ssl_config_service_;
3340 session_context_.http_server_properties = &http_server_properties_;
Victor Vasiliev7752898d2019-11-14 21:30:223341 session_context_.quic_context = &quic_context_;
Ryan Hamilton64f21d52019-08-31 07:10:513342 }
3343
3344 protected:
3345 HttpNetworkSession::Params session_params_;
3346 HttpNetworkSession::Context session_context_;
3347 std::unique_ptr<HttpNetworkSession> session_;
3348 HttpServerProperties http_server_properties_;
Victor Vasilieva1e66d72019-12-05 17:55:383349 QuicContext quic_context_;
Ryan Hamilton64f21d52019-08-31 07:10:513350
3351 private:
3352 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_ =
3353 ProxyResolutionService::CreateDirect();
3354 SSLConfigServiceDefaults ssl_config_service_;
3355 MockClientSocketFactory socket_factory_;
3356 MockHostResolver host_resolver_;
3357 MockCertVerifier cert_verifier_;
3358 TransportSecurityState transport_security_state_;
3359 MultiLogCTVerifier ct_verifier_;
3360 DefaultCTPolicyEnforcer ct_policy_enforcer_;
3361};
3362
3363TEST_F(ProcessAlternativeServicesTest, ProcessEmptyAltSvc) {
3364 session_ =
3365 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
3366 url::SchemeHostPort origin;
3367 NetworkIsolationKey network_isolation_key;
3368
3369 scoped_refptr<HttpResponseHeaders> headers(
3370 base::MakeRefCounted<HttpResponseHeaders>(""));
3371 session_->http_stream_factory()->ProcessAlternativeServices(
3372 session_.get(), network_isolation_key, headers.get(), origin);
3373
3374 AlternativeServiceInfoVector alternatives =
3375 http_server_properties_.GetAlternativeServiceInfos(origin,
3376 network_isolation_key);
3377 EXPECT_TRUE(alternatives.empty());
3378}
3379
3380TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcClear) {
3381 session_ =
3382 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
3383 url::SchemeHostPort origin(url::kHttpsScheme, "example.com", 443);
3384 ;
3385 NetworkIsolationKey network_isolation_key(
3386 url::Origin::Create(GURL("https://example.com")),
3387 url::Origin::Create(GURL("https://example.com")));
3388
3389 http_server_properties_.SetAlternativeServices(
3390 origin, network_isolation_key,
3391 {AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3392 {kProtoQUIC, "", 443},
3393 base::Time::Now() + base::TimeDelta::FromSeconds(30),
3394 quic::AllSupportedVersions())});
3395
3396 EXPECT_FALSE(http_server_properties_
3397 .GetAlternativeServiceInfos(origin, network_isolation_key)
3398 .empty());
3399
3400 scoped_refptr<HttpResponseHeaders> headers(
3401 base::MakeRefCounted<HttpResponseHeaders>(""));
3402 headers->AddHeader("alt-svc: clear");
3403
3404 session_->http_stream_factory()->ProcessAlternativeServices(
3405 session_.get(), network_isolation_key, headers.get(), origin);
3406
3407 AlternativeServiceInfoVector alternatives =
3408 http_server_properties_.GetAlternativeServiceInfos(origin,
3409 network_isolation_key);
3410 EXPECT_TRUE(alternatives.empty());
3411}
3412
3413TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:383414 quic_context_.params()->supported_versions = quic::AllSupportedVersions();
Ryan Hamilton64f21d52019-08-31 07:10:513415 session_ =
3416 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
3417 url::SchemeHostPort origin(url::kHttpsScheme, "example.com", 443);
3418
3419 NetworkIsolationKey network_isolation_key(
3420 url::Origin::Create(GURL("https://example.com")),
3421 url::Origin::Create(GURL("https://example.com")));
3422
3423 scoped_refptr<HttpResponseHeaders> headers(
3424 base::MakeRefCounted<HttpResponseHeaders>(""));
Victor Vasiliev7da08172019-10-14 06:04:253425 headers->AddHeader("alt-svc: quic=\":443\"; v=\"99,50,49,48,47,46,43,39\"");
Ryan Hamilton64f21d52019-08-31 07:10:513426
3427 session_->http_stream_factory()->ProcessAlternativeServices(
3428 session_.get(), network_isolation_key, headers.get(), origin);
3429
3430 AlternativeServiceInfoVector alternatives =
3431 http_server_properties_.GetAlternativeServiceInfos(origin,
3432 network_isolation_key);
3433 ASSERT_EQ(1u, alternatives.size());
3434 EXPECT_EQ(kProtoQUIC, alternatives[0].protocol());
3435 EXPECT_EQ(HostPortPair("example.com", 443), alternatives[0].host_port_pair());
3436 EXPECT_EQ(quic::AllSupportedVersions().size(),
3437 alternatives[0].advertised_versions().size());
3438 for (quic::ParsedQuicVersion version : quic::AllSupportedVersions()) {
3439 EXPECT_TRUE(base::Contains(alternatives[0].advertised_versions(), version))
3440 << version;
3441 }
3442}
3443
3444TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcQuicIetf) {
Victor Vasilieva1e66d72019-12-05 17:55:383445 quic_context_.params()->supported_versions = quic::AllSupportedVersions();
Ryan Hamilton64f21d52019-08-31 07:10:513446 session_ =
3447 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
3448 url::SchemeHostPort origin(url::kHttpsScheme, "example.com", 443);
3449
3450 NetworkIsolationKey network_isolation_key(
3451 url::Origin::Create(GURL("https://example.com")),
3452 url::Origin::Create(GURL("https://example.com")));
3453
3454 scoped_refptr<HttpResponseHeaders> headers(
3455 base::MakeRefCounted<HttpResponseHeaders>(""));
3456 headers->AddHeader(
3457 "alt-svc: "
Victor Vasiliev7da08172019-10-14 06:04:253458 "h3-Q099=\":443\",h3-Q050=\":443\",h3-Q049=\":443\",h3-Q048=\":443\",h3-"
3459 "Q047=\":443\",h3-"
Dan Zhangbfca7ee2019-09-27 16:00:363460 "Q043=\":443\",h3-"
Ryan Hamilton64f21d52019-08-31 07:10:513461 "Q039=\":443\"");
3462
3463 session_->http_stream_factory()->ProcessAlternativeServices(
3464 session_.get(), network_isolation_key, headers.get(), origin);
3465
3466 quic::ParsedQuicVersionVector versions = {
3467 {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_99},
Victor Vasiliev7da08172019-10-14 06:04:253468 {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_50},
Dan Zhangbfca7ee2019-09-27 16:00:363469 {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_49},
Ryan Hamilton64f21d52019-08-31 07:10:513470 {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_48},
Ryan Hamilton64f21d52019-08-31 07:10:513471 {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_43},
Ryan Hamilton64f21d52019-08-31 07:10:513472 };
3473 AlternativeServiceInfoVector alternatives =
3474 http_server_properties_.GetAlternativeServiceInfos(origin,
3475 network_isolation_key);
3476 ASSERT_EQ(versions.size(), alternatives.size());
3477 for (size_t i = 0; i < alternatives.size(); ++i) {
3478 EXPECT_EQ(kProtoQUIC, alternatives[i].protocol());
3479 EXPECT_EQ(HostPortPair("example.com", 443),
3480 alternatives[i].host_port_pair());
3481 EXPECT_EQ(1u, alternatives[i].advertised_versions().size());
3482 EXPECT_EQ(versions[i], alternatives[i].advertised_versions()[0]);
3483 }
3484}
3485
3486TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcHttp2) {
Victor Vasilieva1e66d72019-12-05 17:55:383487 quic_context_.params()->supported_versions = quic::AllSupportedVersions();
Ryan Hamilton64f21d52019-08-31 07:10:513488 session_ =
3489 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
3490 url::SchemeHostPort origin(url::kHttpsScheme, "example.com", 443);
3491
3492 NetworkIsolationKey network_isolation_key(
3493 url::Origin::Create(GURL("https://example.com")),
3494 url::Origin::Create(GURL("https://example.com")));
3495
3496 scoped_refptr<HttpResponseHeaders> headers(
3497 base::MakeRefCounted<HttpResponseHeaders>(""));
3498 headers->AddHeader("alt-svc: h2=\"other.example.com:443\"");
3499
3500 session_->http_stream_factory()->ProcessAlternativeServices(
3501 session_.get(), network_isolation_key, headers.get(), origin);
3502
3503 AlternativeServiceInfoVector alternatives =
3504 http_server_properties_.GetAlternativeServiceInfos(origin,
3505 network_isolation_key);
3506 ASSERT_EQ(1u, alternatives.size());
3507 EXPECT_EQ(kProtoHTTP2, alternatives[0].protocol());
3508 EXPECT_EQ(HostPortPair("other.example.com", 443),
3509 alternatives[0].host_port_pair());
3510 EXPECT_EQ(0u, alternatives[0].advertised_versions().size());
3511}
3512
[email protected]81cdfcd2010-10-16 00:49:003513} // namespace
3514
3515} // namespace net