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