1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/http/http_stream_factory.h"
6
7 #include <stdint.h>
8
9 #include <memory>
10 #include <set>
11 #include <string>
12 #include <tuple>
13 #include <utility>
14 #include <vector>
15
16 #include "base/compiler_specific.h"
17 #include "base/containers/contains.h"
18 #include "base/memory/ptr_util.h"
19 #include "base/no_destructor.h"
20 #include "base/run_loop.h"
21 #include "base/strings/strcat.h"
22 #include "base/strings/string_piece.h"
23 #include "base/test/metrics/histogram_tester.h"
24 #include "base/test/scoped_feature_list.h"
25 #include "build/build_config.h"
26 #include "net/base/completion_once_callback.h"
27 #include "net/base/features.h"
28 #include "net/base/net_errors.h"
29 #include "net/base/network_isolation_key.h"
30 #include "net/base/port_util.h"
31 #include "net/base/privacy_mode.h"
32 #include "net/base/proxy_chain.h"
33 #include "net/base/proxy_server.h"
34 #include "net/base/proxy_string_util.h"
35 #include "net/base/schemeful_site.h"
36 #include "net/base/test_completion_callback.h"
37 #include "net/base/test_proxy_delegate.h"
38 #include "net/cert/ct_policy_enforcer.h"
39 #include "net/cert/mock_cert_verifier.h"
40 #include "net/cert/multi_log_ct_verifier.h"
41 #include "net/dns/mock_host_resolver.h"
42 #include "net/dns/public/secure_dns_policy.h"
43 #include "net/http/bidirectional_stream_impl.h"
44 #include "net/http/bidirectional_stream_request_info.h"
45 #include "net/http/http_auth_handler_factory.h"
46 #include "net/http/http_network_session.h"
47 #include "net/http/http_network_session_peer.h"
48 #include "net/http/http_network_transaction.h"
49 #include "net/http/http_proxy_connect_job.h"
50 #include "net/http/http_request_info.h"
51 #include "net/http/http_server_properties.h"
52 #include "net/http/http_stream.h"
53 #include "net/http/transport_security_state.h"
54 #include "net/log/net_log_with_source.h"
55 #include "net/proxy_resolution/configured_proxy_resolution_service.h"
56 #include "net/proxy_resolution/proxy_info.h"
57 #include "net/quic/mock_crypto_client_stream_factory.h"
58 #include "net/quic/mock_quic_context.h"
59 #include "net/quic/quic_http_utils.h"
60 #include "net/quic/quic_stream_factory_peer.h"
61 #include "net/quic/quic_test_packet_maker.h"
62 #include "net/quic/quic_test_packet_printer.h"
63 #include "net/socket/client_socket_handle.h"
64 #include "net/socket/client_socket_pool.h"
65 #include "net/socket/connect_job.h"
66 #include "net/socket/mock_client_socket_pool_manager.h"
67 #include "net/socket/next_proto.h"
68 #include "net/socket/socket_tag.h"
69 #include "net/socket/socket_test_util.h"
70 #include "net/socket/socks_connect_job.h"
71 #include "net/socket/ssl_connect_job.h"
72 #include "net/socket/transport_connect_job.h"
73 #include "net/spdy/spdy_session.h"
74 #include "net/spdy/spdy_session_pool.h"
75 #include "net/spdy/spdy_test_util_common.h"
76 #include "net/ssl/ssl_config_service.h"
77 #include "net/ssl/ssl_config_service_defaults.h"
78 #include "net/test/cert_test_util.h"
79 #include "net/test/gtest_util.h"
80 #include "net/test/test_data_directory.h"
81 #include "net/test/test_with_task_environment.h"
82 #include "net/third_party/quiche/src/quiche/quic/core/quic_server_id.h"
83 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
84 #include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
85 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
86 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
87 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
88 // This file can be included from net/http even though
89 // it is in net/websockets because it doesn't
90 // introduce any link dependency to net/websockets.
91 #include "net/websockets/websocket_handshake_stream_base.h"
92 #include "testing/gmock/include/gmock/gmock.h"
93 #include "testing/gtest/include/gtest/gtest.h"
94 #include "third_party/abseil-cpp/absl/types/optional.h"
95 #include "url/gurl.h"
96 #include "url/scheme_host_port.h"
97 #include "url/url_constants.h"
98
99 using ::testing::Contains;
100 using ::testing::ElementsAre;
101 using ::testing::IsEmpty;
102 using ::testing::Key;
103 using ::testing::SizeIs;
104
105 using net::test::IsError;
106 using net::test::IsOk;
107
108 namespace base {
109 class Value;
110 } // namespace base
111
112 namespace net {
113
114 class BidirectionalStreamImpl;
115 class WebSocketEndpointLockManager;
116
117 namespace {
118
119 class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
120 public:
121 enum StreamType {
122 kStreamTypeBasic,
123 kStreamTypeSpdy,
124 };
125
MockWebSocketHandshakeStream(StreamType type)126 explicit MockWebSocketHandshakeStream(StreamType type) : type_(type) {}
127
128 ~MockWebSocketHandshakeStream() override = default;
129
type() const130 StreamType type() const { return type_; }
131
132 // HttpStream methods
RegisterRequest(const HttpRequestInfo * request_info)133 void RegisterRequest(const HttpRequestInfo* request_info) override {}
InitializeStream(bool can_send_early,RequestPriority priority,const NetLogWithSource & net_log,CompletionOnceCallback callback)134 int InitializeStream(bool can_send_early,
135 RequestPriority priority,
136 const NetLogWithSource& net_log,
137 CompletionOnceCallback callback) override {
138 return ERR_IO_PENDING;
139 }
SendRequest(const HttpRequestHeaders & request_headers,HttpResponseInfo * response,CompletionOnceCallback callback)140 int SendRequest(const HttpRequestHeaders& request_headers,
141 HttpResponseInfo* response,
142 CompletionOnceCallback callback) override {
143 return ERR_IO_PENDING;
144 }
ReadResponseHeaders(CompletionOnceCallback callback)145 int ReadResponseHeaders(CompletionOnceCallback callback) override {
146 return ERR_IO_PENDING;
147 }
ReadResponseBody(IOBuffer * buf,int buf_len,CompletionOnceCallback callback)148 int ReadResponseBody(IOBuffer* buf,
149 int buf_len,
150 CompletionOnceCallback callback) override {
151 return ERR_IO_PENDING;
152 }
Close(bool not_reusable)153 void Close(bool not_reusable) override {}
IsResponseBodyComplete() const154 bool IsResponseBodyComplete() const override { return false; }
IsConnectionReused() const155 bool IsConnectionReused() const override { return false; }
SetConnectionReused()156 void SetConnectionReused() override {}
CanReuseConnection() const157 bool CanReuseConnection() const override { return false; }
GetTotalReceivedBytes() const158 int64_t GetTotalReceivedBytes() const override { return 0; }
GetTotalSentBytes() const159 int64_t GetTotalSentBytes() const override { return 0; }
GetLoadTimingInfo(LoadTimingInfo * load_timing_info) const160 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
161 return false;
162 }
GetAlternativeService(AlternativeService * alternative_service) const163 bool GetAlternativeService(
164 AlternativeService* alternative_service) const override {
165 return false;
166 }
GetSSLInfo(SSLInfo * ssl_info)167 void GetSSLInfo(SSLInfo* ssl_info) override {}
GetSSLCertRequestInfo(SSLCertRequestInfo * cert_request_info)168 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {}
GetRemoteEndpoint(IPEndPoint * endpoint)169 int GetRemoteEndpoint(IPEndPoint* endpoint) override {
170 return ERR_UNEXPECTED;
171 }
Drain(HttpNetworkSession * session)172 void Drain(HttpNetworkSession* session) override {}
PopulateNetErrorDetails(NetErrorDetails * details)173 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
SetPriority(RequestPriority priority)174 void SetPriority(RequestPriority priority) override {}
RenewStreamForAuth()175 std::unique_ptr<HttpStream> RenewStreamForAuth() override { return nullptr; }
GetDnsAliases() const176 const std::set<std::string>& GetDnsAliases() const override {
177 static const base::NoDestructor<std::set<std::string>> nullset_result;
178 return *nullset_result;
179 }
GetAcceptChViaAlps() const180 base::StringPiece GetAcceptChViaAlps() const override { return {}; }
181
Upgrade()182 std::unique_ptr<WebSocketStream> Upgrade() override { return nullptr; }
183
CanReadFromStream() const184 bool CanReadFromStream() const override { return true; }
185
GetWeakPtr()186 base::WeakPtr<WebSocketHandshakeStreamBase> GetWeakPtr() override {
187 return weak_ptr_factory_.GetWeakPtr();
188 }
189
190 private:
191 const StreamType type_;
192 base::WeakPtrFactory<MockWebSocketHandshakeStream> weak_ptr_factory_{this};
193 };
194
195 // HttpStreamFactory subclass that can wait until a preconnect is complete.
196 class MockHttpStreamFactoryForPreconnect : public HttpStreamFactory {
197 public:
MockHttpStreamFactoryForPreconnect(HttpNetworkSession * session)198 explicit MockHttpStreamFactoryForPreconnect(HttpNetworkSession* session)
199 : HttpStreamFactory(session) {}
200 ~MockHttpStreamFactoryForPreconnect() override = default;
201
WaitForPreconnects()202 void WaitForPreconnects() {
203 while (!preconnect_done_) {
204 waiting_for_preconnect_ = true;
205 loop_.Run();
206 waiting_for_preconnect_ = false;
207 }
208 }
209
210 private:
211 // HttpStreamFactory methods.
OnPreconnectsCompleteInternal()212 void OnPreconnectsCompleteInternal() override {
213 preconnect_done_ = true;
214 if (waiting_for_preconnect_)
215 loop_.QuitWhenIdle();
216 }
217
218 bool preconnect_done_ = false;
219 bool waiting_for_preconnect_ = false;
220 base::RunLoop loop_;
221 };
222
223 class StreamRequestWaiter : public HttpStreamRequest::Delegate {
224 public:
225 StreamRequestWaiter() = default;
226
227 StreamRequestWaiter(const StreamRequestWaiter&) = delete;
228 StreamRequestWaiter& operator=(const StreamRequestWaiter&) = delete;
229
230 // HttpStreamRequest::Delegate
231
OnStreamReady(const SSLConfig & used_ssl_config,const ProxyInfo & used_proxy_info,std::unique_ptr<HttpStream> stream)232 void OnStreamReady(const SSLConfig& used_ssl_config,
233 const ProxyInfo& used_proxy_info,
234 std::unique_ptr<HttpStream> stream) override {
235 stream_done_ = true;
236 if (loop_)
237 loop_->Quit();
238 stream_ = std::move(stream);
239 used_ssl_config_ = used_ssl_config;
240 used_proxy_info_ = used_proxy_info;
241 }
242
OnWebSocketHandshakeStreamReady(const SSLConfig & used_ssl_config,const ProxyInfo & used_proxy_info,std::unique_ptr<WebSocketHandshakeStreamBase> stream)243 void OnWebSocketHandshakeStreamReady(
244 const SSLConfig& used_ssl_config,
245 const ProxyInfo& used_proxy_info,
246 std::unique_ptr<WebSocketHandshakeStreamBase> stream) override {
247 stream_done_ = true;
248 if (loop_)
249 loop_->Quit();
250 websocket_stream_ = std::move(stream);
251 used_ssl_config_ = used_ssl_config;
252 used_proxy_info_ = used_proxy_info;
253 }
254
OnBidirectionalStreamImplReady(const SSLConfig & used_ssl_config,const ProxyInfo & used_proxy_info,std::unique_ptr<BidirectionalStreamImpl> stream)255 void OnBidirectionalStreamImplReady(
256 const SSLConfig& used_ssl_config,
257 const ProxyInfo& used_proxy_info,
258 std::unique_ptr<BidirectionalStreamImpl> stream) override {
259 stream_done_ = true;
260 if (loop_)
261 loop_->Quit();
262 bidirectional_stream_impl_ = std::move(stream);
263 used_ssl_config_ = used_ssl_config;
264 used_proxy_info_ = used_proxy_info;
265 }
266
OnStreamFailed(int status,const NetErrorDetails & net_error_details,const SSLConfig & used_ssl_config,const ProxyInfo & used_proxy_info,ResolveErrorInfo resolve_error_info)267 void OnStreamFailed(int status,
268 const NetErrorDetails& net_error_details,
269 const SSLConfig& used_ssl_config,
270 const ProxyInfo& used_proxy_info,
271 ResolveErrorInfo resolve_error_info) override {
272 stream_done_ = true;
273 if (loop_)
274 loop_->Quit();
275 used_ssl_config_ = used_ssl_config;
276 error_status_ = status;
277 }
278
OnCertificateError(int status,const SSLConfig & used_ssl_config,const SSLInfo & ssl_info)279 void OnCertificateError(int status,
280 const SSLConfig& used_ssl_config,
281 const SSLInfo& ssl_info) override {}
282
OnNeedsProxyAuth(const HttpResponseInfo & proxy_response,const SSLConfig & used_ssl_config,const ProxyInfo & used_proxy_info,HttpAuthController * auth_controller)283 void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response,
284 const SSLConfig& used_ssl_config,
285 const ProxyInfo& used_proxy_info,
286 HttpAuthController* auth_controller) override {}
287
OnNeedsClientAuth(const SSLConfig & used_ssl_config,SSLCertRequestInfo * cert_info)288 void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
289 SSLCertRequestInfo* cert_info) override {}
290
OnQuicBroken()291 void OnQuicBroken() override {}
292
WaitForStream()293 void WaitForStream() {
294 stream_done_ = false;
295 loop_ = std::make_unique<base::RunLoop>();
296 while (!stream_done_)
297 loop_->Run();
298 loop_.reset();
299 }
300
used_ssl_config() const301 const SSLConfig& used_ssl_config() const { return used_ssl_config_; }
302
used_proxy_info() const303 const ProxyInfo& used_proxy_info() const { return used_proxy_info_; }
304
stream()305 HttpStream* stream() { return stream_.get(); }
306
websocket_stream()307 MockWebSocketHandshakeStream* websocket_stream() {
308 return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get());
309 }
310
bidirectional_stream_impl()311 BidirectionalStreamImpl* bidirectional_stream_impl() {
312 return bidirectional_stream_impl_.get();
313 }
314
stream_done() const315 bool stream_done() const { return stream_done_; }
error_status() const316 int error_status() const { return error_status_; }
317
318 protected:
319 bool stream_done_ = false;
320 std::unique_ptr<base::RunLoop> loop_;
321 std::unique_ptr<HttpStream> stream_;
322 std::unique_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
323 std::unique_ptr<BidirectionalStreamImpl> bidirectional_stream_impl_;
324 SSLConfig used_ssl_config_;
325 ProxyInfo used_proxy_info_;
326 int error_status_ = OK;
327 };
328
329 class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream {
330 public:
WebSocketBasicHandshakeStream(std::unique_ptr<ClientSocketHandle> connection)331 explicit WebSocketBasicHandshakeStream(
332 std::unique_ptr<ClientSocketHandle> connection)
333 : MockWebSocketHandshakeStream(kStreamTypeBasic),
334 connection_(std::move(connection)) {}
335
~WebSocketBasicHandshakeStream()336 ~WebSocketBasicHandshakeStream() override {
337 connection_->socket()->Disconnect();
338 }
339
connection()340 ClientSocketHandle* connection() { return connection_.get(); }
341
342 private:
343 std::unique_ptr<ClientSocketHandle> connection_;
344 };
345
346 class WebSocketStreamCreateHelper
347 : public WebSocketHandshakeStreamBase::CreateHelper {
348 public:
349 ~WebSocketStreamCreateHelper() override = default;
350
CreateBasicStream(std::unique_ptr<ClientSocketHandle> connection,bool using_proxy,WebSocketEndpointLockManager * websocket_endpoint_lock_manager)351 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
352 std::unique_ptr<ClientSocketHandle> connection,
353 bool using_proxy,
354 WebSocketEndpointLockManager* websocket_endpoint_lock_manager) override {
355 return std::make_unique<WebSocketBasicHandshakeStream>(
356 std::move(connection));
357 }
CreateHttp2Stream(base::WeakPtr<SpdySession> session,std::set<std::string> dns_aliases)358 std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp2Stream(
359 base::WeakPtr<SpdySession> session,
360 std::set<std::string> dns_aliases) override {
361 NOTREACHED();
362 return nullptr;
363 }
CreateHttp3Stream(std::unique_ptr<QuicChromiumClientSession::Handle> session,std::set<std::string> dns_aliases)364 std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp3Stream(
365 std::unique_ptr<QuicChromiumClientSession::Handle> session,
366 std::set<std::string> dns_aliases) override {
367 NOTREACHED();
368 return nullptr;
369 }
370 };
371
372 struct TestCase {
373 int num_streams;
374 bool ssl;
375 };
376
377 TestCase kTests[] = {
378 {1, false},
379 {2, false},
380 {1, true},
381 {2, true},
382 };
383
PreconnectHelperForURL(int num_streams,const GURL & url,NetworkAnonymizationKey network_anonymization_key,SecureDnsPolicy secure_dns_policy,HttpNetworkSession * session)384 void PreconnectHelperForURL(int num_streams,
385 const GURL& url,
386 NetworkAnonymizationKey network_anonymization_key,
387 SecureDnsPolicy secure_dns_policy,
388 HttpNetworkSession* session) {
389 HttpNetworkSessionPeer peer(session);
390 auto mock_factory =
391 std::make_unique<MockHttpStreamFactoryForPreconnect>(session);
392 auto* mock_factory_ptr = mock_factory.get();
393 peer.SetHttpStreamFactory(std::move(mock_factory));
394
395 HttpRequestInfo request;
396 request.method = "GET";
397 request.url = url;
398 request.load_flags = 0;
399 request.network_anonymization_key = network_anonymization_key;
400 request.secure_dns_policy = secure_dns_policy;
401 request.traffic_annotation =
402 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
403
404 session->http_stream_factory()->PreconnectStreams(num_streams, request);
405 mock_factory_ptr->WaitForPreconnects();
406 }
407
PreconnectHelper(const TestCase & test,HttpNetworkSession * session)408 void PreconnectHelper(const TestCase& test, HttpNetworkSession* session) {
409 GURL url =
410 test.ssl ? GURL("https://www.google.com") : GURL("http://www.google.com");
411 PreconnectHelperForURL(test.num_streams, url, NetworkAnonymizationKey(),
412 SecureDnsPolicy::kAllow, session);
413 }
414
GetGroupId(const TestCase & test)415 ClientSocketPool::GroupId GetGroupId(const TestCase& test) {
416 if (test.ssl) {
417 return ClientSocketPool::GroupId(
418 url::SchemeHostPort(url::kHttpsScheme, "www.google.com", 443),
419 PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
420 SecureDnsPolicy::kAllow);
421 }
422 return ClientSocketPool::GroupId(
423 url::SchemeHostPort(url::kHttpScheme, "www.google.com", 80),
424 PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
425 SecureDnsPolicy::kAllow);
426 }
427
428 class CapturePreconnectsTransportSocketPool : public TransportClientSocketPool {
429 public:
CapturePreconnectsTransportSocketPool(const CommonConnectJobParams * common_connect_job_params)430 explicit CapturePreconnectsTransportSocketPool(
431 const CommonConnectJobParams* common_connect_job_params)
432 : TransportClientSocketPool(/*max_sockets=*/0,
433 /*max_sockets_per_group=*/0,
434 base::TimeDelta(),
435 ProxyChain::Direct(),
436 /*is_for_websockets=*/false,
437 common_connect_job_params) {}
438
last_num_streams() const439 int last_num_streams() const { return last_num_streams_; }
last_group_id() const440 const ClientSocketPool::GroupId& last_group_id() const {
441 return last_group_id_;
442 }
443
444 // Resets |last_num_streams_| and |last_group_id_| default values.
reset()445 void reset() {
446 last_num_streams_ = -1;
447 // Group ID that shouldn't match much.
448 last_group_id_ = ClientSocketPool::GroupId(
449 url::SchemeHostPort(url::kHttpsScheme,
450 "unexpected.to.conflict.with.anything.test", 9999),
451 PrivacyMode::PRIVACY_MODE_ENABLED, NetworkAnonymizationKey(),
452 SecureDnsPolicy::kAllow);
453 }
454
RequestSocket(const ClientSocketPool::GroupId & group_id,scoped_refptr<ClientSocketPool::SocketParams> socket_params,const absl::optional<NetworkTrafficAnnotationTag> & proxy_annotation_tag,RequestPriority priority,const SocketTag & socket_tag,ClientSocketPool::RespectLimits respect_limits,ClientSocketHandle * handle,CompletionOnceCallback callback,const ClientSocketPool::ProxyAuthCallback & proxy_auth_callback,const NetLogWithSource & net_log)455 int RequestSocket(
456 const ClientSocketPool::GroupId& group_id,
457 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
458 const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
459 RequestPriority priority,
460 const SocketTag& socket_tag,
461 ClientSocketPool::RespectLimits respect_limits,
462 ClientSocketHandle* handle,
463 CompletionOnceCallback callback,
464 const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback,
465 const NetLogWithSource& net_log) override {
466 ADD_FAILURE();
467 return ERR_UNEXPECTED;
468 }
469
RequestSockets(const ClientSocketPool::GroupId & group_id,scoped_refptr<ClientSocketPool::SocketParams> socket_params,const absl::optional<NetworkTrafficAnnotationTag> & proxy_annotation_tag,int num_sockets,CompletionOnceCallback callback,const NetLogWithSource & net_log)470 int RequestSockets(
471 const ClientSocketPool::GroupId& group_id,
472 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
473 const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
474 int num_sockets,
475 CompletionOnceCallback callback,
476 const NetLogWithSource& net_log) override {
477 last_num_streams_ = num_sockets;
478 last_group_id_ = group_id;
479 return OK;
480 }
481
CancelRequest(const ClientSocketPool::GroupId & group_id,ClientSocketHandle * handle,bool cancel_connect_job)482 void CancelRequest(const ClientSocketPool::GroupId& group_id,
483 ClientSocketHandle* handle,
484 bool cancel_connect_job) override {
485 ADD_FAILURE();
486 }
ReleaseSocket(const ClientSocketPool::GroupId & group_id,std::unique_ptr<StreamSocket> socket,int64_t generation)487 void ReleaseSocket(const ClientSocketPool::GroupId& group_id,
488 std::unique_ptr<StreamSocket> socket,
489 int64_t generation) override {
490 ADD_FAILURE();
491 }
CloseIdleSockets(const char * net_log_reason_utf8)492 void CloseIdleSockets(const char* net_log_reason_utf8) override {
493 ADD_FAILURE();
494 }
IdleSocketCount() const495 int IdleSocketCount() const override {
496 ADD_FAILURE();
497 return 0;
498 }
IdleSocketCountInGroup(const ClientSocketPool::GroupId & group_id) const499 size_t IdleSocketCountInGroup(
500 const ClientSocketPool::GroupId& group_id) const override {
501 ADD_FAILURE();
502 return 0;
503 }
GetLoadState(const ClientSocketPool::GroupId & group_id,const ClientSocketHandle * handle) const504 LoadState GetLoadState(const ClientSocketPool::GroupId& group_id,
505 const ClientSocketHandle* handle) const override {
506 ADD_FAILURE();
507 return LOAD_STATE_IDLE;
508 }
509
510 private:
511 int last_num_streams_ = -1;
512 ClientSocketPool::GroupId last_group_id_;
513 };
514
515 using HttpStreamFactoryTest = TestWithTaskEnvironment;
516
TEST_F(HttpStreamFactoryTest,PreconnectDirect)517 TEST_F(HttpStreamFactoryTest, PreconnectDirect) {
518 for (const auto& test : kTests) {
519 SpdySessionDependencies session_deps(
520 ConfiguredProxyResolutionService::CreateDirect());
521 std::unique_ptr<HttpNetworkSession> session(
522 SpdySessionDependencies::SpdyCreateSession(&session_deps));
523 HttpNetworkSessionPeer peer(session.get());
524 CommonConnectJobParams common_connect_job_params =
525 session->CreateCommonConnectJobParams();
526 std::unique_ptr<CapturePreconnectsTransportSocketPool>
527 owned_transport_conn_pool =
528 std::make_unique<CapturePreconnectsTransportSocketPool>(
529 &common_connect_job_params);
530 CapturePreconnectsTransportSocketPool* transport_conn_pool =
531 owned_transport_conn_pool.get();
532 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
533 mock_pool_manager->SetSocketPool(ProxyChain::Direct(),
534 std::move(owned_transport_conn_pool));
535 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
536 PreconnectHelper(test, session.get());
537 EXPECT_EQ(test.num_streams, transport_conn_pool->last_num_streams());
538 EXPECT_EQ(GetGroupId(test), transport_conn_pool->last_group_id());
539 }
540 }
541
TEST_F(HttpStreamFactoryTest,PreconnectHttpProxy)542 TEST_F(HttpStreamFactoryTest, PreconnectHttpProxy) {
543 for (const auto& test : kTests) {
544 SpdySessionDependencies session_deps(
545 ConfiguredProxyResolutionService::CreateFixedForTest(
546 "http_proxy", TRAFFIC_ANNOTATION_FOR_TESTS));
547 std::unique_ptr<HttpNetworkSession> session(
548 SpdySessionDependencies::SpdyCreateSession(&session_deps));
549 HttpNetworkSessionPeer peer(session.get());
550 ProxyChain proxy_chain(ProxyServer::SCHEME_HTTP,
551 HostPortPair("http_proxy", 80));
552 CommonConnectJobParams common_connect_job_params =
553 session->CreateCommonConnectJobParams();
554
555 auto http_proxy_pool =
556 std::make_unique<CapturePreconnectsTransportSocketPool>(
557 &common_connect_job_params);
558 auto* http_proxy_pool_ptr = http_proxy_pool.get();
559 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
560 mock_pool_manager->SetSocketPool(proxy_chain, std::move(http_proxy_pool));
561 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
562 PreconnectHelper(test, session.get());
563 EXPECT_EQ(test.num_streams, http_proxy_pool_ptr->last_num_streams());
564 EXPECT_EQ(GetGroupId(test), http_proxy_pool_ptr->last_group_id());
565 }
566 }
567
TEST_F(HttpStreamFactoryTest,PreconnectSocksProxy)568 TEST_F(HttpStreamFactoryTest, PreconnectSocksProxy) {
569 for (const auto& test : kTests) {
570 SpdySessionDependencies session_deps(
571 ConfiguredProxyResolutionService::CreateFixedForTest(
572 "socks4://socks_proxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS));
573 std::unique_ptr<HttpNetworkSession> session(
574 SpdySessionDependencies::SpdyCreateSession(&session_deps));
575 HttpNetworkSessionPeer peer(session.get());
576 ProxyChain proxy_chain(ProxyServer::SCHEME_SOCKS4,
577 HostPortPair("socks_proxy", 1080));
578 CommonConnectJobParams common_connect_job_params =
579 session->CreateCommonConnectJobParams();
580 auto socks_proxy_pool =
581 std::make_unique<CapturePreconnectsTransportSocketPool>(
582 &common_connect_job_params);
583 auto* socks_proxy_pool_ptr = socks_proxy_pool.get();
584 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
585 mock_pool_manager->SetSocketPool(proxy_chain, std::move(socks_proxy_pool));
586 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
587 PreconnectHelper(test, session.get());
588 EXPECT_EQ(test.num_streams, socks_proxy_pool_ptr->last_num_streams());
589 EXPECT_EQ(GetGroupId(test), socks_proxy_pool_ptr->last_group_id());
590 }
591 }
592
TEST_F(HttpStreamFactoryTest,PreconnectDirectWithExistingSpdySession)593 TEST_F(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
594 for (const auto& test : kTests) {
595 SpdySessionDependencies session_deps(
596 ConfiguredProxyResolutionService::CreateDirect());
597 std::unique_ptr<HttpNetworkSession> session(
598 SpdySessionDependencies::SpdyCreateSession(&session_deps));
599 HttpNetworkSessionPeer peer(session.get());
600
601 // Put a SpdySession in the pool.
602 HostPortPair host_port_pair("www.google.com", 443);
603 SpdySessionKey key(host_port_pair, ProxyChain::Direct(),
604 PRIVACY_MODE_DISABLED,
605 SpdySessionKey::IsProxySession::kFalse, SocketTag(),
606 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
607 std::ignore = CreateFakeSpdySession(session->spdy_session_pool(), key);
608
609 CommonConnectJobParams common_connect_job_params =
610 session->CreateCommonConnectJobParams();
611 std::unique_ptr<CapturePreconnectsTransportSocketPool>
612 owned_transport_conn_pool =
613 std::make_unique<CapturePreconnectsTransportSocketPool>(
614 &common_connect_job_params);
615 CapturePreconnectsTransportSocketPool* transport_conn_pool =
616 owned_transport_conn_pool.get();
617 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
618 mock_pool_manager->SetSocketPool(ProxyChain::Direct(),
619 std::move(owned_transport_conn_pool));
620 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
621 PreconnectHelper(test, session.get());
622 // We shouldn't be preconnecting if we have an existing session, which is
623 // the case for https://www.google.com.
624 if (test.ssl)
625 EXPECT_EQ(-1, transport_conn_pool->last_num_streams());
626 else
627 EXPECT_EQ(test.num_streams, transport_conn_pool->last_num_streams());
628 }
629 }
630
631 // Verify that preconnects to unsafe ports are cancelled before they reach
632 // the SocketPool.
TEST_F(HttpStreamFactoryTest,PreconnectUnsafePort)633 TEST_F(HttpStreamFactoryTest, PreconnectUnsafePort) {
634 ASSERT_FALSE(IsPortAllowedForScheme(7, "http"));
635
636 SpdySessionDependencies session_deps(
637 ConfiguredProxyResolutionService::CreateDirect());
638 std::unique_ptr<HttpNetworkSession> session(
639 SpdySessionDependencies::SpdyCreateSession(&session_deps));
640 HttpNetworkSessionPeer peer(session.get());
641 CommonConnectJobParams common_connect_job_params =
642 session->CreateCommonConnectJobParams();
643 std::unique_ptr<CapturePreconnectsTransportSocketPool>
644 owned_transport_conn_pool =
645 std::make_unique<CapturePreconnectsTransportSocketPool>(
646 &common_connect_job_params);
647 CapturePreconnectsTransportSocketPool* transport_conn_pool =
648 owned_transport_conn_pool.get();
649 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
650 mock_pool_manager->SetSocketPool(ProxyChain::Direct(),
651 std::move(owned_transport_conn_pool));
652 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
653
654 PreconnectHelperForURL(1, GURL("http://www.google.com:7"),
655 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
656 session.get());
657 EXPECT_EQ(-1, transport_conn_pool->last_num_streams());
658 }
659
660 // Verify that preconnects use the specified NetworkAnonymizationKey.
TEST_F(HttpStreamFactoryTest,PreconnectNetworkIsolationKey)661 TEST_F(HttpStreamFactoryTest, PreconnectNetworkIsolationKey) {
662 base::test::ScopedFeatureList feature_list;
663 feature_list.InitAndEnableFeature(
664 features::kPartitionConnectionsByNetworkIsolationKey);
665
666 SpdySessionDependencies session_deps(
667 ConfiguredProxyResolutionService::CreateDirect());
668 std::unique_ptr<HttpNetworkSession> session(
669 SpdySessionDependencies::SpdyCreateSession(&session_deps));
670 HttpNetworkSessionPeer peer(session.get());
671 CommonConnectJobParams common_connect_job_params =
672 session->CreateCommonConnectJobParams();
673 std::unique_ptr<CapturePreconnectsTransportSocketPool>
674 owned_transport_conn_pool =
675 std::make_unique<CapturePreconnectsTransportSocketPool>(
676 &common_connect_job_params);
677 CapturePreconnectsTransportSocketPool* transport_conn_pool =
678 owned_transport_conn_pool.get();
679 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
680 mock_pool_manager->SetSocketPool(ProxyChain::Direct(),
681 std::move(owned_transport_conn_pool));
682 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
683
684 const GURL kURL("http://foo.test/");
685 SchemefulSite kSiteFoo(GURL("http://foo.test"));
686 SchemefulSite kSiteBar(GURL("http://bar.test"));
687 const auto kKey1 = NetworkAnonymizationKey::CreateSameSite(kSiteFoo);
688 const auto kKey2 = NetworkAnonymizationKey::CreateSameSite(kSiteBar);
689 PreconnectHelperForURL(1, kURL, kKey1, SecureDnsPolicy::kAllow,
690 session.get());
691 EXPECT_EQ(1, transport_conn_pool->last_num_streams());
692 EXPECT_EQ(kKey1,
693 transport_conn_pool->last_group_id().network_anonymization_key());
694
695 PreconnectHelperForURL(2, kURL, kKey2, SecureDnsPolicy::kAllow,
696 session.get());
697 EXPECT_EQ(2, transport_conn_pool->last_num_streams());
698 EXPECT_EQ(kKey2,
699 transport_conn_pool->last_group_id().network_anonymization_key());
700 }
701
702 // Verify that preconnects use the specified Secure DNS Tag.
TEST_F(HttpStreamFactoryTest,PreconnectDisableSecureDns)703 TEST_F(HttpStreamFactoryTest, PreconnectDisableSecureDns) {
704 SpdySessionDependencies session_deps(
705 ConfiguredProxyResolutionService::CreateDirect());
706 std::unique_ptr<HttpNetworkSession> session(
707 SpdySessionDependencies::SpdyCreateSession(&session_deps));
708 HttpNetworkSessionPeer peer(session.get());
709 CommonConnectJobParams common_connect_job_params =
710 session->CreateCommonConnectJobParams();
711 std::unique_ptr<CapturePreconnectsTransportSocketPool>
712 owned_transport_conn_pool =
713 std::make_unique<CapturePreconnectsTransportSocketPool>(
714 &common_connect_job_params);
715 CapturePreconnectsTransportSocketPool* transport_conn_pool =
716 owned_transport_conn_pool.get();
717 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
718 mock_pool_manager->SetSocketPool(ProxyChain::Direct(),
719 std::move(owned_transport_conn_pool));
720 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
721
722 const GURL kURL("http://foo.test/");
723 SchemefulSite kSiteFoo(GURL("http://foo.test"));
724 SchemefulSite kSiteBar(GURL("http://bar.test"));
725 PreconnectHelperForURL(1, kURL, NetworkAnonymizationKey(),
726 SecureDnsPolicy::kAllow, session.get());
727 EXPECT_EQ(1, transport_conn_pool->last_num_streams());
728 EXPECT_EQ(SecureDnsPolicy::kAllow,
729 transport_conn_pool->last_group_id().secure_dns_policy());
730
731 PreconnectHelperForURL(2, kURL, NetworkAnonymizationKey(),
732 SecureDnsPolicy::kDisable, session.get());
733 EXPECT_EQ(2, transport_conn_pool->last_num_streams());
734 EXPECT_EQ(SecureDnsPolicy::kDisable,
735 transport_conn_pool->last_group_id().secure_dns_policy());
736 }
737
TEST_F(HttpStreamFactoryTest,JobNotifiesProxy)738 TEST_F(HttpStreamFactoryTest, JobNotifiesProxy) {
739 const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT";
740 SpdySessionDependencies session_deps(
741 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
742 kProxyString, TRAFFIC_ANNOTATION_FOR_TESTS));
743
744 // First connection attempt fails
745 StaticSocketDataProvider socket_data1;
746 socket_data1.set_connect_data(MockConnect(ASYNC, ERR_ADDRESS_UNREACHABLE));
747 session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
748
749 // Second connection attempt succeeds
750 StaticSocketDataProvider socket_data2;
751 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
752 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
753
754 std::unique_ptr<HttpNetworkSession> session(
755 SpdySessionDependencies::SpdyCreateSession(&session_deps));
756
757 // Now request a stream. It should succeed using the second proxy in the
758 // list.
759 HttpRequestInfo request_info;
760 request_info.method = "GET";
761 request_info.url = GURL("http://www.google.com");
762 request_info.traffic_annotation =
763 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
764
765 SSLConfig ssl_config;
766 StreamRequestWaiter waiter;
767 std::unique_ptr<HttpStreamRequest> request(
768 session->http_stream_factory()->RequestStream(
769 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
770 /* enable_ip_based_pooling = */ true,
771 /* enable_alternative_services = */ true, NetLogWithSource()));
772 waiter.WaitForStream();
773
774 // The proxy that failed should now be known to the proxy_resolution_service
775 // as bad.
776 const ProxyRetryInfoMap& retry_info =
777 session->proxy_resolution_service()->proxy_retry_info();
778 EXPECT_EQ(1u, retry_info.size());
779 auto iter = retry_info.find(
780 ProxyChain(ProxyUriToProxyServer("bad:99", ProxyServer::SCHEME_HTTP)));
781 EXPECT_TRUE(iter != retry_info.end());
782 }
783
784 // This test requests a stream for an https:// URL using an HTTP proxy.
785 // The proxy will fail to establish a tunnel via connect, and the resolved
786 // proxy list includes a fallback to DIRECT.
787 //
788 // The expected behavior is that proxy fallback does NOT occur, even though the
789 // request might work using the fallback. This is a regression test for
790 // https://crbug.com/680837.
TEST_F(HttpStreamFactoryTest,NoProxyFallbackOnTunnelFail)791 TEST_F(HttpStreamFactoryTest, NoProxyFallbackOnTunnelFail) {
792 const char* kProxyString = "PROXY bad:99; DIRECT";
793 SpdySessionDependencies session_deps(
794 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
795 kProxyString, TRAFFIC_ANNOTATION_FOR_TESTS));
796
797 // A 404 in response to a CONNECT will trigger
798 // ERR_TUNNEL_CONNECTION_FAILED.
799 MockRead data_reads[] = {
800 MockRead("HTTP/1.1 404 Not Found\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
801 };
802
803 // Simulate a failure during CONNECT to bad:99.
804 StaticSocketDataProvider socket_data1(data_reads, base::span<MockWrite>());
805 socket_data1.set_connect_data(MockConnect(SYNCHRONOUS, OK));
806 session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
807
808 std::unique_ptr<HttpNetworkSession> session(
809 SpdySessionDependencies::SpdyCreateSession(&session_deps));
810
811 // Request a stream for an https:// URL. The exact URL doesn't matter for
812 // this test, since it mocks a failure immediately when establishing a
813 // tunnel through the proxy.
814 HttpRequestInfo request_info;
815 request_info.method = "GET";
816 request_info.url = GURL("https://www.google.com");
817 request_info.traffic_annotation =
818 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
819
820 SSLConfig ssl_config;
821 StreamRequestWaiter waiter;
822 std::unique_ptr<HttpStreamRequest> request(
823 session->http_stream_factory()->RequestStream(
824 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
825 /* enable_ip_based_pooling = */ true,
826 /* enable_alternative_services = */ true, NetLogWithSource()));
827 waiter.WaitForStream();
828
829 // The stream should have failed, since the proxy server failed to
830 // establish a tunnel.
831 ASSERT_THAT(waiter.error_status(), IsError(ERR_TUNNEL_CONNECTION_FAILED));
832
833 // The proxy should NOT have been marked as bad.
834 const ProxyRetryInfoMap& retry_info =
835 session->proxy_resolution_service()->proxy_retry_info();
836 EXPECT_EQ(0u, retry_info.size());
837 }
838
839 // List of errors that are used in the tests related to QUIC proxy.
840 const int quic_proxy_test_mock_errors[] = {
841 ERR_PROXY_CONNECTION_FAILED,
842 ERR_NAME_NOT_RESOLVED,
843 ERR_ADDRESS_UNREACHABLE,
844 ERR_CONNECTION_CLOSED,
845 ERR_CONNECTION_TIMED_OUT,
846 ERR_CONNECTION_RESET,
847 ERR_CONNECTION_REFUSED,
848 ERR_CONNECTION_ABORTED,
849 ERR_TIMED_OUT,
850 ERR_SOCKS_CONNECTION_FAILED,
851 ERR_PROXY_CERTIFICATE_INVALID,
852 ERR_QUIC_PROTOCOL_ERROR,
853 ERR_QUIC_HANDSHAKE_FAILED,
854 ERR_SSL_PROTOCOL_ERROR,
855 ERR_MSG_TOO_BIG,
856 };
857
858 // Tests that a bad QUIC proxy is added to the list of bad proxies.
TEST_F(HttpStreamFactoryTest,QuicProxyMarkedAsBad)859 TEST_F(HttpStreamFactoryTest, QuicProxyMarkedAsBad) {
860 for (int quic_proxy_test_mock_error : quic_proxy_test_mock_errors) {
861 std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
862 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
863 "QUIC bad:99; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS);
864
865 HttpNetworkSessionParams session_params;
866 session_params.enable_quic = true;
867
868 HttpNetworkSessionContext session_context;
869 SSLConfigServiceDefaults ssl_config_service;
870 HttpServerProperties http_server_properties;
871 MockClientSocketFactory socket_factory;
872 session_context.client_socket_factory = &socket_factory;
873 MockHostResolver host_resolver;
874 session_context.host_resolver = &host_resolver;
875 MockCertVerifier cert_verifier;
876 session_context.cert_verifier = &cert_verifier;
877 TransportSecurityState transport_security_state;
878 session_context.transport_security_state = &transport_security_state;
879 DefaultCTPolicyEnforcer ct_policy_enforcer;
880 QuicContext quic_context;
881 session_context.ct_policy_enforcer = &ct_policy_enforcer;
882 session_context.proxy_resolution_service = proxy_resolution_service.get();
883 session_context.ssl_config_service = &ssl_config_service;
884 session_context.http_server_properties = &http_server_properties;
885 session_context.quic_context = &quic_context;
886
887 host_resolver.rules()->AddRule("www.google.com", "2.3.4.5");
888 host_resolver.rules()->AddRule("bad", "1.2.3.4");
889
890 auto session =
891 std::make_unique<HttpNetworkSession>(session_params, session_context);
892 session->quic_stream_factory()
893 ->set_is_quic_known_to_work_on_current_network(true);
894
895 StaticSocketDataProvider socket_data1;
896 socket_data1.set_connect_data(
897 MockConnect(ASYNC, quic_proxy_test_mock_error));
898 socket_factory.AddSocketDataProvider(&socket_data1);
899
900 // Second connection attempt succeeds.
901 StaticSocketDataProvider socket_data2;
902 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
903 socket_factory.AddSocketDataProvider(&socket_data2);
904
905 // Now request a stream. It should succeed using the second proxy in the
906 // list.
907 HttpRequestInfo request_info;
908 request_info.method = "GET";
909 request_info.url = GURL("http://www.google.com");
910 request_info.traffic_annotation =
911 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
912
913 SSLConfig ssl_config;
914 StreamRequestWaiter waiter;
915 std::unique_ptr<HttpStreamRequest> request(
916 session->http_stream_factory()->RequestStream(
917 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
918 /* enable_ip_based_pooling = */ true,
919 /* enable_alternative_services = */ true, NetLogWithSource()));
920 waiter.WaitForStream();
921
922 // The proxy that failed should now be known to the
923 // proxy_resolution_service as bad.
924 const ProxyRetryInfoMap& retry_info =
925 session->proxy_resolution_service()->proxy_retry_info();
926 EXPECT_EQ(1u, retry_info.size()) << quic_proxy_test_mock_error;
927 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
928
929 auto iter = retry_info.find(ProxyChain(
930 ProxyUriToProxyServer("quic://bad:99", ProxyServer::SCHEME_QUIC)));
931 EXPECT_TRUE(iter != retry_info.end()) << quic_proxy_test_mock_error;
932 }
933 }
934
935 // BidirectionalStreamImpl::Delegate to wait until response headers are
936 // received.
937 class TestBidirectionalDelegate : public BidirectionalStreamImpl::Delegate {
938 public:
WaitUntilDone()939 void WaitUntilDone() { loop_.Run(); }
940
response_headers() const941 const spdy::Http2HeaderBlock& response_headers() const {
942 return response_headers_;
943 }
944
945 private:
OnStreamReady(bool request_headers_sent)946 void OnStreamReady(bool request_headers_sent) override {}
OnHeadersReceived(const spdy::Http2HeaderBlock & response_headers)947 void OnHeadersReceived(
948 const spdy::Http2HeaderBlock& response_headers) override {
949 response_headers_ = response_headers.Clone();
950 loop_.Quit();
951 }
OnDataRead(int bytes_read)952 void OnDataRead(int bytes_read) override { NOTREACHED(); }
OnDataSent()953 void OnDataSent() override { NOTREACHED(); }
OnTrailersReceived(const spdy::Http2HeaderBlock & trailers)954 void OnTrailersReceived(const spdy::Http2HeaderBlock& trailers) override {
955 NOTREACHED();
956 }
OnFailed(int error)957 void OnFailed(int error) override { NOTREACHED(); }
958 base::RunLoop loop_;
959 spdy::Http2HeaderBlock response_headers_;
960 };
961
962 // Helper class to encapsulate MockReads and MockWrites for QUIC.
963 // Simplify ownership issues and the interaction with the MockSocketFactory.
964 class MockQuicData {
965 public:
MockQuicData(quic::ParsedQuicVersion version)966 explicit MockQuicData(quic::ParsedQuicVersion version) : printer_(version) {}
967
968 ~MockQuicData() = default;
969
AddRead(std::unique_ptr<quic::QuicEncryptedPacket> packet)970 void AddRead(std::unique_ptr<quic::QuicEncryptedPacket> packet) {
971 reads_.emplace_back(ASYNC, packet->data(), packet->length(),
972 packet_number_++);
973 packets_.push_back(std::move(packet));
974 }
975
AddRead(IoMode mode,int rv)976 void AddRead(IoMode mode, int rv) {
977 reads_.emplace_back(mode, rv, packet_number_++);
978 }
979
AddWrite(std::unique_ptr<quic::QuicEncryptedPacket> packet)980 void AddWrite(std::unique_ptr<quic::QuicEncryptedPacket> packet) {
981 writes_.emplace_back(SYNCHRONOUS, packet->data(), packet->length(),
982 packet_number_++);
983 packets_.push_back(std::move(packet));
984 }
985
AddSocketDataToFactory(MockClientSocketFactory * factory)986 void AddSocketDataToFactory(MockClientSocketFactory* factory) {
987 socket_data_ = std::make_unique<SequencedSocketData>(reads_, writes_);
988 socket_data_->set_printer(&printer_);
989 factory->AddSocketDataProvider(socket_data_.get());
990 }
991
992 private:
993 std::vector<std::unique_ptr<quic::QuicEncryptedPacket>> packets_;
994 std::vector<MockWrite> writes_;
995 std::vector<MockRead> reads_;
996 size_t packet_number_ = 0;
997 QuicPacketPrinter printer_;
998 std::unique_ptr<SequencedSocketData> socket_data_;
999 };
1000
1001 } // namespace
1002
TEST_F(HttpStreamFactoryTest,UsePreConnectIfNoZeroRTT)1003 TEST_F(HttpStreamFactoryTest, UsePreConnectIfNoZeroRTT) {
1004 for (int num_streams = 1; num_streams < 3; ++num_streams) {
1005 GURL url = GURL("https://www.google.com");
1006
1007 SpdySessionDependencies session_deps(
1008 ConfiguredProxyResolutionService::CreateFixedForTest(
1009 "http_proxy", TRAFFIC_ANNOTATION_FOR_TESTS));
1010
1011 // Setup params to disable preconnect, but QUIC doesn't 0RTT.
1012 HttpNetworkSessionParams session_params =
1013 SpdySessionDependencies::CreateSessionParams(&session_deps);
1014 session_params.enable_quic = true;
1015
1016 // Set up QUIC as alternative_service.
1017 HttpServerProperties http_server_properties;
1018 const AlternativeService alternative_service(kProtoQUIC, url.host().c_str(),
1019 url.IntPort());
1020 base::Time expiration = base::Time::Now() + base::Days(1);
1021 HostPortPair host_port_pair(alternative_service.host_port_pair());
1022 url::SchemeHostPort server("https", host_port_pair.host(),
1023 host_port_pair.port());
1024 http_server_properties.SetQuicAlternativeService(
1025 server, NetworkAnonymizationKey(), alternative_service, expiration,
1026 DefaultSupportedQuicVersions());
1027
1028 HttpNetworkSessionContext session_context =
1029 SpdySessionDependencies::CreateSessionContext(&session_deps);
1030 session_context.http_server_properties = &http_server_properties;
1031
1032 auto session =
1033 std::make_unique<HttpNetworkSession>(session_params, session_context);
1034 HttpNetworkSessionPeer peer(session.get());
1035 ProxyChain proxy_chain(ProxyServer::SCHEME_HTTP,
1036 HostPortPair("http_proxy", 80));
1037 CommonConnectJobParams common_connect_job_params =
1038 session->CreateCommonConnectJobParams();
1039 auto http_proxy_pool =
1040 std::make_unique<CapturePreconnectsTransportSocketPool>(
1041 &common_connect_job_params);
1042 auto* http_proxy_pool_ptr = http_proxy_pool.get();
1043 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
1044 mock_pool_manager->SetSocketPool(proxy_chain, std::move(http_proxy_pool));
1045 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
1046 PreconnectHelperForURL(num_streams, url, NetworkAnonymizationKey(),
1047 SecureDnsPolicy::kAllow, session.get());
1048 EXPECT_EQ(num_streams, http_proxy_pool_ptr->last_num_streams());
1049 }
1050 }
1051
1052 namespace {
1053
1054 // Return count of distinct groups in given socket pool.
GetSocketPoolGroupCount(ClientSocketPool * pool)1055 int GetSocketPoolGroupCount(ClientSocketPool* pool) {
1056 int count = 0;
1057 base::Value dict = pool->GetInfoAsValue("", "");
1058 EXPECT_TRUE(dict.is_dict());
1059 const base::Value::Dict* groups = dict.GetDict().FindDict("groups");
1060 if (groups) {
1061 count = groups->size();
1062 }
1063 return count;
1064 }
1065
1066 // Return count of distinct spdy sessions.
GetSpdySessionCount(HttpNetworkSession * session)1067 int GetSpdySessionCount(HttpNetworkSession* session) {
1068 std::unique_ptr<base::Value> value(
1069 session->spdy_session_pool()->SpdySessionPoolInfoToValue());
1070 if (!value || !value->is_list())
1071 return -1;
1072 return value->GetList().size();
1073 }
1074
1075 // Return count of sockets handed out by a given socket pool.
GetHandedOutSocketCount(ClientSocketPool * pool)1076 int GetHandedOutSocketCount(ClientSocketPool* pool) {
1077 base::Value dict = pool->GetInfoAsValue("", "");
1078 EXPECT_TRUE(dict.is_dict());
1079 return dict.GetDict().FindInt("handed_out_socket_count").value_or(-1);
1080 }
1081
1082 // Return count of distinct QUIC sessions.
GetQuicSessionCount(HttpNetworkSession * session)1083 int GetQuicSessionCount(HttpNetworkSession* session) {
1084 base::Value dict(session->QuicInfoToValue());
1085 base::Value::List* session_list = dict.GetDict().FindList("sessions");
1086 if (!session_list)
1087 return -1;
1088 return session_list->size();
1089 }
1090
TEST_F(HttpStreamFactoryTest,PrivacyModeUsesDifferentSocketPoolGroup)1091 TEST_F(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) {
1092 SpdySessionDependencies session_deps(
1093 ConfiguredProxyResolutionService::CreateDirect());
1094
1095 StaticSocketDataProvider socket_data_1;
1096 socket_data_1.set_connect_data(MockConnect(ASYNC, OK));
1097 session_deps.socket_factory->AddSocketDataProvider(&socket_data_1);
1098 StaticSocketDataProvider socket_data_2;
1099 socket_data_2.set_connect_data(MockConnect(ASYNC, OK));
1100 session_deps.socket_factory->AddSocketDataProvider(&socket_data_2);
1101 StaticSocketDataProvider socket_data_3;
1102 socket_data_3.set_connect_data(MockConnect(ASYNC, OK));
1103 session_deps.socket_factory->AddSocketDataProvider(&socket_data_3);
1104
1105 SSLSocketDataProvider ssl_1(ASYNC, OK);
1106 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_1);
1107 SSLSocketDataProvider ssl_2(ASYNC, OK);
1108 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_2);
1109 SSLSocketDataProvider ssl_3(ASYNC, OK);
1110 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_3);
1111
1112 std::unique_ptr<HttpNetworkSession> session(
1113 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1114 ClientSocketPool* ssl_pool = session->GetSocketPool(
1115 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct());
1116
1117 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0);
1118
1119 HttpRequestInfo request_info;
1120 request_info.method = "GET";
1121 request_info.url = GURL("https://www.google.com");
1122 request_info.load_flags = 0;
1123 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
1124 request_info.traffic_annotation =
1125 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1126
1127 SSLConfig ssl_config;
1128 StreamRequestWaiter waiter;
1129
1130 std::unique_ptr<HttpStreamRequest> request1(
1131 session->http_stream_factory()->RequestStream(
1132 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1133 /* enable_ip_based_pooling = */ true,
1134 /* enable_alternative_services = */ true, NetLogWithSource()));
1135 waiter.WaitForStream();
1136
1137 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
1138
1139 std::unique_ptr<HttpStreamRequest> request2(
1140 session->http_stream_factory()->RequestStream(
1141 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1142 /* enable_ip_based_pooling = */ true,
1143 /* enable_alternative_services = */ true, NetLogWithSource()));
1144 waiter.WaitForStream();
1145
1146 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
1147
1148 request_info.privacy_mode = PRIVACY_MODE_ENABLED;
1149 std::unique_ptr<HttpStreamRequest> request3(
1150 session->http_stream_factory()->RequestStream(
1151 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1152 /* enable_ip_based_pooling = */ true,
1153 /* enable_alternative_services = */ true, NetLogWithSource()));
1154 waiter.WaitForStream();
1155
1156 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2);
1157 }
1158
TEST_F(HttpStreamFactoryTest,DisableSecureDnsUsesDifferentSocketPoolGroup)1159 TEST_F(HttpStreamFactoryTest, DisableSecureDnsUsesDifferentSocketPoolGroup) {
1160 SpdySessionDependencies session_deps(
1161 ConfiguredProxyResolutionService::CreateDirect());
1162
1163 StaticSocketDataProvider socket_data_1;
1164 socket_data_1.set_connect_data(MockConnect(ASYNC, OK));
1165 session_deps.socket_factory->AddSocketDataProvider(&socket_data_1);
1166 StaticSocketDataProvider socket_data_2;
1167 socket_data_2.set_connect_data(MockConnect(ASYNC, OK));
1168 session_deps.socket_factory->AddSocketDataProvider(&socket_data_2);
1169 StaticSocketDataProvider socket_data_3;
1170 socket_data_3.set_connect_data(MockConnect(ASYNC, OK));
1171 session_deps.socket_factory->AddSocketDataProvider(&socket_data_3);
1172
1173 SSLSocketDataProvider ssl_1(ASYNC, OK);
1174 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_1);
1175 SSLSocketDataProvider ssl_2(ASYNC, OK);
1176 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_2);
1177 SSLSocketDataProvider ssl_3(ASYNC, OK);
1178 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_3);
1179
1180 std::unique_ptr<HttpNetworkSession> session(
1181 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1182 ClientSocketPool* ssl_pool = session->GetSocketPool(
1183 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct());
1184
1185 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0);
1186
1187 HttpRequestInfo request_info;
1188 request_info.method = "GET";
1189 request_info.url = GURL("https://www.google.com");
1190 request_info.load_flags = 0;
1191 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
1192 request_info.traffic_annotation =
1193 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1194 request_info.secure_dns_policy = SecureDnsPolicy::kAllow;
1195
1196 SSLConfig ssl_config;
1197 StreamRequestWaiter waiter;
1198
1199 std::unique_ptr<HttpStreamRequest> request1(
1200 session->http_stream_factory()->RequestStream(
1201 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1202 /* enable_ip_based_pooling = */ true,
1203 /* enable_alternative_services = */ true, NetLogWithSource()));
1204 waiter.WaitForStream();
1205
1206 EXPECT_EQ(SecureDnsPolicy::kAllow,
1207 session_deps.host_resolver->last_secure_dns_policy());
1208 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
1209
1210 std::unique_ptr<HttpStreamRequest> request2(
1211 session->http_stream_factory()->RequestStream(
1212 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1213 /* enable_ip_based_pooling = */ true,
1214 /* enable_alternative_services = */ true, NetLogWithSource()));
1215 waiter.WaitForStream();
1216
1217 EXPECT_EQ(SecureDnsPolicy::kAllow,
1218 session_deps.host_resolver->last_secure_dns_policy());
1219 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
1220
1221 request_info.secure_dns_policy = SecureDnsPolicy::kDisable;
1222 std::unique_ptr<HttpStreamRequest> request3(
1223 session->http_stream_factory()->RequestStream(
1224 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1225 /* enable_ip_based_pooling = */ true,
1226 /* enable_alternative_services = */ true, NetLogWithSource()));
1227 waiter.WaitForStream();
1228
1229 EXPECT_EQ(SecureDnsPolicy::kDisable,
1230 session_deps.host_resolver->last_secure_dns_policy());
1231 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2);
1232 }
1233
TEST_F(HttpStreamFactoryTest,GetLoadState)1234 TEST_F(HttpStreamFactoryTest, GetLoadState) {
1235 SpdySessionDependencies session_deps(
1236 ConfiguredProxyResolutionService::CreateDirect());
1237
1238 StaticSocketDataProvider socket_data;
1239 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1240 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1241
1242 std::unique_ptr<HttpNetworkSession> session(
1243 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1244
1245 HttpRequestInfo request_info;
1246 request_info.method = "GET";
1247 request_info.url = GURL("http://www.google.com");
1248 request_info.traffic_annotation =
1249 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1250
1251 SSLConfig ssl_config;
1252 StreamRequestWaiter waiter;
1253 std::unique_ptr<HttpStreamRequest> request(
1254 session->http_stream_factory()->RequestStream(
1255 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1256 /* enable_ip_based_pooling = */ true,
1257 /* enable_alternative_services = */ true, NetLogWithSource()));
1258
1259 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState());
1260
1261 waiter.WaitForStream();
1262 }
1263
TEST_F(HttpStreamFactoryTest,RequestHttpStream)1264 TEST_F(HttpStreamFactoryTest, RequestHttpStream) {
1265 SpdySessionDependencies session_deps(
1266 ConfiguredProxyResolutionService::CreateDirect());
1267
1268 StaticSocketDataProvider socket_data;
1269 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1270 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1271
1272 std::unique_ptr<HttpNetworkSession> session(
1273 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1274
1275 // Now request a stream. It should succeed using the second proxy in the
1276 // list.
1277 HttpRequestInfo request_info;
1278 request_info.method = "GET";
1279 request_info.url = GURL("http://www.google.com");
1280 request_info.load_flags = 0;
1281 request_info.traffic_annotation =
1282 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1283
1284 SSLConfig ssl_config;
1285 StreamRequestWaiter waiter;
1286 std::unique_ptr<HttpStreamRequest> request(
1287 session->http_stream_factory()->RequestStream(
1288 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1289 /* enable_ip_based_pooling = */ true,
1290 /* enable_alternative_services = */ true, NetLogWithSource()));
1291 waiter.WaitForStream();
1292 EXPECT_TRUE(waiter.stream_done());
1293 ASSERT_TRUE(nullptr != waiter.stream());
1294 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1295
1296 EXPECT_EQ(0, GetSpdySessionCount(session.get()));
1297 EXPECT_EQ(1,
1298 GetSocketPoolGroupCount(session->GetSocketPool(
1299 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
1300 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1301 }
1302
1303 // Test the race of SetPriority versus stream completion where SetPriority may
1304 // be called on an HttpStreamFactory::Job after the stream has been created by
1305 // the job.
TEST_F(HttpStreamFactoryTest,ReprioritizeAfterStreamReceived)1306 TEST_F(HttpStreamFactoryTest, ReprioritizeAfterStreamReceived) {
1307 SpdySessionDependencies session_deps(
1308 ConfiguredProxyResolutionService::CreateDirect());
1309 session_deps.host_resolver->set_synchronous_mode(true);
1310
1311 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1312 StaticSocketDataProvider socket_data(base::make_span(&mock_read, 1u),
1313 base::span<MockWrite>());
1314 socket_data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1315 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1316
1317 SSLSocketDataProvider ssl_socket_data(SYNCHRONOUS, OK);
1318 ssl_socket_data.next_proto = kProtoHTTP2;
1319 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1320
1321 std::unique_ptr<HttpNetworkSession> session(
1322 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1323
1324 // Now request a stream.
1325 HttpRequestInfo request_info;
1326 request_info.method = "GET";
1327 request_info.url = GURL("https://www.google.com");
1328 request_info.load_flags = 0;
1329 request_info.traffic_annotation =
1330 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1331
1332 SSLConfig ssl_config;
1333 StreamRequestWaiter waiter;
1334 EXPECT_EQ(0, GetSpdySessionCount(session.get()));
1335 std::unique_ptr<HttpStreamRequest> request(
1336 session->http_stream_factory()->RequestStream(
1337 request_info, LOWEST, ssl_config, &waiter,
1338 /* enable_ip_based_pooling = */ true,
1339 /* enable_alternative_services = */ true, NetLogWithSource()));
1340 EXPECT_FALSE(waiter.stream_done());
1341
1342 // Confirm a stream has been created by asserting that a new session
1343 // has been created. (The stream is only created at the SPDY level on
1344 // first write, which happens after the request has returned a stream).
1345 ASSERT_EQ(1, GetSpdySessionCount(session.get()));
1346
1347 // Test to confirm that a SetPriority received after the stream is created
1348 // but before the request returns it does not crash.
1349 request->SetPriority(HIGHEST);
1350
1351 waiter.WaitForStream();
1352 EXPECT_TRUE(waiter.stream_done());
1353 ASSERT_TRUE(waiter.stream());
1354 EXPECT_FALSE(waiter.websocket_stream());
1355 }
1356
TEST_F(HttpStreamFactoryTest,RequestHttpStreamOverSSL)1357 TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
1358 SpdySessionDependencies session_deps(
1359 ConfiguredProxyResolutionService::CreateDirect());
1360
1361 MockRead mock_read(ASYNC, OK);
1362 StaticSocketDataProvider socket_data(base::make_span(&mock_read, 1u),
1363 base::span<MockWrite>());
1364 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1365 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1366
1367 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1368 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1369
1370 std::unique_ptr<HttpNetworkSession> session(
1371 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1372
1373 // Now request a stream.
1374 HttpRequestInfo request_info;
1375 request_info.method = "GET";
1376 request_info.url = GURL("https://www.google.com");
1377 request_info.load_flags = 0;
1378 request_info.traffic_annotation =
1379 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1380
1381 SSLConfig ssl_config;
1382 StreamRequestWaiter waiter;
1383 std::unique_ptr<HttpStreamRequest> request(
1384 session->http_stream_factory()->RequestStream(
1385 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1386 /* enable_ip_based_pooling = */ true,
1387 /* enable_alternative_services = */ true, NetLogWithSource()));
1388 waiter.WaitForStream();
1389 EXPECT_TRUE(waiter.stream_done());
1390 ASSERT_TRUE(nullptr != waiter.stream());
1391 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1392
1393 EXPECT_EQ(0, GetSpdySessionCount(session.get()));
1394 EXPECT_EQ(1,
1395 GetSocketPoolGroupCount(session->GetSocketPool(
1396 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
1397 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1398 }
1399
TEST_F(HttpStreamFactoryTest,RequestHttpStreamOverProxy)1400 TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
1401 SpdySessionDependencies session_deps(
1402 ConfiguredProxyResolutionService::CreateFixedForTest(
1403 "myproxy:8888", TRAFFIC_ANNOTATION_FOR_TESTS));
1404
1405 StaticSocketDataProvider socket_data;
1406 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1407 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1408
1409 std::unique_ptr<HttpNetworkSession> session(
1410 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1411
1412 // Now request a stream. It should succeed using the second proxy in the
1413 // list.
1414 HttpRequestInfo request_info;
1415 request_info.method = "GET";
1416 request_info.url = GURL("http://www.google.com");
1417 request_info.load_flags = 0;
1418 request_info.traffic_annotation =
1419 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1420
1421 SSLConfig ssl_config;
1422 StreamRequestWaiter waiter;
1423 std::unique_ptr<HttpStreamRequest> request(
1424 session->http_stream_factory()->RequestStream(
1425 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1426 /* enable_ip_based_pooling = */ true,
1427 /* enable_alternative_services = */ true, NetLogWithSource()));
1428 waiter.WaitForStream();
1429 EXPECT_TRUE(waiter.stream_done());
1430 ASSERT_TRUE(nullptr != waiter.stream());
1431 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1432
1433 EXPECT_EQ(0, GetSpdySessionCount(session.get()));
1434 EXPECT_EQ(0,
1435 GetSocketPoolGroupCount(session->GetSocketPool(
1436 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
1437 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPool(
1438 HttpNetworkSession::NORMAL_SOCKET_POOL,
1439 ProxyChain(ProxyServer::SCHEME_HTTP,
1440 HostPortPair("myproxy", 8888)))));
1441 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPool(
1442 HttpNetworkSession::NORMAL_SOCKET_POOL,
1443 ProxyChain(ProxyServer::SCHEME_HTTPS,
1444 HostPortPair("myproxy", 8888)))));
1445 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPool(
1446 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1447 ProxyChain(ProxyServer::SCHEME_HTTP,
1448 HostPortPair("myproxy", 8888)))));
1449 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1450 }
1451
TEST_F(HttpStreamFactoryTest,RequestWebSocketBasicHandshakeStream)1452 TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
1453 SpdySessionDependencies session_deps(
1454 ConfiguredProxyResolutionService::CreateDirect());
1455
1456 StaticSocketDataProvider socket_data;
1457 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1458 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1459
1460 std::unique_ptr<HttpNetworkSession> session(
1461 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1462
1463 // Now request a stream.
1464 HttpRequestInfo request_info;
1465 request_info.method = "GET";
1466 request_info.url = GURL("ws://www.google.com");
1467 request_info.load_flags = 0;
1468 request_info.traffic_annotation =
1469 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1470
1471 SSLConfig ssl_config;
1472 StreamRequestWaiter waiter;
1473 WebSocketStreamCreateHelper create_helper;
1474 std::unique_ptr<HttpStreamRequest> request(
1475 session->http_stream_factory()->RequestWebSocketHandshakeStream(
1476 request_info, DEFAULT_PRIORITY, ssl_config, &waiter, &create_helper,
1477 /* enable_ip_based_pooling = */ true,
1478 /* enable_alternative_services = */ true, NetLogWithSource()));
1479 waiter.WaitForStream();
1480 EXPECT_TRUE(waiter.stream_done());
1481 EXPECT_TRUE(nullptr == waiter.stream());
1482 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1483 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1484 waiter.websocket_stream()->type());
1485 EXPECT_EQ(0,
1486 GetSocketPoolGroupCount(session->GetSocketPool(
1487 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
1488 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1489 }
1490
TEST_F(HttpStreamFactoryTest,RequestWebSocketBasicHandshakeStreamOverSSL)1491 TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
1492 SpdySessionDependencies session_deps(
1493 ConfiguredProxyResolutionService::CreateDirect());
1494
1495 MockRead mock_read(ASYNC, OK);
1496 StaticSocketDataProvider socket_data(base::make_span(&mock_read, 1u),
1497 base::span<MockWrite>());
1498 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1499 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1500
1501 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1502 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1503
1504 std::unique_ptr<HttpNetworkSession> session(
1505 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1506
1507 // Now request a stream.
1508 HttpRequestInfo request_info;
1509 request_info.method = "GET";
1510 request_info.url = GURL("wss://www.google.com");
1511 request_info.load_flags = 0;
1512 request_info.traffic_annotation =
1513 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1514
1515 SSLConfig ssl_config;
1516 StreamRequestWaiter waiter;
1517 WebSocketStreamCreateHelper create_helper;
1518 std::unique_ptr<HttpStreamRequest> request(
1519 session->http_stream_factory()->RequestWebSocketHandshakeStream(
1520 request_info, DEFAULT_PRIORITY, ssl_config, &waiter, &create_helper,
1521 /* enable_ip_based_pooling = */ true,
1522 /* enable_alternative_services = */ true, NetLogWithSource()));
1523 waiter.WaitForStream();
1524 EXPECT_TRUE(waiter.stream_done());
1525 EXPECT_TRUE(nullptr == waiter.stream());
1526 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1527 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1528 waiter.websocket_stream()->type());
1529 EXPECT_EQ(0,
1530 GetSocketPoolGroupCount(session->GetSocketPool(
1531 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
1532 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1533 }
1534
TEST_F(HttpStreamFactoryTest,RequestWebSocketBasicHandshakeStreamOverProxy)1535 TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
1536 SpdySessionDependencies session_deps(
1537 ConfiguredProxyResolutionService::CreateFixedForTest(
1538 "myproxy:8888", TRAFFIC_ANNOTATION_FOR_TESTS));
1539
1540 MockRead reads[] = {
1541 MockRead(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n")};
1542 StaticSocketDataProvider socket_data(reads, base::span<MockWrite>());
1543 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1544 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1545
1546 std::unique_ptr<HttpNetworkSession> session(
1547 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1548
1549 // Now request a stream.
1550 HttpRequestInfo request_info;
1551 request_info.method = "GET";
1552 request_info.url = GURL("ws://www.google.com");
1553 request_info.load_flags = 0;
1554 request_info.traffic_annotation =
1555 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1556
1557 SSLConfig ssl_config;
1558 StreamRequestWaiter waiter;
1559 WebSocketStreamCreateHelper create_helper;
1560 std::unique_ptr<HttpStreamRequest> request(
1561 session->http_stream_factory()->RequestWebSocketHandshakeStream(
1562 request_info, DEFAULT_PRIORITY, ssl_config, &waiter, &create_helper,
1563 /* enable_ip_based_pooling = */ true,
1564 /* enable_alternative_services = */ true, NetLogWithSource()));
1565 waiter.WaitForStream();
1566 EXPECT_TRUE(waiter.stream_done());
1567 EXPECT_TRUE(nullptr == waiter.stream());
1568 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1569 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1570 waiter.websocket_stream()->type());
1571 EXPECT_EQ(
1572 0, GetSocketPoolGroupCount(session->GetSocketPool(
1573 HttpNetworkSession::WEBSOCKET_SOCKET_POOL, ProxyChain::Direct())));
1574 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPool(
1575 HttpNetworkSession::NORMAL_SOCKET_POOL,
1576 ProxyChain(ProxyServer::SCHEME_HTTP,
1577 HostPortPair("myproxy", 8888)))));
1578 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPool(
1579 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1580 ProxyChain(ProxyServer::SCHEME_HTTP,
1581 HostPortPair("myproxy", 8888)))));
1582 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1583 }
1584
TEST_F(HttpStreamFactoryTest,RequestSpdyHttpStreamHttpsURL)1585 TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpsURL) {
1586 SpdySessionDependencies session_deps(
1587 ConfiguredProxyResolutionService::CreateDirect());
1588
1589 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1590 SequencedSocketData socket_data(base::make_span(&mock_read, 1u),
1591 base::span<MockWrite>());
1592 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1593 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1594
1595 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1596 ssl_socket_data.next_proto = kProtoHTTP2;
1597 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1598
1599 HostPortPair host_port_pair("www.google.com", 443);
1600 std::unique_ptr<HttpNetworkSession> session(
1601 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1602
1603 // Now request a stream.
1604 HttpRequestInfo request_info;
1605 request_info.method = "GET";
1606 request_info.url = GURL("https://www.google.com");
1607 request_info.load_flags = 0;
1608 request_info.traffic_annotation =
1609 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1610
1611 SSLConfig ssl_config;
1612 StreamRequestWaiter waiter;
1613 std::unique_ptr<HttpStreamRequest> request(
1614 session->http_stream_factory()->RequestStream(
1615 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1616 /* enable_ip_based_pooling = */ true,
1617 /* enable_alternative_services = */ true, NetLogWithSource()));
1618 waiter.WaitForStream();
1619 EXPECT_TRUE(waiter.stream_done());
1620 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1621 ASSERT_TRUE(nullptr != waiter.stream());
1622
1623 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
1624 EXPECT_EQ(1,
1625 GetSocketPoolGroupCount(session->GetSocketPool(
1626 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
1627 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1628 }
1629
TEST_F(HttpStreamFactoryTest,RequestSpdyHttpStreamHttpURL)1630 TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpURL) {
1631 url::SchemeHostPort scheme_host_port("http", "myproxy.org", 443);
1632 auto session_deps = std::make_unique<SpdySessionDependencies>(
1633 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
1634 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS));
1635 std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
1636 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
1637 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
1638
1639 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1640 SequencedSocketData socket_data(base::make_span(&mock_read, 1u),
1641 base::span<MockWrite>());
1642 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1643 session_deps->socket_factory->AddSocketDataProvider(&socket_data);
1644
1645 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1646 ssl_socket_data.next_proto = kProtoHTTP2;
1647 session_deps->socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1648 session_deps->proxy_resolution_service = std::move(proxy_resolution_service);
1649
1650 std::unique_ptr<HttpNetworkSession> session(
1651 SpdySessionDependencies::SpdyCreateSession(session_deps.get()));
1652
1653 HttpServerProperties* http_server_properties =
1654 session->spdy_session_pool()->http_server_properties();
1655 EXPECT_FALSE(http_server_properties->GetSupportsSpdy(
1656 scheme_host_port, NetworkAnonymizationKey()));
1657
1658 // Now request a stream.
1659 HttpRequestInfo request_info;
1660 request_info.method = "GET";
1661 request_info.url = GURL("http://www.google.com");
1662 request_info.load_flags = 0;
1663 request_info.traffic_annotation =
1664 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1665
1666 SSLConfig ssl_config;
1667 StreamRequestWaiter waiter;
1668 std::unique_ptr<HttpStreamRequest> request(
1669 session->http_stream_factory()->RequestStream(
1670 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1671 /* enable_ip_based_pooling = */ true,
1672 /* enable_alternative_services = */ true, NetLogWithSource()));
1673 waiter.WaitForStream();
1674 EXPECT_TRUE(waiter.stream_done());
1675 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1676 ASSERT_TRUE(nullptr != waiter.stream());
1677
1678 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
1679 EXPECT_EQ(0,
1680 GetSocketPoolGroupCount(session->GetSocketPool(
1681 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
1682 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1683 EXPECT_TRUE(http_server_properties->GetSupportsSpdy(
1684 scheme_host_port, NetworkAnonymizationKey()));
1685 }
1686
1687 // Same as above, but checks HttpServerProperties is updated using the correct
1688 // NetworkAnonymizationKey. When/if NetworkAnonymizationKey is enabled by
1689 // default, this should probably be merged into the above test.
TEST_F(HttpStreamFactoryTest,RequestSpdyHttpStreamHttpURLWithNetworkAnonymizationKey)1690 TEST_F(HttpStreamFactoryTest,
1691 RequestSpdyHttpStreamHttpURLWithNetworkAnonymizationKey) {
1692 const SchemefulSite kSite1(GURL("https://foo.test/"));
1693 const auto kNetworkAnonymizationKey1 =
1694 NetworkAnonymizationKey::CreateSameSite(kSite1);
1695 const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
1696 const SchemefulSite kSite2(GURL("https://bar.test/"));
1697 const auto kNetworkAnonymizationKey2 =
1698 NetworkAnonymizationKey::CreateSameSite(kSite2);
1699 const NetworkIsolationKey kNetworkIsolationKey2(kSite1, kSite1);
1700
1701 base::test::ScopedFeatureList feature_list;
1702 feature_list.InitAndEnableFeature(
1703 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1704
1705 url::SchemeHostPort scheme_host_port("http", "myproxy.org", 443);
1706 auto session_deps = std::make_unique<SpdySessionDependencies>(
1707 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
1708 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS));
1709 std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
1710 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
1711 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
1712
1713 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1714 SequencedSocketData socket_data(base::make_span(&mock_read, 1u),
1715 base::span<MockWrite>());
1716 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1717 session_deps->socket_factory->AddSocketDataProvider(&socket_data);
1718
1719 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1720 ssl_socket_data.next_proto = kProtoHTTP2;
1721 session_deps->socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1722 session_deps->proxy_resolution_service = std::move(proxy_resolution_service);
1723
1724 std::unique_ptr<HttpNetworkSession> session(
1725 SpdySessionDependencies::SpdyCreateSession(session_deps.get()));
1726
1727 HttpServerProperties* http_server_properties =
1728 session->spdy_session_pool()->http_server_properties();
1729 EXPECT_FALSE(http_server_properties->GetSupportsSpdy(
1730 scheme_host_port, kNetworkAnonymizationKey1));
1731
1732 // Now request a stream.
1733 HttpRequestInfo request_info;
1734 request_info.method = "GET";
1735 request_info.url = GURL("http://www.google.com");
1736 request_info.load_flags = 0;
1737 request_info.network_isolation_key = kNetworkIsolationKey1;
1738 request_info.network_anonymization_key = kNetworkAnonymizationKey1;
1739 request_info.traffic_annotation =
1740 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1741
1742 SSLConfig ssl_config;
1743 StreamRequestWaiter waiter;
1744 std::unique_ptr<HttpStreamRequest> request(
1745 session->http_stream_factory()->RequestStream(
1746 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1747 /* enable_ip_based_pooling = */ true,
1748 /* enable_alternative_services = */ true, NetLogWithSource()));
1749 waiter.WaitForStream();
1750 EXPECT_TRUE(waiter.stream_done());
1751 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1752 ASSERT_TRUE(nullptr != waiter.stream());
1753
1754 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
1755 EXPECT_EQ(0,
1756 GetSocketPoolGroupCount(session->GetSocketPool(
1757 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
1758 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1759 EXPECT_TRUE(http_server_properties->GetSupportsSpdy(
1760 scheme_host_port, kNetworkAnonymizationKey1));
1761 // Other NetworkAnonymizationKeys should not be recorded as supporting SPDY.
1762 EXPECT_FALSE(http_server_properties->GetSupportsSpdy(
1763 scheme_host_port, NetworkAnonymizationKey()));
1764 EXPECT_FALSE(http_server_properties->GetSupportsSpdy(
1765 scheme_host_port, kNetworkAnonymizationKey2));
1766 }
1767
1768 // Tests that when a new SpdySession is established, duplicated idle H2 sockets
1769 // to the same server are closed.
TEST_F(HttpStreamFactoryTest,NewSpdySessionCloseIdleH2Sockets)1770 TEST_F(HttpStreamFactoryTest, NewSpdySessionCloseIdleH2Sockets) {
1771 SpdySessionDependencies session_deps(
1772 ConfiguredProxyResolutionService::CreateDirect());
1773
1774 const int kNumIdleSockets = 4;
1775 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
1776 std::vector<std::unique_ptr<SequencedSocketData>> providers;
1777 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1778 ssl_socket_data.next_proto = kProtoHTTP2;
1779 for (int i = 0; i < kNumIdleSockets; i++) {
1780 auto provider =
1781 std::make_unique<SequencedSocketData>(reads, base::span<MockWrite>());
1782 provider->set_connect_data(MockConnect(ASYNC, OK));
1783 session_deps.socket_factory->AddSocketDataProvider(provider.get());
1784 providers.push_back(std::move(provider));
1785 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1786 }
1787
1788 std::unique_ptr<HttpNetworkSession> session(
1789 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1790
1791 url::SchemeHostPort destination(url::kHttpsScheme, "www.google.com", 443);
1792
1793 // Create some HTTP/2 sockets.
1794 std::vector<std::unique_ptr<ClientSocketHandle>> handles;
1795 for (size_t i = 0; i < kNumIdleSockets; i++) {
1796 auto connection = std::make_unique<ClientSocketHandle>();
1797 TestCompletionCallback callback;
1798
1799 auto ssl_config_for_origin = std::make_unique<SSLConfig>();
1800 ssl_config_for_origin->alpn_protos = session->GetAlpnProtos();
1801 scoped_refptr<ClientSocketPool::SocketParams> socket_params =
1802 base::MakeRefCounted<ClientSocketPool::SocketParams>(
1803 std::move(ssl_config_for_origin),
1804 /*base_ssl_config_for_proxies=*/nullptr);
1805 ClientSocketPool::GroupId group_id(
1806 destination, PrivacyMode::PRIVACY_MODE_DISABLED,
1807 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
1808 int rv = connection->Init(
1809 group_id, socket_params, absl::nullopt /* proxy_annotation_tag */,
1810 MEDIUM, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1811 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1812 session->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
1813 ProxyChain::Direct()),
1814 NetLogWithSource());
1815 rv = callback.GetResult(rv);
1816 handles.push_back(std::move(connection));
1817 }
1818
1819 // Releases handles now, and these sockets should go into the socket pool.
1820 handles.clear();
1821 EXPECT_EQ(kNumIdleSockets,
1822 session
1823 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
1824 ProxyChain::Direct())
1825 ->IdleSocketCount());
1826
1827 // Request two streams at once and make sure they use the same connection.
1828 HttpRequestInfo request_info;
1829 request_info.method = "GET";
1830 request_info.url = GURL("https://www.google.com");
1831 request_info.load_flags = 0;
1832 request_info.traffic_annotation =
1833 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1834
1835 SSLConfig ssl_config;
1836 StreamRequestWaiter waiter1;
1837 StreamRequestWaiter waiter2;
1838 std::unique_ptr<HttpStreamRequest> request1(
1839 session->http_stream_factory()->RequestStream(
1840 request_info, DEFAULT_PRIORITY, ssl_config, &waiter1,
1841 /* enable_ip_based_pooling = */ true,
1842 /* enable_alternative_services = */ true, NetLogWithSource()));
1843 std::unique_ptr<HttpStreamRequest> request2(
1844 session->http_stream_factory()->RequestStream(
1845 request_info, DEFAULT_PRIORITY, ssl_config, &waiter2,
1846 /* enable_ip_based_pooling = */ true,
1847 /* enable_alternative_services = */ true, NetLogWithSource()));
1848 waiter1.WaitForStream();
1849 waiter2.WaitForStream();
1850 EXPECT_TRUE(waiter1.stream_done());
1851 EXPECT_TRUE(waiter2.stream_done());
1852 ASSERT_NE(nullptr, waiter1.stream());
1853 ASSERT_NE(nullptr, waiter2.stream());
1854 ASSERT_NE(waiter1.stream(), waiter2.stream());
1855
1856 // Establishing the SpdySession will close idle H2 sockets.
1857 EXPECT_EQ(0, session
1858 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
1859 ProxyChain::Direct())
1860 ->IdleSocketCount());
1861 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
1862 }
1863
1864 // Regression test for https://crbug.com/706974.
TEST_F(HttpStreamFactoryTest,TwoSpdyConnects)1865 TEST_F(HttpStreamFactoryTest, TwoSpdyConnects) {
1866 SpdySessionDependencies session_deps(
1867 ConfiguredProxyResolutionService::CreateDirect());
1868
1869 SSLSocketDataProvider ssl_socket_data0(ASYNC, OK);
1870 ssl_socket_data0.next_proto = kProtoHTTP2;
1871 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data0);
1872
1873 MockRead reads0[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
1874 SequencedSocketData data0(reads0, base::span<MockWrite>());
1875 data0.set_connect_data(MockConnect(ASYNC, OK));
1876 session_deps.socket_factory->AddSocketDataProvider(&data0);
1877
1878 SSLSocketDataProvider ssl_socket_data1(ASYNC, OK);
1879 ssl_socket_data1.next_proto = kProtoHTTP2;
1880 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data1);
1881
1882 SequencedSocketData data1;
1883 data1.set_connect_data(MockConnect(ASYNC, OK));
1884 session_deps.socket_factory->AddSocketDataProvider(&data1);
1885
1886 std::unique_ptr<HttpNetworkSession> session =
1887 SpdySessionDependencies::SpdyCreateSession(&session_deps);
1888 HttpRequestInfo request_info;
1889 request_info.method = "GET";
1890 request_info.url = GURL("https://www.google.com");
1891 request_info.load_flags = 0;
1892 request_info.traffic_annotation =
1893 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1894 SSLConfig ssl_config;
1895
1896 // Request two streams at once and make sure they use the same connection.
1897 StreamRequestWaiter waiter1;
1898 std::unique_ptr<HttpStreamRequest> request1 =
1899 session->http_stream_factory()->RequestStream(
1900 request_info, DEFAULT_PRIORITY, ssl_config, &waiter1,
1901 /* enable_ip_based_pooling = */ true,
1902 /* enable_alternative_services = */ true, NetLogWithSource());
1903
1904 StreamRequestWaiter waiter2;
1905 std::unique_ptr<HttpStreamRequest> request2 =
1906 session->http_stream_factory()->RequestStream(
1907 request_info, DEFAULT_PRIORITY, ssl_config, &waiter2,
1908 /* enable_ip_based_pooling = */ true,
1909 /* enable_alternative_services = */ true, NetLogWithSource());
1910
1911 waiter1.WaitForStream();
1912 waiter2.WaitForStream();
1913
1914 EXPECT_TRUE(waiter1.stream_done());
1915 EXPECT_TRUE(waiter2.stream_done());
1916 ASSERT_NE(nullptr, waiter1.stream());
1917 ASSERT_NE(nullptr, waiter2.stream());
1918 ASSERT_NE(waiter1.stream(), waiter2.stream());
1919
1920 // Establishing the SpdySession will close the extra H2 socket.
1921 EXPECT_EQ(0, session
1922 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
1923 ProxyChain::Direct())
1924 ->IdleSocketCount());
1925 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
1926 EXPECT_TRUE(data0.AllReadDataConsumed());
1927 EXPECT_TRUE(data1.AllReadDataConsumed());
1928 }
1929
TEST_F(HttpStreamFactoryTest,RequestBidirectionalStreamImpl)1930 TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImpl) {
1931 SpdySessionDependencies session_deps(
1932 ConfiguredProxyResolutionService::CreateDirect());
1933
1934 MockRead mock_read(ASYNC, OK);
1935 SequencedSocketData socket_data(base::make_span(&mock_read, 1u),
1936 base::span<MockWrite>());
1937 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1938 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1939
1940 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1941 ssl_socket_data.next_proto = kProtoHTTP2;
1942 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1943
1944 std::unique_ptr<HttpNetworkSession> session(
1945 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1946
1947 // Now request a stream.
1948 HttpRequestInfo request_info;
1949 request_info.method = "GET";
1950 request_info.url = GURL("https://www.google.com");
1951 request_info.load_flags = 0;
1952 request_info.traffic_annotation =
1953 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1954
1955 SSLConfig ssl_config;
1956 StreamRequestWaiter waiter;
1957 std::unique_ptr<HttpStreamRequest> request(
1958 session->http_stream_factory()->RequestBidirectionalStreamImpl(
1959 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
1960 /* enable_ip_based_pooling = */ true,
1961 /* enable_alternative_services = */ true, NetLogWithSource()));
1962 waiter.WaitForStream();
1963 EXPECT_TRUE(waiter.stream_done());
1964 EXPECT_FALSE(waiter.websocket_stream());
1965 ASSERT_FALSE(waiter.stream());
1966 ASSERT_TRUE(waiter.bidirectional_stream_impl());
1967 EXPECT_EQ(1,
1968 GetSocketPoolGroupCount(session->GetSocketPool(
1969 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
1970 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1971 }
1972
1973 class HttpStreamFactoryBidirectionalQuicTest
1974 : public TestWithTaskEnvironment,
1975 public ::testing::WithParamInterface<quic::ParsedQuicVersion> {
1976 protected:
HttpStreamFactoryBidirectionalQuicTest()1977 HttpStreamFactoryBidirectionalQuicTest()
1978 : default_url_(kDefaultUrl),
1979 version_(GetParam()),
1980 client_packet_maker_(version_,
1981 quic::QuicUtils::CreateRandomConnectionId(
1982 quic_context_.random_generator()),
1983 quic_context_.clock(),
1984 "www.example.org",
1985 quic::Perspective::IS_CLIENT),
1986 server_packet_maker_(version_,
1987 quic::QuicUtils::CreateRandomConnectionId(
1988 quic_context_.random_generator()),
1989 quic_context_.clock(),
1990 "www.example.org",
1991 quic::Perspective::IS_SERVER,
1992 false),
1993 proxy_resolution_service_(
1994 ConfiguredProxyResolutionService::CreateDirect()),
1995 ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()) {
1996 FLAGS_quic_enable_http3_grease_randomness = false;
1997 quic_context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
1998 quic::QuicEnableVersion(version_);
1999 }
2000
TearDown()2001 void TearDown() override { session_.reset(); }
2002
Initialize()2003 void Initialize() {
2004 params_.enable_quic = true;
2005 quic_context_.params()->supported_versions =
2006 quic::test::SupportedVersions(version_);
2007
2008 HttpNetworkSessionContext session_context;
2009 session_context.http_server_properties = &http_server_properties_;
2010 session_context.quic_context = &quic_context_;
2011
2012 // Load a certificate that is valid for *.example.org
2013 scoped_refptr<X509Certificate> test_cert(
2014 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
2015 EXPECT_TRUE(test_cert.get());
2016 verify_details_.cert_verify_result.verified_cert = test_cert;
2017 verify_details_.cert_verify_result.is_issued_by_known_root = true;
2018 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
2019 crypto_client_stream_factory_.set_handshake_mode(
2020 MockCryptoClientStream::CONFIRM_HANDSHAKE);
2021 session_context.cert_verifier = &cert_verifier_;
2022 session_context.quic_crypto_client_stream_factory =
2023 &crypto_client_stream_factory_;
2024 session_context.transport_security_state = &transport_security_state_;
2025 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
2026 session_context.host_resolver = &host_resolver_;
2027 session_context.proxy_resolution_service = proxy_resolution_service_.get();
2028 session_context.ssl_config_service = ssl_config_service_.get();
2029 session_context.client_socket_factory = &socket_factory_;
2030 session_ = std::make_unique<HttpNetworkSession>(params_, session_context);
2031 session_->quic_stream_factory()
2032 ->set_is_quic_known_to_work_on_current_network(true);
2033 }
2034
AddQuicAlternativeService(const url::SchemeHostPort & request_url,const std::string & alternative_destination)2035 void AddQuicAlternativeService(const url::SchemeHostPort& request_url,
2036 const std::string& alternative_destination) {
2037 const AlternativeService alternative_service(kProtoQUIC,
2038 alternative_destination, 443);
2039 base::Time expiration = base::Time::Now() + base::Days(1);
2040 http_server_properties_.SetQuicAlternativeService(
2041 request_url, NetworkAnonymizationKey(), alternative_service, expiration,
2042 session_->context().quic_context->params()->supported_versions);
2043 }
2044
AddQuicAlternativeService()2045 void AddQuicAlternativeService() {
2046 AddQuicAlternativeService(url::SchemeHostPort(default_url_),
2047 "www.example.org");
2048 }
2049
client_packet_maker()2050 test::QuicTestPacketMaker& client_packet_maker() {
2051 return client_packet_maker_;
2052 }
server_packet_maker()2053 test::QuicTestPacketMaker& server_packet_maker() {
2054 return server_packet_maker_;
2055 }
2056
socket_factory()2057 MockTaggingClientSocketFactory& socket_factory() { return socket_factory_; }
2058
session()2059 HttpNetworkSession* session() { return session_.get(); }
2060
2061 const GURL default_url_;
2062
GetNthClientInitiatedBidirectionalStreamId(int n)2063 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
2064 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
2065 version_.transport_version, n);
2066 }
2067
version() const2068 quic::ParsedQuicVersion version() const { return version_; }
2069
host_resolver()2070 MockHostResolver* host_resolver() { return &host_resolver_; }
2071
2072 private:
2073 quic::test::QuicFlagSaver saver_;
2074 const quic::ParsedQuicVersion version_;
2075 MockQuicContext quic_context_;
2076 test::QuicTestPacketMaker client_packet_maker_;
2077 test::QuicTestPacketMaker server_packet_maker_;
2078 MockTaggingClientSocketFactory socket_factory_;
2079 std::unique_ptr<HttpNetworkSession> session_;
2080 MockCertVerifier cert_verifier_;
2081 ProofVerifyDetailsChromium verify_details_;
2082 MockCryptoClientStreamFactory crypto_client_stream_factory_;
2083 HttpServerProperties http_server_properties_;
2084 TransportSecurityState transport_security_state_;
2085 DefaultCTPolicyEnforcer ct_policy_enforcer_;
2086 MockHostResolver host_resolver_{
2087 /*default_result=*/
2088 MockHostResolverBase::RuleResolver::GetLocalhostResult()};
2089 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
2090 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
2091 HttpNetworkSessionParams params_;
2092 };
2093
2094 INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
2095 HttpStreamFactoryBidirectionalQuicTest,
2096 ::testing::ValuesIn(AllSupportedQuicVersions()),
2097 ::testing::PrintToStringParamName());
2098
TEST_P(HttpStreamFactoryBidirectionalQuicTest,RequestBidirectionalStreamImplQuicAlternative)2099 TEST_P(HttpStreamFactoryBidirectionalQuicTest,
2100 RequestBidirectionalStreamImplQuicAlternative) {
2101 MockQuicData mock_quic_data(version());
2102 // Set priority to default value so that
2103 // QuicTestPacketMaker::MakeRequestHeadersPacket() does not add mock
2104 // PRIORITY_UPDATE frame, which BidirectionalStreamQuicImpl currently does not
2105 // send.
2106 // TODO(https://crbug.com/1059250): Implement PRIORITY_UPDATE in
2107 // BidirectionalStreamQuicImpl.
2108 spdy::SpdyPriority priority =
2109 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2110 size_t spdy_headers_frame_length;
2111 int packet_num = 1;
2112 mock_quic_data.AddWrite(
2113 client_packet_maker().MakeInitialSettingsPacket(packet_num++));
2114 mock_quic_data.AddWrite(client_packet_maker().MakeRequestHeadersPacket(
2115 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2116 /*fin=*/true, priority,
2117 client_packet_maker().GetRequestHeaders("GET", "https", "/"),
2118 &spdy_headers_frame_length));
2119 size_t spdy_response_headers_frame_length;
2120 mock_quic_data.AddRead(server_packet_maker().MakeResponseHeadersPacket(
2121 1, GetNthClientInitiatedBidirectionalStreamId(0),
2122 /*fin=*/true, server_packet_maker().GetResponseHeaders("200"),
2123 &spdy_response_headers_frame_length));
2124 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
2125 mock_quic_data.AddSocketDataToFactory(&socket_factory());
2126
2127 // Add hanging data for http job.
2128 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
2129 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
2130 hanging_data->set_connect_data(hanging_connect);
2131 socket_factory().AddSocketDataProvider(hanging_data.get());
2132 SSLSocketDataProvider ssl_data(ASYNC, OK);
2133 socket_factory().AddSSLSocketDataProvider(&ssl_data);
2134
2135 // Set up QUIC as alternative_service.
2136 Initialize();
2137 AddQuicAlternativeService();
2138
2139 // Now request a stream.
2140 SSLConfig ssl_config;
2141 HttpRequestInfo request_info;
2142 request_info.method = "GET";
2143 request_info.url = default_url_;
2144 request_info.load_flags = 0;
2145 request_info.traffic_annotation =
2146 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2147
2148 StreamRequestWaiter waiter;
2149 std::unique_ptr<HttpStreamRequest> request(
2150 session()->http_stream_factory()->RequestBidirectionalStreamImpl(
2151 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
2152 /* enable_ip_based_pooling = */ true,
2153 /* enable_alternative_services = */ true, NetLogWithSource()));
2154
2155 waiter.WaitForStream();
2156 EXPECT_TRUE(waiter.stream_done());
2157 EXPECT_FALSE(waiter.websocket_stream());
2158 ASSERT_FALSE(waiter.stream());
2159 ASSERT_TRUE(waiter.bidirectional_stream_impl());
2160 BidirectionalStreamImpl* stream_impl = waiter.bidirectional_stream_impl();
2161
2162 BidirectionalStreamRequestInfo bidi_request_info;
2163 bidi_request_info.method = "GET";
2164 bidi_request_info.url = default_url_;
2165 bidi_request_info.end_stream_on_headers = true;
2166 bidi_request_info.priority = LOWEST;
2167
2168 TestBidirectionalDelegate delegate;
2169 stream_impl->Start(&bidi_request_info, NetLogWithSource(),
2170 /*send_request_headers_automatically=*/true, &delegate,
2171 nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
2172 delegate.WaitUntilDone();
2173
2174 auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(1);
2175 EXPECT_THAT(stream_impl->ReadData(buffer.get(), 1), IsOk());
2176 EXPECT_EQ(kProtoQUIC, stream_impl->GetProtocol());
2177 EXPECT_EQ("200", delegate.response_headers().find(":status")->second);
2178 EXPECT_EQ(0,
2179 GetSocketPoolGroupCount(session()->GetSocketPool(
2180 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2181 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
2182 }
2183
2184 // Tests that if Http job fails, but Quic job succeeds, we return
2185 // BidirectionalStreamQuicImpl.
TEST_P(HttpStreamFactoryBidirectionalQuicTest,RequestBidirectionalStreamImplHttpJobFailsQuicJobSucceeds)2186 TEST_P(HttpStreamFactoryBidirectionalQuicTest,
2187 RequestBidirectionalStreamImplHttpJobFailsQuicJobSucceeds) {
2188 // Set up Quic data.
2189 MockQuicData mock_quic_data(version());
2190 // Set priority to default value so that
2191 // QuicTestPacketMaker::MakeRequestHeadersPacket() does not add mock
2192 // PRIORITY_UPDATE frame, which BidirectionalStreamQuicImpl currently does not
2193 // send.
2194 // TODO(https://crbug.com/1059250): Implement PRIORITY_UPDATE in
2195 // BidirectionalStreamQuicImpl.
2196 spdy::SpdyPriority priority =
2197 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2198 size_t spdy_headers_frame_length;
2199 int packet_num = 1;
2200 mock_quic_data.AddWrite(
2201 client_packet_maker().MakeInitialSettingsPacket(packet_num++));
2202 mock_quic_data.AddWrite(client_packet_maker().MakeRequestHeadersPacket(
2203 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2204 /*fin=*/true, priority,
2205 client_packet_maker().GetRequestHeaders("GET", "https", "/"),
2206 &spdy_headers_frame_length));
2207 size_t spdy_response_headers_frame_length;
2208 mock_quic_data.AddRead(server_packet_maker().MakeResponseHeadersPacket(
2209 1, GetNthClientInitiatedBidirectionalStreamId(0),
2210 /*fin=*/true, server_packet_maker().GetResponseHeaders("200"),
2211 &spdy_response_headers_frame_length));
2212 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
2213 mock_quic_data.AddSocketDataToFactory(&socket_factory());
2214
2215 // Make the http job fail.
2216 auto http_job_data = std::make_unique<StaticSocketDataProvider>();
2217 MockConnect failed_connect(ASYNC, ERR_CONNECTION_REFUSED);
2218 http_job_data->set_connect_data(failed_connect);
2219 socket_factory().AddSocketDataProvider(http_job_data.get());
2220 SSLSocketDataProvider ssl_data(ASYNC, OK);
2221 socket_factory().AddSSLSocketDataProvider(&ssl_data);
2222
2223 // Set up QUIC as alternative_service.
2224 Initialize();
2225 AddQuicAlternativeService();
2226
2227 // Now request a stream.
2228 SSLConfig ssl_config;
2229 HttpRequestInfo request_info;
2230 request_info.method = "GET";
2231 request_info.url = default_url_;
2232 request_info.load_flags = 0;
2233 request_info.traffic_annotation =
2234 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2235
2236 StreamRequestWaiter waiter;
2237 std::unique_ptr<HttpStreamRequest> request(
2238 session()->http_stream_factory()->RequestBidirectionalStreamImpl(
2239 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
2240 /* enable_ip_based_pooling = */ true,
2241 /* enable_alternative_services = */ true, NetLogWithSource()));
2242
2243 waiter.WaitForStream();
2244 EXPECT_TRUE(waiter.stream_done());
2245 EXPECT_FALSE(waiter.websocket_stream());
2246 ASSERT_FALSE(waiter.stream());
2247 ASSERT_TRUE(waiter.bidirectional_stream_impl());
2248 BidirectionalStreamImpl* stream_impl = waiter.bidirectional_stream_impl();
2249
2250 BidirectionalStreamRequestInfo bidi_request_info;
2251 bidi_request_info.method = "GET";
2252 bidi_request_info.url = default_url_;
2253 bidi_request_info.end_stream_on_headers = true;
2254 bidi_request_info.priority = LOWEST;
2255
2256 TestBidirectionalDelegate delegate;
2257 stream_impl->Start(&bidi_request_info, NetLogWithSource(),
2258 /*send_request_headers_automatically=*/true, &delegate,
2259 nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
2260 delegate.WaitUntilDone();
2261
2262 // Make sure the BidirectionalStream negotiated goes through QUIC.
2263 auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(1);
2264 EXPECT_THAT(stream_impl->ReadData(buffer.get(), 1), IsOk());
2265 EXPECT_EQ(kProtoQUIC, stream_impl->GetProtocol());
2266 EXPECT_EQ("200", delegate.response_headers().find(":status")->second);
2267 // There is no Http2 socket pool.
2268 EXPECT_EQ(0,
2269 GetSocketPoolGroupCount(session()->GetSocketPool(
2270 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2271 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
2272 }
2273
TEST_F(HttpStreamFactoryTest,RequestBidirectionalStreamImplFailure)2274 TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImplFailure) {
2275 SpdySessionDependencies session_deps(
2276 ConfiguredProxyResolutionService::CreateDirect());
2277
2278 MockRead mock_read(ASYNC, OK);
2279 SequencedSocketData socket_data(base::make_span(&mock_read, 1u),
2280 base::span<MockWrite>());
2281 socket_data.set_connect_data(MockConnect(ASYNC, OK));
2282 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
2283
2284 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
2285
2286 // If HTTP/1 is used, BidirectionalStreamImpl should not be obtained.
2287 ssl_socket_data.next_proto = kProtoHTTP11;
2288 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
2289
2290 std::unique_ptr<HttpNetworkSession> session(
2291 SpdySessionDependencies::SpdyCreateSession(&session_deps));
2292
2293 // Now request a stream.
2294 HttpRequestInfo request_info;
2295 request_info.method = "GET";
2296 request_info.url = GURL("https://www.google.com");
2297 request_info.load_flags = 0;
2298 request_info.traffic_annotation =
2299 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2300
2301 SSLConfig ssl_config;
2302 StreamRequestWaiter waiter;
2303 std::unique_ptr<HttpStreamRequest> request(
2304 session->http_stream_factory()->RequestBidirectionalStreamImpl(
2305 request_info, DEFAULT_PRIORITY, ssl_config, &waiter,
2306 /* enable_ip_based_pooling = */ true,
2307 /* enable_alternative_services = */ true, NetLogWithSource()));
2308 waiter.WaitForStream();
2309 EXPECT_TRUE(waiter.stream_done());
2310 ASSERT_THAT(waiter.error_status(), IsError(ERR_FAILED));
2311 EXPECT_FALSE(waiter.websocket_stream());
2312 ASSERT_FALSE(waiter.stream());
2313 ASSERT_FALSE(waiter.bidirectional_stream_impl());
2314 EXPECT_EQ(1,
2315 GetSocketPoolGroupCount(session->GetSocketPool(
2316 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2317 }
2318
2319 #if BUILDFLAG(IS_ANDROID)
2320 // Verify HttpStreamFactory::Job passes socket tag along properly and that
2321 // SpdySessions have unique socket tags (e.g. one sessions should not be shared
2322 // amongst streams with different socket tags).
TEST_F(HttpStreamFactoryTest,Tag)2323 TEST_F(HttpStreamFactoryTest, Tag) {
2324 SpdySessionDependencies session_deps;
2325 auto socket_factory = std::make_unique<MockTaggingClientSocketFactory>();
2326 auto* socket_factory_ptr = socket_factory.get();
2327 session_deps.socket_factory = std::move(socket_factory);
2328
2329 // Prepare for two HTTPS connects.
2330 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
2331 SequencedSocketData socket_data(base::make_span(&mock_read, 1u),
2332 base::span<MockWrite>());
2333 socket_data.set_connect_data(MockConnect(ASYNC, OK));
2334 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
2335 MockRead mock_read2(SYNCHRONOUS, ERR_IO_PENDING);
2336 SequencedSocketData socket_data2(base::make_span(&mock_read2, 1u),
2337 base::span<MockWrite>());
2338 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
2339 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
2340 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
2341 ssl_socket_data.ssl_info.cert =
2342 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
2343 ssl_socket_data.next_proto = kProtoHTTP2;
2344 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
2345 SSLSocketDataProvider ssl_socket_data2(ASYNC, OK);
2346 ssl_socket_data2.ssl_info.cert =
2347 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
2348 ssl_socket_data2.next_proto = kProtoHTTP2;
2349 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data2);
2350
2351 std::unique_ptr<HttpNetworkSession> session(
2352 SpdySessionDependencies::SpdyCreateSession(&session_deps));
2353
2354 // Prepare two different tags and corresponding HttpRequestInfos.
2355 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
2356 HttpRequestInfo request_info1;
2357 request_info1.method = "GET";
2358 request_info1.url = GURL("https://example.org");
2359 request_info1.load_flags = 0;
2360 request_info1.socket_tag = tag1;
2361 request_info1.traffic_annotation =
2362 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2363 SocketTag tag2(getuid(), 0x87654321);
2364 HttpRequestInfo request_info2 = request_info1;
2365 request_info2.socket_tag = tag2;
2366 request_info2.traffic_annotation =
2367 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2368
2369 // Verify one stream with one tag results in one session, group and
2370 // socket.
2371 SSLConfig ssl_config;
2372 StreamRequestWaiter waiter1;
2373 std::unique_ptr<HttpStreamRequest> request1(
2374 session->http_stream_factory()->RequestStream(
2375 request_info1, DEFAULT_PRIORITY, ssl_config, &waiter1,
2376 /* enable_ip_based_pooling = */ true,
2377 /* enable_alternative_services = */ true, NetLogWithSource()));
2378 waiter1.WaitForStream();
2379 EXPECT_TRUE(waiter1.stream_done());
2380 EXPECT_TRUE(nullptr == waiter1.websocket_stream());
2381 ASSERT_TRUE(nullptr != waiter1.stream());
2382
2383 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
2384 EXPECT_EQ(1,
2385 GetSocketPoolGroupCount(session->GetSocketPool(
2386 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2387 EXPECT_EQ(1,
2388 GetHandedOutSocketCount(session->GetSocketPool(
2389 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2390 // Verify socket tagged appropriately.
2391 EXPECT_TRUE(tag1 == socket_factory_ptr->GetLastProducedTCPSocket()->tag());
2392 EXPECT_TRUE(socket_factory_ptr->GetLastProducedTCPSocket()
2393 ->tagged_before_connected());
2394
2395 // Verify one more stream with a different tag results in one more session and
2396 // socket.
2397 StreamRequestWaiter waiter2;
2398 std::unique_ptr<HttpStreamRequest> request2(
2399 session->http_stream_factory()->RequestStream(
2400 request_info2, DEFAULT_PRIORITY, ssl_config, &waiter2,
2401 /* enable_ip_based_pooling = */ true,
2402 /* enable_alternative_services = */ true, NetLogWithSource()));
2403 waiter2.WaitForStream();
2404 EXPECT_TRUE(waiter2.stream_done());
2405 EXPECT_TRUE(nullptr == waiter2.websocket_stream());
2406 ASSERT_TRUE(nullptr != waiter2.stream());
2407
2408 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
2409 EXPECT_EQ(1,
2410 GetSocketPoolGroupCount(session->GetSocketPool(
2411 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2412 EXPECT_EQ(2,
2413 GetHandedOutSocketCount(session->GetSocketPool(
2414 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2415 // Verify socket tagged appropriately.
2416 EXPECT_TRUE(tag2 == socket_factory_ptr->GetLastProducedTCPSocket()->tag());
2417 EXPECT_TRUE(socket_factory_ptr->GetLastProducedTCPSocket()
2418 ->tagged_before_connected());
2419
2420 // Verify one more stream reusing a tag does not create new sessions, groups
2421 // or sockets.
2422 StreamRequestWaiter waiter3;
2423 std::unique_ptr<HttpStreamRequest> request3(
2424 session->http_stream_factory()->RequestStream(
2425 request_info2, DEFAULT_PRIORITY, ssl_config, &waiter3,
2426 /* enable_ip_based_pooling = */ true,
2427 /* enable_alternative_services = */ true, NetLogWithSource()));
2428 waiter3.WaitForStream();
2429 EXPECT_TRUE(waiter3.stream_done());
2430 EXPECT_TRUE(nullptr == waiter3.websocket_stream());
2431 ASSERT_TRUE(nullptr != waiter3.stream());
2432
2433 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
2434 EXPECT_EQ(1,
2435 GetSocketPoolGroupCount(session->GetSocketPool(
2436 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2437 EXPECT_EQ(2,
2438 GetHandedOutSocketCount(session->GetSocketPool(
2439 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2440 }
2441
2442 // Verify HttpStreamFactory::Job passes socket tag along properly to QUIC
2443 // sessions and that QuicSessions have unique socket tags (e.g. one sessions
2444 // should not be shared amongst streams with different socket tags).
TEST_P(HttpStreamFactoryBidirectionalQuicTest,Tag)2445 TEST_P(HttpStreamFactoryBidirectionalQuicTest, Tag) {
2446 // Prepare mock QUIC data for a first session establishment.
2447 MockQuicData mock_quic_data(version());
2448 spdy::SpdyPriority priority =
2449 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2450 size_t spdy_headers_frame_length;
2451 int packet_num = 1;
2452 mock_quic_data.AddWrite(
2453 client_packet_maker().MakeInitialSettingsPacket(packet_num++));
2454 mock_quic_data.AddWrite(client_packet_maker().MakeRequestHeadersPacket(
2455 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2456 /*fin=*/true, priority,
2457 client_packet_maker().GetRequestHeaders("GET", "https", "/"),
2458 &spdy_headers_frame_length));
2459 size_t spdy_response_headers_frame_length;
2460 mock_quic_data.AddRead(server_packet_maker().MakeResponseHeadersPacket(
2461 1, GetNthClientInitiatedBidirectionalStreamId(0),
2462 /*fin=*/true, server_packet_maker().GetResponseHeaders("200"),
2463 &spdy_response_headers_frame_length));
2464 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
2465 mock_quic_data.AddSocketDataToFactory(&socket_factory());
2466
2467 // Prepare mock QUIC data for a second session establishment.
2468 client_packet_maker().Reset();
2469 MockQuicData mock_quic_data2(version());
2470 packet_num = 1;
2471 mock_quic_data2.AddWrite(
2472 client_packet_maker().MakeInitialSettingsPacket(packet_num++));
2473 mock_quic_data2.AddWrite(client_packet_maker().MakeRequestHeadersPacket(
2474 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2475 /*fin=*/true, priority,
2476 client_packet_maker().GetRequestHeaders("GET", "https", "/"),
2477 &spdy_headers_frame_length));
2478 mock_quic_data2.AddRead(server_packet_maker().MakeResponseHeadersPacket(
2479 1, GetNthClientInitiatedBidirectionalStreamId(0),
2480 /*fin=*/true, server_packet_maker().GetResponseHeaders("200"),
2481 &spdy_response_headers_frame_length));
2482 mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
2483 mock_quic_data2.AddSocketDataToFactory(&socket_factory());
2484
2485 // Add hanging data for http job.
2486 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
2487 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
2488 hanging_data->set_connect_data(hanging_connect);
2489 socket_factory().AddSocketDataProvider(hanging_data.get());
2490 SSLSocketDataProvider ssl_data(ASYNC, OK);
2491 socket_factory().AddSSLSocketDataProvider(&ssl_data);
2492
2493 // Set up QUIC as alternative_service.
2494 Initialize();
2495 AddQuicAlternativeService();
2496
2497 // Prepare two different tags and corresponding HttpRequestInfos.
2498 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
2499 HttpRequestInfo request_info1;
2500 request_info1.method = "GET";
2501 request_info1.url = default_url_;
2502 request_info1.load_flags = 0;
2503 request_info1.socket_tag = tag1;
2504 request_info1.traffic_annotation =
2505 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2506 SocketTag tag2(getuid(), 0x87654321);
2507 HttpRequestInfo request_info2 = request_info1;
2508 request_info2.socket_tag = tag2;
2509 request_info2.traffic_annotation =
2510 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2511
2512 // Verify one stream with one tag results in one QUIC session.
2513 SSLConfig ssl_config;
2514 StreamRequestWaiter waiter1;
2515 std::unique_ptr<HttpStreamRequest> request1(
2516 session()->http_stream_factory()->RequestStream(
2517 request_info1, DEFAULT_PRIORITY, ssl_config, &waiter1,
2518 /* enable_ip_based_pooling = */ true,
2519 /* enable_alternative_services = */ true, NetLogWithSource()));
2520 waiter1.WaitForStream();
2521 EXPECT_TRUE(waiter1.stream_done());
2522 EXPECT_TRUE(nullptr == waiter1.websocket_stream());
2523 ASSERT_TRUE(nullptr != waiter1.stream());
2524 EXPECT_EQ(kProtoQUIC, request1->negotiated_protocol());
2525 EXPECT_EQ(1, GetQuicSessionCount(session()));
2526
2527 // Verify socket tagged appropriately.
2528 EXPECT_TRUE(tag1 == socket_factory().GetLastProducedUDPSocket()->tag());
2529 EXPECT_TRUE(socket_factory()
2530 .GetLastProducedUDPSocket()
2531 ->tagged_before_data_transferred());
2532
2533 // Verify one more stream with a different tag results in one more session and
2534 // socket.
2535 StreamRequestWaiter waiter2;
2536 std::unique_ptr<HttpStreamRequest> request2(
2537 session()->http_stream_factory()->RequestStream(
2538 request_info2, DEFAULT_PRIORITY, ssl_config, &waiter2,
2539 /* enable_ip_based_pooling = */ true,
2540 /* enable_alternative_services = */ true, NetLogWithSource()));
2541 waiter2.WaitForStream();
2542 EXPECT_TRUE(waiter2.stream_done());
2543 EXPECT_TRUE(nullptr == waiter2.websocket_stream());
2544 ASSERT_TRUE(nullptr != waiter2.stream());
2545 EXPECT_EQ(kProtoQUIC, request2->negotiated_protocol());
2546 EXPECT_EQ(2, GetQuicSessionCount(session()));
2547
2548 // Verify socket tagged appropriately.
2549 EXPECT_TRUE(tag2 == socket_factory().GetLastProducedUDPSocket()->tag());
2550 EXPECT_TRUE(socket_factory()
2551 .GetLastProducedUDPSocket()
2552 ->tagged_before_data_transferred());
2553
2554 // Verify one more stream reusing a tag does not create new sessions.
2555 StreamRequestWaiter waiter3;
2556 std::unique_ptr<HttpStreamRequest> request3(
2557 session()->http_stream_factory()->RequestStream(
2558 request_info2, DEFAULT_PRIORITY, ssl_config, &waiter3,
2559 /* enable_ip_based_pooling = */ true,
2560 /* enable_alternative_services = */ true, NetLogWithSource()));
2561 waiter3.WaitForStream();
2562 EXPECT_TRUE(waiter3.stream_done());
2563 EXPECT_TRUE(nullptr == waiter3.websocket_stream());
2564 ASSERT_TRUE(nullptr != waiter3.stream());
2565 EXPECT_EQ(kProtoQUIC, request3->negotiated_protocol());
2566 EXPECT_EQ(2, GetQuicSessionCount(session()));
2567 }
2568
TEST_F(HttpStreamFactoryTest,ChangeSocketTag)2569 TEST_F(HttpStreamFactoryTest, ChangeSocketTag) {
2570 SpdySessionDependencies session_deps;
2571 auto socket_factory = std::make_unique<MockTaggingClientSocketFactory>();
2572 auto* socket_factory_ptr = socket_factory.get();
2573 session_deps.socket_factory = std::move(socket_factory);
2574
2575 // Prepare for two HTTPS connects.
2576 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
2577 SequencedSocketData socket_data(base::make_span(&mock_read, 1u),
2578 base::span<MockWrite>());
2579 socket_data.set_connect_data(MockConnect(ASYNC, OK));
2580 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
2581 MockRead mock_read2(SYNCHRONOUS, ERR_IO_PENDING);
2582 SequencedSocketData socket_data2(base::make_span(&mock_read2, 1u),
2583 base::span<MockWrite>());
2584 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
2585 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
2586 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
2587 // Use cert for *.example.org
2588 ssl_socket_data.ssl_info.cert =
2589 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
2590 ssl_socket_data.next_proto = kProtoHTTP2;
2591 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
2592 SSLSocketDataProvider ssl_socket_data2(ASYNC, OK);
2593 // Use cert for *.example.org
2594 ssl_socket_data2.ssl_info.cert =
2595 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
2596 ssl_socket_data2.next_proto = kProtoHTTP2;
2597 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data2);
2598
2599 std::unique_ptr<HttpNetworkSession> session(
2600 SpdySessionDependencies::SpdyCreateSession(&session_deps));
2601
2602 // Prepare two different tags and corresponding HttpRequestInfos.
2603 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
2604 HttpRequestInfo request_info1;
2605 request_info1.method = "GET";
2606 request_info1.url = GURL("https://www.example.org");
2607 request_info1.load_flags = 0;
2608 request_info1.socket_tag = tag1;
2609 request_info1.traffic_annotation =
2610 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2611
2612 SocketTag tag2(getuid(), 0x87654321);
2613 HttpRequestInfo request_info2 = request_info1;
2614 request_info2.socket_tag = tag2;
2615 request_info2.traffic_annotation =
2616 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2617
2618 // Prepare another HttpRequestInfo with tag1 and a different host name.
2619 HttpRequestInfo request_info3 = request_info1;
2620 request_info3.url = GURL("https://foo.example.org");
2621 request_info3.traffic_annotation =
2622 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2623
2624 // Verify one stream with one tag results in one session, group and
2625 // socket.
2626 SSLConfig ssl_config;
2627 StreamRequestWaiter waiter1;
2628 std::unique_ptr<HttpStreamRequest> request1(
2629 session->http_stream_factory()->RequestStream(
2630 request_info1, DEFAULT_PRIORITY, ssl_config, &waiter1,
2631 /* enable_ip_based_pooling = */ true,
2632 /* enable_alternative_services = */ true, NetLogWithSource()));
2633 waiter1.WaitForStream();
2634 EXPECT_TRUE(waiter1.stream_done());
2635 EXPECT_FALSE(waiter1.websocket_stream());
2636 ASSERT_TRUE(waiter1.stream());
2637
2638 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
2639 EXPECT_EQ(1,
2640 GetSocketPoolGroupCount(session->GetSocketPool(
2641 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2642 EXPECT_EQ(1,
2643 GetHandedOutSocketCount(session->GetSocketPool(
2644 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2645 // Verify socket tagged appropriately.
2646 MockTaggingStreamSocket* socket =
2647 socket_factory_ptr->GetLastProducedTCPSocket();
2648 EXPECT_TRUE(tag1 == socket->tag());
2649 EXPECT_TRUE(socket->tagged_before_connected());
2650
2651 // Verify the socket tag on the first session can be changed.
2652 StreamRequestWaiter waiter2;
2653 std::unique_ptr<HttpStreamRequest> request2(
2654 session->http_stream_factory()->RequestStream(
2655 request_info2, DEFAULT_PRIORITY, ssl_config, &waiter2,
2656 /* enable_ip_based_pooling = */ true,
2657 /* enable_alternative_services = */ true, NetLogWithSource()));
2658 waiter2.WaitForStream();
2659 EXPECT_TRUE(waiter2.stream_done());
2660 EXPECT_FALSE(waiter2.websocket_stream());
2661 ASSERT_TRUE(waiter2.stream());
2662 // Verify still have just one session.
2663 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
2664 EXPECT_EQ(1,
2665 GetSocketPoolGroupCount(session->GetSocketPool(
2666 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2667 EXPECT_EQ(1,
2668 GetHandedOutSocketCount(session->GetSocketPool(
2669 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2670 // Verify no new sockets created.
2671 EXPECT_EQ(socket, socket_factory_ptr->GetLastProducedTCPSocket());
2672 // Verify socket tag changed.
2673 EXPECT_TRUE(tag2 == socket->tag());
2674 EXPECT_FALSE(socket->tagged_before_connected());
2675
2676 // Verify attempting to use the first stream fails because the session's
2677 // socket tag has since changed.
2678 TestCompletionCallback callback1;
2679 waiter1.stream()->RegisterRequest(&request_info1);
2680 EXPECT_EQ(ERR_FAILED, waiter1.stream()->InitializeStream(
2681 /* can_send_early = */ false, DEFAULT_PRIORITY,
2682 NetLogWithSource(), callback1.callback()));
2683
2684 // Verify the socket tag can be changed, this time using an IP alias
2685 // (different host, same IP).
2686 StreamRequestWaiter waiter3;
2687 std::unique_ptr<HttpStreamRequest> request3(
2688 session->http_stream_factory()->RequestStream(
2689 request_info3, DEFAULT_PRIORITY, ssl_config, &waiter3,
2690 /* enable_ip_based_pooling = */ true,
2691 /* enable_alternative_services = */ true, NetLogWithSource()));
2692 waiter3.WaitForStream();
2693 EXPECT_TRUE(waiter3.stream_done());
2694 EXPECT_FALSE(waiter3.websocket_stream());
2695 ASSERT_TRUE(waiter3.stream());
2696 // Verify still have just one session.
2697 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
2698 EXPECT_EQ(1,
2699 GetSocketPoolGroupCount(session->GetSocketPool(
2700 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2701 EXPECT_EQ(1,
2702 GetHandedOutSocketCount(session->GetSocketPool(
2703 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2704 // Verify no new sockets created.
2705 EXPECT_EQ(socket, socket_factory_ptr->GetLastProducedTCPSocket());
2706 // Verify socket tag changed.
2707 EXPECT_TRUE(tag1 == socket->tag());
2708 EXPECT_FALSE(socket->tagged_before_connected());
2709
2710 // Initialize the third stream, thus marking the session active, so it cannot
2711 // have its socket tag changed.
2712 TestCompletionCallback callback3;
2713 waiter3.stream()->RegisterRequest(&request_info3);
2714 EXPECT_EQ(OK, waiter3.stream()->InitializeStream(
2715 /* can_send_early = */ false, DEFAULT_PRIORITY,
2716 NetLogWithSource(), callback3.callback()));
2717
2718 // Verify a new session is created when a request with a different tag is
2719 // started.
2720 StreamRequestWaiter waiter4;
2721 std::unique_ptr<HttpStreamRequest> request4(
2722 session->http_stream_factory()->RequestStream(
2723 request_info2, DEFAULT_PRIORITY, ssl_config, &waiter4,
2724 /* enable_ip_based_pooling = */ true,
2725 /* enable_alternative_services = */ true, NetLogWithSource()));
2726 waiter4.WaitForStream();
2727 EXPECT_TRUE(waiter4.stream_done());
2728 EXPECT_FALSE(waiter4.websocket_stream());
2729 ASSERT_TRUE(waiter4.stream());
2730 // Verify we now have two sessions.
2731 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
2732 EXPECT_EQ(1,
2733 GetSocketPoolGroupCount(session->GetSocketPool(
2734 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2735 EXPECT_EQ(2,
2736 GetHandedOutSocketCount(session->GetSocketPool(
2737 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2738 // Verify a new socket was created.
2739 MockTaggingStreamSocket* socket2 =
2740 socket_factory_ptr->GetLastProducedTCPSocket();
2741 EXPECT_NE(socket, socket2);
2742 // Verify tag set appropriately.
2743 EXPECT_TRUE(tag2 == socket2->tag());
2744 EXPECT_TRUE(socket2->tagged_before_connected());
2745 // Verify tag on original socket is unchanged.
2746 EXPECT_TRUE(tag1 == socket->tag());
2747
2748 waiter3.stream()->Close(/* not_reusable = */ true);
2749 }
2750
2751 // Regression test for https://crbug.com/954503.
TEST_F(HttpStreamFactoryTest,ChangeSocketTagAvoidOverwrite)2752 TEST_F(HttpStreamFactoryTest, ChangeSocketTagAvoidOverwrite) {
2753 SpdySessionDependencies session_deps;
2754 auto socket_factory = std::make_unique<MockTaggingClientSocketFactory>();
2755 auto* socket_factory_ptr = socket_factory.get();
2756 session_deps.socket_factory = std::move(socket_factory);
2757
2758 // Prepare for two HTTPS connects.
2759 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
2760 SequencedSocketData socket_data(base::make_span(&mock_read, 1u),
2761 base::span<MockWrite>());
2762 socket_data.set_connect_data(MockConnect(ASYNC, OK));
2763 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
2764 MockRead mock_read2(SYNCHRONOUS, ERR_IO_PENDING);
2765 SequencedSocketData socket_data2(base::make_span(&mock_read2, 1u),
2766 base::span<MockWrite>());
2767 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
2768 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
2769 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
2770 // Use cert for *.example.org
2771 ssl_socket_data.ssl_info.cert =
2772 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
2773 ssl_socket_data.next_proto = kProtoHTTP2;
2774 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
2775 SSLSocketDataProvider ssl_socket_data2(ASYNC, OK);
2776 // Use cert for *.example.org
2777 ssl_socket_data2.ssl_info.cert =
2778 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
2779 ssl_socket_data2.next_proto = kProtoHTTP2;
2780 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data2);
2781
2782 std::unique_ptr<HttpNetworkSession> session(
2783 SpdySessionDependencies::SpdyCreateSession(&session_deps));
2784
2785 // Prepare three different tags and corresponding HttpRequestInfos.
2786 SocketTag tag1(SocketTag::UNSET_UID, 2);
2787 HttpRequestInfo request_info1;
2788 request_info1.method = "GET";
2789 request_info1.url = GURL("https://www.example.org");
2790 request_info1.load_flags = 0;
2791 request_info1.socket_tag = tag1;
2792 request_info1.traffic_annotation =
2793 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2794
2795 SocketTag tag2(SocketTag::UNSET_UID, 1);
2796 HttpRequestInfo request_info2 = request_info1;
2797 request_info2.socket_tag = tag2;
2798
2799 HttpRequestInfo request_info3 = request_info1;
2800 SocketTag tag3(SocketTag::UNSET_UID, 3);
2801 request_info3.socket_tag = tag3;
2802
2803 // Prepare another HttpRequestInfo with tag3 and a different host name.
2804 HttpRequestInfo request_info4 = request_info1;
2805 request_info4.socket_tag = tag3;
2806 request_info4.url = GURL("https://foo.example.org");
2807
2808 // Verify one stream with one tag results in one session, group and
2809 // socket.
2810 SSLConfig ssl_config;
2811 StreamRequestWaiter waiter1;
2812 std::unique_ptr<HttpStreamRequest> request1(
2813 session->http_stream_factory()->RequestStream(
2814 request_info1, DEFAULT_PRIORITY, ssl_config, &waiter1,
2815 /* enable_ip_based_pooling = */ true,
2816 /* enable_alternative_services = */ true, NetLogWithSource()));
2817 waiter1.WaitForStream();
2818 EXPECT_TRUE(waiter1.stream_done());
2819 EXPECT_FALSE(waiter1.websocket_stream());
2820 ASSERT_TRUE(waiter1.stream());
2821
2822 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
2823 EXPECT_EQ(1,
2824 GetSocketPoolGroupCount(session->GetSocketPool(
2825 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2826 EXPECT_EQ(1,
2827 GetHandedOutSocketCount(session->GetSocketPool(
2828 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2829 // Verify socket tagged appropriately.
2830 MockTaggingStreamSocket* socket =
2831 socket_factory_ptr->GetLastProducedTCPSocket();
2832 EXPECT_TRUE(tag1 == socket->tag());
2833 EXPECT_TRUE(socket->tagged_before_connected());
2834
2835 // Initialize the first stream, thus marking the session active, so it cannot
2836 // have its socket tag changed and be reused for the second session.
2837 TestCompletionCallback callback1;
2838 waiter1.stream()->RegisterRequest(&request_info1);
2839 EXPECT_EQ(OK, waiter1.stream()->InitializeStream(
2840 /* can_send_early = */ false, DEFAULT_PRIORITY,
2841 NetLogWithSource(), callback1.callback()));
2842
2843 // Create a second stream with a new tag.
2844 StreamRequestWaiter waiter2;
2845 std::unique_ptr<HttpStreamRequest> request2(
2846 session->http_stream_factory()->RequestStream(
2847 request_info2, DEFAULT_PRIORITY, ssl_config, &waiter2,
2848 /* enable_ip_based_pooling = */ true,
2849 /* enable_alternative_services = */ true, NetLogWithSource()));
2850 waiter2.WaitForStream();
2851 EXPECT_TRUE(waiter2.stream_done());
2852 EXPECT_FALSE(waiter2.websocket_stream());
2853 ASSERT_TRUE(waiter2.stream());
2854 // Verify we now have two sessions.
2855 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
2856 EXPECT_EQ(1,
2857 GetSocketPoolGroupCount(session->GetSocketPool(
2858 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2859 EXPECT_EQ(2,
2860 GetHandedOutSocketCount(session->GetSocketPool(
2861 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2862 // Verify a new socket was created.
2863 MockTaggingStreamSocket* socket2 =
2864 socket_factory_ptr->GetLastProducedTCPSocket();
2865 EXPECT_NE(socket, socket2);
2866 // Verify tag set appropriately.
2867 EXPECT_TRUE(tag2 == socket2->tag());
2868 EXPECT_TRUE(socket2->tagged_before_connected());
2869 // Verify tag on original socket is unchanged.
2870 EXPECT_TRUE(tag1 == socket->tag());
2871
2872 // Initialize the second stream, thus marking the session active, so it cannot
2873 // have its socket tag changed and be reused for the third session.
2874 TestCompletionCallback callback2;
2875 waiter2.stream()->RegisterRequest(&request_info2);
2876 EXPECT_EQ(OK, waiter2.stream()->InitializeStream(
2877 /* can_send_early = */ false, DEFAULT_PRIORITY,
2878 NetLogWithSource(), callback2.callback()));
2879
2880 // Release first stream so first session can be retagged for third request.
2881 waiter1.stream()->Close(/* not_reusable = */ true);
2882
2883 // Verify the first session can be retagged for a third request.
2884 StreamRequestWaiter waiter3;
2885 std::unique_ptr<HttpStreamRequest> request3(
2886 session->http_stream_factory()->RequestStream(
2887 request_info3, DEFAULT_PRIORITY, ssl_config, &waiter3,
2888 /* enable_ip_based_pooling = */ true,
2889 /* enable_alternative_services = */ true, NetLogWithSource()));
2890 waiter3.WaitForStream();
2891 EXPECT_TRUE(waiter3.stream_done());
2892 EXPECT_FALSE(waiter3.websocket_stream());
2893 ASSERT_TRUE(waiter3.stream());
2894 // Verify still have two sessions.
2895 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
2896 EXPECT_EQ(1,
2897 GetSocketPoolGroupCount(session->GetSocketPool(
2898 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2899 EXPECT_EQ(2,
2900 GetHandedOutSocketCount(session->GetSocketPool(
2901 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
2902 // Verify no new sockets created.
2903 EXPECT_EQ(socket2, socket_factory_ptr->GetLastProducedTCPSocket());
2904 // Verify socket tag changed.
2905 EXPECT_TRUE(tag3 == socket->tag());
2906 EXPECT_FALSE(socket->tagged_before_connected());
2907
2908 // Release second stream so second session can be retagged for fourth request.
2909 waiter2.stream()->Close(/* not_reusable = */ true);
2910
2911 // Request a stream with a new tag and a different host that aliases existing
2912 // sessions.
2913 StreamRequestWaiter waiter4;
2914 std::unique_ptr<HttpStreamRequest> request4(
2915 session->http_stream_factory()->RequestStream(
2916 request_info4, DEFAULT_PRIORITY, ssl_config, &waiter4,
2917 /* enable_ip_based_pooling = */ true,
2918 /* enable_alternative_services = */ true, NetLogWithSource()));
2919 waiter4.WaitForStream();
2920 EXPECT_TRUE(waiter4.stream_done());
2921 EXPECT_FALSE(waiter4.websocket_stream());
2922 ASSERT_TRUE(waiter4.stream());
2923 // Verify no new sockets created.
2924 EXPECT_EQ(socket2, socket_factory_ptr->GetLastProducedTCPSocket());
2925 }
2926 #endif
2927
2928 // Test that when creating a stream all sessions that alias an IP are tried,
2929 // not just one. This is important because there can be multiple sessions
2930 // that could satisfy a stream request and they should all be tried.
TEST_F(HttpStreamFactoryTest,MultiIPAliases)2931 TEST_F(HttpStreamFactoryTest, MultiIPAliases) {
2932 SpdySessionDependencies session_deps;
2933
2934 // Prepare for two HTTPS connects.
2935 MockRead mock_read1(SYNCHRONOUS, ERR_IO_PENDING);
2936 SequencedSocketData socket_data1(base::make_span(&mock_read1, 1u),
2937 base::span<MockWrite>());
2938 socket_data1.set_connect_data(MockConnect(ASYNC, OK));
2939 session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
2940 MockRead mock_read2(SYNCHRONOUS, ERR_IO_PENDING);
2941 SequencedSocketData socket_data2(base::make_span(&mock_read2, 1u),
2942 base::span<MockWrite>());
2943 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
2944 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
2945 SSLSocketDataProvider ssl_socket_data1(ASYNC, OK);
2946 // Load cert for *.example.org
2947 ssl_socket_data1.ssl_info.cert =
2948 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
2949 ssl_socket_data1.next_proto = kProtoHTTP2;
2950 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data1);
2951 SSLSocketDataProvider ssl_socket_data2(ASYNC, OK);
2952 // Load cert for *.example.org
2953 ssl_socket_data2.ssl_info.cert =
2954 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
2955 ssl_socket_data2.next_proto = kProtoHTTP2;
2956 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data2);
2957
2958 std::unique_ptr<HttpNetworkSession> session(
2959 SpdySessionDependencies::SpdyCreateSession(&session_deps));
2960
2961 // Create two HttpRequestInfos, differing only in host name.
2962 // Both will resolve to 127.0.0.1 and hence be IP aliases.
2963 HttpRequestInfo request_info1;
2964 request_info1.method = "GET";
2965 request_info1.url = GURL("https://a.example.org");
2966 request_info1.privacy_mode = PRIVACY_MODE_DISABLED;
2967 request_info1.traffic_annotation =
2968 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2969 HttpRequestInfo request_info1_alias = request_info1;
2970 request_info1.url = GURL("https://b.example.org");
2971
2972 // Create two more HttpRequestInfos but with different privacy_mode.
2973 HttpRequestInfo request_info2;
2974 request_info2.method = "GET";
2975 request_info2.url = GURL("https://a.example.org");
2976 request_info2.privacy_mode = PRIVACY_MODE_ENABLED;
2977 request_info2.traffic_annotation =
2978 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2979 HttpRequestInfo request_info2_alias = request_info2;
2980 request_info2.url = GURL("https://b.example.org");
2981
2982 // Open one session.
2983 SSLConfig ssl_config;
2984 StreamRequestWaiter waiter1;
2985 std::unique_ptr<HttpStreamRequest> request1(
2986 session->http_stream_factory()->RequestStream(
2987 request_info1, DEFAULT_PRIORITY, ssl_config, &waiter1,
2988 /* enable_ip_based_pooling = */ true,
2989 /* enable_alternative_services = */ true, NetLogWithSource()));
2990 waiter1.WaitForStream();
2991 EXPECT_TRUE(waiter1.stream_done());
2992 EXPECT_FALSE(waiter1.websocket_stream());
2993 ASSERT_TRUE(waiter1.stream());
2994
2995 // Verify just one session created.
2996 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
2997 EXPECT_EQ(1,
2998 GetSocketPoolGroupCount(session->GetSocketPool(
2999 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3000 EXPECT_EQ(1,
3001 GetHandedOutSocketCount(session->GetSocketPool(
3002 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3003
3004 // Open another session to same IP but with different privacy mode.
3005 StreamRequestWaiter waiter2;
3006 std::unique_ptr<HttpStreamRequest> request2(
3007 session->http_stream_factory()->RequestStream(
3008 request_info2, DEFAULT_PRIORITY, ssl_config, &waiter2,
3009 /* enable_ip_based_pooling = */ true,
3010 /* enable_alternative_services = */ true, NetLogWithSource()));
3011 waiter2.WaitForStream();
3012 EXPECT_TRUE(waiter2.stream_done());
3013 EXPECT_FALSE(waiter2.websocket_stream());
3014 ASSERT_TRUE(waiter2.stream());
3015
3016 // Verify two sessions are now open.
3017 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
3018 EXPECT_EQ(2,
3019 GetSocketPoolGroupCount(session->GetSocketPool(
3020 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3021 EXPECT_EQ(2,
3022 GetHandedOutSocketCount(session->GetSocketPool(
3023 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3024
3025 // Open a third session that IP aliases first session.
3026 StreamRequestWaiter waiter3;
3027 std::unique_ptr<HttpStreamRequest> request3(
3028 session->http_stream_factory()->RequestStream(
3029 request_info1_alias, DEFAULT_PRIORITY, ssl_config, &waiter3,
3030 /* enable_ip_based_pooling = */ true,
3031 /* enable_alternative_services = */ true, NetLogWithSource()));
3032 waiter3.WaitForStream();
3033 EXPECT_TRUE(waiter3.stream_done());
3034 EXPECT_FALSE(waiter3.websocket_stream());
3035 ASSERT_TRUE(waiter3.stream());
3036
3037 // Verify the session pool reused the first session and no new session is
3038 // created. This will fail unless the session pool supports multiple
3039 // sessions aliasing a single IP.
3040 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
3041 EXPECT_EQ(2,
3042 GetSocketPoolGroupCount(session->GetSocketPool(
3043 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3044 EXPECT_EQ(2,
3045 GetHandedOutSocketCount(session->GetSocketPool(
3046 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3047
3048 // Open a fourth session that IP aliases the second session.
3049 StreamRequestWaiter waiter4;
3050 std::unique_ptr<HttpStreamRequest> request4(
3051 session->http_stream_factory()->RequestStream(
3052 request_info2_alias, DEFAULT_PRIORITY, ssl_config, &waiter4,
3053 /* enable_ip_based_pooling = */ true,
3054 /* enable_alternative_services = */ true, NetLogWithSource()));
3055 waiter4.WaitForStream();
3056 EXPECT_TRUE(waiter4.stream_done());
3057 EXPECT_FALSE(waiter4.websocket_stream());
3058 ASSERT_TRUE(waiter4.stream());
3059
3060 // Verify the session pool reused the second session. This will fail unless
3061 // the session pool supports multiple sessions aliasing a single IP.
3062 EXPECT_EQ(2, GetSpdySessionCount(session.get()));
3063 EXPECT_EQ(2,
3064 GetSocketPoolGroupCount(session->GetSocketPool(
3065 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3066 EXPECT_EQ(2,
3067 GetHandedOutSocketCount(session->GetSocketPool(
3068 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3069 }
3070
TEST_F(HttpStreamFactoryTest,SpdyIPPoolingWithDnsAliases)3071 TEST_F(HttpStreamFactoryTest, SpdyIPPoolingWithDnsAliases) {
3072 SpdySessionDependencies session_deps;
3073
3074 const std::set<std::string> kDnsAliasesA({"alias1", "alias2"});
3075 const std::set<std::string> kDnsAliasesB({"b.com", "b.org", "b.net"});
3076 const std::string kHostnameC("c.example.org");
3077
3078 session_deps.host_resolver->rules()->AddIPLiteralRuleWithDnsAliases(
3079 "a.example.org", "127.0.0.1", kDnsAliasesA);
3080 session_deps.host_resolver->rules()->AddIPLiteralRuleWithDnsAliases(
3081 "b.example.org", "127.0.0.1", kDnsAliasesB);
3082 session_deps.host_resolver->rules()->AddIPLiteralRuleWithDnsAliases(
3083 "c.example.org", "127.0.0.1", /*dns_aliases=*/std::set<std::string>());
3084
3085 // Prepare for an HTTPS connect.
3086 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
3087 SequencedSocketData socket_data(base::make_span(&mock_read, 1u),
3088 base::span<MockWrite>());
3089 socket_data.set_connect_data(MockConnect(ASYNC, OK));
3090 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
3091 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
3092 // Load cert for *.example.org
3093 ssl_socket_data.ssl_info.cert =
3094 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
3095 ssl_socket_data.next_proto = kProtoHTTP2;
3096 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
3097
3098 std::unique_ptr<HttpNetworkSession> session(
3099 SpdySessionDependencies::SpdyCreateSession(&session_deps));
3100
3101 // Create three HttpRequestInfos, differing only in host name.
3102 // All three will resolve to 127.0.0.1 and hence be IP aliases.
3103 HttpRequestInfo request_info_a;
3104 request_info_a.method = "GET";
3105 request_info_a.url = GURL("https://a.example.org");
3106 request_info_a.privacy_mode = PRIVACY_MODE_DISABLED;
3107 request_info_a.traffic_annotation =
3108 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3109 HttpRequestInfo request_info_b = request_info_a;
3110 HttpRequestInfo request_info_c = request_info_a;
3111 request_info_b.url = GURL("https://b.example.org");
3112 request_info_c.url = GURL("https://c.example.org");
3113
3114 // Open one session.
3115 SSLConfig ssl_config;
3116 StreamRequestWaiter waiter1;
3117 std::unique_ptr<HttpStreamRequest> request1(
3118 session->http_stream_factory()->RequestStream(
3119 request_info_a, DEFAULT_PRIORITY, ssl_config, &waiter1,
3120 /* enable_ip_based_pooling = */ true,
3121 /* enable_alternative_services = */ true, NetLogWithSource()));
3122 waiter1.WaitForStream();
3123 EXPECT_TRUE(waiter1.stream_done());
3124 EXPECT_FALSE(waiter1.websocket_stream());
3125 ASSERT_TRUE(waiter1.stream());
3126 EXPECT_EQ(kDnsAliasesA, waiter1.stream()->GetDnsAliases());
3127
3128 // Verify just one session created.
3129 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
3130 EXPECT_EQ(1,
3131 GetSocketPoolGroupCount(session->GetSocketPool(
3132 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3133 EXPECT_EQ(1,
3134 GetHandedOutSocketCount(session->GetSocketPool(
3135 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3136
3137 // Open a session that IP aliases first session.
3138 StreamRequestWaiter waiter2;
3139 std::unique_ptr<HttpStreamRequest> request2(
3140 session->http_stream_factory()->RequestStream(
3141 request_info_b, DEFAULT_PRIORITY, ssl_config, &waiter2,
3142 /* enable_ip_based_pooling = */ true,
3143 /* enable_alternative_services = */ true, NetLogWithSource()));
3144 waiter2.WaitForStream();
3145 EXPECT_TRUE(waiter2.stream_done());
3146 EXPECT_FALSE(waiter2.websocket_stream());
3147 ASSERT_TRUE(waiter2.stream());
3148 EXPECT_EQ(kDnsAliasesB, waiter2.stream()->GetDnsAliases());
3149
3150 // Verify the session pool reused the first session and no new session is
3151 // created. This will fail unless the session pool supports multiple
3152 // sessions aliasing a single IP.
3153 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
3154 EXPECT_EQ(1,
3155 GetSocketPoolGroupCount(session->GetSocketPool(
3156 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3157 EXPECT_EQ(1,
3158 GetHandedOutSocketCount(session->GetSocketPool(
3159 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3160
3161 // Open another session that IP aliases the first session.
3162 StreamRequestWaiter waiter3;
3163 std::unique_ptr<HttpStreamRequest> request3(
3164 session->http_stream_factory()->RequestStream(
3165 request_info_c, DEFAULT_PRIORITY, ssl_config, &waiter3,
3166 /* enable_ip_based_pooling = */ true,
3167 /* enable_alternative_services = */ true, NetLogWithSource()));
3168 waiter3.WaitForStream();
3169 EXPECT_TRUE(waiter3.stream_done());
3170 EXPECT_FALSE(waiter3.websocket_stream());
3171 ASSERT_TRUE(waiter3.stream());
3172 EXPECT_THAT(waiter3.stream()->GetDnsAliases(), ElementsAre(kHostnameC));
3173
3174 // Verify the session pool reused the first session and no new session is
3175 // created. This will fail unless the session pool supports multiple
3176 // sessions aliasing a single IP.
3177 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
3178 EXPECT_EQ(1,
3179 GetSocketPoolGroupCount(session->GetSocketPool(
3180 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3181 EXPECT_EQ(1,
3182 GetHandedOutSocketCount(session->GetSocketPool(
3183 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3184
3185 // Clear host resolver rules to ensure that cached values for DNS aliases
3186 // are used.
3187 session_deps.host_resolver->rules()->ClearRules();
3188
3189 // Re-request the original resource using `request_info_a`, which had
3190 // non-default DNS aliases.
3191 std::unique_ptr<HttpStreamRequest> request4(
3192 session->http_stream_factory()->RequestStream(
3193 request_info_a, DEFAULT_PRIORITY, ssl_config, &waiter1,
3194 /* enable_ip_based_pooling = */ true,
3195 /* enable_alternative_services = */ true, NetLogWithSource()));
3196 waiter1.WaitForStream();
3197 EXPECT_TRUE(waiter1.stream_done());
3198 EXPECT_FALSE(waiter1.websocket_stream());
3199 ASSERT_TRUE(waiter1.stream());
3200 EXPECT_EQ(kDnsAliasesA, waiter1.stream()->GetDnsAliases());
3201
3202 // Verify the session pool reused the first session and no new session is
3203 // created.
3204 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
3205 EXPECT_EQ(1,
3206 GetSocketPoolGroupCount(session->GetSocketPool(
3207 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3208 EXPECT_EQ(1,
3209 GetHandedOutSocketCount(session->GetSocketPool(
3210 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3211
3212 // Re-request a resource using `request_info_b`, which had non-default DNS
3213 // aliases.
3214 std::unique_ptr<HttpStreamRequest> request5(
3215 session->http_stream_factory()->RequestStream(
3216 request_info_b, DEFAULT_PRIORITY, ssl_config, &waiter2,
3217 /* enable_ip_based_pooling = */ true,
3218 /* enable_alternative_services = */ true, NetLogWithSource()));
3219 waiter2.WaitForStream();
3220 EXPECT_TRUE(waiter2.stream_done());
3221 EXPECT_FALSE(waiter2.websocket_stream());
3222 ASSERT_TRUE(waiter2.stream());
3223 EXPECT_EQ(kDnsAliasesB, waiter2.stream()->GetDnsAliases());
3224
3225 // Verify the session pool reused the first session and no new session is
3226 // created. This will fail unless the session pool supports multiple
3227 // sessions aliasing a single IP.
3228 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
3229 EXPECT_EQ(1,
3230 GetSocketPoolGroupCount(session->GetSocketPool(
3231 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3232 EXPECT_EQ(1,
3233 GetHandedOutSocketCount(session->GetSocketPool(
3234 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3235
3236 // Re-request a resource using `request_info_c`, which had only the default
3237 // DNS alias (the host name).
3238 std::unique_ptr<HttpStreamRequest> request6(
3239 session->http_stream_factory()->RequestStream(
3240 request_info_c, DEFAULT_PRIORITY, ssl_config, &waiter3,
3241 /* enable_ip_based_pooling = */ true,
3242 /* enable_alternative_services = */ true, NetLogWithSource()));
3243 waiter3.WaitForStream();
3244 EXPECT_TRUE(waiter3.stream_done());
3245 EXPECT_FALSE(waiter3.websocket_stream());
3246 ASSERT_TRUE(waiter3.stream());
3247 EXPECT_THAT(waiter3.stream()->GetDnsAliases(), ElementsAre(kHostnameC));
3248
3249 // Verify the session pool reused the first session and no new session is
3250 // created. This will fail unless the session pool supports multiple
3251 // sessions aliasing a single IP.
3252 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
3253 EXPECT_EQ(1,
3254 GetSocketPoolGroupCount(session->GetSocketPool(
3255 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3256 EXPECT_EQ(1,
3257 GetHandedOutSocketCount(session->GetSocketPool(
3258 HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
3259 }
3260
TEST_P(HttpStreamFactoryBidirectionalQuicTest,QuicIPPoolingWithDnsAliases)3261 TEST_P(HttpStreamFactoryBidirectionalQuicTest, QuicIPPoolingWithDnsAliases) {
3262 const GURL kUrlA("https://a.example.org");
3263 const GURL kUrlB("https://b.example.org");
3264 const GURL kUrlC("https://c.example.org");
3265 const std::set<std::string> kDnsAliasesA({"alias1", "alias2"});
3266 const std::set<std::string> kDnsAliasesB({"b.com", "b.org", "b.net"});
3267
3268 host_resolver()->rules()->AddIPLiteralRuleWithDnsAliases(
3269 kUrlA.host(), "127.0.0.1", kDnsAliasesA);
3270 host_resolver()->rules()->AddIPLiteralRuleWithDnsAliases(
3271 kUrlB.host(), "127.0.0.1", kDnsAliasesB);
3272 host_resolver()->rules()->AddIPLiteralRuleWithDnsAliases(
3273 kUrlC.host(), "127.0.0.1",
3274 /*dns_aliases=*/std::set<std::string>());
3275
3276 // Prepare mock QUIC data for a first session establishment.
3277 MockQuicData mock_quic_data(version());
3278 spdy::SpdyPriority priority =
3279 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3280 size_t spdy_headers_frame_length;
3281 int packet_num = 1;
3282 mock_quic_data.AddWrite(
3283 client_packet_maker().MakeInitialSettingsPacket(packet_num++));
3284 mock_quic_data.AddWrite(client_packet_maker().MakeRequestHeadersPacket(
3285 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
3286 /*fin=*/true, priority,
3287 client_packet_maker().GetRequestHeaders("GET", "https", "/"),
3288 &spdy_headers_frame_length));
3289 size_t spdy_response_headers_frame_length;
3290 mock_quic_data.AddRead(server_packet_maker().MakeResponseHeadersPacket(
3291 1, GetNthClientInitiatedBidirectionalStreamId(0),
3292 /*fin=*/true, server_packet_maker().GetResponseHeaders("200"),
3293 &spdy_response_headers_frame_length));
3294 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
3295 mock_quic_data.AddSocketDataToFactory(&socket_factory());
3296
3297 // Add hanging data for http job.
3298 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
3299 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
3300 hanging_data->set_connect_data(hanging_connect);
3301 socket_factory().AddSocketDataProvider(hanging_data.get());
3302 SSLSocketDataProvider ssl_data(ASYNC, OK);
3303 socket_factory().AddSSLSocketDataProvider(&ssl_data);
3304
3305 // Set up QUIC as alternative_service.
3306 Initialize();
3307 AddQuicAlternativeService(url::SchemeHostPort(kUrlA), kUrlA.host());
3308 AddQuicAlternativeService(url::SchemeHostPort(kUrlB), kUrlB.host());
3309 AddQuicAlternativeService(url::SchemeHostPort(kUrlC), kUrlC.host());
3310
3311 // Create three HttpRequestInfos, differing only in host name.
3312 // All three will resolve to 127.0.0.1 and hence be IP aliases.
3313 HttpRequestInfo request_info_a;
3314 request_info_a.method = "GET";
3315 request_info_a.url = kUrlA;
3316 request_info_a.privacy_mode = PRIVACY_MODE_DISABLED;
3317 request_info_a.traffic_annotation =
3318 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3319 HttpRequestInfo request_info_b = request_info_a;
3320 HttpRequestInfo request_info_c = request_info_a;
3321 request_info_b.url = kUrlB;
3322 request_info_c.url = kUrlC;
3323
3324 // Open one session.
3325 SSLConfig ssl_config;
3326 StreamRequestWaiter waiter1;
3327 std::unique_ptr<HttpStreamRequest> request1(
3328 session()->http_stream_factory()->RequestStream(
3329 request_info_a, DEFAULT_PRIORITY, ssl_config, &waiter1,
3330 /* enable_ip_based_pooling = */ true,
3331 /* enable_alternative_services = */ true, NetLogWithSource()));
3332 waiter1.WaitForStream();
3333 EXPECT_TRUE(waiter1.stream_done());
3334 EXPECT_FALSE(waiter1.websocket_stream());
3335 ASSERT_TRUE(waiter1.stream());
3336 EXPECT_EQ(kDnsAliasesA, waiter1.stream()->GetDnsAliases());
3337
3338 // Verify just one session created.
3339 EXPECT_EQ(1, GetQuicSessionCount(session()));
3340 EXPECT_EQ(kProtoQUIC, request1->negotiated_protocol());
3341
3342 // Create a request that will alias and reuse the first session.
3343 StreamRequestWaiter waiter2;
3344 std::unique_ptr<HttpStreamRequest> request2(
3345 session()->http_stream_factory()->RequestStream(
3346 request_info_b, DEFAULT_PRIORITY, ssl_config, &waiter2,
3347 /* enable_ip_based_pooling = */ true,
3348 /* enable_alternative_services = */ true, NetLogWithSource()));
3349 waiter2.WaitForStream();
3350 EXPECT_TRUE(waiter2.stream_done());
3351 EXPECT_FALSE(waiter2.websocket_stream());
3352 ASSERT_TRUE(waiter2.stream());
3353 EXPECT_EQ(kDnsAliasesB, waiter2.stream()->GetDnsAliases());
3354
3355 // Verify the session pool reused the first session and no new session is
3356 // created. This will fail unless the session pool supports multiple
3357 // sessions aliasing a single IP.
3358 EXPECT_EQ(1, GetQuicSessionCount(session()));
3359 EXPECT_EQ(kProtoQUIC, request2->negotiated_protocol());
3360
3361 // Create another request that will alias and reuse the first session.
3362 StreamRequestWaiter waiter3;
3363 std::unique_ptr<HttpStreamRequest> request3(
3364 session()->http_stream_factory()->RequestStream(
3365 request_info_c, DEFAULT_PRIORITY, ssl_config, &waiter3,
3366 /* enable_ip_based_pooling = */ true,
3367 /* enable_alternative_services = */ true, NetLogWithSource()));
3368 waiter3.WaitForStream();
3369 EXPECT_TRUE(waiter3.stream_done());
3370 EXPECT_FALSE(waiter3.websocket_stream());
3371 ASSERT_TRUE(waiter3.stream());
3372 EXPECT_THAT(waiter3.stream()->GetDnsAliases(), ElementsAre(kUrlC.host()));
3373
3374 // Clear the host resolve rules to ensure that we are using cached info.
3375 host_resolver()->rules()->ClearRules();
3376
3377 // Verify the session pool reused the first session and no new session is
3378 // created. This will fail unless the session pool supports multiple
3379 // sessions aliasing a single IP.
3380 EXPECT_EQ(1, GetQuicSessionCount(session()));
3381 EXPECT_EQ(kProtoQUIC, request3->negotiated_protocol());
3382
3383 // Create a request that will reuse the first session.
3384 std::unique_ptr<HttpStreamRequest> request4(
3385 session()->http_stream_factory()->RequestStream(
3386 request_info_a, DEFAULT_PRIORITY, ssl_config, &waiter1,
3387 /* enable_ip_based_pooling = */ true,
3388 /* enable_alternative_services = */ true, NetLogWithSource()));
3389 waiter1.WaitForStream();
3390 EXPECT_TRUE(waiter1.stream_done());
3391 EXPECT_FALSE(waiter1.websocket_stream());
3392 ASSERT_TRUE(waiter1.stream());
3393 EXPECT_EQ(kDnsAliasesA, waiter1.stream()->GetDnsAliases());
3394
3395 // Verify the session pool reused the first session and no new session is
3396 // created.
3397 EXPECT_EQ(1, GetQuicSessionCount(session()));
3398 EXPECT_EQ(kProtoQUIC, request4->negotiated_protocol());
3399
3400 // Create another request that will alias and reuse the first session.
3401 std::unique_ptr<HttpStreamRequest> request5(
3402 session()->http_stream_factory()->RequestStream(
3403 request_info_b, DEFAULT_PRIORITY, ssl_config, &waiter2,
3404 /* enable_ip_based_pooling = */ true,
3405 /* enable_alternative_services = */ true, NetLogWithSource()));
3406 waiter2.WaitForStream();
3407 EXPECT_TRUE(waiter2.stream_done());
3408 EXPECT_FALSE(waiter2.websocket_stream());
3409 ASSERT_TRUE(waiter2.stream());
3410 EXPECT_EQ(kDnsAliasesB, waiter2.stream()->GetDnsAliases());
3411
3412 // Verify the session pool reused the first session and no new session is
3413 // created. This will fail unless the session pool supports multiple
3414 // sessions aliasing a single IP.
3415 EXPECT_EQ(1, GetQuicSessionCount(session()));
3416 EXPECT_EQ(kProtoQUIC, request5->negotiated_protocol());
3417
3418 // Create another request that will alias and reuse the first session.
3419 std::unique_ptr<HttpStreamRequest> request6(
3420 session()->http_stream_factory()->RequestStream(
3421 request_info_c, DEFAULT_PRIORITY, ssl_config, &waiter3,
3422 /* enable_ip_based_pooling = */ true,
3423 /* enable_alternative_services = */ true, NetLogWithSource()));
3424 waiter3.WaitForStream();
3425 EXPECT_TRUE(waiter3.stream_done());
3426 EXPECT_FALSE(waiter3.websocket_stream());
3427 ASSERT_TRUE(waiter3.stream());
3428 EXPECT_THAT(waiter3.stream()->GetDnsAliases(), ElementsAre(kUrlC.host()));
3429
3430 // Verify the session pool reused the first session and no new session is
3431 // created. This will fail unless the session pool supports multiple
3432 // sessions aliasing a single IP.
3433 EXPECT_EQ(1, GetQuicSessionCount(session()));
3434 EXPECT_EQ(kProtoQUIC, request6->negotiated_protocol());
3435 }
3436
3437 class ProcessAlternativeServicesTest : public TestWithTaskEnvironment {
3438 public:
ProcessAlternativeServicesTest()3439 ProcessAlternativeServicesTest() {
3440 session_params_.enable_quic = true;
3441
3442 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
3443 session_context_.host_resolver = &host_resolver_;
3444 session_context_.cert_verifier = &cert_verifier_;
3445 session_context_.transport_security_state = &transport_security_state_;
3446 session_context_.client_socket_factory = &socket_factory_;
3447 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
3448 session_context_.ssl_config_service = &ssl_config_service_;
3449 session_context_.http_server_properties = &http_server_properties_;
3450 session_context_.quic_context = &quic_context_;
3451 }
3452
3453 private:
3454 // Parameters passed in the NetworkSessionContext must outlive the
3455 // HttpNetworkSession.
3456 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_ =
3457 ConfiguredProxyResolutionService::CreateDirect();
3458 SSLConfigServiceDefaults ssl_config_service_;
3459 MockClientSocketFactory socket_factory_;
3460 MockHostResolver host_resolver_;
3461 MockCertVerifier cert_verifier_;
3462 TransportSecurityState transport_security_state_;
3463 DefaultCTPolicyEnforcer ct_policy_enforcer_;
3464
3465 protected:
3466 HttpServerProperties http_server_properties_;
3467 QuicContext quic_context_;
3468 HttpNetworkSessionParams session_params_;
3469 HttpNetworkSessionContext session_context_;
3470 std::unique_ptr<HttpNetworkSession> session_;
3471
3472 };
3473
TEST_F(ProcessAlternativeServicesTest,ProcessEmptyAltSvc)3474 TEST_F(ProcessAlternativeServicesTest, ProcessEmptyAltSvc) {
3475 session_ =
3476 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
3477 url::SchemeHostPort origin;
3478 NetworkAnonymizationKey network_anonymization_key;
3479
3480 auto headers = base::MakeRefCounted<HttpResponseHeaders>("");
3481
3482 session_->http_stream_factory()->ProcessAlternativeServices(
3483 session_.get(), network_anonymization_key, headers.get(), origin);
3484
3485 AlternativeServiceInfoVector alternatives =
3486 http_server_properties_.GetAlternativeServiceInfos(
3487 origin, network_anonymization_key);
3488 EXPECT_TRUE(alternatives.empty());
3489 }
3490
TEST_F(ProcessAlternativeServicesTest,ProcessAltSvcClear)3491 TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcClear) {
3492 session_ =
3493 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
3494 url::SchemeHostPort origin(url::kHttpsScheme, "example.com", 443);
3495
3496 auto network_anonymization_key = NetworkAnonymizationKey::CreateSameSite(
3497 SchemefulSite(GURL("https://example.com")));
3498
3499 http_server_properties_.SetAlternativeServices(
3500 origin, network_anonymization_key,
3501 {AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3502 {kProtoQUIC, "", 443}, base::Time::Now() + base::Seconds(30),
3503 quic::AllSupportedVersions())});
3504
3505 EXPECT_FALSE(
3506 http_server_properties_
3507 .GetAlternativeServiceInfos(origin, network_anonymization_key)
3508 .empty());
3509
3510 auto headers = base::MakeRefCounted<HttpResponseHeaders>("");
3511 headers->AddHeader("alt-svc", "clear");
3512
3513 session_->http_stream_factory()->ProcessAlternativeServices(
3514 session_.get(), network_anonymization_key, headers.get(), origin);
3515
3516 AlternativeServiceInfoVector alternatives =
3517 http_server_properties_.GetAlternativeServiceInfos(
3518 origin, network_anonymization_key);
3519 EXPECT_TRUE(alternatives.empty());
3520 }
3521
TEST_F(ProcessAlternativeServicesTest,ProcessAltSvcQuicIetf)3522 TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcQuicIetf) {
3523 quic_context_.params()->supported_versions = quic::AllSupportedVersions();
3524 session_ =
3525 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
3526 url::SchemeHostPort origin(url::kHttpsScheme, "example.com", 443);
3527
3528 auto network_anonymization_key = NetworkAnonymizationKey::CreateSameSite(
3529 SchemefulSite(GURL("https://example.com")));
3530
3531 auto headers = base::MakeRefCounted<HttpResponseHeaders>("");
3532 headers->AddHeader("alt-svc",
3533 "h3-29=\":443\","
3534 "h3-Q050=\":443\","
3535 "h3-Q043=\":443\"");
3536
3537 session_->http_stream_factory()->ProcessAlternativeServices(
3538 session_.get(), network_anonymization_key, headers.get(), origin);
3539
3540 quic::ParsedQuicVersionVector versions = {
3541 quic::ParsedQuicVersion::Draft29(),
3542 quic::ParsedQuicVersion::Q050(),
3543 };
3544 AlternativeServiceInfoVector alternatives =
3545 http_server_properties_.GetAlternativeServiceInfos(
3546 origin, network_anonymization_key);
3547 ASSERT_EQ(versions.size(), alternatives.size());
3548 for (size_t i = 0; i < alternatives.size(); ++i) {
3549 EXPECT_EQ(kProtoQUIC, alternatives[i].protocol());
3550 EXPECT_EQ(HostPortPair("example.com", 443),
3551 alternatives[i].host_port_pair());
3552 EXPECT_EQ(1u, alternatives[i].advertised_versions().size());
3553 EXPECT_EQ(versions[i], alternatives[i].advertised_versions()[0]);
3554 }
3555 }
3556
TEST_F(ProcessAlternativeServicesTest,ProcessAltSvcHttp2)3557 TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcHttp2) {
3558 quic_context_.params()->supported_versions = quic::AllSupportedVersions();
3559 session_ =
3560 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
3561 url::SchemeHostPort origin(url::kHttpsScheme, "example.com", 443);
3562
3563 auto network_anonymization_key = NetworkAnonymizationKey::CreateSameSite(
3564 SchemefulSite(GURL("https://example.com")));
3565
3566 auto headers = base::MakeRefCounted<HttpResponseHeaders>("");
3567 headers->AddHeader("alt-svc", "h2=\"other.example.com:443\"");
3568
3569 session_->http_stream_factory()->ProcessAlternativeServices(
3570 session_.get(), network_anonymization_key, headers.get(), origin);
3571
3572 AlternativeServiceInfoVector alternatives =
3573 http_server_properties_.GetAlternativeServiceInfos(
3574 origin, network_anonymization_key);
3575 ASSERT_EQ(1u, alternatives.size());
3576 EXPECT_EQ(kProtoHTTP2, alternatives[0].protocol());
3577 EXPECT_EQ(HostPortPair("other.example.com", 443),
3578 alternatives[0].host_port_pair());
3579 EXPECT_EQ(0u, alternatives[0].advertised_versions().size());
3580 }
3581
3582 } // namespace
3583
3584 } // namespace net
3585