xref: /aosp_15_r20/external/cronet/net/http/http_network_transaction_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 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_network_transaction.h"
6 
7 #include <math.h>  // ceil
8 #include <stdarg.h>
9 #include <stdint.h>
10 
11 #include <limits>
12 #include <memory>
13 #include <optional>
14 #include <set>
15 #include <string>
16 #include <string_view>
17 #include <utility>
18 #include <vector>
19 
20 #include "base/compiler_specific.h"
21 #include "base/files/file_path.h"
22 #include "base/files/file_util.h"
23 #include "base/functional/bind.h"
24 #include "base/json/json_writer.h"
25 #include "base/logging.h"
26 #include "base/memory/ptr_util.h"
27 #include "base/memory/raw_ptr.h"
28 #include "base/memory/weak_ptr.h"
29 #include "base/run_loop.h"
30 #include "base/strings/string_util.h"
31 #include "base/strings/stringprintf.h"
32 #include "base/strings/utf_string_conversions.h"
33 #include "base/task/single_thread_task_runner.h"
34 #include "base/test/metrics/histogram_tester.h"
35 #include "base/test/scoped_feature_list.h"
36 #include "base/test/simple_test_clock.h"
37 #include "base/test/simple_test_tick_clock.h"
38 #include "base/test/task_environment.h"
39 #include "base/test/test_file_util.h"
40 #include "base/time/time.h"
41 #include "build/build_config.h"
42 #include "net/base/auth.h"
43 #include "net/base/chunked_upload_data_stream.h"
44 #include "net/base/completion_once_callback.h"
45 #include "net/base/elements_upload_data_stream.h"
46 #include "net/base/features.h"
47 #include "net/base/host_port_pair.h"
48 #include "net/base/ip_address.h"
49 #include "net/base/ip_endpoint.h"
50 #include "net/base/load_timing_info.h"
51 #include "net/base/load_timing_info_test_util.h"
52 #include "net/base/net_errors.h"
53 #include "net/base/network_anonymization_key.h"
54 #include "net/base/network_isolation_key.h"
55 #include "net/base/privacy_mode.h"
56 #include "net/base/proxy_chain.h"
57 #include "net/base/proxy_delegate.h"
58 #include "net/base/proxy_server.h"
59 #include "net/base/proxy_string_util.h"
60 #include "net/base/request_priority.h"
61 #include "net/base/schemeful_site.h"
62 #include "net/base/session_usage.h"
63 #include "net/base/test_completion_callback.h"
64 #include "net/base/test_proxy_delegate.h"
65 #include "net/base/upload_bytes_element_reader.h"
66 #include "net/base/upload_file_element_reader.h"
67 #include "net/cert/cert_status_flags.h"
68 #include "net/cert/mock_cert_verifier.h"
69 #include "net/dns/mock_host_resolver.h"
70 #include "net/dns/public/secure_dns_policy.h"
71 #include "net/http/http_auth_challenge_tokenizer.h"
72 #include "net/http/http_auth_handler_digest.h"
73 #include "net/http/http_auth_handler_mock.h"
74 #include "net/http/http_auth_handler_ntlm.h"
75 #include "net/http/http_auth_ntlm_mechanism.h"
76 #include "net/http/http_auth_scheme.h"
77 #include "net/http/http_basic_stream.h"
78 #include "net/http/http_network_session.h"
79 #include "net/http/http_network_session_peer.h"
80 #include "net/http/http_proxy_connect_job.h"
81 #include "net/http/http_request_headers.h"
82 #include "net/http/http_response_info.h"
83 #include "net/http/http_server_properties.h"
84 #include "net/http/http_stream.h"
85 #include "net/http/http_stream_factory.h"
86 #include "net/http/http_transaction_test_util.h"
87 #include "net/log/net_log.h"
88 #include "net/log/net_log_event_type.h"
89 #include "net/log/net_log_source.h"
90 #include "net/log/test_net_log.h"
91 #include "net/log/test_net_log_util.h"
92 #include "net/proxy_resolution/configured_proxy_resolution_service.h"
93 #include "net/proxy_resolution/mock_proxy_resolver.h"
94 #include "net/proxy_resolution/proxy_config_service_fixed.h"
95 #include "net/proxy_resolution/proxy_info.h"
96 #include "net/proxy_resolution/proxy_resolver.h"
97 #include "net/proxy_resolution/proxy_resolver_factory.h"
98 #include "net/socket/client_socket_factory.h"
99 #include "net/socket/client_socket_pool.h"
100 #include "net/socket/client_socket_pool_manager.h"
101 #include "net/socket/connect_job.h"
102 #include "net/socket/connection_attempts.h"
103 #include "net/socket/mock_client_socket_pool_manager.h"
104 #include "net/socket/next_proto.h"
105 #include "net/socket/socket_tag.h"
106 #include "net/socket/socket_test_util.h"
107 #include "net/socket/socks_connect_job.h"
108 #include "net/socket/ssl_client_socket.h"
109 #include "net/spdy/spdy_session.h"
110 #include "net/spdy/spdy_session_pool.h"
111 #include "net/spdy/spdy_test_util_common.h"
112 #include "net/ssl/client_cert_identity_test_util.h"
113 #include "net/ssl/ssl_cert_request_info.h"
114 #include "net/ssl/ssl_config.h"
115 #include "net/ssl/ssl_config_service.h"
116 #include "net/ssl/ssl_info.h"
117 #include "net/ssl/ssl_private_key.h"
118 #include "net/ssl/test_ssl_config_service.h"
119 #include "net/test/cert_test_util.h"
120 #include "net/test/gtest_util.h"
121 #include "net/test/test_data_directory.h"
122 #include "net/test/test_with_task_environment.h"
123 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"
124 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
125 #include "net/url_request/static_http_user_agent_settings.h"
126 #include "net/websockets/websocket_handshake_stream_base.h"
127 #include "net/websockets/websocket_test_util.h"
128 #include "testing/gmock/include/gmock/gmock.h"
129 #include "testing/gtest/include/gtest/gtest.h"
130 #include "testing/platform_test.h"
131 #include "url/gurl.h"
132 #include "url/scheme_host_port.h"
133 #include "url/url_constants.h"
134 
135 #if defined(NTLM_PORTABLE)
136 #include "base/base64.h"
137 #include "net/ntlm/ntlm_test_data.h"
138 #endif
139 
140 #if BUILDFLAG(ENABLE_REPORTING)
141 #include "net/network_error_logging/network_error_logging_service.h"
142 #include "net/network_error_logging/network_error_logging_test_util.h"
143 #include "net/reporting/reporting_cache.h"
144 #include "net/reporting/reporting_endpoint.h"
145 #include "net/reporting/reporting_header_parser.h"
146 #include "net/reporting/reporting_service.h"
147 #include "net/reporting/reporting_test_util.h"
148 #endif  // BUILDFLAG(ENABLE_REPORTING)
149 
150 using net::test::IsError;
151 using net::test::IsOk;
152 
153 using base::ASCIIToUTF16;
154 
155 using testing::AnyOf;
156 using testing::ElementsAre;
157 using testing::IsEmpty;
158 
159 //-----------------------------------------------------------------------------
160 
161 namespace net {
162 
163 namespace {
164 
165 const std::u16string kBar(u"bar");
166 const std::u16string kBar2(u"bar2");
167 const std::u16string kBar3(u"bar3");
168 const std::u16string kBaz(u"baz");
169 const std::u16string kFirst(u"first");
170 const std::u16string kFoo(u"foo");
171 const std::u16string kFoo2(u"foo2");
172 const std::u16string kFoo3(u"foo3");
173 const std::u16string kFou(u"fou");
174 const std::u16string kSecond(u"second");
175 const std::u16string kWrongPassword(u"wrongpassword");
176 
177 const char kAlternativeServiceHttpHeader[] =
178     "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
179 
GetIdleSocketCountInTransportSocketPool(HttpNetworkSession * session)180 int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
181   return session
182       ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
183                       ProxyChain::Direct())
184       ->IdleSocketCount();
185 }
186 
IsTransportSocketPoolStalled(HttpNetworkSession * session)187 bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
188   return session
189       ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
190                       ProxyChain::Direct())
191       ->IsStalled();
192 }
193 
194 // Takes in a Value created from a NetLogHttpResponseParameter, and returns
195 // a JSONified list of headers as a single string.  Uses single quotes instead
196 // of double quotes for easier comparison.
GetHeaders(const base::Value::Dict & params)197 std::string GetHeaders(const base::Value::Dict& params) {
198   const base::Value::List* header_list = params.FindList("headers");
199   if (!header_list) {
200     return "";
201   }
202   std::string headers;
203   base::JSONWriter::Write(*header_list, &headers);
204   base::ReplaceChars(headers, "\"", "'", &headers);
205   return headers;
206 }
207 
208 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is
209 // used.
TestLoadTimingReused(const LoadTimingInfo & load_timing_info)210 void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
211   EXPECT_TRUE(load_timing_info.socket_reused);
212   EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
213 
214   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
215   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
216 
217   ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
218   EXPECT_FALSE(load_timing_info.send_start.is_null());
219 
220   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
221 
222   // Set at a higher level.
223   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
224   EXPECT_TRUE(load_timing_info.request_start.is_null());
225   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
226 }
227 
228 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is
229 // used.
TestLoadTimingNotReused(const LoadTimingInfo & load_timing_info,int connect_timing_flags)230 void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
231                              int connect_timing_flags) {
232   EXPECT_FALSE(load_timing_info.socket_reused);
233   EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
234 
235   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
236   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
237 
238   ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
239                               connect_timing_flags);
240   EXPECT_LE(load_timing_info.connect_timing.connect_end,
241             load_timing_info.send_start);
242 
243   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
244 
245   // Set at a higher level.
246   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
247   EXPECT_TRUE(load_timing_info.request_start.is_null());
248   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
249 }
250 
251 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is
252 // used.
TestLoadTimingReusedWithPac(const LoadTimingInfo & load_timing_info)253 void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
254   EXPECT_TRUE(load_timing_info.socket_reused);
255   EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
256 
257   ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
258 
259   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
260   EXPECT_LE(load_timing_info.proxy_resolve_start,
261             load_timing_info.proxy_resolve_end);
262   EXPECT_LE(load_timing_info.proxy_resolve_end, load_timing_info.send_start);
263   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
264 
265   // Set at a higher level.
266   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
267   EXPECT_TRUE(load_timing_info.request_start.is_null());
268   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
269 }
270 
271 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is
272 // used.
TestLoadTimingNotReusedWithPac(const LoadTimingInfo & load_timing_info,int connect_timing_flags)273 void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
274                                     int connect_timing_flags) {
275   EXPECT_FALSE(load_timing_info.socket_reused);
276   EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
277 
278   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
279   EXPECT_LE(load_timing_info.proxy_resolve_start,
280             load_timing_info.proxy_resolve_end);
281   EXPECT_LE(load_timing_info.proxy_resolve_end,
282             load_timing_info.connect_timing.connect_start);
283   ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
284                               connect_timing_flags);
285   EXPECT_LE(load_timing_info.connect_timing.connect_end,
286             load_timing_info.send_start);
287 
288   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
289 
290   // Set at a higher level.
291   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
292   EXPECT_TRUE(load_timing_info.request_start.is_null());
293   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
294 }
295 
296 // ProxyResolver that records URLs passed to it, and that can be told what
297 // result to return.
298 class CapturingProxyResolver : public ProxyResolver {
299  public:
300   struct LookupInfo {
301     GURL url;
302     NetworkAnonymizationKey network_anonymization_key;
303   };
304 
CapturingProxyResolver()305   CapturingProxyResolver()
306       : proxy_chain_(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 80)) {}
307 
308   CapturingProxyResolver(const CapturingProxyResolver&) = delete;
309   CapturingProxyResolver& operator=(const CapturingProxyResolver&) = delete;
310 
311   ~CapturingProxyResolver() override = default;
312 
GetProxyForURL(const GURL & url,const NetworkAnonymizationKey & network_anonymization_key,ProxyInfo * results,CompletionOnceCallback callback,std::unique_ptr<Request> * request,const NetLogWithSource & net_log)313   int GetProxyForURL(const GURL& url,
314                      const NetworkAnonymizationKey& network_anonymization_key,
315                      ProxyInfo* results,
316                      CompletionOnceCallback callback,
317                      std::unique_ptr<Request>* request,
318                      const NetLogWithSource& net_log) override {
319     results->UseProxyChain(proxy_chain_);
320     lookup_info_.push_back(LookupInfo{url, network_anonymization_key});
321     return OK;
322   }
323 
324   // Sets whether the resolver should use direct connections, instead of a
325   // proxy.
set_proxy_chain(const ProxyChain & proxy_chain)326   void set_proxy_chain(const ProxyChain& proxy_chain) {
327     proxy_chain_ = proxy_chain;
328   }
329 
lookup_info() const330   const std::vector<LookupInfo>& lookup_info() const { return lookup_info_; }
331 
332  private:
333   std::vector<LookupInfo> lookup_info_;
334 
335   ProxyChain proxy_chain_;
336 };
337 
338 class CapturingProxyResolverFactory : public ProxyResolverFactory {
339  public:
CapturingProxyResolverFactory(CapturingProxyResolver * resolver)340   explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
341       : ProxyResolverFactory(false), resolver_(resolver) {}
342 
CreateProxyResolver(const scoped_refptr<PacFileData> & pac_script,std::unique_ptr<ProxyResolver> * resolver,CompletionOnceCallback callback,std::unique_ptr<Request> * request)343   int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
344                           std::unique_ptr<ProxyResolver>* resolver,
345                           CompletionOnceCallback callback,
346                           std::unique_ptr<Request>* request) override {
347     *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
348     return OK;
349   }
350 
351  private:
352   raw_ptr<ProxyResolver> resolver_ = nullptr;
353 };
354 
CreateSession(SpdySessionDependencies * session_deps)355 std::unique_ptr<HttpNetworkSession> CreateSession(
356     SpdySessionDependencies* session_deps) {
357   return SpdySessionDependencies::SpdyCreateSession(session_deps);
358 }
359 
360 class FailingProxyResolverFactory : public ProxyResolverFactory {
361  public:
FailingProxyResolverFactory()362   FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
363 
364   // ProxyResolverFactory override.
CreateProxyResolver(const scoped_refptr<PacFileData> & script_data,std::unique_ptr<ProxyResolver> * result,CompletionOnceCallback callback,std::unique_ptr<Request> * request)365   int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
366                           std::unique_ptr<ProxyResolver>* result,
367                           CompletionOnceCallback callback,
368                           std::unique_ptr<Request>* request) override {
369     return ERR_PAC_SCRIPT_FAILED;
370   }
371 };
372 
373 // A default minimal HttpRequestInfo for use in tests, targeting HTTP.
DefaultRequestInfo()374 HttpRequestInfo DefaultRequestInfo() {
375   HttpRequestInfo info;
376   info.method = "GET";
377   info.url = GURL("http://foo.test");
378   info.traffic_annotation =
379       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
380   return info;
381 }
382 
383 // The default info for transports to the embedded HTTP server.
EmbeddedHttpServerTransportInfo()384 TransportInfo EmbeddedHttpServerTransportInfo() {
385   TransportInfo info;
386   info.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 80);
387   return info;
388 }
389 
390 }  // namespace
391 
392 class HttpNetworkTransactionTestBase : public PlatformTest,
393                                        public WithTaskEnvironment {
394  public:
~HttpNetworkTransactionTestBase()395   ~HttpNetworkTransactionTestBase() override {
396     // Important to restore the per-pool limit first, since the pool limit must
397     // always be greater than group limit, and the tests reduce both limits.
398     ClientSocketPoolManager::set_max_sockets_per_pool(
399         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
400     ClientSocketPoolManager::set_max_sockets_per_group(
401         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
402   }
403 
404  protected:
HttpNetworkTransactionTestBase()405   HttpNetworkTransactionTestBase()
406       : WithTaskEnvironment(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
407         dummy_connect_job_params_(
408             /*client_socket_factory=*/nullptr,
409             /*host_resolver=*/nullptr,
410             /*http_auth_cache=*/nullptr,
411             /*http_auth_handler_factory=*/nullptr,
412             /*spdy_session_pool=*/nullptr,
413             /*quic_supported_versions=*/nullptr,
414             /*quic_session_pool=*/nullptr,
415             /*proxy_delegate=*/nullptr,
416             /*http_user_agent_settings=*/nullptr,
417             /*ssl_client_context=*/nullptr,
418             /*socket_performance_watcher_factory=*/nullptr,
419             /*network_quality_estimator=*/nullptr,
420             /*net_log=*/nullptr,
421             /*websocket_endpoint_lock_manager=*/nullptr,
422             /*http_server_properties=*/nullptr,
423             /*alpn_protos=*/nullptr,
424             /*application_settings=*/nullptr,
425             /*ignore_certificate_errors=*/nullptr,
426             /*early_data_enabled=*/nullptr),
427         spdy_util_(/*use_priority_header=*/true),
428         ssl_(ASYNC, OK),
429         old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
430             HttpNetworkSession::NORMAL_SOCKET_POOL)),
431         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
432             HttpNetworkSession::NORMAL_SOCKET_POOL)) {
433     session_deps_.enable_http2_alternative_service = true;
434   }
435 
436   struct SimpleGetHelperResult {
437     int rv;
438     std::string status_line;
439     std::string response_data;
440     int64_t total_received_bytes;
441     int64_t total_sent_bytes;
442     LoadTimingInfo load_timing_info;
443     ConnectionAttempts connection_attempts;
444     IPEndPoint remote_endpoint_after_start;
445   };
446 
SetUp()447   void SetUp() override {
448     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
449     base::RunLoop().RunUntilIdle();
450     // Set an initial delay to ensure that the first call to TimeTicks::Now()
451     // before incrementing the counter does not return a null value.
452     FastForwardBy(base::Seconds(1));
453   }
454 
TearDown()455   void TearDown() override {
456     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
457     base::RunLoop().RunUntilIdle();
458     // Empty the current queue.
459     base::RunLoop().RunUntilIdle();
460     PlatformTest::TearDown();
461     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
462     base::RunLoop().RunUntilIdle();
463   }
464 
465   void Check100ResponseTiming(bool use_spdy);
466 
467   // Either |write_failure| specifies a write failure or |read_failure|
468   // specifies a read failure when using a reused socket.  In either case, the
469   // failure should cause the network transaction to resend the request, and the
470   // other argument should be NULL.
471   void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
472                                             const MockRead* read_failure);
473 
474   // Either |write_failure| specifies a write failure or |read_failure|
475   // specifies a read failure when using a reused socket.  In either case, the
476   // failure should cause the network transaction to resend the request, and the
477   // other argument should be NULL.
478   void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
479                                         const MockRead* read_failure,
480                                         bool use_spdy,
481                                         bool upload = false);
482 
SimpleGetHelperForData(base::span<StaticSocketDataProvider * > providers)483   SimpleGetHelperResult SimpleGetHelperForData(
484       base::span<StaticSocketDataProvider*> providers) {
485     SimpleGetHelperResult out;
486 
487     HttpRequestInfo request;
488     request.method = "GET";
489     request.url = GURL("http://www.example.org/");
490     request.traffic_annotation =
491         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
492 
493     RecordingNetLogObserver net_log_observer;
494     NetLogWithSource net_log_with_source =
495         NetLogWithSource::Make(NetLogSourceType::NONE);
496     session_deps_.net_log = NetLog::Get();
497     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
498     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
499 
500     for (auto* provider : providers) {
501       session_deps_.socket_factory->AddSocketDataProvider(provider);
502     }
503 
504     TestCompletionCallback callback;
505 
506     EXPECT_TRUE(net_log_with_source.IsCapturing());
507     int rv = trans.Start(&request, callback.callback(), net_log_with_source);
508     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
509 
510     out.rv = callback.WaitForResult();
511     out.total_received_bytes = trans.GetTotalReceivedBytes();
512     out.total_sent_bytes = trans.GetTotalSentBytes();
513 
514     // Even in the failure cases that use this function, connections are always
515     // successfully established before the error.
516     EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
517     TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
518 
519     if (out.rv != OK) {
520       return out;
521     }
522 
523     const HttpResponseInfo* response = trans.GetResponseInfo();
524     // Can't use ASSERT_* inside helper functions like this, so
525     // return an error.
526     if (!response || !response->headers) {
527       out.rv = ERR_UNEXPECTED;
528       return out;
529     }
530     out.status_line = response->headers->GetStatusLine();
531 
532     EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
533     EXPECT_EQ(80, response->remote_endpoint.port());
534 
535     bool got_endpoint =
536         trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
537     EXPECT_EQ(got_endpoint,
538               out.remote_endpoint_after_start.address().size() > 0);
539 
540     rv = ReadTransaction(&trans, &out.response_data);
541     EXPECT_THAT(rv, IsOk());
542 
543     auto entries = net_log_observer.GetEntries();
544     size_t pos = ExpectLogContainsSomewhere(
545         entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
546         NetLogEventPhase::NONE);
547     ExpectLogContainsSomewhere(
548         entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
549         NetLogEventPhase::NONE);
550 
551     EXPECT_EQ("GET / HTTP/1.1\r\n",
552               GetStringValueFromParams(entries[pos], "line"));
553 
554     EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
555               GetHeaders(entries[pos].params));
556 
557     out.total_received_bytes = trans.GetTotalReceivedBytes();
558     // The total number of sent bytes should not have changed.
559     EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
560 
561     out.connection_attempts = trans.GetConnectionAttempts();
562     return out;
563   }
564 
SimpleGetHelper(base::span<const MockRead> data_reads)565   SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
566     MockWrite data_writes[] = {
567         MockWrite("GET / HTTP/1.1\r\n"
568                   "Host: www.example.org\r\n"
569                   "Connection: keep-alive\r\n\r\n"),
570     };
571 
572     StaticSocketDataProvider reads(data_reads, data_writes);
573     StaticSocketDataProvider* data[] = {&reads};
574     SimpleGetHelperResult out = SimpleGetHelperForData(data);
575 
576     EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
577     return out;
578   }
579 
AddSSLSocketData()580   void AddSSLSocketData() {
581     ssl_.next_proto = kProtoHTTP2;
582     ssl_.ssl_info.cert =
583         ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
584     ASSERT_TRUE(ssl_.ssl_info.cert);
585     session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
586   }
587 
588   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
589                                              int expected_status);
590 
591   void ConnectStatusHelper(const MockRead& status);
592 
593   void CheckErrorIsPassedBack(int error, IoMode mode);
594 
FastForwardByCallback(base::TimeDelta delta)595   base::RepeatingClosure FastForwardByCallback(base::TimeDelta delta) {
596     return base::BindRepeating(&HttpNetworkTransactionTestBase::FastForwardBy,
597                                base::Unretained(this), delta);
598   }
599 
600   void HttpsNestedProxyNoSocketReuseHelper(const net::ProxyChain& chain1,
601                                            const net::ProxyChain& chain2);
602 
603   const CommonConnectJobParams dummy_connect_job_params_;
604 
605   const net::NetworkAnonymizationKey kNetworkAnonymizationKey =
606       NetworkAnonymizationKey::CreateCrossSite(
607           SchemefulSite(GURL("https://foo.test/")));
608 
609   const net::NetworkIsolationKey kNetworkIsolationKey =
610       NetworkIsolationKey(SchemefulSite(GURL("https://foo.test/")),
611                           SchemefulSite(GURL("https://bar.test/")));
612 
613   // These clocks are defined here, even though they're only used in the
614   // Reporting tests below, since they need to be destroyed after
615   // |session_deps_|.
616   base::SimpleTestClock clock_;
617   base::SimpleTestTickClock tick_clock_;
618 
619   SpdyTestUtil spdy_util_;
620   SpdySessionDependencies session_deps_;
621   SSLSocketDataProvider ssl_;
622 
623   // Original socket limits.  Some tests set these.  Safest to always restore
624   // them once each test has been run.
625   int old_max_group_sockets_;
626   int old_max_pool_sockets_;
627 };
628 
629 class HttpNetworkTransactionTest : public HttpNetworkTransactionTestBase,
630                                    public ::testing::WithParamInterface<bool> {
631  protected:
HttpNetworkTransactionTest()632   HttpNetworkTransactionTest() {
633     if (PriorityHeaderEnabled()) {
634       feature_list_.InitAndEnableFeature(net::features::kPriorityHeader);
635     } else {
636       feature_list_.InitAndDisableFeature(net::features::kPriorityHeader);
637     }
638   }
639 
PriorityHeaderEnabled() const640   bool PriorityHeaderEnabled() const { return GetParam(); }
641 
642  private:
643   base::test::ScopedFeatureList feature_list_;
644 };
645 
646 INSTANTIATE_TEST_SUITE_P(All,
647                          HttpNetworkTransactionTest,
648                          testing::Values(true, false));
649 
650 namespace {
651 
652 // Fill |str| with a long header list that consumes >= |size| bytes.
FillLargeHeadersString(std::string * str,int size)653 void FillLargeHeadersString(std::string* str, int size) {
654   const char kRow[] =
655       "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
656   const int sizeof_row = strlen(kRow);
657   const int num_rows =
658       static_cast<int>(ceil(static_cast<float>(size) / sizeof_row));
659   const int sizeof_data = num_rows * sizeof_row;
660   DCHECK(sizeof_data >= size);
661   str->reserve(sizeof_data);
662 
663   for (int i = 0; i < num_rows; ++i) {
664     str->append(kRow, sizeof_row);
665   }
666 }
667 
668 #if defined(NTLM_PORTABLE)
MockGetMSTime()669 uint64_t MockGetMSTime() {
670   // Tue, 23 May 2017 20:13:07 +0000
671   return 131400439870000000;
672 }
673 
674 // Alternative functions that eliminate randomness and dependency on the local
675 // host name so that the generated NTLM messages are reproducible.
MockGenerateRandom(uint8_t * output,size_t n)676 void MockGenerateRandom(uint8_t* output, size_t n) {
677   // This is set to 0xaa because the client challenge for testing in
678   // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
679   memset(output, 0xaa, n);
680 }
681 
MockGetHostName()682 std::string MockGetHostName() {
683   return ntlm::test::kHostnameAscii;
684 }
685 #endif  // defined(NTLM_PORTABLE)
686 
687 class CaptureGroupIdTransportSocketPool : public TransportClientSocketPool {
688  public:
CaptureGroupIdTransportSocketPool(const CommonConnectJobParams * common_connect_job_params)689   explicit CaptureGroupIdTransportSocketPool(
690       const CommonConnectJobParams* common_connect_job_params)
691       : TransportClientSocketPool(/*max_sockets=*/0,
692                                   /*max_sockets_per_group=*/0,
693                                   base::TimeDelta(),
694                                   ProxyChain::Direct(),
695                                   /*is_for_websockets=*/false,
696                                   common_connect_job_params) {}
697 
last_group_id_received() const698   const ClientSocketPool::GroupId& last_group_id_received() const {
699     return last_group_id_;
700   }
701 
socket_requested() const702   bool socket_requested() const { return socket_requested_; }
703 
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)704   int RequestSocket(
705       const ClientSocketPool::GroupId& group_id,
706       scoped_refptr<ClientSocketPool::SocketParams> socket_params,
707       const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
708       RequestPriority priority,
709       const SocketTag& socket_tag,
710       ClientSocketPool::RespectLimits respect_limits,
711       ClientSocketHandle* handle,
712       CompletionOnceCallback callback,
713       const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback,
714       const NetLogWithSource& net_log) override {
715     last_group_id_ = group_id;
716     socket_requested_ = true;
717     return ERR_IO_PENDING;
718   }
CancelRequest(const ClientSocketPool::GroupId & group_id,ClientSocketHandle * handle,bool cancel_connect_job)719   void CancelRequest(const ClientSocketPool::GroupId& group_id,
720                      ClientSocketHandle* handle,
721                      bool cancel_connect_job) override {}
ReleaseSocket(const ClientSocketPool::GroupId & group_id,std::unique_ptr<StreamSocket> socket,int64_t generation)722   void ReleaseSocket(const ClientSocketPool::GroupId& group_id,
723                      std::unique_ptr<StreamSocket> socket,
724                      int64_t generation) override {}
CloseIdleSockets(const char * net_log_reason_utf8)725   void CloseIdleSockets(const char* net_log_reason_utf8) override {}
CloseIdleSocketsInGroup(const ClientSocketPool::GroupId & group_id,const char * net_log_reason_utf8)726   void CloseIdleSocketsInGroup(const ClientSocketPool::GroupId& group_id,
727                                const char* net_log_reason_utf8) override {}
IdleSocketCount() const728   int IdleSocketCount() const override { return 0; }
IdleSocketCountInGroup(const ClientSocketPool::GroupId & group_id) const729   size_t IdleSocketCountInGroup(
730       const ClientSocketPool::GroupId& group_id) const override {
731     return 0;
732   }
GetLoadState(const ClientSocketPool::GroupId & group_id,const ClientSocketHandle * handle) const733   LoadState GetLoadState(const ClientSocketPool::GroupId& group_id,
734                          const ClientSocketHandle* handle) const override {
735     return LOAD_STATE_IDLE;
736   }
737 
738  private:
739   ClientSocketPool::GroupId last_group_id_;
740   bool socket_requested_ = false;
741 };
742 
743 //-----------------------------------------------------------------------------
744 
745 // Helper functions for validating that AuthChallengeInfo's are correctly
746 // configured for common cases.
CheckBasicServerAuth(const std::optional<AuthChallengeInfo> & auth_challenge)747 bool CheckBasicServerAuth(
748     const std::optional<AuthChallengeInfo>& auth_challenge) {
749   if (!auth_challenge) {
750     return false;
751   }
752   EXPECT_FALSE(auth_challenge->is_proxy);
753   EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
754   EXPECT_EQ("MyRealm1", auth_challenge->realm);
755   EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
756   return true;
757 }
758 
CheckBasicSecureServerAuth(const std::optional<AuthChallengeInfo> & auth_challenge)759 bool CheckBasicSecureServerAuth(
760     const std::optional<AuthChallengeInfo>& auth_challenge) {
761   if (!auth_challenge) {
762     return false;
763   }
764   EXPECT_FALSE(auth_challenge->is_proxy);
765   EXPECT_EQ("https://www.example.org", auth_challenge->challenger.Serialize());
766   EXPECT_EQ("MyRealm1", auth_challenge->realm);
767   EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
768   return true;
769 }
770 
CheckBasicProxyAuth(const std::optional<AuthChallengeInfo> & auth_challenge)771 bool CheckBasicProxyAuth(
772     const std::optional<AuthChallengeInfo>& auth_challenge) {
773   if (!auth_challenge) {
774     return false;
775   }
776   EXPECT_TRUE(auth_challenge->is_proxy);
777   EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
778   EXPECT_EQ("MyRealm1", auth_challenge->realm);
779   EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
780   return true;
781 }
782 
CheckBasicSecureProxyAuth(const std::optional<AuthChallengeInfo> & auth_challenge)783 bool CheckBasicSecureProxyAuth(
784     const std::optional<AuthChallengeInfo>& auth_challenge) {
785   if (!auth_challenge) {
786     return false;
787   }
788   EXPECT_TRUE(auth_challenge->is_proxy);
789   EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
790   EXPECT_EQ("MyRealm1", auth_challenge->realm);
791   EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
792   return true;
793 }
794 
CheckDigestServerAuth(const std::optional<AuthChallengeInfo> & auth_challenge)795 bool CheckDigestServerAuth(
796     const std::optional<AuthChallengeInfo>& auth_challenge) {
797   if (!auth_challenge) {
798     return false;
799   }
800   EXPECT_FALSE(auth_challenge->is_proxy);
801   EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
802   EXPECT_EQ("digestive", auth_challenge->realm);
803   EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
804   return true;
805 }
806 
807 #if defined(NTLM_PORTABLE)
CheckNTLMServerAuth(const std::optional<AuthChallengeInfo> & auth_challenge)808 bool CheckNTLMServerAuth(
809     const std::optional<AuthChallengeInfo>& auth_challenge) {
810   if (!auth_challenge) {
811     return false;
812   }
813   EXPECT_FALSE(auth_challenge->is_proxy);
814   EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
815   EXPECT_EQ(std::string(), auth_challenge->realm);
816   EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
817   return true;
818 }
819 
CheckNTLMProxyAuth(const std::optional<AuthChallengeInfo> & auth_challenge)820 bool CheckNTLMProxyAuth(
821     const std::optional<AuthChallengeInfo>& auth_challenge) {
822   if (!auth_challenge) {
823     return false;
824   }
825   EXPECT_TRUE(auth_challenge->is_proxy);
826   EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
827   EXPECT_EQ(std::string(), auth_challenge->realm);
828   EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
829   return true;
830 }
831 #endif  // defined(NTLM_PORTABLE)
832 
833 }  // namespace
834 
TEST_P(HttpNetworkTransactionTest,Basic)835 TEST_P(HttpNetworkTransactionTest, Basic) {
836   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
837   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
838 }
839 
TEST_P(HttpNetworkTransactionTest,SimpleGET)840 TEST_P(HttpNetworkTransactionTest, SimpleGET) {
841   MockRead data_reads[] = {
842       MockRead("HTTP/1.0 200 OK\r\n\r\n"),
843       MockRead("hello world"),
844       MockRead(SYNCHRONOUS, OK),
845   };
846   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
847   EXPECT_THAT(out.rv, IsOk());
848   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
849   EXPECT_EQ("hello world", out.response_data);
850   int64_t reads_size = CountReadBytes(data_reads);
851   EXPECT_EQ(reads_size, out.total_received_bytes);
852   EXPECT_EQ(0u, out.connection_attempts.size());
853 
854   EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
855 }
856 
857 // Response with no status line.
TEST_P(HttpNetworkTransactionTest,SimpleGETNoHeaders)858 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
859   MockRead data_reads[] = {
860       MockRead("hello world"),
861       MockRead(SYNCHRONOUS, OK),
862   };
863   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
864   EXPECT_THAT(out.rv, IsOk());
865   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
866   EXPECT_EQ("hello world", out.response_data);
867   int64_t reads_size = CountReadBytes(data_reads);
868   EXPECT_EQ(reads_size, out.total_received_bytes);
869 }
870 
871 // Response with no status line, and a weird port.  Should fail by default.
TEST_P(HttpNetworkTransactionTest,SimpleGETNoHeadersWeirdPort)872 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
873   MockRead data_reads[] = {
874       MockRead("hello world"),
875       MockRead(SYNCHRONOUS, OK),
876   };
877 
878   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
879   session_deps_.socket_factory->AddSocketDataProvider(&data);
880 
881   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
882 
883   HttpRequestInfo request;
884   auto trans =
885       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
886 
887   request.method = "GET";
888   request.url = GURL("http://www.example.com:2000/");
889   request.traffic_annotation =
890       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
891 
892   TestCompletionCallback callback;
893   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
894   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
895 }
896 
897 // Tests that request info can be destroyed after the headers phase is complete.
TEST_P(HttpNetworkTransactionTest,SimpleGETNoReadDestroyRequestInfo)898 TEST_P(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
899   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
900   auto trans =
901       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
902 
903   MockRead data_reads[] = {
904       MockRead("HTTP/1.0 200 OK\r\n"),
905       MockRead("Connection: keep-alive\r\n"),
906       MockRead("Content-Length: 100\r\n\r\n"),
907       MockRead(SYNCHRONOUS, 0),
908   };
909   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
910   session_deps_.socket_factory->AddSocketDataProvider(&data);
911 
912   TestCompletionCallback callback;
913 
914   {
915     auto request = std::make_unique<HttpRequestInfo>();
916     request->method = "GET";
917     request->url = GURL("http://www.example.org/");
918     request->traffic_annotation =
919         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
920 
921     int rv =
922         trans->Start(request.get(), callback.callback(), NetLogWithSource());
923 
924     EXPECT_THAT(callback.GetResult(rv), IsOk());
925   }  // Let request info be destroyed.
926 
927   trans.reset();
928 }
929 
930 // Test that a failure in resolving the hostname is retrievable.
TEST_P(HttpNetworkTransactionTest,SimpleGETHostResolutionFailure)931 TEST_P(HttpNetworkTransactionTest, SimpleGETHostResolutionFailure) {
932   HttpRequestInfo request;
933   request.method = "GET";
934   request.url = GURL("http://www.example.org/");
935   request.traffic_annotation =
936       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
937 
938   auto resolver = std::make_unique<MockHostResolver>();
939   resolver->rules()->AddSimulatedTimeoutFailure("www.example.org");
940   session_deps_.net_log = net::NetLog::Get();
941   session_deps_.host_resolver = std::move(resolver);
942   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
943   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
944   TestCompletionCallback callback;
945 
946   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
947   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
948   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
949 
950   const HttpResponseInfo* response = trans.GetResponseInfo();
951   ASSERT_TRUE(response);
952   EXPECT_THAT(response->resolve_error_info.error, IsError(ERR_DNS_TIMED_OUT));
953 }
954 
955 // This test verifies that if the transaction fails before even connecting to a
956 // remote endpoint, the ConnectedCallback is never called.
TEST_P(HttpNetworkTransactionTest,ConnectedCallbackNeverCalled)957 TEST_P(HttpNetworkTransactionTest, ConnectedCallbackNeverCalled) {
958   auto resolver = std::make_unique<MockHostResolver>();
959   resolver->rules()->AddSimulatedTimeoutFailure("bar.test");
960   session_deps_.host_resolver = std::move(resolver);
961 
962   ConnectedHandler connected_handler;
963   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
964 
965   auto request = DefaultRequestInfo();
966   request.url = GURL("http://bar.test");
967 
968   HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session.get());
969   transaction.SetConnectedCallback(connected_handler.Callback());
970 
971   TestCompletionCallback callback;
972   transaction.Start(&request, callback.callback(), NetLogWithSource());
973   callback.WaitForResult();
974 
975   EXPECT_THAT(connected_handler.transports(), IsEmpty());
976 }
977 
978 // This test verifies that if the ConnectedCallback returns an error, the
979 // entire transaction fails with that error.
TEST_P(HttpNetworkTransactionTest,ConnectedCallbackFailure)980 TEST_P(HttpNetworkTransactionTest, ConnectedCallbackFailure) {
981   // The exact error code does not matter, as long as it is the same one
982   // returned by the transaction overall.
983   ConnectedHandler connected_handler;
984   connected_handler.set_result(ERR_NOT_IMPLEMENTED);
985 
986   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
987   auto request = DefaultRequestInfo();
988   HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session.get());
989   transaction.SetConnectedCallback(connected_handler.Callback());
990 
991   // We never get to writing any data, but we still need a socket.
992   StaticSocketDataProvider data;
993   session_deps_.socket_factory->AddSocketDataProvider(&data);
994 
995   TestCompletionCallback callback;
996   EXPECT_THAT(
997       transaction.Start(&request, callback.callback(), NetLogWithSource()),
998       IsError(ERR_IO_PENDING));
999   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NOT_IMPLEMENTED));
1000 
1001   EXPECT_THAT(connected_handler.transports(),
1002               ElementsAre(EmbeddedHttpServerTransportInfo()));
1003 }
1004 
1005 // This test verifies that if the ConnectedCallback returns an error, the
1006 // underlying socket is not closed and can be reused by the next transaction.
TEST_P(HttpNetworkTransactionTest,ConnectedCallbackFailureAllowsSocketReuse)1007 TEST_P(HttpNetworkTransactionTest, ConnectedCallbackFailureAllowsSocketReuse) {
1008   ConnectedHandler connected_handler;
1009   connected_handler.set_result(ERR_NOT_IMPLEMENTED);
1010 
1011   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
1012   auto request = DefaultRequestInfo();
1013 
1014   // A single socket should be opened and used for both transactions. Data
1015   // providers are matched to sockets at most once.
1016   MockRead data_reads[] = {
1017       MockRead("HTTP/1.0 200 OK\r\n"),
1018       MockRead("X-Test-Header: foo\r\n\r\n"),
1019       MockRead(SYNCHRONOUS, OK),
1020   };
1021   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1022   session_deps_.socket_factory->AddSocketDataProvider(&data);
1023 
1024   {
1025     HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session.get());
1026     transaction.SetConnectedCallback(connected_handler.Callback());
1027 
1028     TestCompletionCallback callback;
1029     EXPECT_THAT(
1030         transaction.Start(&request, callback.callback(), NetLogWithSource()),
1031         IsError(ERR_IO_PENDING));
1032     EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NOT_IMPLEMENTED));
1033   }
1034 
1035   // The data provider should still be linked to a socket.
1036   EXPECT_TRUE(data.socket());
1037   auto* socket = data.socket();
1038 
1039   {
1040     HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session.get());
1041 
1042     TestCompletionCallback callback;
1043     EXPECT_THAT(
1044         transaction.Start(&request, callback.callback(), NetLogWithSource()),
1045         IsError(ERR_IO_PENDING));
1046     EXPECT_THAT(callback.WaitForResult(), IsOk());
1047 
1048     EXPECT_TRUE(transaction.GetResponseInfo()->headers->HasHeaderValue(
1049         "X-Test-Header", "foo"));
1050 
1051     // Still linked to the same socket.
1052     EXPECT_EQ(data.socket(), socket);
1053   }
1054 }
1055 
1056 // This test verifies that the ConnectedCallback is called once in the case of
1057 // simple requests.
TEST_P(HttpNetworkTransactionTest,ConnectedCallbackCalledOnce)1058 TEST_P(HttpNetworkTransactionTest, ConnectedCallbackCalledOnce) {
1059   MockRead data_reads[] = {
1060       MockRead("HTTP/1.0 200 OK\r\n"),
1061       MockRead(SYNCHRONOUS, OK),
1062   };
1063   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1064   session_deps_.socket_factory->AddSocketDataProvider(&data);
1065 
1066   ConnectedHandler connected_handler;
1067   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
1068   auto request = DefaultRequestInfo();
1069   HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session.get());
1070   transaction.SetConnectedCallback(connected_handler.Callback());
1071 
1072   TestCompletionCallback callback;
1073   EXPECT_THAT(
1074       transaction.Start(&request, callback.callback(), NetLogWithSource()),
1075       IsError(ERR_IO_PENDING));
1076   EXPECT_THAT(callback.WaitForResult(), IsOk());
1077 
1078   EXPECT_THAT(connected_handler.transports(),
1079               ElementsAre(EmbeddedHttpServerTransportInfo()));
1080 }
1081 
1082 // This test verifies that the ConnectedCallback is called once more per
1083 // authentication challenge.
TEST_P(HttpNetworkTransactionTest,ConnectedCallbackCalledOnEachAuthChallenge)1084 TEST_P(HttpNetworkTransactionTest, ConnectedCallbackCalledOnEachAuthChallenge) {
1085   ConnectedHandler connected_handler;
1086   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
1087   auto request = DefaultRequestInfo();
1088   HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session.get());
1089   transaction.SetConnectedCallback(connected_handler.Callback());
1090 
1091   // First request receives an auth challenge.
1092   MockRead data_reads1[] = {
1093       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1094       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
1095       MockRead(SYNCHRONOUS, ERR_FAILED),
1096   };
1097   StaticSocketDataProvider data1(data_reads1, base::span<MockWrite>());
1098   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1099 
1100   // Second request is allowed through.
1101   MockRead data_reads2[] = {
1102       MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1103       MockRead(SYNCHRONOUS, OK),
1104   };
1105   StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
1106   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1107 
1108   // First request, connects once.
1109   TestCompletionCallback callback1;
1110   EXPECT_THAT(
1111       transaction.Start(&request, callback1.callback(), NetLogWithSource()),
1112       IsError(ERR_IO_PENDING));
1113   EXPECT_THAT(callback1.WaitForResult(), IsOk());
1114 
1115   EXPECT_THAT(connected_handler.transports(),
1116               ElementsAre(EmbeddedHttpServerTransportInfo()));
1117 
1118   // Second request, connects again.
1119   TestCompletionCallback callback2;
1120   EXPECT_THAT(transaction.RestartWithAuth(AuthCredentials(kFoo, kBar),
1121                                           callback2.callback()),
1122               IsError(ERR_IO_PENDING));
1123   EXPECT_THAT(callback2.WaitForResult(), IsOk());
1124 
1125   EXPECT_THAT(connected_handler.transports(),
1126               ElementsAre(EmbeddedHttpServerTransportInfo(),
1127                           EmbeddedHttpServerTransportInfo()));
1128 }
1129 
1130 // This test verifies that the ConnectedCallback is called once more per retry.
TEST_P(HttpNetworkTransactionTest,ConnectedCallbackCalledOnEachRetry)1131 TEST_P(HttpNetworkTransactionTest, ConnectedCallbackCalledOnEachRetry) {
1132   ConnectedHandler connected_handler;
1133   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
1134   auto request = DefaultRequestInfo();
1135   HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session.get());
1136   transaction.SetConnectedCallback(connected_handler.Callback());
1137 
1138   // First request receives a retryable error.
1139   MockRead data_reads1[] = {
1140       MockRead(SYNCHRONOUS, ERR_HTTP2_SERVER_REFUSED_STREAM),
1141   };
1142   StaticSocketDataProvider data1(data_reads1, base::span<MockWrite>());
1143   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1144 
1145   // Second request is allowed through.
1146   MockRead data_reads2[] = {
1147       MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1148       MockRead(SYNCHRONOUS, OK),
1149   };
1150   StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
1151   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1152 
1153   TestCompletionCallback callback1;
1154   EXPECT_THAT(
1155       transaction.Start(&request, callback1.callback(), NetLogWithSource()),
1156       IsError(ERR_IO_PENDING));
1157   EXPECT_THAT(callback1.WaitForResult(), IsOk());
1158 
1159   EXPECT_THAT(connected_handler.transports(),
1160               ElementsAre(EmbeddedHttpServerTransportInfo(),
1161                           EmbeddedHttpServerTransportInfo()));
1162 }
1163 
TEST_P(HttpNetworkTransactionTest,ConnectedCallbackCalledAsync)1164 TEST_P(HttpNetworkTransactionTest, ConnectedCallbackCalledAsync) {
1165   MockRead data_reads[] = {
1166       MockRead("HTTP/1.0 200 OK\r\n"),
1167       MockRead(SYNCHRONOUS, OK),
1168   };
1169   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1170   session_deps_.socket_factory->AddSocketDataProvider(&data);
1171 
1172   ConnectedHandler connected_handler;
1173   connected_handler.set_run_callback(true);
1174   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
1175   auto request = DefaultRequestInfo();
1176   HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session.get());
1177   transaction.SetConnectedCallback(connected_handler.Callback());
1178 
1179   TestCompletionCallback callback;
1180   EXPECT_THAT(
1181       transaction.Start(&request, callback.callback(), NetLogWithSource()),
1182       IsError(ERR_IO_PENDING));
1183   EXPECT_THAT(callback.WaitForResult(), IsOk());
1184 
1185   EXPECT_THAT(connected_handler.transports(),
1186               ElementsAre(EmbeddedHttpServerTransportInfo()));
1187 }
1188 
TEST_P(HttpNetworkTransactionTest,ConnectedCallbackCalledAsyncError)1189 TEST_P(HttpNetworkTransactionTest, ConnectedCallbackCalledAsyncError) {
1190   MockRead data_reads[] = {
1191       MockRead("HTTP/1.0 200 OK\r\n"),
1192       MockRead(SYNCHRONOUS, OK),
1193   };
1194   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1195   session_deps_.socket_factory->AddSocketDataProvider(&data);
1196 
1197   ConnectedHandler connected_handler;
1198   connected_handler.set_run_callback(true);
1199   connected_handler.set_result(ERR_FAILED);
1200   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
1201   auto request = DefaultRequestInfo();
1202   HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session.get());
1203   transaction.SetConnectedCallback(connected_handler.Callback());
1204 
1205   TestCompletionCallback callback;
1206   EXPECT_THAT(
1207       transaction.Start(&request, callback.callback(), NetLogWithSource()),
1208       IsError(ERR_IO_PENDING));
1209   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FAILED));
1210 
1211   EXPECT_THAT(connected_handler.transports(),
1212               ElementsAre(EmbeddedHttpServerTransportInfo()));
1213 }
1214 
1215 // Allow up to 4 bytes of junk to precede status line.
TEST_P(HttpNetworkTransactionTest,StatusLineJunk3Bytes)1216 TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
1217   MockRead data_reads[] = {
1218       MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
1219       MockRead(SYNCHRONOUS, OK),
1220   };
1221   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1222   EXPECT_THAT(out.rv, IsOk());
1223   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
1224   EXPECT_EQ("DATA", out.response_data);
1225   int64_t reads_size = CountReadBytes(data_reads);
1226   EXPECT_EQ(reads_size, out.total_received_bytes);
1227 }
1228 
1229 // Allow up to 4 bytes of junk to precede status line.
TEST_P(HttpNetworkTransactionTest,StatusLineJunk4Bytes)1230 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
1231   MockRead data_reads[] = {
1232       MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
1233       MockRead(SYNCHRONOUS, OK),
1234   };
1235   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1236   EXPECT_THAT(out.rv, IsOk());
1237   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
1238   EXPECT_EQ("DATA", out.response_data);
1239   int64_t reads_size = CountReadBytes(data_reads);
1240   EXPECT_EQ(reads_size, out.total_received_bytes);
1241 }
1242 
1243 // Beyond 4 bytes of slop and it should fail to find a status line.
TEST_P(HttpNetworkTransactionTest,StatusLineJunk5Bytes)1244 TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
1245   MockRead data_reads[] = {
1246       MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
1247       MockRead(SYNCHRONOUS, OK),
1248   };
1249   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1250   EXPECT_THAT(out.rv, IsOk());
1251   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
1252   EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
1253   int64_t reads_size = CountReadBytes(data_reads);
1254   EXPECT_EQ(reads_size, out.total_received_bytes);
1255 }
1256 
1257 // Same as StatusLineJunk4Bytes, except the read chunks are smaller.
TEST_P(HttpNetworkTransactionTest,StatusLineJunk4Bytes_Slow)1258 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
1259   MockRead data_reads[] = {
1260       MockRead("\n"),
1261       MockRead("\n"),
1262       MockRead("Q"),
1263       MockRead("J"),
1264       MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
1265       MockRead(SYNCHRONOUS, OK),
1266   };
1267   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1268   EXPECT_THAT(out.rv, IsOk());
1269   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
1270   EXPECT_EQ("DATA", out.response_data);
1271   int64_t reads_size = CountReadBytes(data_reads);
1272   EXPECT_EQ(reads_size, out.total_received_bytes);
1273 }
1274 
1275 // Close the connection before enough bytes to have a status line.
TEST_P(HttpNetworkTransactionTest,StatusLinePartial)1276 TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
1277   MockRead data_reads[] = {
1278       MockRead("HTT"),
1279       MockRead(SYNCHRONOUS, OK),
1280   };
1281   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1282   EXPECT_THAT(out.rv, IsOk());
1283   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
1284   EXPECT_EQ("HTT", out.response_data);
1285   int64_t reads_size = CountReadBytes(data_reads);
1286   EXPECT_EQ(reads_size, out.total_received_bytes);
1287 }
1288 
1289 // Simulate a 204 response, lacking a Content-Length header, sent over a
1290 // persistent connection.  The response should still terminate since a 204
1291 // cannot have a response body.
TEST_P(HttpNetworkTransactionTest,StopsReading204)1292 TEST_P(HttpNetworkTransactionTest, StopsReading204) {
1293   char junk[] = "junk";
1294   MockRead data_reads[] = {
1295       MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1296       MockRead(junk),  // Should not be read!!
1297       MockRead(SYNCHRONOUS, OK),
1298   };
1299   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1300   EXPECT_THAT(out.rv, IsOk());
1301   EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1302   EXPECT_EQ("", out.response_data);
1303   int64_t reads_size = CountReadBytes(data_reads);
1304   int64_t response_size = reads_size - strlen(junk);
1305   EXPECT_EQ(response_size, out.total_received_bytes);
1306 }
1307 
1308 // A simple request using chunked encoding with some extra data after.
TEST_P(HttpNetworkTransactionTest,ChunkedEncoding)1309 TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
1310   std::string final_chunk = "0\r\n\r\n";
1311   std::string extra_data = "HTTP/1.1 200 OK\r\n";
1312   std::string last_read = final_chunk + extra_data;
1313   MockRead data_reads[] = {
1314       MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1315       MockRead("5\r\nHello\r\n"),
1316       MockRead("1\r\n"),
1317       MockRead(" \r\n"),
1318       MockRead("5\r\nworld\r\n"),
1319       MockRead(last_read.data()),
1320       MockRead(SYNCHRONOUS, OK),
1321   };
1322   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1323   EXPECT_THAT(out.rv, IsOk());
1324   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1325   EXPECT_EQ("Hello world", out.response_data);
1326   int64_t reads_size = CountReadBytes(data_reads);
1327   int64_t response_size = reads_size - extra_data.size();
1328   EXPECT_EQ(response_size, out.total_received_bytes);
1329 }
1330 
1331 // Next tests deal with http://crbug.com/56344.
1332 
TEST_P(HttpNetworkTransactionTest,MultipleContentLengthHeadersNoTransferEncoding)1333 TEST_P(HttpNetworkTransactionTest,
1334        MultipleContentLengthHeadersNoTransferEncoding) {
1335   MockRead data_reads[] = {
1336       MockRead("HTTP/1.1 200 OK\r\n"),
1337       MockRead("Content-Length: 10\r\n"),
1338       MockRead("Content-Length: 5\r\n\r\n"),
1339   };
1340   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1341   EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
1342 }
1343 
TEST_P(HttpNetworkTransactionTest,DuplicateContentLengthHeadersNoTransferEncoding)1344 TEST_P(HttpNetworkTransactionTest,
1345        DuplicateContentLengthHeadersNoTransferEncoding) {
1346   MockRead data_reads[] = {
1347       MockRead("HTTP/1.1 200 OK\r\n"),
1348       MockRead("Content-Length: 5\r\n"),
1349       MockRead("Content-Length: 5\r\n\r\n"),
1350       MockRead("Hello"),
1351   };
1352   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1353   EXPECT_THAT(out.rv, IsOk());
1354   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1355   EXPECT_EQ("Hello", out.response_data);
1356 }
1357 
TEST_P(HttpNetworkTransactionTest,ComplexContentLengthHeadersNoTransferEncoding)1358 TEST_P(HttpNetworkTransactionTest,
1359        ComplexContentLengthHeadersNoTransferEncoding) {
1360   // More than 2 dupes.
1361   {
1362     MockRead data_reads[] = {
1363         MockRead("HTTP/1.1 200 OK\r\n"),
1364         MockRead("Content-Length: 5\r\n"),
1365         MockRead("Content-Length: 5\r\n"),
1366         MockRead("Content-Length: 5\r\n\r\n"),
1367         MockRead("Hello"),
1368     };
1369     SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1370     EXPECT_THAT(out.rv, IsOk());
1371     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1372     EXPECT_EQ("Hello", out.response_data);
1373   }
1374   // HTTP/1.0
1375   {
1376     MockRead data_reads[] = {
1377         MockRead("HTTP/1.0 200 OK\r\n"),
1378         MockRead("Content-Length: 5\r\n"),
1379         MockRead("Content-Length: 5\r\n"),
1380         MockRead("Content-Length: 5\r\n\r\n"),
1381         MockRead("Hello"),
1382     };
1383     SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1384     EXPECT_THAT(out.rv, IsOk());
1385     EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1386     EXPECT_EQ("Hello", out.response_data);
1387   }
1388   // 2 dupes and one mismatched.
1389   {
1390     MockRead data_reads[] = {
1391         MockRead("HTTP/1.1 200 OK\r\n"),
1392         MockRead("Content-Length: 10\r\n"),
1393         MockRead("Content-Length: 10\r\n"),
1394         MockRead("Content-Length: 5\r\n\r\n"),
1395     };
1396     SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1397     EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
1398   }
1399 }
1400 
TEST_P(HttpNetworkTransactionTest,MultipleContentLengthHeadersTransferEncoding)1401 TEST_P(HttpNetworkTransactionTest,
1402        MultipleContentLengthHeadersTransferEncoding) {
1403   MockRead data_reads[] = {
1404       MockRead("HTTP/1.1 200 OK\r\n"),
1405       MockRead("Content-Length: 666\r\n"),
1406       MockRead("Content-Length: 1337\r\n"),
1407       MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1408       MockRead("5\r\nHello\r\n"),
1409       MockRead("1\r\n"),
1410       MockRead(" \r\n"),
1411       MockRead("5\r\nworld\r\n"),
1412       MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
1413       MockRead(SYNCHRONOUS, OK),
1414   };
1415   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1416   EXPECT_THAT(out.rv, IsOk());
1417   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1418   EXPECT_EQ("Hello world", out.response_data);
1419 }
1420 
1421 // Next tests deal with http://crbug.com/98895.
1422 
1423 // Checks that a single Content-Disposition header results in no error.
TEST_P(HttpNetworkTransactionTest,SingleContentDispositionHeader)1424 TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
1425   MockRead data_reads[] = {
1426       MockRead("HTTP/1.1 200 OK\r\n"),
1427       MockRead(
1428           "Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1429       MockRead("Content-Length: 5\r\n\r\n"),
1430       MockRead("Hello"),
1431   };
1432   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1433   EXPECT_THAT(out.rv, IsOk());
1434   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1435   EXPECT_EQ("Hello", out.response_data);
1436 }
1437 
1438 // Checks that two identical Content-Disposition headers result in no error.
TEST_P(HttpNetworkTransactionTest,TwoIdenticalContentDispositionHeaders)1439 TEST_P(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
1440   MockRead data_reads[] = {
1441       MockRead("HTTP/1.1 200 OK\r\n"),
1442       MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1443       MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1444       MockRead("Content-Length: 5\r\n\r\n"),
1445       MockRead("Hello"),
1446   };
1447   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1448   EXPECT_THAT(out.rv, IsOk());
1449   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1450   EXPECT_EQ("Hello", out.response_data);
1451 }
1452 
1453 // Checks that two distinct Content-Disposition headers result in an error.
TEST_P(HttpNetworkTransactionTest,TwoDistinctContentDispositionHeaders)1454 TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
1455   MockRead data_reads[] = {
1456       MockRead("HTTP/1.1 200 OK\r\n"),
1457       MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1458       MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1459       MockRead("Content-Length: 5\r\n\r\n"),
1460       MockRead("Hello"),
1461   };
1462   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1463   EXPECT_THAT(out.rv,
1464               IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
1465 }
1466 
1467 // Checks that two identical Location headers result in no error.
1468 // Also tests Location header behavior.
TEST_P(HttpNetworkTransactionTest,TwoIdenticalLocationHeaders)1469 TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
1470   MockRead data_reads[] = {
1471       MockRead("HTTP/1.1 302 Redirect\r\n"),
1472       MockRead("Location: http://good.com/\r\n"),
1473       MockRead("Location: http://good.com/\r\n"),
1474       MockRead("Content-Length: 0\r\n\r\n"),
1475       MockRead(SYNCHRONOUS, OK),
1476   };
1477 
1478   HttpRequestInfo request;
1479   request.method = "GET";
1480   request.url = GURL("http://redirect.com/");
1481   request.traffic_annotation =
1482       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1483 
1484   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1485   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1486 
1487   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1488   session_deps_.socket_factory->AddSocketDataProvider(&data);
1489 
1490   TestCompletionCallback callback;
1491 
1492   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1493   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1494 
1495   EXPECT_THAT(callback.WaitForResult(), IsOk());
1496 
1497   const HttpResponseInfo* response = trans.GetResponseInfo();
1498   ASSERT_TRUE(response);
1499   ASSERT_TRUE(response->headers);
1500   EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1501   std::string url;
1502   EXPECT_TRUE(response->headers->IsRedirect(&url));
1503   EXPECT_EQ("http://good.com/", url);
1504   EXPECT_TRUE(response->proxy_chain.is_direct());
1505 }
1506 
1507 // Checks that two distinct Location headers result in an error.
TEST_P(HttpNetworkTransactionTest,TwoDistinctLocationHeaders)1508 TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
1509   MockRead data_reads[] = {
1510       MockRead("HTTP/1.1 302 Redirect\r\n"),
1511       MockRead("Location: http://good.com/\r\n"),
1512       MockRead("Location: http://evil.com/\r\n"),
1513       MockRead("Content-Length: 0\r\n\r\n"),
1514       MockRead(SYNCHRONOUS, OK),
1515   };
1516   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1517   EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
1518 }
1519 
1520 // Do a request using the HEAD method. Verify that we don't try to read the
1521 // message body (since HEAD has none).
TEST_P(HttpNetworkTransactionTest,Head)1522 TEST_P(HttpNetworkTransactionTest, Head) {
1523   HttpRequestInfo request;
1524   request.method = "HEAD";
1525   request.url = GURL("http://www.example.org/");
1526   request.traffic_annotation =
1527       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1528 
1529   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1530   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1531   ConnectedHandler connected_handler;
1532   trans.SetConnectedCallback(connected_handler.Callback());
1533 
1534   MockWrite data_writes1[] = {
1535       MockWrite("HEAD / HTTP/1.1\r\n"
1536                 "Host: www.example.org\r\n"
1537                 "Connection: keep-alive\r\n\r\n"),
1538   };
1539   MockRead data_reads1[] = {
1540       MockRead("HTTP/1.1 404 Not Found\r\n"),
1541       MockRead("Server: Blah\r\n"),
1542       MockRead("Content-Length: 1234\r\n\r\n"),
1543 
1544       // No response body because the test stops reading here.
1545       MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
1546   };
1547 
1548   StaticSocketDataProvider data1(data_reads1, data_writes1);
1549   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1550 
1551   TestCompletionCallback callback1;
1552 
1553   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
1554   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1555 
1556   rv = callback1.WaitForResult();
1557   EXPECT_THAT(rv, IsOk());
1558 
1559   const HttpResponseInfo* response = trans.GetResponseInfo();
1560   ASSERT_TRUE(response);
1561 
1562   // Check that the headers got parsed.
1563   EXPECT_TRUE(response->headers);
1564   EXPECT_EQ(1234, response->headers->GetContentLength());
1565   EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
1566   EXPECT_TRUE(response->proxy_chain.is_direct());
1567   EXPECT_THAT(connected_handler.transports(),
1568               ElementsAre(EmbeddedHttpServerTransportInfo()));
1569 
1570   std::string server_header;
1571   size_t iter = 0;
1572   bool has_server_header =
1573       response->headers->EnumerateHeader(&iter, "Server", &server_header);
1574   EXPECT_TRUE(has_server_header);
1575   EXPECT_EQ("Blah", server_header);
1576 
1577   // Reading should give EOF right away, since there is no message body
1578   // (despite non-zero content-length).
1579   std::string response_data;
1580   rv = ReadTransaction(&trans, &response_data);
1581   EXPECT_THAT(rv, IsOk());
1582   EXPECT_EQ("", response_data);
1583 }
1584 
TEST_P(HttpNetworkTransactionTest,ReuseConnection)1585 TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
1586   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1587 
1588   MockRead data_reads[] = {
1589       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1590       MockRead("hello"),
1591       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1592       MockRead("world"),
1593       MockRead(SYNCHRONOUS, OK),
1594   };
1595   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1596   session_deps_.socket_factory->AddSocketDataProvider(&data);
1597 
1598   const char* const kExpectedResponseData[] = {"hello", "world"};
1599 
1600   for (const auto* expected_response_data : kExpectedResponseData) {
1601     HttpRequestInfo request;
1602     request.method = "GET";
1603     request.url = GURL("http://www.example.org/");
1604     request.traffic_annotation =
1605         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1606 
1607     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1608 
1609     TestCompletionCallback callback;
1610 
1611     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1612     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1613 
1614     rv = callback.WaitForResult();
1615     EXPECT_THAT(rv, IsOk());
1616 
1617     const HttpResponseInfo* response = trans.GetResponseInfo();
1618     ASSERT_TRUE(response);
1619 
1620     EXPECT_TRUE(response->headers);
1621     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1622     EXPECT_TRUE(response->proxy_chain.is_direct());
1623 
1624     std::string response_data;
1625     rv = ReadTransaction(&trans, &response_data);
1626     EXPECT_THAT(rv, IsOk());
1627     EXPECT_EQ(expected_response_data, response_data);
1628   }
1629 }
1630 
TEST_P(HttpNetworkTransactionTest,Ignores100)1631 TEST_P(HttpNetworkTransactionTest, Ignores100) {
1632   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
1633   element_readers.push_back(
1634       std::make_unique<UploadBytesElementReader>("foo", 3));
1635   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
1636 
1637   HttpRequestInfo request;
1638   request.method = "POST";
1639   request.url = GURL("http://www.foo.com/");
1640   request.upload_data_stream = &upload_data_stream;
1641   request.traffic_annotation =
1642       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1643 
1644   // Check the upload progress returned before initialization is correct.
1645   UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1646   EXPECT_EQ(0u, progress.size());
1647   EXPECT_EQ(0u, progress.position());
1648 
1649   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1650   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1651 
1652   MockRead data_reads[] = {
1653       MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1654       MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1655       MockRead("hello world"),
1656       MockRead(SYNCHRONOUS, OK),
1657   };
1658   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1659   session_deps_.socket_factory->AddSocketDataProvider(&data);
1660 
1661   TestCompletionCallback callback;
1662 
1663   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1664   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1665 
1666   rv = callback.WaitForResult();
1667   EXPECT_THAT(rv, IsOk());
1668 
1669   const HttpResponseInfo* response = trans.GetResponseInfo();
1670   ASSERT_TRUE(response);
1671 
1672   EXPECT_TRUE(response->headers);
1673   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
1674 
1675   std::string response_data;
1676   rv = ReadTransaction(&trans, &response_data);
1677   EXPECT_THAT(rv, IsOk());
1678   EXPECT_EQ("hello world", response_data);
1679 }
1680 
1681 // This test is almost the same as Ignores100 above, but the response contains
1682 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
1683 // HTTP/1.1 and the two status headers are read in one read.
TEST_P(HttpNetworkTransactionTest,Ignores1xx)1684 TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
1685   HttpRequestInfo request;
1686   request.method = "GET";
1687   request.url = GURL("http://www.foo.com/");
1688   request.traffic_annotation =
1689       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1690 
1691   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1692   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1693 
1694   MockRead data_reads[] = {
1695       MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1696                "HTTP/1.1 200 OK\r\n\r\n"),
1697       MockRead("hello world"),
1698       MockRead(SYNCHRONOUS, OK),
1699   };
1700   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1701   session_deps_.socket_factory->AddSocketDataProvider(&data);
1702 
1703   TestCompletionCallback callback;
1704 
1705   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1706   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1707 
1708   rv = callback.WaitForResult();
1709   EXPECT_THAT(rv, IsOk());
1710 
1711   const HttpResponseInfo* response = trans.GetResponseInfo();
1712   ASSERT_TRUE(response);
1713 
1714   EXPECT_TRUE(response->headers);
1715   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1716 
1717   std::string response_data;
1718   rv = ReadTransaction(&trans, &response_data);
1719   EXPECT_THAT(rv, IsOk());
1720   EXPECT_EQ("hello world", response_data);
1721 }
1722 
TEST_P(HttpNetworkTransactionTest,LoadTimingMeasuresTimeToFirstByteForHttp)1723 TEST_P(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1724   static const base::TimeDelta kDelayAfterFirstByte = base::Milliseconds(10);
1725 
1726   HttpRequestInfo request;
1727   request.method = "GET";
1728   request.url = GURL("http://www.foo.com/");
1729   request.traffic_annotation =
1730       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1731 
1732   std::vector<MockWrite> data_writes = {
1733       MockWrite(ASYNC, 0,
1734                 "GET / HTTP/1.1\r\n"
1735                 "Host: www.foo.com\r\n"
1736                 "Connection: keep-alive\r\n\r\n"),
1737   };
1738 
1739   std::vector<MockRead> data_reads = {
1740       // Write one byte of the status line, followed by a pause.
1741       MockRead(ASYNC, 1, "H"),
1742       MockRead(ASYNC, ERR_IO_PENDING, 2),
1743       MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1744       MockRead(ASYNC, 4, "hello world"),
1745       MockRead(SYNCHRONOUS, OK, 5),
1746   };
1747 
1748   SequencedSocketData data(data_reads, data_writes);
1749   session_deps_.socket_factory->AddSocketDataProvider(&data);
1750 
1751   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1752 
1753   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1754 
1755   TestCompletionCallback callback;
1756 
1757   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1758   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1759 
1760   data.RunUntilPaused();
1761   ASSERT_TRUE(data.IsPaused());
1762   FastForwardBy(kDelayAfterFirstByte);
1763   data.Resume();
1764 
1765   rv = callback.WaitForResult();
1766   EXPECT_THAT(rv, IsOk());
1767 
1768   const HttpResponseInfo* response = trans.GetResponseInfo();
1769   ASSERT_TRUE(response);
1770 
1771   EXPECT_TRUE(response->headers);
1772   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1773 
1774   LoadTimingInfo load_timing_info;
1775   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1776   EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1777   EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
1778   // Ensure we didn't include the delay in the TTFB time.
1779   EXPECT_EQ(load_timing_info.receive_headers_start,
1780             load_timing_info.connect_timing.connect_end);
1781   // Ensure that the mock clock advanced at all.
1782   EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1783             kDelayAfterFirstByte);
1784 
1785   std::string response_data;
1786   rv = ReadTransaction(&trans, &response_data);
1787   EXPECT_THAT(rv, IsOk());
1788   EXPECT_EQ("hello world", response_data);
1789 }
1790 
1791 // Tests that the time-to-first-byte reported in a transaction's load timing
1792 // info uses the first response, even if 1XX/informational.
Check100ResponseTiming(bool use_spdy)1793 void HttpNetworkTransactionTestBase::Check100ResponseTiming(bool use_spdy) {
1794   static const base::TimeDelta kDelayAfter100Response = base::Milliseconds(10);
1795 
1796   HttpRequestInfo request;
1797   request.method = "GET";
1798   request.url = GURL("https://www.foo.com/");
1799   request.traffic_annotation =
1800       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1801 
1802   SSLSocketDataProvider ssl(ASYNC, OK);
1803   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1804 
1805   std::vector<MockWrite> data_writes;
1806   std::vector<MockRead> data_reads;
1807 
1808   spdy::SpdySerializedFrame spdy_req(
1809       spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1810 
1811   spdy::Http2HeaderBlock spdy_resp1_headers;
1812   spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1813   spdy::SpdySerializedFrame spdy_resp1(
1814       spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1815   spdy::SpdySerializedFrame spdy_resp2(
1816       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1817   spdy::SpdySerializedFrame spdy_data(
1818       spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1819 
1820   if (use_spdy) {
1821     ssl.next_proto = kProtoHTTP2;
1822 
1823     data_writes = {CreateMockWrite(spdy_req, 0)};
1824 
1825     data_reads = {
1826         CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1827         CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1828         MockRead(SYNCHRONOUS, OK, 5),
1829     };
1830   } else {
1831     data_writes = {
1832         MockWrite(ASYNC, 0,
1833                   "GET / HTTP/1.1\r\n"
1834                   "Host: www.foo.com\r\n"
1835                   "Connection: keep-alive\r\n\r\n"),
1836     };
1837 
1838     data_reads = {
1839         MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1840         MockRead(ASYNC, ERR_IO_PENDING, 2),
1841 
1842         MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1843         MockRead(ASYNC, 4, "hello world"),
1844         MockRead(SYNCHRONOUS, OK, 5),
1845     };
1846   }
1847 
1848   SequencedSocketData data(data_reads, data_writes);
1849   session_deps_.socket_factory->AddSocketDataProvider(&data);
1850 
1851   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1852 
1853   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1854 
1855   TestCompletionCallback callback;
1856 
1857   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1858   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1859 
1860   data.RunUntilPaused();
1861   // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1862   // the delay before parsing the 200 response.
1863   ASSERT_TRUE(data.IsPaused());
1864   FastForwardBy(kDelayAfter100Response);
1865   data.Resume();
1866 
1867   rv = callback.WaitForResult();
1868   EXPECT_THAT(rv, IsOk());
1869 
1870   const HttpResponseInfo* response = trans.GetResponseInfo();
1871   ASSERT_TRUE(response);
1872 
1873   LoadTimingInfo load_timing_info;
1874   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1875   EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1876   EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
1877   // Ensure we didn't include the delay in the TTFB time.
1878   EXPECT_EQ(load_timing_info.receive_headers_start,
1879             load_timing_info.connect_timing.connect_end);
1880   // Ensure that the mock clock advanced at all.
1881   EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1882             kDelayAfter100Response);
1883 
1884   std::string response_data;
1885   rv = ReadTransaction(&trans, &response_data);
1886   EXPECT_THAT(rv, IsOk());
1887   EXPECT_EQ("hello world", response_data);
1888 }
1889 
TEST_P(HttpNetworkTransactionTest,MeasuresTimeToFirst100ResponseForHttp)1890 TEST_P(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
1891   Check100ResponseTiming(false /* use_spdy */);
1892 }
1893 
TEST_P(HttpNetworkTransactionTest,MeasuresTimeToFirst100ResponseForSpdy)1894 TEST_P(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
1895   Check100ResponseTiming(true /* use_spdy */);
1896 }
1897 
TEST_P(HttpNetworkTransactionTest,Incomplete100ThenEOF)1898 TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
1899   HttpRequestInfo request;
1900   request.method = "POST";
1901   request.url = GURL("http://www.foo.com/");
1902   request.traffic_annotation =
1903       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1904 
1905   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1906   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1907 
1908   MockRead data_reads[] = {
1909       MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1910       MockRead(ASYNC, 0),
1911   };
1912   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1913   session_deps_.socket_factory->AddSocketDataProvider(&data);
1914 
1915   TestCompletionCallback callback;
1916 
1917   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1918   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1919 
1920   rv = callback.WaitForResult();
1921   EXPECT_THAT(rv, IsOk());
1922 
1923   std::string response_data;
1924   rv = ReadTransaction(&trans, &response_data);
1925   EXPECT_THAT(rv, IsOk());
1926   EXPECT_EQ("", response_data);
1927 }
1928 
TEST_P(HttpNetworkTransactionTest,EmptyResponse)1929 TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
1930   HttpRequestInfo request;
1931   request.method = "POST";
1932   request.url = GURL("http://www.foo.com/");
1933   request.traffic_annotation =
1934       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1935 
1936   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1937   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1938 
1939   MockRead data_reads[] = {
1940       MockRead(ASYNC, 0),
1941   };
1942   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1943   session_deps_.socket_factory->AddSocketDataProvider(&data);
1944 
1945   TestCompletionCallback callback;
1946 
1947   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1948   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1949 
1950   rv = callback.WaitForResult();
1951   EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
1952 }
1953 
KeepAliveConnectionResendRequestTest(const MockWrite * write_failure,const MockRead * read_failure)1954 void HttpNetworkTransactionTestBase::KeepAliveConnectionResendRequestTest(
1955     const MockWrite* write_failure,
1956     const MockRead* read_failure) {
1957   HttpRequestInfo request;
1958   request.method = "GET";
1959   request.url = GURL("http://www.foo.com/");
1960   request.traffic_annotation =
1961       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1962 
1963   session_deps_.net_log = net::NetLog::Get();
1964   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1965 
1966   // Written data for successfully sending both requests.
1967   MockWrite data1_writes[] = {MockWrite("GET / HTTP/1.1\r\n"
1968                                         "Host: www.foo.com\r\n"
1969                                         "Connection: keep-alive\r\n\r\n"),
1970                               MockWrite("GET / HTTP/1.1\r\n"
1971                                         "Host: www.foo.com\r\n"
1972                                         "Connection: keep-alive\r\n\r\n")};
1973 
1974   // Read results for the first request.
1975   MockRead data1_reads[] = {
1976       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1977       MockRead("hello"),
1978       MockRead(ASYNC, OK),
1979   };
1980 
1981   if (write_failure) {
1982     ASSERT_FALSE(read_failure);
1983     data1_writes[1] = *write_failure;
1984   } else {
1985     ASSERT_TRUE(read_failure);
1986     data1_reads[2] = *read_failure;
1987   }
1988 
1989   StaticSocketDataProvider data1(data1_reads, data1_writes);
1990   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1991 
1992   MockRead data2_reads[] = {
1993       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1994       MockRead("world"),
1995       MockRead(ASYNC, OK),
1996   };
1997   StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
1998   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1999 
2000   const char* const kExpectedResponseData[] = {"hello", "world"};
2001 
2002   uint32_t first_socket_log_id = NetLogSource::kInvalidId;
2003   for (int i = 0; i < 2; ++i) {
2004     TestCompletionCallback callback;
2005 
2006     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2007 
2008     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
2009     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2010 
2011     rv = callback.WaitForResult();
2012     EXPECT_THAT(rv, IsOk());
2013 
2014     LoadTimingInfo load_timing_info;
2015     EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
2016     TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2017     if (i == 0) {
2018       first_socket_log_id = load_timing_info.socket_log_id;
2019     } else {
2020       // The second request should be using a new socket.
2021       EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
2022     }
2023 
2024     const HttpResponseInfo* response = trans.GetResponseInfo();
2025     ASSERT_TRUE(response);
2026 
2027     EXPECT_TRUE(response->headers);
2028     EXPECT_TRUE(response->proxy_chain.is_direct());
2029     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2030 
2031     std::string response_data;
2032     rv = ReadTransaction(&trans, &response_data);
2033     EXPECT_THAT(rv, IsOk());
2034     EXPECT_EQ(kExpectedResponseData[i], response_data);
2035   }
2036 }
2037 
PreconnectErrorResendRequestTest(const MockWrite * write_failure,const MockRead * read_failure,bool use_spdy,bool chunked_upload)2038 void HttpNetworkTransactionTestBase::PreconnectErrorResendRequestTest(
2039     const MockWrite* write_failure,
2040     const MockRead* read_failure,
2041     bool use_spdy,
2042     bool chunked_upload) {
2043   SpdyTestUtil spdy_util(/*use_priority_header=*/true);
2044   HttpRequestInfo request;
2045   request.method = "GET";
2046   request.url = GURL("https://www.foo.com/");
2047   request.traffic_annotation =
2048       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2049 
2050   const char upload_data[] = "foobar";
2051   ChunkedUploadDataStream upload_data_stream(0);
2052   if (chunked_upload) {
2053     request.method = "POST";
2054     upload_data_stream.AppendData(upload_data, std::size(upload_data) - 1,
2055                                   true);
2056     request.upload_data_stream = &upload_data_stream;
2057   }
2058 
2059   session_deps_.net_log = net::NetLog::Get();
2060   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2061 
2062   SSLSocketDataProvider ssl1(ASYNC, OK);
2063   SSLSocketDataProvider ssl2(ASYNC, OK);
2064   if (use_spdy) {
2065     ssl1.next_proto = kProtoHTTP2;
2066     ssl2.next_proto = kProtoHTTP2;
2067   }
2068   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
2069   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
2070 
2071   // SPDY versions of the request and response.
2072 
2073   spdy::Http2HeaderBlock spdy_post_header_block;
2074   spdy_post_header_block[spdy::kHttp2MethodHeader] = "POST";
2075   spdy_util.AddUrlToHeaderBlock(request.url.spec(), &spdy_post_header_block);
2076   spdy::SpdySerializedFrame spdy_request(
2077       chunked_upload
2078           ? spdy_util.ConstructSpdyHeaders(1, std::move(spdy_post_header_block),
2079                                            DEFAULT_PRIORITY, false)
2080           : spdy_util.ConstructSpdyGet(request.url.spec().c_str(), 1,
2081                                        DEFAULT_PRIORITY));
2082 
2083   spdy::SpdySerializedFrame spdy_request_body(
2084       spdy_util.ConstructSpdyDataFrame(1, "foobar", true));
2085   spdy::SpdySerializedFrame spdy_response(
2086       spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
2087   spdy::SpdySerializedFrame spdy_data(
2088       spdy_util.ConstructSpdyDataFrame(1, "hello", true));
2089 
2090   // HTTP/1.1 versions of the request and response.
2091   const std::string http_request =
2092       std::string(chunked_upload ? "POST" : "GET") +
2093       " / HTTP/1.1\r\n"
2094       "Host: www.foo.com\r\n"
2095       "Connection: keep-alive\r\n" +
2096       (chunked_upload ? "Transfer-Encoding: chunked\r\n\r\n" : "\r\n");
2097   const char* kHttpRequest = http_request.c_str();
2098   const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
2099   const char kHttpData[] = "hello";
2100 
2101   std::vector<MockRead> data1_reads;
2102   std::vector<MockWrite> data1_writes;
2103   if (write_failure) {
2104     ASSERT_FALSE(read_failure);
2105     data1_writes.push_back(*write_failure);
2106     data1_reads.emplace_back(ASYNC, OK);
2107   } else {
2108     ASSERT_TRUE(read_failure);
2109     if (use_spdy) {
2110       data1_writes.push_back(CreateMockWrite(spdy_request));
2111       if (chunked_upload) {
2112         data1_writes.push_back(CreateMockWrite(spdy_request_body));
2113       }
2114     } else {
2115       data1_writes.emplace_back(kHttpRequest);
2116       if (chunked_upload) {
2117         data1_writes.emplace_back("6\r\nfoobar\r\n");
2118         data1_writes.emplace_back("0\r\n\r\n");
2119       }
2120     }
2121     data1_reads.push_back(*read_failure);
2122   }
2123 
2124   StaticSocketDataProvider data1(data1_reads, data1_writes);
2125   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2126 
2127   std::vector<MockRead> data2_reads;
2128   std::vector<MockWrite> data2_writes;
2129 
2130   if (use_spdy) {
2131     int seq = 0;
2132     data2_writes.push_back(CreateMockWrite(spdy_request, seq++, ASYNC));
2133     if (chunked_upload) {
2134       data2_writes.push_back(CreateMockWrite(spdy_request_body, seq++, ASYNC));
2135     }
2136     data2_reads.push_back(CreateMockRead(spdy_response, seq++, ASYNC));
2137     data2_reads.push_back(CreateMockRead(spdy_data, seq++, ASYNC));
2138     data2_reads.emplace_back(ASYNC, OK, seq++);
2139   } else {
2140     int seq = 0;
2141     data2_writes.emplace_back(ASYNC, kHttpRequest, strlen(kHttpRequest), seq++);
2142     if (chunked_upload) {
2143       data2_writes.emplace_back(ASYNC, "6\r\nfoobar\r\n", 11, seq++);
2144       data2_writes.emplace_back(ASYNC, "0\r\n\r\n", 5, seq++);
2145     }
2146     data2_reads.emplace_back(ASYNC, kHttpResponse, strlen(kHttpResponse),
2147                              seq++);
2148     data2_reads.emplace_back(ASYNC, kHttpData, strlen(kHttpData), seq++);
2149     data2_reads.emplace_back(ASYNC, OK, seq++);
2150   }
2151   SequencedSocketData data2(data2_reads, data2_writes);
2152   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2153 
2154   // Preconnect a socket.
2155   session->http_stream_factory()->PreconnectStreams(1, request);
2156   // Wait for the preconnect to complete.
2157   // TODO(davidben): Some way to wait for an idle socket count might be handy.
2158   base::RunLoop().RunUntilIdle();
2159   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
2160 
2161   // Make the request.
2162   TestCompletionCallback callback;
2163 
2164   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2165 
2166   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
2167   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2168 
2169   rv = callback.WaitForResult();
2170   EXPECT_THAT(rv, IsOk());
2171 
2172   LoadTimingInfo load_timing_info;
2173   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
2174   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES |
2175                                                 CONNECT_TIMING_HAS_SSL_TIMES);
2176 
2177   const HttpResponseInfo* response = trans.GetResponseInfo();
2178   ASSERT_TRUE(response);
2179 
2180   EXPECT_TRUE(response->headers);
2181   if (response->was_fetched_via_spdy) {
2182     EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
2183   } else {
2184     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2185   }
2186 
2187   std::string response_data;
2188   rv = ReadTransaction(&trans, &response_data);
2189   EXPECT_THAT(rv, IsOk());
2190   EXPECT_EQ(kHttpData, response_data);
2191 }
2192 
2193 // Test that we do not retry indefinitely when a server sends an error like
2194 // ERR_HTTP2_PING_FAILED, ERR_HTTP2_SERVER_REFUSED_STREAM,
2195 // ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
TEST_P(HttpNetworkTransactionTest,FiniteRetriesOnIOError)2196 TEST_P(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
2197   HttpRequestInfo request;
2198   request.method = "GET";
2199   request.url = GURL("https://www.foo.com/");
2200   request.traffic_annotation =
2201       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2202 
2203   // Check whether we give up after the third try.
2204 
2205   // Construct an HTTP2 request and a "Go away" response.
2206   spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
2207       request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
2208   spdy::SpdySerializedFrame spdy_response_go_away(
2209       spdy_util_.ConstructSpdyGoAway(0));
2210   MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
2211   MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
2212 
2213   // Three go away responses.
2214   StaticSocketDataProvider data1(data_read1, data_write);
2215   StaticSocketDataProvider data2(data_read1, data_write);
2216   StaticSocketDataProvider data3(data_read1, data_write);
2217 
2218   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2219   AddSSLSocketData();
2220   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2221   AddSSLSocketData();
2222   session_deps_.socket_factory->AddSocketDataProvider(&data3);
2223   AddSSLSocketData();
2224 
2225   TestCompletionCallback callback;
2226   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2227   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2228 
2229   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
2230   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2231 
2232   rv = callback.WaitForResult();
2233   EXPECT_THAT(rv, IsError(ERR_HTTP2_SERVER_REFUSED_STREAM));
2234 }
2235 
TEST_P(HttpNetworkTransactionTest,RetryTwiceOnIOError)2236 TEST_P(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
2237   HttpRequestInfo request;
2238   request.method = "GET";
2239   request.url = GURL("https://www.foo.com/");
2240   request.traffic_annotation =
2241       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2242 
2243   // Check whether we try atleast thrice before giving up.
2244 
2245   // Construct an HTTP2 request and a "Go away" response.
2246   spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
2247       request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
2248   spdy::SpdySerializedFrame spdy_response_go_away(
2249       spdy_util_.ConstructSpdyGoAway(0));
2250   MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
2251   MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
2252 
2253   // Construct a non error HTTP2 response.
2254   spdy::SpdySerializedFrame spdy_response_no_error(
2255       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
2256   spdy::SpdySerializedFrame spdy_data(
2257       spdy_util_.ConstructSpdyDataFrame(1, true));
2258   MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
2259                            CreateMockRead(spdy_data, 2)};
2260 
2261   // Two error responses.
2262   StaticSocketDataProvider data1(data_read1, data_write);
2263   StaticSocketDataProvider data2(data_read1, data_write);
2264   // Followed by a success response.
2265   SequencedSocketData data3(data_read2, data_write);
2266 
2267   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2268   AddSSLSocketData();
2269   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2270   AddSSLSocketData();
2271   session_deps_.socket_factory->AddSocketDataProvider(&data3);
2272   AddSSLSocketData();
2273 
2274   TestCompletionCallback callback;
2275   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2276   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2277 
2278   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
2279   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2280 
2281   rv = callback.WaitForResult();
2282   EXPECT_THAT(rv, IsOk());
2283 }
2284 
TEST_P(HttpNetworkTransactionTest,KeepAliveConnectionNotConnectedOnWrite)2285 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
2286   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
2287   KeepAliveConnectionResendRequestTest(&write_failure, nullptr);
2288 }
2289 
TEST_P(HttpNetworkTransactionTest,KeepAliveConnectionReset)2290 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
2291   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
2292   KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
2293 }
2294 
TEST_P(HttpNetworkTransactionTest,KeepAliveConnectionEOF)2295 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
2296   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
2297   KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
2298 }
2299 
2300 // Make sure that on a 408 response (Request Timeout), the request is retried,
2301 // if the socket was a reused keep alive socket.
TEST_P(HttpNetworkTransactionTest,KeepAlive408)2302 TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
2303   MockRead read_failure(SYNCHRONOUS,
2304                         "HTTP/1.1 408 Request Timeout\r\n"
2305                         "Connection: Keep-Alive\r\n"
2306                         "Content-Length: 6\r\n\r\n"
2307                         "Pickle");
2308   KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
2309 }
2310 
TEST_P(HttpNetworkTransactionTest,PreconnectErrorNotConnectedOnWrite)2311 TEST_P(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
2312   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
2313   PreconnectErrorResendRequestTest(&write_failure, nullptr,
2314                                    false /* use_spdy */);
2315   PreconnectErrorResendRequestTest(
2316       &write_failure, nullptr, false /* use_spdy */, true /* chunked_upload */);
2317 }
2318 
TEST_P(HttpNetworkTransactionTest,PreconnectErrorReset)2319 TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
2320   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
2321   PreconnectErrorResendRequestTest(nullptr, &read_failure,
2322                                    false /* use_spdy */);
2323   PreconnectErrorResendRequestTest(nullptr, &read_failure, false /* use_spdy */,
2324                                    true /* chunked_upload */);
2325 }
2326 
TEST_P(HttpNetworkTransactionTest,PreconnectErrorEOF)2327 TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
2328   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
2329   PreconnectErrorResendRequestTest(nullptr, &read_failure,
2330                                    false /* use_spdy */);
2331   PreconnectErrorResendRequestTest(nullptr, &read_failure, false /* use_spdy */,
2332                                    true /* chunked_upload */);
2333 }
2334 
TEST_P(HttpNetworkTransactionTest,PreconnectErrorAsyncEOF)2335 TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
2336   MockRead read_failure(ASYNC, OK);  // EOF
2337   PreconnectErrorResendRequestTest(nullptr, &read_failure,
2338                                    false /* use_spdy */);
2339   PreconnectErrorResendRequestTest(nullptr, &read_failure, false /* use_spdy */,
2340                                    true /* chunked_upload */);
2341 }
2342 
2343 // Make sure that on a 408 response (Request Timeout), the request is retried,
2344 // if the socket was a preconnected (UNUSED_IDLE) socket.
TEST_P(HttpNetworkTransactionTest,RetryOnIdle408)2345 TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
2346   MockRead read_failure(SYNCHRONOUS,
2347                         "HTTP/1.1 408 Request Timeout\r\n"
2348                         "Connection: Keep-Alive\r\n"
2349                         "Content-Length: 6\r\n\r\n"
2350                         "Pickle");
2351   KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
2352   PreconnectErrorResendRequestTest(nullptr, &read_failure,
2353                                    false /* use_spdy */);
2354   PreconnectErrorResendRequestTest(nullptr, &read_failure, false /* use_spdy */,
2355                                    true /* chunked_upload */);
2356 }
2357 
TEST_P(HttpNetworkTransactionTest,SpdyPreconnectErrorNotConnectedOnWrite)2358 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
2359   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
2360   PreconnectErrorResendRequestTest(&write_failure, nullptr,
2361                                    true /* use_spdy */);
2362   PreconnectErrorResendRequestTest(&write_failure, nullptr, true /* use_spdy */,
2363                                    true /* chunked_upload */);
2364 }
2365 
TEST_P(HttpNetworkTransactionTest,SpdyPreconnectErrorReset)2366 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
2367   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
2368   PreconnectErrorResendRequestTest(nullptr, &read_failure, true /* use_spdy */);
2369   PreconnectErrorResendRequestTest(nullptr, &read_failure, true /* use_spdy */,
2370                                    true /* chunked_upload */);
2371 }
2372 
TEST_P(HttpNetworkTransactionTest,SpdyPreconnectErrorEOF)2373 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
2374   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
2375   PreconnectErrorResendRequestTest(nullptr, &read_failure, true /* use_spdy */);
2376   PreconnectErrorResendRequestTest(nullptr, &read_failure, true /* use_spdy */,
2377                                    true /* chunked_upload */);
2378 }
2379 
TEST_P(HttpNetworkTransactionTest,SpdyPreconnectErrorAsyncEOF)2380 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
2381   MockRead read_failure(ASYNC, OK);  // EOF
2382   PreconnectErrorResendRequestTest(nullptr, &read_failure, true /* use_spdy */);
2383   PreconnectErrorResendRequestTest(nullptr, &read_failure, true /* use_spdy */,
2384                                    true /* chunked_upload */);
2385 }
2386 
TEST_P(HttpNetworkTransactionTest,NonKeepAliveConnectionReset)2387 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
2388   HttpRequestInfo request;
2389   request.method = "GET";
2390   request.url = GURL("http://www.example.org/");
2391   request.traffic_annotation =
2392       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2393 
2394   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2395   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2396 
2397   MockRead data_reads[] = {
2398       MockRead(ASYNC, ERR_CONNECTION_RESET),
2399       MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
2400       MockRead("hello world"),
2401       MockRead(SYNCHRONOUS, OK),
2402   };
2403   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
2404   session_deps_.socket_factory->AddSocketDataProvider(&data);
2405 
2406   TestCompletionCallback callback;
2407 
2408   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
2409   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2410 
2411   rv = callback.WaitForResult();
2412   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
2413 
2414   IPEndPoint endpoint;
2415   EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
2416   EXPECT_LT(0u, endpoint.address().size());
2417 }
2418 
2419 // What do various browsers do when the server closes a non-keepalive
2420 // connection without sending any response header or body?
2421 //
2422 // IE7: error page
2423 // Safari 3.1.2 (Windows): error page
2424 // Firefox 3.0.1: blank page
2425 // Opera 9.52: after five attempts, blank page
2426 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2427 // Us: error page (EMPTY_RESPONSE)
TEST_P(HttpNetworkTransactionTest,NonKeepAliveConnectionEOF)2428 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
2429   MockRead data_reads[] = {
2430       MockRead(SYNCHRONOUS, OK),            // EOF
2431       MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
2432       MockRead("hello world"),
2433       MockRead(SYNCHRONOUS, OK),
2434   };
2435   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
2436   EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
2437 }
2438 
2439 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2440 // tests. There was a bug causing HttpNetworkTransaction to hang in the
2441 // destructor in such situations.
2442 // See http://crbug.com/154712 and http://crbug.com/156609.
TEST_P(HttpNetworkTransactionTest,KeepAliveEarlyClose)2443 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
2444   HttpRequestInfo request;
2445   request.method = "GET";
2446   request.url = GURL("http://www.example.org/");
2447   request.traffic_annotation =
2448       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2449 
2450   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2451   auto trans =
2452       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2453 
2454   MockRead data_reads[] = {
2455       MockRead("HTTP/1.0 200 OK\r\n"),
2456       MockRead("Connection: keep-alive\r\n"),
2457       MockRead("Content-Length: 100\r\n\r\n"),
2458       MockRead("hello"),
2459       MockRead(SYNCHRONOUS, 0),
2460   };
2461   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
2462   session_deps_.socket_factory->AddSocketDataProvider(&data);
2463 
2464   TestCompletionCallback callback;
2465 
2466   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
2467   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2468 
2469   rv = callback.WaitForResult();
2470   EXPECT_THAT(rv, IsOk());
2471 
2472   scoped_refptr<IOBufferWithSize> io_buf =
2473       base::MakeRefCounted<IOBufferWithSize>(100);
2474   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
2475   if (rv == ERR_IO_PENDING) {
2476     rv = callback.WaitForResult();
2477   }
2478   EXPECT_EQ(5, rv);
2479   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
2480   EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
2481 
2482   trans.reset();
2483   base::RunLoop().RunUntilIdle();
2484   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2485 }
2486 
TEST_P(HttpNetworkTransactionTest,KeepAliveEarlyClose2)2487 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
2488   HttpRequestInfo request;
2489   request.method = "GET";
2490   request.url = GURL("http://www.example.org/");
2491   request.traffic_annotation =
2492       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2493 
2494   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2495   auto trans =
2496       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2497 
2498   MockRead data_reads[] = {
2499       MockRead("HTTP/1.0 200 OK\r\n"),
2500       MockRead("Connection: keep-alive\r\n"),
2501       MockRead("Content-Length: 100\r\n\r\n"),
2502       MockRead(SYNCHRONOUS, 0),
2503   };
2504   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
2505   session_deps_.socket_factory->AddSocketDataProvider(&data);
2506 
2507   TestCompletionCallback callback;
2508 
2509   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
2510   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2511 
2512   rv = callback.WaitForResult();
2513   EXPECT_THAT(rv, IsOk());
2514 
2515   scoped_refptr<IOBufferWithSize> io_buf(
2516       base::MakeRefCounted<IOBufferWithSize>(100));
2517   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
2518   if (rv == ERR_IO_PENDING) {
2519     rv = callback.WaitForResult();
2520   }
2521   EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
2522 
2523   trans.reset();
2524   base::RunLoop().RunUntilIdle();
2525   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2526 }
2527 
2528 // Test that we correctly reuse a keep-alive connection after not explicitly
2529 // reading the body.
TEST_P(HttpNetworkTransactionTest,KeepAliveAfterUnreadBody)2530 TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
2531   HttpRequestInfo request;
2532   request.method = "GET";
2533   request.url = GURL("http://www.foo.com/");
2534   request.traffic_annotation =
2535       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2536 
2537   session_deps_.net_log = net::NetLog::Get();
2538   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2539 
2540   const char kRequestData[] =
2541       "GET / HTTP/1.1\r\n"
2542       "Host: www.foo.com\r\n"
2543       "Connection: keep-alive\r\n\r\n";
2544   MockWrite data_writes[] = {
2545       MockWrite(ASYNC, 0, kRequestData),  MockWrite(ASYNC, 2, kRequestData),
2546       MockWrite(ASYNC, 4, kRequestData),  MockWrite(ASYNC, 6, kRequestData),
2547       MockWrite(ASYNC, 8, kRequestData),  MockWrite(ASYNC, 10, kRequestData),
2548       MockWrite(ASYNC, 12, kRequestData), MockWrite(ASYNC, 14, kRequestData),
2549       MockWrite(ASYNC, 17, kRequestData), MockWrite(ASYNC, 20, kRequestData),
2550   };
2551 
2552   // Note that because all these reads happen in the same
2553   // StaticSocketDataProvider, it shows that the same socket is being reused for
2554   // all transactions.
2555   MockRead data_reads[] = {
2556       MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2557       MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2558       MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2559       MockRead(ASYNC, 7,
2560                "HTTP/1.1 302 Found\r\n"
2561                "Content-Length: 0\r\n\r\n"),
2562       MockRead(ASYNC, 9,
2563                "HTTP/1.1 302 Found\r\n"
2564                "Content-Length: 5\r\n\r\n"
2565                "hello"),
2566       MockRead(ASYNC, 11,
2567                "HTTP/1.1 301 Moved Permanently\r\n"
2568                "Content-Length: 0\r\n\r\n"),
2569       MockRead(ASYNC, 13,
2570                "HTTP/1.1 301 Moved Permanently\r\n"
2571                "Content-Length: 5\r\n\r\n"
2572                "hello"),
2573 
2574       // In the next two rounds, IsConnectedAndIdle returns false, due to
2575       // the set_busy_before_sync_reads(true) call, while the
2576       // HttpNetworkTransaction is being shut down, but the socket is still
2577       // reuseable.  See http://crbug.com/544255.
2578       MockRead(ASYNC, 15,
2579                "HTTP/1.1 200 Hunky-Dory\r\n"
2580                "Content-Length: 5\r\n\r\n"),
2581       MockRead(SYNCHRONOUS, 16, "hello"),
2582 
2583       MockRead(ASYNC, 18,
2584                "HTTP/1.1 200 Hunky-Dory\r\n"
2585                "Content-Length: 5\r\n\r\n"
2586                "he"),
2587       MockRead(SYNCHRONOUS, 19, "llo"),
2588 
2589       // The body of the final request is actually read.
2590       MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2591       MockRead(ASYNC, 22, "hello"),
2592   };
2593   SequencedSocketData data(data_reads, data_writes);
2594   data.set_busy_before_sync_reads(true);
2595   session_deps_.socket_factory->AddSocketDataProvider(&data);
2596 
2597   const int kNumUnreadBodies = std::size(data_writes) - 1;
2598   std::string response_lines[kNumUnreadBodies];
2599 
2600   uint32_t first_socket_log_id = NetLogSource::kInvalidId;
2601   for (size_t i = 0; i < kNumUnreadBodies; ++i) {
2602     TestCompletionCallback callback;
2603 
2604     auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
2605                                                           session.get());
2606 
2607     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
2608     EXPECT_THAT(callback.GetResult(rv), IsOk());
2609 
2610     LoadTimingInfo load_timing_info;
2611     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2612     if (i == 0) {
2613       TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2614       first_socket_log_id = load_timing_info.socket_log_id;
2615     } else {
2616       TestLoadTimingReused(load_timing_info);
2617       EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2618     }
2619 
2620     const HttpResponseInfo* response = trans->GetResponseInfo();
2621     ASSERT_TRUE(response);
2622 
2623     ASSERT_TRUE(response->headers);
2624     response_lines[i] = response->headers->GetStatusLine();
2625 
2626     // Delete the transaction without reading the response bodies.  Then spin
2627     // the message loop, so the response bodies are drained.
2628     trans.reset();
2629     base::RunLoop().RunUntilIdle();
2630   }
2631 
2632   const char* const kStatusLines[] = {
2633       "HTTP/1.1 204 No Content",
2634       "HTTP/1.1 205 Reset Content",
2635       "HTTP/1.1 304 Not Modified",
2636       "HTTP/1.1 302 Found",
2637       "HTTP/1.1 302 Found",
2638       "HTTP/1.1 301 Moved Permanently",
2639       "HTTP/1.1 301 Moved Permanently",
2640       "HTTP/1.1 200 Hunky-Dory",
2641       "HTTP/1.1 200 Hunky-Dory",
2642   };
2643 
2644   static_assert(kNumUnreadBodies == std::size(kStatusLines),
2645                 "forgot to update kStatusLines");
2646 
2647   for (int i = 0; i < kNumUnreadBodies; ++i) {
2648     EXPECT_EQ(kStatusLines[i], response_lines[i]);
2649   }
2650 
2651   TestCompletionCallback callback;
2652   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2653   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
2654   EXPECT_THAT(callback.GetResult(rv), IsOk());
2655   const HttpResponseInfo* response = trans.GetResponseInfo();
2656   ASSERT_TRUE(response);
2657   ASSERT_TRUE(response->headers);
2658   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2659   std::string response_data;
2660   rv = ReadTransaction(&trans, &response_data);
2661   EXPECT_THAT(rv, IsOk());
2662   EXPECT_EQ("hello", response_data);
2663 }
2664 
2665 // Sockets that receive extra data after a response is complete should not be
2666 // reused.
TEST_P(HttpNetworkTransactionTest,KeepAliveWithUnusedData1)2667 TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
2668   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2669   MockWrite data_writes1[] = {
2670       MockWrite("HEAD / HTTP/1.1\r\n"
2671                 "Host: www.borked.com\r\n"
2672                 "Connection: keep-alive\r\n\r\n"),
2673   };
2674 
2675   MockRead data_reads1[] = {
2676       MockRead("HTTP/1.1 200 OK\r\n"
2677                "Connection: keep-alive\r\n"
2678                "Content-Length: 22\r\n\r\n"
2679                "This server is borked."),
2680   };
2681 
2682   MockWrite data_writes2[] = {
2683       MockWrite("GET /foo HTTP/1.1\r\n"
2684                 "Host: www.borked.com\r\n"
2685                 "Connection: keep-alive\r\n\r\n"),
2686   };
2687 
2688   MockRead data_reads2[] = {
2689       MockRead("HTTP/1.1 200 OK\r\n"
2690                "Content-Length: 3\r\n\r\n"
2691                "foo"),
2692   };
2693   StaticSocketDataProvider data1(data_reads1, data_writes1);
2694   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2695   StaticSocketDataProvider data2(data_reads2, data_writes2);
2696   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2697 
2698   TestCompletionCallback callback;
2699   HttpRequestInfo request1;
2700   request1.method = "HEAD";
2701   request1.url = GURL("http://www.borked.com/");
2702   request1.traffic_annotation =
2703       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2704 
2705   auto trans1 =
2706       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2707   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
2708   EXPECT_THAT(callback.GetResult(rv), IsOk());
2709 
2710   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2711   ASSERT_TRUE(response1);
2712   ASSERT_TRUE(response1->headers);
2713   EXPECT_EQ(200, response1->headers->response_code());
2714   EXPECT_TRUE(response1->headers->IsKeepAlive());
2715 
2716   std::string response_data1;
2717   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
2718   EXPECT_EQ("", response_data1);
2719   // Deleting the transaction attempts to release the socket back into the
2720   // socket pool.
2721   trans1.reset();
2722 
2723   HttpRequestInfo request2;
2724   request2.method = "GET";
2725   request2.url = GURL("http://www.borked.com/foo");
2726   request2.traffic_annotation =
2727       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2728 
2729   auto trans2 =
2730       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2731   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
2732   EXPECT_THAT(callback.GetResult(rv), IsOk());
2733 
2734   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2735   ASSERT_TRUE(response2);
2736   ASSERT_TRUE(response2->headers);
2737   EXPECT_EQ(200, response2->headers->response_code());
2738 
2739   std::string response_data2;
2740   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
2741   EXPECT_EQ("foo", response_data2);
2742 }
2743 
TEST_P(HttpNetworkTransactionTest,KeepAliveWithUnusedData2)2744 TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
2745   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2746   MockWrite data_writes1[] = {
2747       MockWrite("GET / HTTP/1.1\r\n"
2748                 "Host: www.borked.com\r\n"
2749                 "Connection: keep-alive\r\n\r\n"),
2750   };
2751 
2752   MockRead data_reads1[] = {
2753       MockRead("HTTP/1.1 200 OK\r\n"
2754                "Connection: keep-alive\r\n"
2755                "Content-Length: 22\r\n\r\n"
2756                "This server is borked."
2757                "Bonus data!"),
2758   };
2759 
2760   MockWrite data_writes2[] = {
2761       MockWrite("GET /foo HTTP/1.1\r\n"
2762                 "Host: www.borked.com\r\n"
2763                 "Connection: keep-alive\r\n\r\n"),
2764   };
2765 
2766   MockRead data_reads2[] = {
2767       MockRead("HTTP/1.1 200 OK\r\n"
2768                "Content-Length: 3\r\n\r\n"
2769                "foo"),
2770   };
2771   StaticSocketDataProvider data1(data_reads1, data_writes1);
2772   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2773   StaticSocketDataProvider data2(data_reads2, data_writes2);
2774   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2775 
2776   TestCompletionCallback callback;
2777   HttpRequestInfo request1;
2778   request1.method = "GET";
2779   request1.url = GURL("http://www.borked.com/");
2780   request1.traffic_annotation =
2781       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2782 
2783   auto trans1 =
2784       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2785   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
2786   EXPECT_THAT(callback.GetResult(rv), IsOk());
2787 
2788   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2789   ASSERT_TRUE(response1);
2790   ASSERT_TRUE(response1->headers);
2791   EXPECT_EQ(200, response1->headers->response_code());
2792   EXPECT_TRUE(response1->headers->IsKeepAlive());
2793 
2794   std::string response_data1;
2795   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
2796   EXPECT_EQ("This server is borked.", response_data1);
2797   // Deleting the transaction attempts to release the socket back into the
2798   // socket pool.
2799   trans1.reset();
2800 
2801   HttpRequestInfo request2;
2802   request2.method = "GET";
2803   request2.url = GURL("http://www.borked.com/foo");
2804   request2.traffic_annotation =
2805       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2806 
2807   auto trans2 =
2808       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2809   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
2810   EXPECT_THAT(callback.GetResult(rv), IsOk());
2811 
2812   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2813   ASSERT_TRUE(response2);
2814   ASSERT_TRUE(response2->headers);
2815   EXPECT_EQ(200, response2->headers->response_code());
2816 
2817   std::string response_data2;
2818   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
2819   EXPECT_EQ("foo", response_data2);
2820 }
2821 
TEST_P(HttpNetworkTransactionTest,KeepAliveWithUnusedData3)2822 TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
2823   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2824   MockWrite data_writes1[] = {
2825       MockWrite("GET / HTTP/1.1\r\n"
2826                 "Host: www.borked.com\r\n"
2827                 "Connection: keep-alive\r\n\r\n"),
2828   };
2829 
2830   MockRead data_reads1[] = {
2831       MockRead("HTTP/1.1 200 OK\r\n"
2832                "Connection: keep-alive\r\n"
2833                "Transfer-Encoding: chunked\r\n\r\n"),
2834       MockRead("16\r\nThis server is borked.\r\n"),
2835       MockRead("0\r\n\r\nBonus data!"),
2836   };
2837 
2838   MockWrite data_writes2[] = {
2839       MockWrite("GET /foo HTTP/1.1\r\n"
2840                 "Host: www.borked.com\r\n"
2841                 "Connection: keep-alive\r\n\r\n"),
2842   };
2843 
2844   MockRead data_reads2[] = {
2845       MockRead("HTTP/1.1 200 OK\r\n"
2846                "Content-Length: 3\r\n\r\n"
2847                "foo"),
2848   };
2849   StaticSocketDataProvider data1(data_reads1, data_writes1);
2850   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2851   StaticSocketDataProvider data2(data_reads2, data_writes2);
2852   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2853 
2854   TestCompletionCallback callback;
2855   HttpRequestInfo request1;
2856   request1.method = "GET";
2857   request1.url = GURL("http://www.borked.com/");
2858   request1.traffic_annotation =
2859       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2860 
2861   auto trans1 =
2862       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2863   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
2864   EXPECT_THAT(callback.GetResult(rv), IsOk());
2865 
2866   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2867   ASSERT_TRUE(response1);
2868   ASSERT_TRUE(response1->headers);
2869   EXPECT_EQ(200, response1->headers->response_code());
2870   EXPECT_TRUE(response1->headers->IsKeepAlive());
2871 
2872   std::string response_data1;
2873   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
2874   EXPECT_EQ("This server is borked.", response_data1);
2875   // Deleting the transaction attempts to release the socket back into the
2876   // socket pool.
2877   trans1.reset();
2878 
2879   HttpRequestInfo request2;
2880   request2.method = "GET";
2881   request2.url = GURL("http://www.borked.com/foo");
2882   request2.traffic_annotation =
2883       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2884 
2885   auto trans2 =
2886       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2887   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
2888   EXPECT_THAT(callback.GetResult(rv), IsOk());
2889 
2890   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2891   ASSERT_TRUE(response2);
2892   ASSERT_TRUE(response2->headers);
2893   EXPECT_EQ(200, response2->headers->response_code());
2894 
2895   std::string response_data2;
2896   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
2897   EXPECT_EQ("foo", response_data2);
2898 }
2899 
2900 // This is a little different from the others - it tests the case that the
2901 // HttpStreamParser doesn't know if there's extra data on a socket or not when
2902 // the HttpNetworkTransaction is torn down, because the response body hasn't
2903 // been read from yet, but the request goes through the HttpResponseBodyDrainer.
TEST_P(HttpNetworkTransactionTest,KeepAliveWithUnusedData4)2904 TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
2905   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2906   MockWrite data_writes1[] = {
2907       MockWrite("GET / HTTP/1.1\r\n"
2908                 "Host: www.borked.com\r\n"
2909                 "Connection: keep-alive\r\n\r\n"),
2910   };
2911 
2912   MockRead data_reads1[] = {
2913       MockRead("HTTP/1.1 200 OK\r\n"
2914                "Connection: keep-alive\r\n"
2915                "Transfer-Encoding: chunked\r\n\r\n"),
2916       MockRead("16\r\nThis server is borked.\r\n"),
2917       MockRead("0\r\n\r\nBonus data!"),
2918   };
2919   StaticSocketDataProvider data1(data_reads1, data_writes1);
2920   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2921 
2922   TestCompletionCallback callback;
2923   HttpRequestInfo request1;
2924   request1.method = "GET";
2925   request1.url = GURL("http://www.borked.com/");
2926   request1.traffic_annotation =
2927       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2928 
2929   auto trans =
2930       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2931   int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
2932   EXPECT_THAT(callback.GetResult(rv), IsOk());
2933 
2934   const HttpResponseInfo* response1 = trans->GetResponseInfo();
2935   ASSERT_TRUE(response1);
2936   ASSERT_TRUE(response1->headers);
2937   EXPECT_EQ(200, response1->headers->response_code());
2938   EXPECT_TRUE(response1->headers->IsKeepAlive());
2939 
2940   // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2941   // response body.
2942   trans.reset();
2943 
2944   // Let the HttpResponseBodyDrainer drain the socket.  It should determine the
2945   // socket can't be reused, rather than returning it to the socket pool.
2946   base::RunLoop().RunUntilIdle();
2947 
2948   // There should be no idle sockets in the pool.
2949   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2950 }
2951 
2952 // Test the request-challenge-retry sequence for basic auth.
2953 // (basic auth is the easiest to mock, because it has no randomness).
TEST_P(HttpNetworkTransactionTest,BasicAuth)2954 TEST_P(HttpNetworkTransactionTest, BasicAuth) {
2955   HttpRequestInfo request;
2956   request.method = "GET";
2957   request.url = GURL("http://www.example.org/");
2958   request.traffic_annotation =
2959       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2960 
2961   session_deps_.net_log = net::NetLog::Get();
2962   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2963   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2964 
2965   MockWrite data_writes1[] = {
2966       MockWrite("GET / HTTP/1.1\r\n"
2967                 "Host: www.example.org\r\n"
2968                 "Connection: keep-alive\r\n\r\n"),
2969   };
2970 
2971   MockRead data_reads1[] = {
2972       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2973       // Give a couple authenticate options (only the middle one is actually
2974       // supported).
2975       MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
2976       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2977       MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2978       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2979       // Large content-length -- won't matter, as connection will be reset.
2980       MockRead("Content-Length: 10000\r\n\r\n"),
2981       MockRead(SYNCHRONOUS, ERR_FAILED),
2982   };
2983 
2984   // After calling trans->RestartWithAuth(), this is the request we should
2985   // be issuing -- the final header line contains the credentials.
2986   MockWrite data_writes2[] = {
2987       MockWrite("GET / HTTP/1.1\r\n"
2988                 "Host: www.example.org\r\n"
2989                 "Connection: keep-alive\r\n"
2990                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2991   };
2992 
2993   // Lastly, the server responds with the actual content.
2994   MockRead data_reads2[] = {
2995       MockRead("HTTP/1.0 200 OK\r\n"),
2996       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2997       MockRead("Content-Length: 100\r\n\r\n"),
2998       MockRead(SYNCHRONOUS, OK),
2999   };
3000 
3001   StaticSocketDataProvider data1(data_reads1, data_writes1);
3002   StaticSocketDataProvider data2(data_reads2, data_writes2);
3003   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3004   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3005 
3006   TestCompletionCallback callback1;
3007 
3008   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
3009   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3010 
3011   rv = callback1.WaitForResult();
3012   EXPECT_THAT(rv, IsOk());
3013 
3014   LoadTimingInfo load_timing_info1;
3015   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
3016   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
3017 
3018   int64_t writes_size1 = CountWriteBytes(data_writes1);
3019   EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
3020   int64_t reads_size1 = CountReadBytes(data_reads1);
3021   EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
3022 
3023   const HttpResponseInfo* response = trans.GetResponseInfo();
3024   ASSERT_TRUE(response);
3025   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
3026 
3027   TestCompletionCallback callback2;
3028 
3029   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3030   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3031 
3032   rv = callback2.WaitForResult();
3033   EXPECT_THAT(rv, IsOk());
3034 
3035   LoadTimingInfo load_timing_info2;
3036   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
3037   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
3038   // The load timing after restart should have a new socket ID, and times after
3039   // those of the first load timing.
3040   EXPECT_LE(load_timing_info1.receive_headers_end,
3041             load_timing_info2.connect_timing.connect_start);
3042   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3043 
3044   int64_t writes_size2 = CountWriteBytes(data_writes2);
3045   EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
3046   int64_t reads_size2 = CountReadBytes(data_reads2);
3047   EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
3048 
3049   response = trans.GetResponseInfo();
3050   ASSERT_TRUE(response);
3051   EXPECT_FALSE(response->auth_challenge.has_value());
3052   EXPECT_EQ(100, response->headers->GetContentLength());
3053 }
3054 
3055 // Test the request-challenge-retry sequence for basic auth.
3056 // (basic auth is the easiest to mock, because it has no randomness).
TEST_P(HttpNetworkTransactionTest,BasicAuthWithAddressChange)3057 TEST_P(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
3058   HttpRequestInfo request;
3059   request.method = "GET";
3060   request.url = GURL("http://www.example.org/");
3061   request.traffic_annotation =
3062       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3063 
3064   auto resolver = std::make_unique<MockHostResolver>();
3065   auto* resolver_ptr = resolver.get();
3066   session_deps_.net_log = net::NetLog::Get();
3067   session_deps_.host_resolver = std::move(resolver);
3068   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
3069   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3070 
3071   resolver_ptr->rules()->ClearRules();
3072   resolver_ptr->rules()->AddRule("www.example.org", "127.0.0.1");
3073 
3074   MockWrite data_writes1[] = {
3075       MockWrite("GET / HTTP/1.1\r\n"
3076                 "Host: www.example.org\r\n"
3077                 "Connection: keep-alive\r\n\r\n"),
3078   };
3079 
3080   MockRead data_reads1[] = {
3081       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3082       // Give a couple authenticate options (only the middle one is actually
3083       // supported).
3084       MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
3085       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3086       MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
3087       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3088       // Large content-length -- won't matter, as connection will be reset.
3089       MockRead("Content-Length: 10000\r\n\r\n"),
3090       MockRead(SYNCHRONOUS, ERR_FAILED),
3091   };
3092 
3093   // After calling trans->RestartWithAuth(), this is the request we should
3094   // be issuing -- the final header line contains the credentials.
3095   MockWrite data_writes2[] = {
3096       MockWrite("GET / HTTP/1.1\r\n"
3097                 "Host: www.example.org\r\n"
3098                 "Connection: keep-alive\r\n"
3099                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3100   };
3101 
3102   // Lastly, the server responds with the actual content.
3103   MockRead data_reads2[] = {
3104       MockRead("HTTP/1.0 200 OK\r\n"),
3105       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3106       MockRead("Content-Length: 100\r\n\r\n"),
3107       MockRead(SYNCHRONOUS, OK),
3108   };
3109 
3110   StaticSocketDataProvider data1(data_reads1, data_writes1);
3111   StaticSocketDataProvider data2(data_reads2, data_writes2);
3112   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3113   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3114 
3115   TestCompletionCallback callback1;
3116 
3117   EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
3118                                                 NetLogWithSource())));
3119 
3120   LoadTimingInfo load_timing_info1;
3121   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
3122   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
3123 
3124   int64_t writes_size1 = CountWriteBytes(data_writes1);
3125   EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
3126   int64_t reads_size1 = CountReadBytes(data_reads1);
3127   EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
3128 
3129   const HttpResponseInfo* response = trans.GetResponseInfo();
3130   ASSERT_TRUE(response);
3131   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
3132 
3133   IPEndPoint endpoint;
3134   EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
3135   ASSERT_FALSE(endpoint.address().empty());
3136   EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
3137 
3138   resolver_ptr->rules()->ClearRules();
3139   resolver_ptr->rules()->AddRule("www.example.org", "127.0.0.2");
3140 
3141   TestCompletionCallback callback2;
3142 
3143   EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
3144                     AuthCredentials(kFoo, kBar), callback2.callback())));
3145 
3146   LoadTimingInfo load_timing_info2;
3147   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
3148   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
3149   // The load timing after restart should have a new socket ID, and times after
3150   // those of the first load timing.
3151   EXPECT_LE(load_timing_info1.receive_headers_end,
3152             load_timing_info2.connect_timing.connect_start);
3153   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3154 
3155   int64_t writes_size2 = CountWriteBytes(data_writes2);
3156   EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
3157   int64_t reads_size2 = CountReadBytes(data_reads2);
3158   EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
3159 
3160   response = trans.GetResponseInfo();
3161   ASSERT_TRUE(response);
3162   EXPECT_FALSE(response->auth_challenge.has_value());
3163   EXPECT_EQ(100, response->headers->GetContentLength());
3164 
3165   EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
3166   ASSERT_FALSE(endpoint.address().empty());
3167   EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
3168 }
3169 
3170 // Test that, if the server requests auth indefinitely, HttpNetworkTransaction
3171 // will eventually give up.
TEST_P(HttpNetworkTransactionTest,BasicAuthForever)3172 TEST_P(HttpNetworkTransactionTest, BasicAuthForever) {
3173   HttpRequestInfo request;
3174   request.method = "GET";
3175   request.url = GURL("http://www.example.org/");
3176   request.traffic_annotation =
3177       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3178 
3179   session_deps_.net_log = net::NetLog::Get();
3180   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3181   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3182 
3183   MockWrite data_writes[] = {
3184       MockWrite("GET / HTTP/1.1\r\n"
3185                 "Host: www.example.org\r\n"
3186                 "Connection: keep-alive\r\n\r\n"),
3187   };
3188 
3189   MockRead data_reads[] = {
3190       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3191       // Give a couple authenticate options (only the middle one is actually
3192       // supported).
3193       MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
3194       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3195       MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
3196       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3197       // Large content-length -- won't matter, as connection will be reset.
3198       MockRead("Content-Length: 10000\r\n\r\n"),
3199       MockRead(SYNCHRONOUS, ERR_FAILED),
3200   };
3201 
3202   // After calling trans->RestartWithAuth(), this is the request we should
3203   // be issuing -- the final header line contains the credentials.
3204   MockWrite data_writes_restart[] = {
3205       MockWrite("GET / HTTP/1.1\r\n"
3206                 "Host: www.example.org\r\n"
3207                 "Connection: keep-alive\r\n"
3208                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3209   };
3210 
3211   StaticSocketDataProvider data(data_reads, data_writes);
3212   session_deps_.socket_factory->AddSocketDataProvider(&data);
3213 
3214   TestCompletionCallback callback;
3215   int rv = callback.GetResult(
3216       trans.Start(&request, callback.callback(), NetLogWithSource()));
3217 
3218   std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
3219   for (int i = 0; i < 32; i++) {
3220     // Check the previous response was a 401.
3221     EXPECT_THAT(rv, IsOk());
3222     const HttpResponseInfo* response = trans.GetResponseInfo();
3223     ASSERT_TRUE(response);
3224     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
3225 
3226     data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
3227         data_reads, data_writes_restart));
3228     session_deps_.socket_factory->AddSocketDataProvider(
3229         data_restarts.back().get());
3230     rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
3231                                                   callback.callback()));
3232   }
3233 
3234   // After too many tries, the transaction should have given up.
3235   EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
3236 }
3237 
TEST_P(HttpNetworkTransactionTest,DoNotSendAuth)3238 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
3239   HttpRequestInfo request;
3240   request.method = "GET";
3241   request.url = GURL("http://www.example.org/");
3242   request.privacy_mode = PRIVACY_MODE_ENABLED;
3243   request.traffic_annotation =
3244       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3245 
3246   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3247   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3248 
3249   MockWrite data_writes[] = {
3250       MockWrite("GET / HTTP/1.1\r\n"
3251                 "Host: www.example.org\r\n"
3252                 "Connection: keep-alive\r\n\r\n"),
3253   };
3254 
3255   MockRead data_reads[] = {
3256       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3257       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3258       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3259       // Large content-length -- won't matter, as connection will be reset.
3260       MockRead("Content-Length: 10000\r\n\r\n"),
3261       MockRead(SYNCHRONOUS, ERR_FAILED),
3262   };
3263 
3264   StaticSocketDataProvider data(data_reads, data_writes);
3265   session_deps_.socket_factory->AddSocketDataProvider(&data);
3266   TestCompletionCallback callback;
3267 
3268   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
3269   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3270 
3271   rv = callback.WaitForResult();
3272   EXPECT_EQ(0, rv);
3273 
3274   int64_t writes_size = CountWriteBytes(data_writes);
3275   EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
3276   int64_t reads_size = CountReadBytes(data_reads);
3277   EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
3278 
3279   const HttpResponseInfo* response = trans.GetResponseInfo();
3280   ASSERT_TRUE(response);
3281   EXPECT_FALSE(response->auth_challenge.has_value());
3282 }
3283 
3284 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
3285 // connection.
TEST_P(HttpNetworkTransactionTest,BasicAuthKeepAlive)3286 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
3287   // On the second pass, the body read of the auth challenge is synchronous, so
3288   // IsConnectedAndIdle returns false.  The socket should still be drained and
3289   // reused.  See http://crbug.com/544255.
3290   for (int i = 0; i < 2; ++i) {
3291     HttpRequestInfo request;
3292     request.method = "GET";
3293     request.url = GURL("http://www.example.org/");
3294     request.traffic_annotation =
3295         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3296 
3297     session_deps_.net_log = net::NetLog::Get();
3298     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3299 
3300     MockWrite data_writes[] = {
3301         MockWrite(ASYNC, 0,
3302                   "GET / HTTP/1.1\r\n"
3303                   "Host: www.example.org\r\n"
3304                   "Connection: keep-alive\r\n\r\n"),
3305 
3306         // After calling trans.RestartWithAuth(), this is the request we should
3307         // be issuing -- the final header line contains the credentials.
3308         MockWrite(ASYNC, 6,
3309                   "GET / HTTP/1.1\r\n"
3310                   "Host: www.example.org\r\n"
3311                   "Connection: keep-alive\r\n"
3312                   "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3313     };
3314 
3315     MockRead data_reads[] = {
3316         MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
3317         MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3318         MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
3319         MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
3320         MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
3321 
3322         // Lastly, the server responds with the actual content.
3323         MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
3324         MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
3325         MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
3326         MockRead(ASYNC, 10, "Hello"),
3327     };
3328 
3329     SequencedSocketData data(data_reads, data_writes);
3330     data.set_busy_before_sync_reads(true);
3331     session_deps_.socket_factory->AddSocketDataProvider(&data);
3332 
3333     TestCompletionCallback callback1;
3334 
3335     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3336     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
3337     ASSERT_THAT(callback1.GetResult(rv), IsOk());
3338 
3339     LoadTimingInfo load_timing_info1;
3340     EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
3341     TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
3342 
3343     const HttpResponseInfo* response = trans.GetResponseInfo();
3344     ASSERT_TRUE(response);
3345     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
3346 
3347     TestCompletionCallback callback2;
3348 
3349     rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
3350                                callback2.callback());
3351     ASSERT_THAT(callback2.GetResult(rv), IsOk());
3352 
3353     LoadTimingInfo load_timing_info2;
3354     EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
3355     TestLoadTimingReused(load_timing_info2);
3356     // The load timing after restart should have the same socket ID, and times
3357     // those of the first load timing.
3358     EXPECT_LE(load_timing_info1.receive_headers_end,
3359               load_timing_info2.send_start);
3360     EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3361 
3362     response = trans.GetResponseInfo();
3363     ASSERT_TRUE(response);
3364     EXPECT_FALSE(response->auth_challenge.has_value());
3365     EXPECT_EQ(5, response->headers->GetContentLength());
3366 
3367     std::string response_data;
3368     EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
3369 
3370     int64_t writes_size = CountWriteBytes(data_writes);
3371     EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
3372     int64_t reads_size = CountReadBytes(data_reads);
3373     EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
3374   }
3375 }
3376 
3377 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
3378 // connection and with no response body to drain.
TEST_P(HttpNetworkTransactionTest,BasicAuthKeepAliveNoBody)3379 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
3380   HttpRequestInfo request;
3381   request.method = "GET";
3382   request.url = GURL("http://www.example.org/");
3383   request.traffic_annotation =
3384       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3385 
3386   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3387 
3388   MockWrite data_writes1[] = {
3389       MockWrite("GET / HTTP/1.1\r\n"
3390                 "Host: www.example.org\r\n"
3391                 "Connection: keep-alive\r\n\r\n"),
3392 
3393       // After calling trans.RestartWithAuth(), this is the request we should
3394       // be issuing -- the final header line contains the credentials.
3395       MockWrite("GET / HTTP/1.1\r\n"
3396                 "Host: www.example.org\r\n"
3397                 "Connection: keep-alive\r\n"
3398                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3399   };
3400 
3401   MockRead data_reads1[] = {
3402       MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3403       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3404       MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
3405 
3406       // Lastly, the server responds with the actual content.
3407       MockRead("HTTP/1.1 200 OK\r\n"),
3408       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3409       MockRead("Content-Length: 5\r\n\r\n"),
3410       MockRead("hello"),
3411   };
3412 
3413   // An incorrect reconnect would cause this to be read.
3414   MockRead data_reads2[] = {
3415       MockRead(SYNCHRONOUS, ERR_FAILED),
3416   };
3417 
3418   StaticSocketDataProvider data1(data_reads1, data_writes1);
3419   StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
3420   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3421   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3422 
3423   TestCompletionCallback callback1;
3424 
3425   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3426   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
3427   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3428 
3429   rv = callback1.WaitForResult();
3430   EXPECT_THAT(rv, IsOk());
3431 
3432   const HttpResponseInfo* response = trans.GetResponseInfo();
3433   ASSERT_TRUE(response);
3434   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
3435 
3436   TestCompletionCallback callback2;
3437 
3438   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3439   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3440 
3441   rv = callback2.WaitForResult();
3442   EXPECT_THAT(rv, IsOk());
3443 
3444   response = trans.GetResponseInfo();
3445   ASSERT_TRUE(response);
3446   EXPECT_FALSE(response->auth_challenge.has_value());
3447   EXPECT_EQ(5, response->headers->GetContentLength());
3448 }
3449 
3450 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
3451 // connection and with a large response body to drain.
TEST_P(HttpNetworkTransactionTest,BasicAuthKeepAliveLargeBody)3452 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
3453   HttpRequestInfo request;
3454   request.method = "GET";
3455   request.url = GURL("http://www.example.org/");
3456   request.traffic_annotation =
3457       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3458 
3459   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3460 
3461   MockWrite data_writes1[] = {
3462       MockWrite("GET / HTTP/1.1\r\n"
3463                 "Host: www.example.org\r\n"
3464                 "Connection: keep-alive\r\n\r\n"),
3465 
3466       // After calling trans.RestartWithAuth(), this is the request we should
3467       // be issuing -- the final header line contains the credentials.
3468       MockWrite("GET / HTTP/1.1\r\n"
3469                 "Host: www.example.org\r\n"
3470                 "Connection: keep-alive\r\n"
3471                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3472   };
3473 
3474   // Respond with 5 kb of response body.
3475   std::string large_body_string("Unauthorized");
3476   large_body_string.append(5 * 1024, ' ');
3477   large_body_string.append("\r\n");
3478 
3479   MockRead data_reads1[] = {
3480       MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3481       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3482       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3483       // 5134 = 12 + 5 * 1024 + 2
3484       MockRead("Content-Length: 5134\r\n\r\n"),
3485       MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
3486 
3487       // Lastly, the server responds with the actual content.
3488       MockRead("HTTP/1.1 200 OK\r\n"),
3489       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3490       MockRead("Content-Length: 5\r\n\r\n"),
3491       MockRead("hello"),
3492   };
3493 
3494   // An incorrect reconnect would cause this to be read.
3495   MockRead data_reads2[] = {
3496       MockRead(SYNCHRONOUS, ERR_FAILED),
3497   };
3498 
3499   StaticSocketDataProvider data1(data_reads1, data_writes1);
3500   StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
3501   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3502   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3503 
3504   TestCompletionCallback callback1;
3505 
3506   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3507   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
3508   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3509 
3510   rv = callback1.WaitForResult();
3511   EXPECT_THAT(rv, IsOk());
3512 
3513   const HttpResponseInfo* response = trans.GetResponseInfo();
3514   ASSERT_TRUE(response);
3515   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
3516 
3517   TestCompletionCallback callback2;
3518 
3519   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3520   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3521 
3522   rv = callback2.WaitForResult();
3523   EXPECT_THAT(rv, IsOk());
3524 
3525   response = trans.GetResponseInfo();
3526   ASSERT_TRUE(response);
3527   EXPECT_FALSE(response->auth_challenge.has_value());
3528   EXPECT_EQ(5, response->headers->GetContentLength());
3529 }
3530 
3531 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
3532 // connection, but the server gets impatient and closes the connection.
TEST_P(HttpNetworkTransactionTest,BasicAuthKeepAliveImpatientServer)3533 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
3534   HttpRequestInfo request;
3535   request.method = "GET";
3536   request.url = GURL("http://www.example.org/");
3537   request.traffic_annotation =
3538       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3539 
3540   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3541 
3542   MockWrite data_writes1[] = {
3543       MockWrite("GET / HTTP/1.1\r\n"
3544                 "Host: www.example.org\r\n"
3545                 "Connection: keep-alive\r\n\r\n"),
3546       // This simulates the seemingly successful write to a closed connection
3547       // if the bug is not fixed.
3548       MockWrite("GET / HTTP/1.1\r\n"
3549                 "Host: www.example.org\r\n"
3550                 "Connection: keep-alive\r\n"
3551                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3552   };
3553 
3554   MockRead data_reads1[] = {
3555       MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3556       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3557       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3558       MockRead("Content-Length: 14\r\n\r\n"),
3559       // Tell MockTCPClientSocket to simulate the server closing the connection.
3560       MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3561       MockRead("Unauthorized\r\n"),
3562       MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
3563   };
3564 
3565   // After calling trans.RestartWithAuth(), this is the request we should
3566   // be issuing -- the final header line contains the credentials.
3567   MockWrite data_writes2[] = {
3568       MockWrite("GET / HTTP/1.1\r\n"
3569                 "Host: www.example.org\r\n"
3570                 "Connection: keep-alive\r\n"
3571                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3572   };
3573 
3574   // Lastly, the server responds with the actual content.
3575   MockRead data_reads2[] = {
3576       MockRead("HTTP/1.1 200 OK\r\n"),
3577       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3578       MockRead("Content-Length: 5\r\n\r\n"),
3579       MockRead("hello"),
3580   };
3581 
3582   StaticSocketDataProvider data1(data_reads1, data_writes1);
3583   StaticSocketDataProvider data2(data_reads2, data_writes2);
3584   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3585   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3586 
3587   TestCompletionCallback callback1;
3588 
3589   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3590   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
3591   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3592 
3593   rv = callback1.WaitForResult();
3594   EXPECT_THAT(rv, IsOk());
3595 
3596   const HttpResponseInfo* response = trans.GetResponseInfo();
3597   ASSERT_TRUE(response);
3598   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
3599 
3600   TestCompletionCallback callback2;
3601 
3602   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3603   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3604 
3605   rv = callback2.WaitForResult();
3606   EXPECT_THAT(rv, IsOk());
3607 
3608   response = trans.GetResponseInfo();
3609   ASSERT_TRUE(response);
3610   EXPECT_FALSE(response->auth_challenge.has_value());
3611   EXPECT_EQ(5, response->headers->GetContentLength());
3612 }
3613 
3614 // Test the request-challenge-retry sequence for basic auth, over a connection
3615 // that requires a restart when setting up an SSL tunnel.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyNoKeepAliveHttp10)3616 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
3617   HttpRequestInfo request;
3618   request.method = "GET";
3619   request.url = GURL("https://www.example.org/");
3620   // when the no authentication data flag is set.
3621   request.privacy_mode = PRIVACY_MODE_ENABLED;
3622   request.traffic_annotation =
3623       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3624 
3625   // Configure against proxy server "myproxy:70".
3626   session_deps_.proxy_resolution_service =
3627       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
3628           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
3629   RecordingNetLogObserver net_log_observer;
3630   NetLogWithSource net_log_with_source =
3631       NetLogWithSource::Make(NetLogSourceType::NONE);
3632   session_deps_.net_log = NetLog::Get();
3633   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3634 
3635   // Since we have proxy, should try to establish tunnel.
3636   MockWrite data_writes1[] = {
3637       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3638                 "Host: www.example.org:443\r\n"
3639                 "Proxy-Connection: keep-alive\r\n\r\n"),
3640   };
3641 
3642   // The proxy responds to the connect with a 407, using a non-persistent
3643   // connection.
3644   MockRead data_reads1[] = {
3645       // No credentials.
3646       MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3647       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
3648   };
3649 
3650   // Since the first connection couldn't be reused, need to establish another
3651   // once given credentials.
3652   MockWrite data_writes2[] = {
3653       // After calling trans->RestartWithAuth(), this is the request we should
3654       // be issuing -- the final header line contains the credentials.
3655       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3656                 "Host: www.example.org:443\r\n"
3657                 "Proxy-Connection: keep-alive\r\n"
3658                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3659 
3660       MockWrite("GET / HTTP/1.1\r\n"
3661                 "Host: www.example.org\r\n"
3662                 "Connection: keep-alive\r\n\r\n"),
3663   };
3664 
3665   MockRead data_reads2[] = {
3666       MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3667 
3668       MockRead("HTTP/1.1 200 OK\r\n"),
3669       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3670       MockRead("Content-Length: 5\r\n\r\n"),
3671       MockRead(SYNCHRONOUS, "hello"),
3672   };
3673 
3674   StaticSocketDataProvider data1(data_reads1, data_writes1);
3675   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3676   StaticSocketDataProvider data2(data_reads2, data_writes2);
3677   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3678   SSLSocketDataProvider ssl(ASYNC, OK);
3679   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3680 
3681   TestCompletionCallback callback1;
3682   ConnectedHandler connected_handler;
3683 
3684   auto trans =
3685       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
3686 
3687   trans->SetConnectedCallback(connected_handler.Callback());
3688 
3689   int rv = trans->Start(&request, callback1.callback(), net_log_with_source);
3690   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3691 
3692   rv = callback1.WaitForResult();
3693   EXPECT_THAT(rv, IsOk());
3694   auto entries = net_log_observer.GetEntries();
3695   size_t pos = ExpectLogContainsSomewhere(
3696       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3697       NetLogEventPhase::NONE);
3698   ExpectLogContainsSomewhere(
3699       entries, pos,
3700       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3701       NetLogEventPhase::NONE);
3702 
3703   // TODO(crbug.com/986744): Fix handling of OnConnected() when proxy
3704   // authentication is required. We should notify the callback that a connection
3705   // was established, even though the stream might not be ready for us to send
3706   // data through it.
3707   EXPECT_THAT(connected_handler.transports(), IsEmpty());
3708 
3709   const HttpResponseInfo* response = trans->GetResponseInfo();
3710   ASSERT_TRUE(response);
3711   EXPECT_FALSE(response->headers->IsKeepAlive());
3712   ASSERT_TRUE(response->headers);
3713   EXPECT_EQ(407, response->headers->response_code());
3714   EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3715   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
3716 
3717   LoadTimingInfo load_timing_info;
3718   // CONNECT requests and responses are handled at the connect job level, so
3719   // the transaction does not yet have a connection.
3720   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3721 
3722   TestCompletionCallback callback2;
3723 
3724   rv =
3725       trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3726   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3727 
3728   rv = callback2.WaitForResult();
3729   EXPECT_THAT(rv, IsOk());
3730 
3731   response = trans->GetResponseInfo();
3732   ASSERT_TRUE(response);
3733 
3734   EXPECT_TRUE(response->headers->IsKeepAlive());
3735   EXPECT_EQ(200, response->headers->response_code());
3736   EXPECT_EQ(5, response->headers->GetContentLength());
3737   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3738 
3739   TransportInfo expected_transport;
3740   expected_transport.type = TransportType::kProxied;
3741   expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 70);
3742   expected_transport.negotiated_protocol = kProtoUnknown;
3743   EXPECT_THAT(connected_handler.transports(), ElementsAre(expected_transport));
3744 
3745   // Check that credentials were successfully cached, with the right target.
3746   HttpAuthCache::Entry* entry = session->http_auth_cache()->Lookup(
3747       url::SchemeHostPort(url::SchemeHostPort(GURL("http://myproxy:70"))),
3748       HttpAuth::AUTH_PROXY, "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
3749       NetworkAnonymizationKey());
3750   ASSERT_TRUE(entry);
3751   ASSERT_EQ(kFoo, entry->credentials().username());
3752   ASSERT_EQ(kBar, entry->credentials().password());
3753 
3754   // The password prompt info should not be set.
3755   EXPECT_FALSE(response->auth_challenge.has_value());
3756 
3757   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3758   TestLoadTimingNotReusedWithPac(load_timing_info,
3759                                  CONNECT_TIMING_HAS_SSL_TIMES);
3760 
3761   trans.reset();
3762   session->CloseAllConnections(ERR_FAILED, "Very good reason");
3763 }
3764 
3765 // Test the request-challenge-retry sequence for basic auth, over a connection
3766 // that requires a restart when setting up an SSL tunnel.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyNoKeepAliveHttp11)3767 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
3768   HttpRequestInfo request;
3769   request.method = "GET";
3770   request.url = GURL("https://www.example.org/");
3771   // when the no authentication data flag is set.
3772   request.privacy_mode = PRIVACY_MODE_ENABLED;
3773   request.traffic_annotation =
3774       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3775 
3776   // Configure against proxy server "myproxy:70".
3777   session_deps_.proxy_resolution_service =
3778       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
3779           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
3780   RecordingNetLogObserver net_log_observer;
3781   session_deps_.net_log = NetLog::Get();
3782   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3783 
3784   // Since we have proxy, should try to establish tunnel.
3785   MockWrite data_writes1[] = {
3786       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3787                 "Host: www.example.org:443\r\n"
3788                 "Proxy-Connection: keep-alive\r\n\r\n"),
3789   };
3790 
3791   // The proxy responds to the connect with a 407, using a non-persistent
3792   // connection.
3793   MockRead data_reads1[] = {
3794       // No credentials.
3795       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3796       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3797       MockRead("Proxy-Connection: close\r\n\r\n"),
3798   };
3799 
3800   MockWrite data_writes2[] = {
3801       // After calling trans->RestartWithAuth(), this is the request we should
3802       // be issuing -- the final header line contains the credentials.
3803       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3804                 "Host: www.example.org:443\r\n"
3805                 "Proxy-Connection: keep-alive\r\n"
3806                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3807 
3808       MockWrite("GET / HTTP/1.1\r\n"
3809                 "Host: www.example.org\r\n"
3810                 "Connection: keep-alive\r\n\r\n"),
3811   };
3812 
3813   MockRead data_reads2[] = {
3814       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3815 
3816       MockRead("HTTP/1.1 200 OK\r\n"),
3817       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3818       MockRead("Content-Length: 5\r\n\r\n"),
3819       MockRead(SYNCHRONOUS, "hello"),
3820   };
3821 
3822   StaticSocketDataProvider data1(data_reads1, data_writes1);
3823   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3824   StaticSocketDataProvider data2(data_reads2, data_writes2);
3825   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3826   SSLSocketDataProvider ssl(ASYNC, OK);
3827   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3828 
3829   ConnectedHandler connected_handler;
3830   TestCompletionCallback callback1;
3831 
3832   auto trans =
3833       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
3834 
3835   trans->SetConnectedCallback(connected_handler.Callback());
3836 
3837   int rv = trans->Start(&request, callback1.callback(),
3838                         NetLogWithSource::Make(NetLogSourceType::NONE));
3839   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3840 
3841   rv = callback1.WaitForResult();
3842   EXPECT_THAT(rv, IsOk());
3843   auto entries = net_log_observer.GetEntries();
3844   size_t pos = ExpectLogContainsSomewhere(
3845       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3846       NetLogEventPhase::NONE);
3847   ExpectLogContainsSomewhere(
3848       entries, pos,
3849       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3850       NetLogEventPhase::NONE);
3851 
3852   const HttpResponseInfo* response = trans->GetResponseInfo();
3853   ASSERT_TRUE(response);
3854   EXPECT_FALSE(response->headers->IsKeepAlive());
3855   ASSERT_TRUE(response->headers);
3856   EXPECT_EQ(407, response->headers->response_code());
3857   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3858   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
3859   EXPECT_EQ(PacResultElementToProxyChain("PROXY myproxy:70"),
3860             response->proxy_chain);
3861 
3862   // TODO(crbug.com/986744): Fix handling of OnConnected() when proxy
3863   // authentication is required. We should notify the callback that a connection
3864   // was established, even though the stream might not be ready for us to send
3865   // data through it.
3866   EXPECT_THAT(connected_handler.transports(), IsEmpty());
3867 
3868   LoadTimingInfo load_timing_info;
3869   // CONNECT requests and responses are handled at the connect job level, so
3870   // the transaction does not yet have a connection.
3871   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3872 
3873   TestCompletionCallback callback2;
3874 
3875   rv =
3876       trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3877   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3878 
3879   rv = callback2.WaitForResult();
3880   EXPECT_THAT(rv, IsOk());
3881 
3882   response = trans->GetResponseInfo();
3883   ASSERT_TRUE(response);
3884 
3885   EXPECT_TRUE(response->headers->IsKeepAlive());
3886   EXPECT_EQ(200, response->headers->response_code());
3887   EXPECT_EQ(5, response->headers->GetContentLength());
3888   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3889   EXPECT_EQ(PacResultElementToProxyChain("PROXY myproxy:70"),
3890             response->proxy_chain);
3891 
3892   TransportInfo expected_transport;
3893   expected_transport.type = TransportType::kProxied;
3894   expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 70);
3895   expected_transport.negotiated_protocol = kProtoUnknown;
3896   EXPECT_THAT(connected_handler.transports(), ElementsAre(expected_transport));
3897 
3898   // The password prompt info should not be set.
3899   EXPECT_FALSE(response->auth_challenge.has_value());
3900 
3901   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3902   TestLoadTimingNotReusedWithPac(load_timing_info,
3903                                  CONNECT_TIMING_HAS_SSL_TIMES);
3904 
3905   trans.reset();
3906   session->CloseAllConnections(ERR_FAILED, "Very good reason");
3907 }
3908 
3909 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
3910 // proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyKeepAliveHttp10)3911 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
3912   // On the second pass, the body read of the auth challenge is synchronous, so
3913   // IsConnectedAndIdle returns false.  The socket should still be drained and
3914   // reused.  See http://crbug.com/544255.
3915   for (int i = 0; i < 2; ++i) {
3916     HttpRequestInfo request;
3917     request.method = "GET";
3918     request.url = GURL("https://www.example.org/");
3919     // Ensure that proxy authentication is attempted even
3920     // when the no authentication data flag is set.
3921     request.privacy_mode = PRIVACY_MODE_ENABLED;
3922     request.traffic_annotation =
3923         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3924 
3925     // Configure against proxy server "myproxy:70".
3926     session_deps_.proxy_resolution_service =
3927         ConfiguredProxyResolutionService::CreateFixedForTest(
3928             "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
3929     RecordingNetLogObserver net_log_observer;
3930     session_deps_.net_log = NetLog::Get();
3931     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3932 
3933     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3934 
3935     // Since we have proxy, should try to establish tunnel.
3936     MockWrite data_writes1[] = {
3937         MockWrite(ASYNC, 0,
3938                   "CONNECT www.example.org:443 HTTP/1.1\r\n"
3939                   "Host: www.example.org:443\r\n"
3940                   "Proxy-Connection: keep-alive\r\n\r\n"),
3941 
3942         // After calling trans.RestartWithAuth(), this is the request we should
3943         // be issuing -- the final header line contains the credentials.
3944         MockWrite(ASYNC, 3,
3945                   "CONNECT www.example.org:443 HTTP/1.1\r\n"
3946                   "Host: www.example.org:443\r\n"
3947                   "Proxy-Connection: keep-alive\r\n"
3948                   "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3949     };
3950 
3951     // The proxy responds to the connect with a 407, using a persistent
3952     // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3953     MockRead data_reads1[] = {
3954         // No credentials.
3955         MockRead(ASYNC, 1,
3956                  "HTTP/1.0 407 Proxy Authentication Required\r\n"
3957                  "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3958                  "Proxy-Connection: keep-alive\r\n"
3959                  "Content-Length: 10\r\n\r\n"),
3960         MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3961 
3962         // Wrong credentials (wrong password).
3963         MockRead(ASYNC, 4,
3964                  "HTTP/1.0 407 Proxy Authentication Required\r\n"
3965                  "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3966                  "Proxy-Connection: keep-alive\r\n"
3967                  "Content-Length: 10\r\n\r\n"),
3968         // No response body because the test stops reading here.
3969         MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3970     };
3971 
3972     SequencedSocketData data1(data_reads1, data_writes1);
3973     data1.set_busy_before_sync_reads(true);
3974     session_deps_.socket_factory->AddSocketDataProvider(&data1);
3975 
3976     TestCompletionCallback callback1;
3977 
3978     int rv = trans.Start(&request, callback1.callback(),
3979                          NetLogWithSource::Make(NetLogSourceType::NONE));
3980     EXPECT_THAT(callback1.GetResult(rv), IsOk());
3981 
3982     auto entries = net_log_observer.GetEntries();
3983     size_t pos = ExpectLogContainsSomewhere(
3984         entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3985         NetLogEventPhase::NONE);
3986     ExpectLogContainsSomewhere(
3987         entries, pos,
3988         NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3989         NetLogEventPhase::NONE);
3990 
3991     const HttpResponseInfo* response = trans.GetResponseInfo();
3992     ASSERT_TRUE(response);
3993     ASSERT_TRUE(response->headers);
3994     EXPECT_TRUE(response->headers->IsKeepAlive());
3995     EXPECT_EQ(407, response->headers->response_code());
3996     EXPECT_EQ(10, response->headers->GetContentLength());
3997     EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3998     EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
3999 
4000     TestCompletionCallback callback2;
4001 
4002     // Wrong password (should be "bar").
4003     rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
4004                                callback2.callback());
4005     EXPECT_THAT(callback2.GetResult(rv), IsOk());
4006 
4007     response = trans.GetResponseInfo();
4008     ASSERT_TRUE(response);
4009     ASSERT_TRUE(response->headers);
4010     EXPECT_TRUE(response->headers->IsKeepAlive());
4011     EXPECT_EQ(407, response->headers->response_code());
4012     EXPECT_EQ(10, response->headers->GetContentLength());
4013     EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
4014     EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
4015 
4016     // Flush the idle socket before the NetLog and HttpNetworkTransaction go
4017     // out of scope.
4018     session->CloseAllConnections(ERR_FAILED, "Very good reason");
4019   }
4020 }
4021 
4022 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
4023 // proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyKeepAliveHttp11)4024 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
4025   // On the second pass, the body read of the auth challenge is synchronous, so
4026   // IsConnectedAndIdle returns false.  The socket should still be drained and
4027   // reused.  See http://crbug.com/544255.
4028   for (int i = 0; i < 2; ++i) {
4029     HttpRequestInfo request;
4030     request.method = "GET";
4031     request.url = GURL("https://www.example.org/");
4032     // Ensure that proxy authentication is attempted even
4033     // when the no authentication data flag is set.
4034     request.privacy_mode = PRIVACY_MODE_ENABLED;
4035     request.traffic_annotation =
4036         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4037 
4038     // Configure against proxy server "myproxy:70".
4039     session_deps_.proxy_resolution_service =
4040         ConfiguredProxyResolutionService::CreateFixedForTest(
4041             "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4042     RecordingNetLogObserver net_log_observer;
4043     session_deps_.net_log = NetLog::Get();
4044     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4045 
4046     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
4047 
4048     // Since we have proxy, should try to establish tunnel.
4049     MockWrite data_writes1[] = {
4050         MockWrite(ASYNC, 0,
4051                   "CONNECT www.example.org:443 HTTP/1.1\r\n"
4052                   "Host: www.example.org:443\r\n"
4053                   "Proxy-Connection: keep-alive\r\n\r\n"),
4054 
4055         // After calling trans.RestartWithAuth(), this is the request we should
4056         // be issuing -- the final header line contains the credentials.
4057         MockWrite(ASYNC, 3,
4058                   "CONNECT www.example.org:443 HTTP/1.1\r\n"
4059                   "Host: www.example.org:443\r\n"
4060                   "Proxy-Connection: keep-alive\r\n"
4061                   "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
4062     };
4063 
4064     // The proxy responds to the connect with a 407, using a persistent
4065     // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
4066     MockRead data_reads1[] = {
4067         // No credentials.
4068         MockRead(ASYNC, 1,
4069                  "HTTP/1.1 407 Proxy Authentication Required\r\n"
4070                  "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4071                  "Content-Length: 10\r\n\r\n"),
4072         MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
4073 
4074         // Wrong credentials (wrong password).
4075         MockRead(ASYNC, 4,
4076                  "HTTP/1.1 407 Proxy Authentication Required\r\n"
4077                  "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4078                  "Content-Length: 10\r\n\r\n"),
4079         // No response body because the test stops reading here.
4080         MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
4081     };
4082 
4083     SequencedSocketData data1(data_reads1, data_writes1);
4084     data1.set_busy_before_sync_reads(true);
4085     session_deps_.socket_factory->AddSocketDataProvider(&data1);
4086 
4087     TestCompletionCallback callback1;
4088 
4089     int rv = trans.Start(&request, callback1.callback(),
4090                          NetLogWithSource::Make(NetLogSourceType::NONE));
4091     EXPECT_THAT(callback1.GetResult(rv), IsOk());
4092 
4093     auto entries = net_log_observer.GetEntries();
4094     size_t pos = ExpectLogContainsSomewhere(
4095         entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4096         NetLogEventPhase::NONE);
4097     ExpectLogContainsSomewhere(
4098         entries, pos,
4099         NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4100         NetLogEventPhase::NONE);
4101 
4102     const HttpResponseInfo* response = trans.GetResponseInfo();
4103     ASSERT_TRUE(response);
4104     ASSERT_TRUE(response->headers);
4105     EXPECT_TRUE(response->headers->IsKeepAlive());
4106     EXPECT_EQ(407, response->headers->response_code());
4107     EXPECT_EQ(10, response->headers->GetContentLength());
4108     EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4109     EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
4110     EXPECT_FALSE(response->did_use_http_auth);
4111     EXPECT_EQ(PacResultElementToProxyChain("PROXY myproxy:70"),
4112               response->proxy_chain);
4113 
4114     TestCompletionCallback callback2;
4115 
4116     // Wrong password (should be "bar").
4117     rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
4118                                callback2.callback());
4119     EXPECT_THAT(callback2.GetResult(rv), IsOk());
4120 
4121     response = trans.GetResponseInfo();
4122     ASSERT_TRUE(response);
4123     ASSERT_TRUE(response->headers);
4124     EXPECT_TRUE(response->headers->IsKeepAlive());
4125     EXPECT_EQ(407, response->headers->response_code());
4126     EXPECT_EQ(10, response->headers->GetContentLength());
4127     EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4128     EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
4129     EXPECT_TRUE(response->did_use_http_auth);
4130     EXPECT_EQ(PacResultElementToProxyChain("PROXY myproxy:70"),
4131               response->proxy_chain);
4132 
4133     // Flush the idle socket before the NetLog and HttpNetworkTransaction go
4134     // out of scope.
4135     session->CloseAllConnections(ERR_FAILED, "Very good reason");
4136   }
4137 }
4138 
4139 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
4140 // proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
4141 // the case the server sends extra data on the original socket, so it can't be
4142 // reused.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyKeepAliveExtraData)4143 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
4144   HttpRequestInfo request;
4145   request.method = "GET";
4146   request.url = GURL("https://www.example.org/");
4147   // when the no authentication data flag is set.
4148   request.privacy_mode = PRIVACY_MODE_ENABLED;
4149   request.traffic_annotation =
4150       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4151 
4152   // Configure against proxy server "myproxy:70".
4153   session_deps_.proxy_resolution_service =
4154       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
4155           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4156   RecordingNetLogObserver net_log_observer;
4157   session_deps_.net_log = NetLog::Get();
4158   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4159 
4160   // Since we have proxy, should try to establish tunnel.
4161   MockWrite data_writes1[] = {
4162       MockWrite(ASYNC, 0,
4163                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4164                 "Host: www.example.org:443\r\n"
4165                 "Proxy-Connection: keep-alive\r\n\r\n"),
4166   };
4167 
4168   // The proxy responds to the connect with a 407, using a persistent, but sends
4169   // extra data, so the socket cannot be reused.
4170   MockRead data_reads1[] = {
4171       // No credentials.
4172       MockRead(ASYNC, 1,
4173                "HTTP/1.1 407 Proxy Authentication Required\r\n"
4174                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4175                "Content-Length: 10\r\n\r\n"),
4176       MockRead(SYNCHRONOUS, 2, "0123456789"),
4177       MockRead(SYNCHRONOUS, 3, "I'm broken!"),
4178   };
4179 
4180   MockWrite data_writes2[] = {
4181       // After calling trans->RestartWithAuth(), this is the request we should
4182       // be issuing -- the final header line contains the credentials.
4183       MockWrite(ASYNC, 0,
4184                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4185                 "Host: www.example.org:443\r\n"
4186                 "Proxy-Connection: keep-alive\r\n"
4187                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4188 
4189       MockWrite(ASYNC, 2,
4190                 "GET / HTTP/1.1\r\n"
4191                 "Host: www.example.org\r\n"
4192                 "Connection: keep-alive\r\n\r\n"),
4193   };
4194 
4195   MockRead data_reads2[] = {
4196       MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
4197 
4198       MockRead(ASYNC, 3,
4199                "HTTP/1.1 200 OK\r\n"
4200                "Content-Type: text/html; charset=iso-8859-1\r\n"
4201                "Content-Length: 5\r\n\r\n"),
4202       // No response body because the test stops reading here.
4203       MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
4204   };
4205 
4206   SequencedSocketData data1(data_reads1, data_writes1);
4207   data1.set_busy_before_sync_reads(true);
4208   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4209   SequencedSocketData data2(data_reads2, data_writes2);
4210   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4211   SSLSocketDataProvider ssl(ASYNC, OK);
4212   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4213 
4214   TestCompletionCallback callback1;
4215 
4216   auto trans =
4217       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4218 
4219   int rv = trans->Start(&request, callback1.callback(),
4220                         NetLogWithSource::Make(NetLogSourceType::NONE));
4221   EXPECT_THAT(callback1.GetResult(rv), IsOk());
4222 
4223   auto entries = net_log_observer.GetEntries();
4224   size_t pos = ExpectLogContainsSomewhere(
4225       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4226       NetLogEventPhase::NONE);
4227   ExpectLogContainsSomewhere(
4228       entries, pos,
4229       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4230       NetLogEventPhase::NONE);
4231 
4232   const HttpResponseInfo* response = trans->GetResponseInfo();
4233   ASSERT_TRUE(response);
4234   ASSERT_TRUE(response->headers);
4235   EXPECT_TRUE(response->headers->IsKeepAlive());
4236   EXPECT_EQ(407, response->headers->response_code());
4237   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4238   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
4239 
4240   LoadTimingInfo load_timing_info;
4241   // CONNECT requests and responses are handled at the connect job level, so
4242   // the transaction does not yet have a connection.
4243   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4244 
4245   TestCompletionCallback callback2;
4246 
4247   rv =
4248       trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
4249   EXPECT_THAT(callback2.GetResult(rv), IsOk());
4250 
4251   EXPECT_TRUE(response->headers->IsKeepAlive());
4252   EXPECT_EQ(200, response->headers->response_code());
4253   EXPECT_EQ(5, response->headers->GetContentLength());
4254   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4255 
4256   // The password prompt info should not be set.
4257   EXPECT_FALSE(response->auth_challenge.has_value());
4258 
4259   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4260   TestLoadTimingNotReusedWithPac(load_timing_info,
4261                                  CONNECT_TIMING_HAS_SSL_TIMES);
4262 
4263   trans.reset();
4264   session->CloseAllConnections(ERR_FAILED, "Very good reason");
4265 }
4266 
4267 // Test the case a proxy closes a socket while the challenge body is being
4268 // drained.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyKeepAliveHangupDuringBody)4269 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
4270   HttpRequestInfo request;
4271   request.method = "GET";
4272   request.url = GURL("https://www.example.org/");
4273   // Ensure that proxy authentication is attempted even
4274   // when the no authentication data flag is set.
4275   request.privacy_mode = PRIVACY_MODE_ENABLED;
4276   request.traffic_annotation =
4277       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4278 
4279   // Configure against proxy server "myproxy:70".
4280   session_deps_.proxy_resolution_service =
4281       ConfiguredProxyResolutionService::CreateFixedForTest(
4282           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4283   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4284 
4285   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
4286 
4287   // Since we have proxy, should try to establish tunnel.
4288   MockWrite data_writes1[] = {
4289       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4290                 "Host: www.example.org:443\r\n"
4291                 "Proxy-Connection: keep-alive\r\n\r\n"),
4292   };
4293 
4294   // The proxy responds to the connect with a 407, using a persistent
4295   // connection.
4296   MockRead data_reads1[] = {
4297       // No credentials.
4298       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4299       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4300       MockRead("Content-Length: 10\r\n\r\n"),
4301       MockRead("spam!"),
4302       // Server hands up in the middle of the body.
4303       MockRead(ASYNC, ERR_CONNECTION_CLOSED),
4304   };
4305 
4306   MockWrite data_writes2[] = {
4307       // After calling trans.RestartWithAuth(), this is the request we should
4308       // be issuing -- the final header line contains the credentials.
4309       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4310                 "Host: www.example.org:443\r\n"
4311                 "Proxy-Connection: keep-alive\r\n"
4312                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4313 
4314       MockWrite("GET / HTTP/1.1\r\n"
4315                 "Host: www.example.org\r\n"
4316                 "Connection: keep-alive\r\n\r\n"),
4317   };
4318 
4319   MockRead data_reads2[] = {
4320       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4321 
4322       MockRead("HTTP/1.1 200 OK\r\n"),
4323       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4324       MockRead("Content-Length: 5\r\n\r\n"),
4325       MockRead(SYNCHRONOUS, "hello"),
4326   };
4327 
4328   StaticSocketDataProvider data1(data_reads1, data_writes1);
4329   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4330   StaticSocketDataProvider data2(data_reads2, data_writes2);
4331   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4332   SSLSocketDataProvider ssl(ASYNC, OK);
4333   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4334 
4335   TestCompletionCallback callback;
4336 
4337   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
4338   EXPECT_THAT(callback.GetResult(rv), IsOk());
4339 
4340   const HttpResponseInfo* response = trans.GetResponseInfo();
4341   ASSERT_TRUE(response);
4342   ASSERT_TRUE(response->headers);
4343   EXPECT_TRUE(response->headers->IsKeepAlive());
4344   EXPECT_EQ(407, response->headers->response_code());
4345   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
4346 
4347   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
4348   EXPECT_THAT(callback.GetResult(rv), IsOk());
4349 
4350   response = trans.GetResponseInfo();
4351   ASSERT_TRUE(response);
4352   ASSERT_TRUE(response->headers);
4353   EXPECT_TRUE(response->headers->IsKeepAlive());
4354   EXPECT_EQ(200, response->headers->response_code());
4355   std::string body;
4356   EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
4357   EXPECT_EQ("hello", body);
4358 }
4359 
4360 // Test that we don't read the response body when we fail to establish a tunnel,
4361 // even if the user cancels the proxy's auth attempt.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyCancelTunnel)4362 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
4363   HttpRequestInfo request;
4364   request.method = "GET";
4365   request.url = GURL("https://www.example.org/");
4366   request.traffic_annotation =
4367       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4368 
4369   // Configure against proxy server "myproxy:70".
4370   session_deps_.proxy_resolution_service =
4371       ConfiguredProxyResolutionService::CreateFixedForTest(
4372           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4373 
4374   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4375 
4376   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
4377 
4378   // Since we have proxy, should try to establish tunnel.
4379   MockWrite data_writes[] = {
4380       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4381                 "Host: www.example.org:443\r\n"
4382                 "Proxy-Connection: keep-alive\r\n\r\n"),
4383   };
4384 
4385   // The proxy responds to the connect with a 407.
4386   MockRead data_reads[] = {
4387       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4388       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4389       MockRead("Content-Length: 10\r\n\r\n"),
4390       MockRead("0123456789"),
4391       MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4392   };
4393 
4394   StaticSocketDataProvider data(data_reads, data_writes);
4395   session_deps_.socket_factory->AddSocketDataProvider(&data);
4396 
4397   TestCompletionCallback callback;
4398 
4399   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
4400   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4401 
4402   rv = callback.WaitForResult();
4403   EXPECT_THAT(rv, IsOk());
4404 
4405   const HttpResponseInfo* response = trans.GetResponseInfo();
4406   ASSERT_TRUE(response);
4407   ASSERT_TRUE(response->headers);
4408   EXPECT_TRUE(response->headers->IsKeepAlive());
4409   EXPECT_EQ(407, response->headers->response_code());
4410   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4411 
4412   std::string response_data;
4413   rv = ReadTransaction(&trans, &response_data);
4414   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
4415 
4416   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4417   session->CloseAllConnections(ERR_FAILED, "Very good reason");
4418 }
4419 
4420 // Test the no-tunnel HTTP auth case where proxy and server origins and realms
4421 // are the same, but the user/passwords are different. Serves to verify
4422 // credentials are correctly separated based on HttpAuth::Target.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyMatchesServerAuthNoTunnel)4423 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyMatchesServerAuthNoTunnel) {
4424   HttpRequestInfo request;
4425   request.method = "GET";
4426   request.url = GURL("http://myproxy:70/");
4427   request.traffic_annotation =
4428       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4429 
4430   // Proxy matches request URL.
4431   session_deps_.proxy_resolution_service =
4432       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
4433           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4434   NetLogWithSource net_log_with_source =
4435       NetLogWithSource::Make(NetLogSourceType::NONE);
4436   session_deps_.net_log = NetLog::Get();
4437   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4438 
4439   MockWrite data_writes[] = {
4440       // Initial request gets a proxy auth challenge.
4441       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4442                 "Host: myproxy:70\r\n"
4443                 "Proxy-Connection: keep-alive\r\n\r\n"),
4444       // Retry with proxy auth credentials, which will result in a server auth
4445       // challenge.
4446       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4447                 "Host: myproxy:70\r\n"
4448                 "Proxy-Connection: keep-alive\r\n"
4449                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4450       // Retry with proxy and server auth credentials, which gets a response.
4451       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4452                 "Host: myproxy:70\r\n"
4453                 "Proxy-Connection: keep-alive\r\n"
4454                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4455                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4456       // A second request should preemptively send the correct proxy and server
4457       // auth headers.
4458       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4459                 "Host: myproxy:70\r\n"
4460                 "Proxy-Connection: keep-alive\r\n"
4461                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4462                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4463   };
4464 
4465   MockRead data_reads[] = {
4466       // Proxy auth challenge.
4467       MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"
4468                "Proxy-Connection: keep-alive\r\n"
4469                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4470                "Content-Length: 0\r\n\r\n"),
4471       // Server auth challenge.
4472       MockRead("HTTP/1.0 401 Authentication Required\r\n"
4473                "Proxy-Connection: keep-alive\r\n"
4474                "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4475                "Content-Length: 0\r\n\r\n"),
4476       // Response.
4477       MockRead("HTTP/1.1 200 OK\r\n"
4478                "Proxy-Connection: keep-alive\r\n"
4479                "Content-Length: 5\r\n\r\n"
4480                "hello"),
4481       // Response to second request.
4482       MockRead("HTTP/1.1 200 OK\r\n"
4483                "Proxy-Connection: keep-alive\r\n"
4484                "Content-Length: 2\r\n\r\n"
4485                "hi"),
4486   };
4487 
4488   StaticSocketDataProvider data(data_reads, data_writes);
4489   session_deps_.socket_factory->AddSocketDataProvider(&data);
4490 
4491   TestCompletionCallback callback;
4492 
4493   auto trans =
4494       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4495   int rv = trans->Start(&request, callback.callback(), net_log_with_source);
4496   EXPECT_THAT(callback.GetResult(rv), IsOk());
4497   const HttpResponseInfo* response = trans->GetResponseInfo();
4498   ASSERT_TRUE(response);
4499   ASSERT_TRUE(response->headers);
4500   EXPECT_EQ(407, response->headers->response_code());
4501   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
4502 
4503   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
4504   EXPECT_THAT(callback.GetResult(rv), IsOk());
4505   response = trans->GetResponseInfo();
4506   ASSERT_TRUE(response);
4507   EXPECT_EQ(401, response->headers->response_code());
4508   EXPECT_FALSE(response->auth_challenge->is_proxy);
4509   EXPECT_EQ("http://myproxy:70",
4510             response->auth_challenge->challenger.Serialize());
4511   EXPECT_EQ("MyRealm1", response->auth_challenge->realm);
4512   EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
4513 
4514   rv = trans->RestartWithAuth(AuthCredentials(kFoo2, kBar2),
4515                               callback.callback());
4516   EXPECT_THAT(callback.GetResult(rv), IsOk());
4517   response = trans->GetResponseInfo();
4518   ASSERT_TRUE(response);
4519   EXPECT_EQ(200, response->headers->response_code());
4520   // The password prompt info should not be set.
4521   EXPECT_FALSE(response->auth_challenge.has_value());
4522 
4523   std::string response_data;
4524   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4525   EXPECT_EQ("hello", response_data);
4526 
4527   // Check that the credentials were cached correctly.
4528   HttpAuthCache::Entry* entry = session->http_auth_cache()->Lookup(
4529       url::SchemeHostPort(url::SchemeHostPort(GURL("http://myproxy:70"))),
4530       HttpAuth::AUTH_PROXY, "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
4531       NetworkAnonymizationKey());
4532   ASSERT_TRUE(entry);
4533   ASSERT_EQ(kFoo, entry->credentials().username());
4534   ASSERT_EQ(kBar, entry->credentials().password());
4535   entry = session->http_auth_cache()->Lookup(
4536       url::SchemeHostPort(url::SchemeHostPort(GURL("http://myproxy:70"))),
4537       HttpAuth::AUTH_SERVER, "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
4538       NetworkAnonymizationKey());
4539   ASSERT_TRUE(entry);
4540   ASSERT_EQ(kFoo2, entry->credentials().username());
4541   ASSERT_EQ(kBar2, entry->credentials().password());
4542 
4543   // Make another request, which should automatically send the correct proxy and
4544   // server auth credentials and get another response.
4545   trans =
4546       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4547   rv = trans->Start(&request, callback.callback(), net_log_with_source);
4548   EXPECT_THAT(callback.GetResult(rv), IsOk());
4549   response = trans->GetResponseInfo();
4550   ASSERT_TRUE(response);
4551   EXPECT_EQ(200, response->headers->response_code());
4552   // The password prompt info should not be set.
4553   EXPECT_FALSE(response->auth_challenge.has_value());
4554 
4555   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4556   EXPECT_EQ("hi", response_data);
4557 
4558   trans.reset();
4559   session->CloseAllConnections(ERR_FAILED, "Very good reason");
4560 }
4561 
4562 // Test the no-tunnel HTTP auth case where proxy and server origins and realms
4563 // are the same, but the user/passwords are different, and with different
4564 // NetworkAnonymizationKeys. Sends one request with a NAK, response to both
4565 // proxy and auth challenges, sends another request with another NAK, expecting
4566 // only the proxy credentials to be cached, and thus sees only a server auth
4567 // challenge. Then sends a request with the original NAK, expecting cached proxy
4568 // and auth credentials that match the ones used in the first request.
4569 //
4570 // Serves to verify credentials are correctly separated based on
4571 // HttpAuth::Target and NetworkAnonymizationKeys, but NetworkAnonymizationKey
4572 // only affects server credentials, not proxy credentials.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyMatchesServerAuthWithNetworkAnonymizationKeyNoTunnel)4573 TEST_P(HttpNetworkTransactionTest,
4574        BasicAuthProxyMatchesServerAuthWithNetworkAnonymizationKeyNoTunnel) {
4575   const SchemefulSite kSite1(GURL("https://foo.test/"));
4576   const auto kNetworkAnonymizationKey1 =
4577       net::NetworkAnonymizationKey::CreateSameSite(kSite1);
4578   const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
4579   const SchemefulSite kSite2(GURL("https://bar.test/"));
4580   const auto kNetworkAnonymizationKey2 =
4581       net::NetworkAnonymizationKey::CreateSameSite(kSite2);
4582   const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
4583 
4584   // This test would need to use a single socket without this option enabled.
4585   // Best to use this option when it would affect a test, as it will eventually
4586   // become the default behavior.
4587   base::test::ScopedFeatureList feature_list;
4588   feature_list.InitAndEnableFeature(
4589       features::kPartitionConnectionsByNetworkIsolationKey);
4590 
4591   // Proxy matches request URL.
4592   session_deps_.proxy_resolution_service =
4593       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
4594           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4595   NetLogWithSource net_log_with_source =
4596       NetLogWithSource::Make(NetLogSourceType::NONE);
4597 
4598   session_deps_.net_log = NetLog::Get();
4599   session_deps_.key_auth_cache_server_entries_by_network_anonymization_key =
4600       true;
4601   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4602 
4603   MockWrite data_writes[] = {
4604       // Initial request gets a proxy auth challenge.
4605       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4606                 "Host: myproxy:70\r\n"
4607                 "Proxy-Connection: keep-alive\r\n\r\n"),
4608       // Retry with proxy auth credentials, which will result in a server auth
4609       // challenge.
4610       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4611                 "Host: myproxy:70\r\n"
4612                 "Proxy-Connection: keep-alive\r\n"
4613                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4614       // Retry with proxy and server auth credentials, which gets a response.
4615       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4616                 "Host: myproxy:70\r\n"
4617                 "Proxy-Connection: keep-alive\r\n"
4618                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4619                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4620       // Another request to the same server and using the same NAK should
4621       // preemptively send the correct cached proxy and server
4622       // auth headers.
4623       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4624                 "Host: myproxy:70\r\n"
4625                 "Proxy-Connection: keep-alive\r\n"
4626                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4627                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4628   };
4629 
4630   MockRead data_reads[] = {
4631       // Proxy auth challenge.
4632       MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"
4633                "Proxy-Connection: keep-alive\r\n"
4634                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4635                "Content-Length: 0\r\n\r\n"),
4636       // Server auth challenge.
4637       MockRead("HTTP/1.0 401 Authentication Required\r\n"
4638                "Proxy-Connection: keep-alive\r\n"
4639                "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4640                "Content-Length: 0\r\n\r\n"),
4641       // Response.
4642       MockRead("HTTP/1.1 200 OK\r\n"
4643                "Proxy-Connection: keep-alive\r\n"
4644                "Content-Length: 5\r\n\r\n"
4645                "hello"),
4646       // Response to second request.
4647       MockRead("HTTP/1.1 200 OK\r\n"
4648                "Proxy-Connection: keep-alive\r\n"
4649                "Content-Length: 2\r\n\r\n"
4650                "hi"),
4651   };
4652 
4653   StaticSocketDataProvider data(data_reads, data_writes);
4654   session_deps_.socket_factory->AddSocketDataProvider(&data);
4655 
4656   MockWrite data_writes2[] = {
4657       // Initial request using a different NetworkAnonymizationKey includes the
4658       // cached proxy credentials, but not server credentials.
4659       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4660                 "Host: myproxy:70\r\n"
4661                 "Proxy-Connection: keep-alive\r\n"
4662                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4663       // Retry with proxy and new server auth credentials, which gets a
4664       // response.
4665       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4666                 "Host: myproxy:70\r\n"
4667                 "Proxy-Connection: keep-alive\r\n"
4668                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4669                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
4670   };
4671 
4672   MockRead data_reads2[] = {
4673       // Server auth challenge.
4674       MockRead("HTTP/1.0 401 Authentication Required\r\n"
4675                "Proxy-Connection: keep-alive\r\n"
4676                "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4677                "Content-Length: 0\r\n\r\n"),
4678       // Response.
4679       MockRead("HTTP/1.1 200 OK\r\n"
4680                "Proxy-Connection: keep-alive\r\n"
4681                "Content-Length: 9\r\n\r\n"
4682                "greetings"),
4683   };
4684 
4685   StaticSocketDataProvider data2(data_reads2, data_writes2);
4686   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4687 
4688   TestCompletionCallback callback;
4689 
4690   HttpRequestInfo request;
4691   request.method = "GET";
4692   request.url = GURL("http://myproxy:70/");
4693   request.traffic_annotation =
4694       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4695   request.network_isolation_key = kNetworkIsolationKey1;
4696   request.network_anonymization_key = kNetworkAnonymizationKey1;
4697 
4698   auto trans =
4699       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4700   int rv = trans->Start(&request, callback.callback(), net_log_with_source);
4701   EXPECT_THAT(callback.GetResult(rv), IsOk());
4702   const HttpResponseInfo* response = trans->GetResponseInfo();
4703   ASSERT_TRUE(response);
4704   ASSERT_TRUE(response->headers);
4705   EXPECT_EQ(407, response->headers->response_code());
4706   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
4707 
4708   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
4709   EXPECT_THAT(callback.GetResult(rv), IsOk());
4710   response = trans->GetResponseInfo();
4711   ASSERT_TRUE(response);
4712   EXPECT_EQ(401, response->headers->response_code());
4713   EXPECT_FALSE(response->auth_challenge->is_proxy);
4714   EXPECT_EQ("http://myproxy:70",
4715             response->auth_challenge->challenger.Serialize());
4716   EXPECT_EQ("MyRealm1", response->auth_challenge->realm);
4717   EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
4718 
4719   rv = trans->RestartWithAuth(AuthCredentials(kFoo2, kBar2),
4720                               callback.callback());
4721   EXPECT_THAT(callback.GetResult(rv), IsOk());
4722   response = trans->GetResponseInfo();
4723   ASSERT_TRUE(response);
4724   EXPECT_EQ(200, response->headers->response_code());
4725   // The password prompt info should not be set.
4726   EXPECT_FALSE(response->auth_challenge.has_value());
4727   std::string response_data;
4728   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4729   EXPECT_EQ("hello", response_data);
4730 
4731   // Check that the proxy credentials were cached correctly. The should be
4732   // accessible with any NetworkAnonymizationKey.
4733   HttpAuthCache::Entry* entry = session->http_auth_cache()->Lookup(
4734       url::SchemeHostPort(url::SchemeHostPort(GURL("http://myproxy:70"))),
4735       HttpAuth::AUTH_PROXY, "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
4736       kNetworkAnonymizationKey1);
4737   ASSERT_TRUE(entry);
4738   ASSERT_EQ(kFoo, entry->credentials().username());
4739   ASSERT_EQ(kBar, entry->credentials().password());
4740   EXPECT_EQ(entry, session->http_auth_cache()->Lookup(
4741                        url::SchemeHostPort(GURL("http://myproxy:70")),
4742                        HttpAuth::AUTH_PROXY, "MyRealm1",
4743                        HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey2));
4744 
4745   // Check that the server credentials were cached correctly. The should be
4746   // accessible with only kNetworkAnonymizationKey1.
4747   entry = session->http_auth_cache()->Lookup(
4748       url::SchemeHostPort(GURL("http://myproxy:70")), HttpAuth::AUTH_SERVER,
4749       "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey1);
4750   ASSERT_TRUE(entry);
4751   ASSERT_EQ(kFoo2, entry->credentials().username());
4752   ASSERT_EQ(kBar2, entry->credentials().password());
4753   // Looking up the server entry with another NetworkAnonymizationKey should
4754   // fail.
4755   EXPECT_FALSE(session->http_auth_cache()->Lookup(
4756       url::SchemeHostPort(GURL("http://myproxy:70")), HttpAuth::AUTH_SERVER,
4757       "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey2));
4758 
4759   // Make another request with a different NetworkAnonymizationKey. It should
4760   // use another socket, reuse the cached proxy credentials, but result in a
4761   // server auth challenge.
4762   request.network_isolation_key = kNetworkIsolationKey2;
4763   request.network_anonymization_key = kNetworkAnonymizationKey2;
4764 
4765   trans =
4766       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4767   rv = trans->Start(&request, callback.callback(), net_log_with_source);
4768   EXPECT_THAT(callback.GetResult(rv), IsOk());
4769   response = trans->GetResponseInfo();
4770   ASSERT_TRUE(response);
4771   EXPECT_EQ(401, response->headers->response_code());
4772   EXPECT_FALSE(response->auth_challenge->is_proxy);
4773   EXPECT_EQ("http://myproxy:70",
4774             response->auth_challenge->challenger.Serialize());
4775   EXPECT_EQ("MyRealm1", response->auth_challenge->realm);
4776   EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
4777 
4778   rv = trans->RestartWithAuth(AuthCredentials(kFoo3, kBar3),
4779                               callback.callback());
4780   EXPECT_THAT(callback.GetResult(rv), IsOk());
4781   response = trans->GetResponseInfo();
4782   ASSERT_TRUE(response);
4783   EXPECT_EQ(200, response->headers->response_code());
4784   // The password prompt info should not be set.
4785   EXPECT_FALSE(response->auth_challenge.has_value());
4786   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4787   EXPECT_EQ("greetings", response_data);
4788 
4789   // Check that the proxy credentials are still cached.
4790   entry = session->http_auth_cache()->Lookup(
4791       url::SchemeHostPort(GURL("http://myproxy:70")), HttpAuth::AUTH_PROXY,
4792       "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey1);
4793   ASSERT_TRUE(entry);
4794   ASSERT_EQ(kFoo, entry->credentials().username());
4795   ASSERT_EQ(kBar, entry->credentials().password());
4796   EXPECT_EQ(entry, session->http_auth_cache()->Lookup(
4797                        url::SchemeHostPort(GURL("http://myproxy:70")),
4798                        HttpAuth::AUTH_PROXY, "MyRealm1",
4799                        HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey2));
4800 
4801   // Check that the correct server credentials are cached for each
4802   // NetworkAnonymizationKey.
4803   entry = session->http_auth_cache()->Lookup(
4804       url::SchemeHostPort(GURL("http://myproxy:70")), HttpAuth::AUTH_SERVER,
4805       "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey1);
4806   ASSERT_TRUE(entry);
4807   ASSERT_EQ(kFoo2, entry->credentials().username());
4808   ASSERT_EQ(kBar2, entry->credentials().password());
4809   entry = session->http_auth_cache()->Lookup(
4810       url::SchemeHostPort(GURL("http://myproxy:70")), HttpAuth::AUTH_SERVER,
4811       "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey2);
4812   ASSERT_TRUE(entry);
4813   ASSERT_EQ(kFoo3, entry->credentials().username());
4814   ASSERT_EQ(kBar3, entry->credentials().password());
4815 
4816   // Make a request with the original NetworkAnonymizationKey. It should reuse
4817   // the first socket, and the proxy credentials sent on the first socket.
4818   request.network_isolation_key = kNetworkIsolationKey1;
4819   request.network_anonymization_key = kNetworkAnonymizationKey1;
4820   trans =
4821       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4822   rv = trans->Start(&request, callback.callback(), net_log_with_source);
4823   EXPECT_THAT(callback.GetResult(rv), IsOk());
4824   response = trans->GetResponseInfo();
4825   ASSERT_TRUE(response);
4826   EXPECT_EQ(200, response->headers->response_code());
4827   // The password prompt info should not be set.
4828   EXPECT_FALSE(response->auth_challenge.has_value());
4829   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4830   EXPECT_EQ("hi", response_data);
4831 
4832   trans.reset();
4833   session->CloseAllConnections(ERR_FAILED, "Very good reason");
4834 }
4835 
4836 // Much like the test above, but uses tunnelled connections.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyMatchesServerAuthWithNetworkAnonymizationKeyWithTunnel)4837 TEST_P(HttpNetworkTransactionTest,
4838        BasicAuthProxyMatchesServerAuthWithNetworkAnonymizationKeyWithTunnel) {
4839   const SchemefulSite kSite1(GURL("https://foo.test/"));
4840   const auto kNetworkAnonymizationKey1 =
4841       net::NetworkAnonymizationKey::CreateSameSite(kSite1);
4842   const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
4843   const SchemefulSite kSite2(GURL("https://bar.test/"));
4844   const auto kNetworkAnonymizationKey2 =
4845       net::NetworkAnonymizationKey::CreateSameSite(kSite2);
4846   const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
4847 
4848   // This test would need to use a single socket without this option enabled.
4849   // Best to use this option when it would affect a test, as it will eventually
4850   // become the default behavior.
4851   base::test::ScopedFeatureList feature_list;
4852   feature_list.InitAndEnableFeature(
4853       features::kPartitionConnectionsByNetworkIsolationKey);
4854 
4855   // Proxy matches request URL.
4856   session_deps_.proxy_resolution_service =
4857       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
4858           "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4859   NetLogWithSource net_log_with_source =
4860       NetLogWithSource::Make(NetLogSourceType::NONE);
4861   session_deps_.net_log = NetLog::Get();
4862   session_deps_.key_auth_cache_server_entries_by_network_anonymization_key =
4863       true;
4864   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4865 
4866   MockWrite data_writes[] = {
4867       // Initial tunnel request gets a proxy auth challenge.
4868       MockWrite("CONNECT myproxy:70 HTTP/1.1\r\n"
4869                 "Host: myproxy:70\r\n"
4870                 "Proxy-Connection: keep-alive\r\n\r\n"),
4871       // Retry with proxy auth credentials, which will result in establishing a
4872       // tunnel.
4873       MockWrite("CONNECT myproxy:70 HTTP/1.1\r\n"
4874                 "Host: myproxy:70\r\n"
4875                 "Proxy-Connection: keep-alive\r\n"
4876                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4877       // Request over the tunnel, which gets a server auth challenge.
4878       MockWrite("GET / HTTP/1.1\r\n"
4879                 "Host: myproxy:70\r\n"
4880                 "Connection: keep-alive\r\n\r\n"),
4881       // Retry with server auth credentials, which gets a response.
4882       MockWrite("GET / HTTP/1.1\r\n"
4883                 "Host: myproxy:70\r\n"
4884                 "Connection: keep-alive\r\n"
4885                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4886       // Another request to the same server and using the same NAK should
4887       // preemptively send the correct cached server
4888       // auth header. Since a tunnel was already established, the proxy headers
4889       // won't be sent again except when establishing another tunnel.
4890       MockWrite("GET / HTTP/1.1\r\n"
4891                 "Host: myproxy:70\r\n"
4892                 "Connection: keep-alive\r\n"
4893                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4894   };
4895 
4896   MockRead data_reads[] = {
4897       // Proxy auth challenge.
4898       MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"
4899                "Proxy-Connection: keep-alive\r\n"
4900                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4901                "Content-Length: 0\r\n\r\n"),
4902       // Tunnel success
4903       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4904       // Server auth challenge.
4905       MockRead("HTTP/1.0 401 Authentication Required\r\n"
4906                "Connection: keep-alive\r\n"
4907                "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4908                "Content-Length: 0\r\n\r\n"),
4909       // Response.
4910       MockRead("HTTP/1.1 200 OK\r\n"
4911                "Connection: keep-alive\r\n"
4912                "Content-Length: 5\r\n\r\n"
4913                "hello"),
4914       // Response to second request.
4915       MockRead("HTTP/1.1 200 OK\r\n"
4916                "Connection: keep-alive\r\n"
4917                "Content-Length: 2\r\n\r\n"
4918                "hi"),
4919   };
4920 
4921   StaticSocketDataProvider data(data_reads, data_writes);
4922   session_deps_.socket_factory->AddSocketDataProvider(&data);
4923   // One for the proxy connection, one of the server connection.
4924   SSLSocketDataProvider ssl(ASYNC, OK);
4925   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4926   SSLSocketDataProvider ssl2(ASYNC, OK);
4927   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
4928 
4929   MockWrite data_writes2[] = {
4930       // Initial request using a different NetworkAnonymizationKey includes the
4931       // cached proxy credentials when establishing a tunnel.
4932       MockWrite("CONNECT myproxy:70 HTTP/1.1\r\n"
4933                 "Host: myproxy:70\r\n"
4934                 "Proxy-Connection: keep-alive\r\n"
4935                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4936       // Request over the tunnel, which gets a server auth challenge. Cached
4937       // credentials cannot be used, since the NAK is different.
4938       MockWrite("GET / HTTP/1.1\r\n"
4939                 "Host: myproxy:70\r\n"
4940                 "Connection: keep-alive\r\n\r\n"),
4941       // Retry with server auth credentials, which gets a response.
4942       MockWrite("GET / HTTP/1.1\r\n"
4943                 "Host: myproxy:70\r\n"
4944                 "Connection: keep-alive\r\n"
4945                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
4946   };
4947 
4948   MockRead data_reads2[] = {
4949       // Tunnel success
4950       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4951       // Server auth challenge.
4952       MockRead("HTTP/1.0 401 Authentication Required\r\n"
4953                "Connection: keep-alive\r\n"
4954                "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4955                "Content-Length: 0\r\n\r\n"),
4956       // Response.
4957       MockRead("HTTP/1.1 200 OK\r\n"
4958                "Connection: keep-alive\r\n"
4959                "Content-Length: 9\r\n\r\n"
4960                "greetings"),
4961   };
4962 
4963   StaticSocketDataProvider data2(data_reads2, data_writes2);
4964   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4965   // One for the proxy connection, one of the server connection.
4966   SSLSocketDataProvider ssl3(ASYNC, OK);
4967   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
4968   SSLSocketDataProvider ssl4(ASYNC, OK);
4969   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl4);
4970 
4971   TestCompletionCallback callback;
4972 
4973   HttpRequestInfo request;
4974   request.method = "GET";
4975   request.url = GURL("https://myproxy:70/");
4976   request.traffic_annotation =
4977       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4978   request.network_isolation_key = kNetworkIsolationKey1;
4979   request.network_anonymization_key = kNetworkAnonymizationKey1;
4980 
4981   auto trans =
4982       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4983   int rv = trans->Start(&request, callback.callback(), net_log_with_source);
4984   EXPECT_THAT(callback.GetResult(rv), IsOk());
4985   const HttpResponseInfo* response = trans->GetResponseInfo();
4986   ASSERT_TRUE(response);
4987   ASSERT_TRUE(response->headers);
4988   EXPECT_EQ(407, response->headers->response_code());
4989   EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
4990 
4991   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
4992   EXPECT_THAT(callback.GetResult(rv), IsOk());
4993   response = trans->GetResponseInfo();
4994   ASSERT_TRUE(response);
4995   EXPECT_EQ(401, response->headers->response_code());
4996   EXPECT_FALSE(response->auth_challenge->is_proxy);
4997   EXPECT_EQ("https://myproxy:70",
4998             response->auth_challenge->challenger.Serialize());
4999   EXPECT_EQ("MyRealm1", response->auth_challenge->realm);
5000   EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
5001 
5002   rv = trans->RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5003                               callback.callback());
5004   EXPECT_THAT(callback.GetResult(rv), IsOk());
5005   response = trans->GetResponseInfo();
5006   ASSERT_TRUE(response);
5007   EXPECT_EQ(200, response->headers->response_code());
5008   // The password prompt info should not be set.
5009   EXPECT_FALSE(response->auth_challenge.has_value());
5010   std::string response_data;
5011   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5012   EXPECT_EQ("hello", response_data);
5013 
5014   // Check that the proxy credentials were cached correctly. The should be
5015   // accessible with any NetworkAnonymizationKey.
5016   HttpAuthCache::Entry* entry = session->http_auth_cache()->Lookup(
5017       url::SchemeHostPort(url::SchemeHostPort(GURL("https://myproxy:70"))),
5018       HttpAuth::AUTH_PROXY, "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
5019       kNetworkAnonymizationKey1);
5020   ASSERT_TRUE(entry);
5021   ASSERT_EQ(kFoo, entry->credentials().username());
5022   ASSERT_EQ(kBar, entry->credentials().password());
5023   EXPECT_EQ(entry, session->http_auth_cache()->Lookup(
5024                        url::SchemeHostPort(GURL("https://myproxy:70")),
5025                        HttpAuth::AUTH_PROXY, "MyRealm1",
5026                        HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey2));
5027 
5028   // Check that the server credentials were cached correctly. The should be
5029   // accessible with only kNetworkAnonymizationKey1.
5030   entry = session->http_auth_cache()->Lookup(
5031       url::SchemeHostPort(GURL("https://myproxy:70")), HttpAuth::AUTH_SERVER,
5032       "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey1);
5033   ASSERT_TRUE(entry);
5034   ASSERT_EQ(kFoo2, entry->credentials().username());
5035   ASSERT_EQ(kBar2, entry->credentials().password());
5036   // Looking up the server entry with another NetworkAnonymiationKey should
5037   // fail.
5038   EXPECT_FALSE(session->http_auth_cache()->Lookup(
5039       url::SchemeHostPort(GURL("https://myproxy:70")), HttpAuth::AUTH_SERVER,
5040       "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey2));
5041 
5042   // Make another request with a different NetworkAnonymiationKey. It should use
5043   // another socket, reuse the cached proxy credentials, but result in a server
5044   // auth challenge.
5045   request.network_isolation_key = kNetworkIsolationKey2;
5046   request.network_anonymization_key = kNetworkAnonymizationKey2;
5047 
5048   trans =
5049       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5050   rv = trans->Start(&request, callback.callback(), net_log_with_source);
5051   EXPECT_THAT(callback.GetResult(rv), IsOk());
5052   response = trans->GetResponseInfo();
5053   ASSERT_TRUE(response);
5054   EXPECT_EQ(401, response->headers->response_code());
5055   EXPECT_FALSE(response->auth_challenge->is_proxy);
5056   EXPECT_EQ("https://myproxy:70",
5057             response->auth_challenge->challenger.Serialize());
5058   EXPECT_EQ("MyRealm1", response->auth_challenge->realm);
5059   EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
5060 
5061   rv = trans->RestartWithAuth(AuthCredentials(kFoo3, kBar3),
5062                               callback.callback());
5063   EXPECT_THAT(callback.GetResult(rv), IsOk());
5064   response = trans->GetResponseInfo();
5065   ASSERT_TRUE(response);
5066   EXPECT_EQ(200, response->headers->response_code());
5067   // The password prompt info should not be set.
5068   EXPECT_FALSE(response->auth_challenge.has_value());
5069   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5070   EXPECT_EQ("greetings", response_data);
5071 
5072   // Check that the proxy credentials are still cached.
5073   entry = session->http_auth_cache()->Lookup(
5074       url::SchemeHostPort(GURL("https://myproxy:70")), HttpAuth::AUTH_PROXY,
5075       "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey1);
5076   ASSERT_TRUE(entry);
5077   ASSERT_EQ(kFoo, entry->credentials().username());
5078   ASSERT_EQ(kBar, entry->credentials().password());
5079   EXPECT_EQ(entry, session->http_auth_cache()->Lookup(
5080                        url::SchemeHostPort(GURL("https://myproxy:70")),
5081                        HttpAuth::AUTH_PROXY, "MyRealm1",
5082                        HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey2));
5083 
5084   // Check that the correct server credentials are cached for each
5085   // NetworkAnonymiationKey.
5086   entry = session->http_auth_cache()->Lookup(
5087       url::SchemeHostPort(GURL("https://myproxy:70")), HttpAuth::AUTH_SERVER,
5088       "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey1);
5089   ASSERT_TRUE(entry);
5090   ASSERT_EQ(kFoo2, entry->credentials().username());
5091   ASSERT_EQ(kBar2, entry->credentials().password());
5092   entry = session->http_auth_cache()->Lookup(
5093       url::SchemeHostPort(GURL("https://myproxy:70")), HttpAuth::AUTH_SERVER,
5094       "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, kNetworkAnonymizationKey2);
5095   ASSERT_TRUE(entry);
5096   ASSERT_EQ(kFoo3, entry->credentials().username());
5097   ASSERT_EQ(kBar3, entry->credentials().password());
5098 
5099   // Make a request with the original NetworkAnonymiationKey. It should reuse
5100   // the first socket, and the proxy credentials sent on the first socket.
5101   request.network_isolation_key = kNetworkIsolationKey1;
5102   request.network_anonymization_key = kNetworkAnonymizationKey1;
5103 
5104   trans =
5105       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5106   rv = trans->Start(&request, callback.callback(), net_log_with_source);
5107   EXPECT_THAT(callback.GetResult(rv), IsOk());
5108   response = trans->GetResponseInfo();
5109   ASSERT_TRUE(response);
5110   EXPECT_EQ(200, response->headers->response_code());
5111   // The password prompt info should not be set.
5112   EXPECT_FALSE(response->auth_challenge.has_value());
5113   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5114   EXPECT_EQ("hi", response_data);
5115 
5116   trans.reset();
5117   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5118 }
5119 
5120 // Test that we don't pass extraneous headers from the proxy's response to the
5121 // caller when the proxy responds to CONNECT with 407.
TEST_P(HttpNetworkTransactionTest,SanitizeProxyAuthHeaders)5122 TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
5123   HttpRequestInfo request;
5124   request.method = "GET";
5125   request.url = GURL("https://www.example.org/");
5126   request.traffic_annotation =
5127       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5128 
5129   // Configure against proxy server "myproxy:70".
5130   session_deps_.proxy_resolution_service =
5131       ConfiguredProxyResolutionService::CreateFixedForTest(
5132           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
5133 
5134   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5135 
5136   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
5137 
5138   // Since we have proxy, should try to establish tunnel.
5139   MockWrite data_writes[] = {
5140       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5141                 "Host: www.example.org:443\r\n"
5142                 "Proxy-Connection: keep-alive\r\n\r\n"),
5143   };
5144 
5145   // The proxy responds to the connect with a 407.
5146   MockRead data_reads[] = {
5147       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5148       MockRead("X-Foo: bar\r\n"),
5149       MockRead("Set-Cookie: foo=bar\r\n"),
5150       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5151       MockRead("Content-Length: 10\r\n\r\n"),
5152       MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
5153   };
5154 
5155   StaticSocketDataProvider data(data_reads, data_writes);
5156   session_deps_.socket_factory->AddSocketDataProvider(&data);
5157 
5158   TestCompletionCallback callback;
5159 
5160   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
5161   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5162 
5163   rv = callback.WaitForResult();
5164   EXPECT_THAT(rv, IsOk());
5165 
5166   const HttpResponseInfo* response = trans.GetResponseInfo();
5167   ASSERT_TRUE(response);
5168   ASSERT_TRUE(response->headers);
5169   EXPECT_TRUE(response->headers->IsKeepAlive());
5170   EXPECT_EQ(407, response->headers->response_code());
5171   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5172   EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
5173   EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
5174 
5175   std::string response_data;
5176   rv = ReadTransaction(&trans, &response_data);
5177   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
5178 
5179   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
5180   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5181 }
5182 
5183 // Test when a server (non-proxy) returns a 407 (proxy-authenticate).
5184 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
TEST_P(HttpNetworkTransactionTest,UnexpectedProxyAuth)5185 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
5186   HttpRequestInfo request;
5187   request.method = "GET";
5188   request.url = GURL("http://www.example.org/");
5189   request.traffic_annotation =
5190       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5191 
5192   // We are using a DIRECT connection (i.e. no proxy) for this session.
5193   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5194   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
5195 
5196   MockWrite data_writes1[] = {
5197       MockWrite("GET / HTTP/1.1\r\n"
5198                 "Host: www.example.org\r\n"
5199                 "Connection: keep-alive\r\n\r\n"),
5200   };
5201 
5202   MockRead data_reads1[] = {
5203       MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
5204       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5205       // Large content-length -- won't matter, as connection will be reset.
5206       MockRead("Content-Length: 10000\r\n\r\n"),
5207       MockRead(SYNCHRONOUS, ERR_FAILED),
5208   };
5209 
5210   StaticSocketDataProvider data1(data_reads1, data_writes1);
5211   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5212 
5213   TestCompletionCallback callback;
5214 
5215   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
5216   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5217 
5218   rv = callback.WaitForResult();
5219   EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
5220 }
5221 
5222 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
5223 // through a non-authenticating proxy. The request should fail with
5224 // ERR_UNEXPECTED_PROXY_AUTH.
5225 // Note that it is impossible to detect if an HTTP server returns a 407 through
5226 // a non-authenticating proxy - there is nothing to indicate whether the
5227 // response came from the proxy or the server, so it is treated as if the proxy
5228 // issued the challenge.
TEST_P(HttpNetworkTransactionTest,HttpsServerRequestsProxyAuthThroughProxy)5229 TEST_P(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
5230   HttpRequestInfo request;
5231   request.method = "GET";
5232   request.url = GURL("https://www.example.org/");
5233   request.traffic_annotation =
5234       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5235 
5236   session_deps_.proxy_resolution_service =
5237       ConfiguredProxyResolutionService::CreateFixedForTest(
5238           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
5239   RecordingNetLogObserver net_log_observer;
5240   session_deps_.net_log = NetLog::Get();
5241   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5242 
5243   // Since we have proxy, should try to establish tunnel.
5244   MockWrite data_writes1[] = {
5245       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5246                 "Host: www.example.org:443\r\n"
5247                 "Proxy-Connection: keep-alive\r\n\r\n"),
5248 
5249       MockWrite("GET / HTTP/1.1\r\n"
5250                 "Host: www.example.org\r\n"
5251                 "Connection: keep-alive\r\n\r\n"),
5252   };
5253 
5254   MockRead data_reads1[] = {
5255       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5256 
5257       MockRead("HTTP/1.1 407 Unauthorized\r\n"),
5258       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5259       MockRead("\r\n"),
5260       MockRead(SYNCHRONOUS, OK),
5261   };
5262 
5263   StaticSocketDataProvider data1(data_reads1, data_writes1);
5264   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5265   SSLSocketDataProvider ssl(ASYNC, OK);
5266   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5267 
5268   TestCompletionCallback callback;
5269 
5270   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
5271 
5272   int rv = trans.Start(&request, callback.callback(),
5273                        NetLogWithSource::Make(NetLogSourceType::NONE));
5274   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5275 
5276   rv = callback.WaitForResult();
5277   EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
5278   auto entries = net_log_observer.GetEntries();
5279   size_t pos = ExpectLogContainsSomewhere(
5280       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
5281       NetLogEventPhase::NONE);
5282   ExpectLogContainsSomewhere(
5283       entries, pos,
5284       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
5285       NetLogEventPhase::NONE);
5286 }
5287 
5288 // Test a proxy auth scheme that allows default credentials and a proxy server
5289 // that uses non-persistent connections.
TEST_P(HttpNetworkTransactionTest,AuthAllowsDefaultCredentialsTunnelConnectionClose)5290 TEST_P(HttpNetworkTransactionTest,
5291        AuthAllowsDefaultCredentialsTunnelConnectionClose) {
5292   HttpRequestInfo request;
5293   request.method = "GET";
5294   request.url = GURL("https://www.example.org/");
5295   request.traffic_annotation =
5296       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5297 
5298   // Configure against proxy server "myproxy:70".
5299   session_deps_.proxy_resolution_service =
5300       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
5301           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
5302 
5303   auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
5304   auth_handler_factory->set_do_init_from_challenge(true);
5305   auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
5306   mock_handler->set_allows_default_credentials(true);
5307   auth_handler_factory->AddMockHandler(std::move(mock_handler),
5308                                        HttpAuth::AUTH_PROXY);
5309   session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
5310 
5311   // Add NetLog just so can verify load timing information gets a NetLog ID.
5312   session_deps_.net_log = NetLog::Get();
5313   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
5314 
5315   // Since we have proxy, should try to establish tunnel.
5316   MockWrite data_writes1[] = {
5317       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5318                 "Host: www.example.org:443\r\n"
5319                 "Proxy-Connection: keep-alive\r\n\r\n"),
5320   };
5321 
5322   // The proxy responds to the connect with a 407, using a non-persistent
5323   // connection.
5324   MockRead data_reads1[] = {
5325       // No credentials.
5326       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5327       MockRead("Proxy-Authenticate: Mock\r\n"),
5328       MockRead("Proxy-Connection: close\r\n\r\n"),
5329   };
5330 
5331   // Since the first connection couldn't be reused, need to establish another
5332   // once given credentials.
5333   MockWrite data_writes2[] = {
5334       // After calling trans->RestartWithAuth(), this is the request we should
5335       // be issuing -- the final header line contains the credentials.
5336       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5337                 "Host: www.example.org:443\r\n"
5338                 "Proxy-Connection: keep-alive\r\n"
5339                 "Proxy-Authorization: auth_token\r\n\r\n"),
5340 
5341       MockWrite("GET / HTTP/1.1\r\n"
5342                 "Host: www.example.org\r\n"
5343                 "Connection: keep-alive\r\n\r\n"),
5344   };
5345 
5346   MockRead data_reads2[] = {
5347       MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
5348 
5349       MockRead("HTTP/1.1 200 OK\r\n"),
5350       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5351       MockRead("Content-Length: 5\r\n\r\n"),
5352       MockRead(SYNCHRONOUS, "hello"),
5353   };
5354 
5355   StaticSocketDataProvider data1(data_reads1, data_writes1);
5356   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5357   StaticSocketDataProvider data2(data_reads2, data_writes2);
5358   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5359   SSLSocketDataProvider ssl(ASYNC, OK);
5360   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5361 
5362   auto trans =
5363       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5364 
5365   TestCompletionCallback callback;
5366   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5367   EXPECT_THAT(callback.GetResult(rv), IsOk());
5368 
5369   const HttpResponseInfo* response = trans->GetResponseInfo();
5370   ASSERT_TRUE(response);
5371   ASSERT_TRUE(response->headers);
5372   EXPECT_FALSE(response->headers->IsKeepAlive());
5373   EXPECT_EQ(407, response->headers->response_code());
5374   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5375   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5376   EXPECT_FALSE(response->auth_challenge.has_value());
5377 
5378   LoadTimingInfo load_timing_info;
5379   // CONNECT requests and responses are handled at the connect job level, so
5380   // the transaction does not yet have a connection.
5381   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
5382 
5383   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5384   EXPECT_THAT(callback.GetResult(rv), IsOk());
5385   response = trans->GetResponseInfo();
5386   ASSERT_TRUE(response);
5387   ASSERT_TRUE(response->headers);
5388   EXPECT_TRUE(response->headers->IsKeepAlive());
5389   EXPECT_EQ(200, response->headers->response_code());
5390   EXPECT_EQ(5, response->headers->GetContentLength());
5391   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5392 
5393   // The password prompt info should not be set.
5394   EXPECT_FALSE(response->auth_challenge.has_value());
5395 
5396   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5397   TestLoadTimingNotReusedWithPac(load_timing_info,
5398                                  CONNECT_TIMING_HAS_SSL_TIMES);
5399 
5400   trans.reset();
5401   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5402 }
5403 
5404 // Test a proxy auth scheme that allows default credentials and a proxy server
5405 // that hangs up when credentials are initially sent.
TEST_P(HttpNetworkTransactionTest,AuthAllowsDefaultCredentialsTunnelServerClosesConnection)5406 TEST_P(HttpNetworkTransactionTest,
5407        AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
5408   HttpRequestInfo request;
5409   request.method = "GET";
5410   request.url = GURL("https://www.example.org/");
5411   request.traffic_annotation =
5412       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5413 
5414   // Configure against proxy server "myproxy:70".
5415   session_deps_.proxy_resolution_service =
5416       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
5417           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
5418 
5419   auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
5420   auth_handler_factory->set_do_init_from_challenge(true);
5421   auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
5422   mock_handler->set_allows_default_credentials(true);
5423   auth_handler_factory->AddMockHandler(std::move(mock_handler),
5424                                        HttpAuth::AUTH_PROXY);
5425   session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
5426 
5427   // Add NetLog just so can verify load timing information gets a NetLog ID.
5428   session_deps_.net_log = NetLog::Get();
5429   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
5430 
5431   // Should try to establish tunnel.
5432   MockWrite data_writes1[] = {
5433       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5434                 "Host: www.example.org:443\r\n"
5435                 "Proxy-Connection: keep-alive\r\n\r\n"),
5436 
5437       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5438                 "Host: www.example.org:443\r\n"
5439                 "Proxy-Connection: keep-alive\r\n"
5440                 "Proxy-Authorization: auth_token\r\n\r\n"),
5441   };
5442 
5443   // The proxy responds to the connect with a 407, using a non-persistent
5444   // connection.
5445   MockRead data_reads1[] = {
5446       // No credentials.
5447       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5448       MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
5449       MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
5450   };
5451 
5452   // Since the first connection was closed, need to establish another once given
5453   // credentials.
5454   MockWrite data_writes2[] = {
5455       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5456                 "Host: www.example.org:443\r\n"
5457                 "Proxy-Connection: keep-alive\r\n"
5458                 "Proxy-Authorization: auth_token\r\n\r\n"),
5459 
5460       MockWrite("GET / HTTP/1.1\r\n"
5461                 "Host: www.example.org\r\n"
5462                 "Connection: keep-alive\r\n\r\n"),
5463   };
5464 
5465   MockRead data_reads2[] = {
5466       MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
5467 
5468       MockRead("HTTP/1.1 200 OK\r\n"),
5469       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5470       MockRead("Content-Length: 5\r\n\r\n"),
5471       MockRead(SYNCHRONOUS, "hello"),
5472   };
5473 
5474   StaticSocketDataProvider data1(data_reads1, data_writes1);
5475   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5476   StaticSocketDataProvider data2(data_reads2, data_writes2);
5477   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5478   SSLSocketDataProvider ssl(ASYNC, OK);
5479   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5480 
5481   auto trans =
5482       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5483 
5484   TestCompletionCallback callback;
5485   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5486   EXPECT_THAT(callback.GetResult(rv), IsOk());
5487 
5488   const HttpResponseInfo* response = trans->GetResponseInfo();
5489   ASSERT_TRUE(response);
5490   ASSERT_TRUE(response->headers);
5491   EXPECT_TRUE(response->headers->IsKeepAlive());
5492   EXPECT_EQ(407, response->headers->response_code());
5493   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5494   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5495   EXPECT_FALSE(response->auth_challenge.has_value());
5496 
5497   LoadTimingInfo load_timing_info;
5498   // CONNECT requests and responses are handled at the connect job level, so
5499   // the transaction does not yet have a connection.
5500   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
5501 
5502   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5503   EXPECT_THAT(callback.GetResult(rv), IsOk());
5504 
5505   response = trans->GetResponseInfo();
5506   ASSERT_TRUE(response);
5507   ASSERT_TRUE(response->headers);
5508   EXPECT_TRUE(response->headers->IsKeepAlive());
5509   EXPECT_EQ(200, response->headers->response_code());
5510   EXPECT_EQ(5, response->headers->GetContentLength());
5511   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5512 
5513   // The password prompt info should not be set.
5514   EXPECT_FALSE(response->auth_challenge.has_value());
5515 
5516   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5517   TestLoadTimingNotReusedWithPac(load_timing_info,
5518                                  CONNECT_TIMING_HAS_SSL_TIMES);
5519 
5520   trans.reset();
5521   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5522 }
5523 
5524 // Test a proxy auth scheme that allows default credentials and a proxy server
5525 // that hangs up when credentials are initially sent, and hangs up again when
5526 // they are retried.
TEST_P(HttpNetworkTransactionTest,AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice)5527 TEST_P(HttpNetworkTransactionTest,
5528        AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
5529   HttpRequestInfo request;
5530   request.method = "GET";
5531   request.url = GURL("https://www.example.org/");
5532   request.traffic_annotation =
5533       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5534 
5535   // Configure against proxy server "myproxy:70".
5536   session_deps_.proxy_resolution_service =
5537       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
5538           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
5539 
5540   auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
5541   auth_handler_factory->set_do_init_from_challenge(true);
5542   auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
5543   mock_handler->set_allows_default_credentials(true);
5544   auth_handler_factory->AddMockHandler(std::move(mock_handler),
5545                                        HttpAuth::AUTH_PROXY);
5546   session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
5547 
5548   // Add NetLog just so can verify load timing information gets a NetLog ID.
5549   session_deps_.net_log = NetLog::Get();
5550   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
5551 
5552   // Should try to establish tunnel.
5553   MockWrite data_writes1[] = {
5554       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5555                 "Host: www.example.org:443\r\n"
5556                 "Proxy-Connection: keep-alive\r\n\r\n"),
5557 
5558       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5559                 "Host: www.example.org:443\r\n"
5560                 "Proxy-Connection: keep-alive\r\n"
5561                 "Proxy-Authorization: auth_token\r\n\r\n"),
5562   };
5563 
5564   // The proxy responds to the connect with a 407, and then hangs up after the
5565   // second request is sent.
5566   MockRead data_reads1[] = {
5567       // No credentials.
5568       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5569       MockRead("Content-Length: 0\r\n"),
5570       MockRead("Proxy-Connection: keep-alive\r\n"),
5571       MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
5572       MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
5573   };
5574 
5575   // HttpNetworkTransaction sees a reused connection that was closed with
5576   // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
5577   // request.
5578   MockWrite data_writes2[] = {
5579       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5580                 "Host: www.example.org:443\r\n"
5581                 "Proxy-Connection: keep-alive\r\n\r\n"),
5582   };
5583 
5584   // The proxy, having had more than enough of us, just hangs up.
5585   MockRead data_reads2[] = {
5586       // No credentials.
5587       MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
5588   };
5589 
5590   StaticSocketDataProvider data1(data_reads1, data_writes1);
5591   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5592   StaticSocketDataProvider data2(data_reads2, data_writes2);
5593   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5594 
5595   auto trans =
5596       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5597 
5598   TestCompletionCallback callback;
5599   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5600   EXPECT_THAT(callback.GetResult(rv), IsOk());
5601 
5602   const HttpResponseInfo* response = trans->GetResponseInfo();
5603   ASSERT_TRUE(response);
5604   ASSERT_TRUE(response->headers);
5605   EXPECT_TRUE(response->headers->IsKeepAlive());
5606   EXPECT_EQ(407, response->headers->response_code());
5607   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5608   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5609   EXPECT_FALSE(response->auth_challenge.has_value());
5610 
5611   LoadTimingInfo load_timing_info;
5612   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
5613 
5614   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5615   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
5616 
5617   trans.reset();
5618   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5619 }
5620 
5621 // This test exercises an odd edge case where the proxy closes the connection
5622 // after the authentication handshake is complete. Presumably this technique is
5623 // used in lieu of returning a 403 or 5xx status code when the authentication
5624 // succeeds, but the user is not authorized to connect to the destination
5625 // server. There's no standard for what a proxy should do to indicate a blocked
5626 // site.
TEST_P(HttpNetworkTransactionTest,AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody)5627 TEST_P(HttpNetworkTransactionTest,
5628        AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
5629   HttpRequestInfo request;
5630   request.method = "GET";
5631   request.url = GURL("https://www.example.org/");
5632   request.traffic_annotation =
5633       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5634 
5635   // Configure against proxy server "myproxy:70".
5636   session_deps_.proxy_resolution_service =
5637       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
5638           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
5639 
5640   auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
5641   auth_handler_factory->set_do_init_from_challenge(true);
5642 
5643   // Create two mock AuthHandlers. This is because the transaction gets retried
5644   // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
5645   // was a real network error.
5646   //
5647   // The handlers support both default and explicit credentials. The retry
5648   // mentioned above should be able to reuse the default identity. Thus there
5649   // should never be a need to prompt for explicit credentials.
5650   auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
5651   mock_handler->set_allows_default_credentials(true);
5652   mock_handler->set_allows_explicit_credentials(true);
5653   mock_handler->set_connection_based(true);
5654   auth_handler_factory->AddMockHandler(std::move(mock_handler),
5655                                        HttpAuth::AUTH_PROXY);
5656   mock_handler = std::make_unique<HttpAuthHandlerMock>();
5657   mock_handler->set_allows_default_credentials(true);
5658   mock_handler->set_allows_explicit_credentials(true);
5659   mock_handler->set_connection_based(true);
5660   auth_handler_factory->AddMockHandler(std::move(mock_handler),
5661                                        HttpAuth::AUTH_PROXY);
5662   session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
5663 
5664   session_deps_.net_log = NetLog::Get();
5665   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
5666 
5667   // Data for both sockets.
5668   //
5669   // Writes are for the tunnel establishment attempts and the
5670   // authentication handshake.
5671   MockWrite data_writes1[] = {
5672       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5673                 "Host: www.example.org:443\r\n"
5674                 "Proxy-Connection: keep-alive\r\n\r\n"),
5675 
5676       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5677                 "Host: www.example.org:443\r\n"
5678                 "Proxy-Connection: keep-alive\r\n"
5679                 "Proxy-Authorization: auth_token\r\n\r\n"),
5680 
5681       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5682                 "Host: www.example.org:443\r\n"
5683                 "Proxy-Connection: keep-alive\r\n"
5684                 "Proxy-Authorization: auth_token\r\n\r\n"),
5685   };
5686 
5687   // The server side of the authentication handshake. Note that the response to
5688   // the final CONNECT request is ERR_CONNECTION_CLOSED.
5689   MockRead data_reads1[] = {
5690       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5691       MockRead("Content-Length: 0\r\n"),
5692       MockRead("Proxy-Connection: keep-alive\r\n"),
5693       MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
5694 
5695       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5696       MockRead("Content-Length: 0\r\n"),
5697       MockRead("Proxy-Connection: keep-alive\r\n"),
5698       MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
5699 
5700       MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
5701   };
5702 
5703   StaticSocketDataProvider data1(data_reads1, data_writes1);
5704   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5705 
5706   // The second socket is for the reconnection attempt. Data is identical to the
5707   // first attempt.
5708   StaticSocketDataProvider data2(data_reads1, data_writes1);
5709   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5710 
5711   auto trans =
5712       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5713 
5714   TestCompletionCallback callback;
5715   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5716 
5717   // Two rounds per handshake. After one retry, the error is propagated up the
5718   // stack.
5719   for (int i = 0; i < 4; ++i) {
5720     EXPECT_THAT(callback.GetResult(rv), IsOk());
5721 
5722     const HttpResponseInfo* response = trans->GetResponseInfo();
5723     ASSERT_TRUE(response);
5724     ASSERT_TRUE(response->headers);
5725     EXPECT_EQ(407, response->headers->response_code());
5726     ASSERT_TRUE(trans->IsReadyToRestartForAuth());
5727 
5728     rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5729   }
5730 
5731   // One shall be the number thou shalt retry, and the number of the retrying
5732   // shall be one.  Two shalt thou not retry, neither retry thou zero, excepting
5733   // that thou then proceed to one.  Three is right out.  Once the number one,
5734   // being the first number, be reached, then lobbest thou thy
5735   // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
5736   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
5737 
5738   trans.reset();
5739   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5740 }
5741 
5742 // Test a proxy auth scheme that allows default credentials and a proxy server
5743 // that hangs up when credentials are initially sent, and sends a challenge
5744 // again they are retried.
TEST_P(HttpNetworkTransactionTest,AuthAllowsDefaultCredentialsTunnelServerChallengesTwice)5745 TEST_P(HttpNetworkTransactionTest,
5746        AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
5747   HttpRequestInfo request;
5748   request.method = "GET";
5749   request.url = GURL("https://www.example.org/");
5750   request.traffic_annotation =
5751       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5752 
5753   // Configure against proxy server "myproxy:70".
5754   session_deps_.proxy_resolution_service =
5755       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
5756           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
5757 
5758   auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
5759   auth_handler_factory->set_do_init_from_challenge(true);
5760   auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
5761   mock_handler->set_allows_default_credentials(true);
5762   auth_handler_factory->AddMockHandler(std::move(mock_handler),
5763                                        HttpAuth::AUTH_PROXY);
5764   // Add another handler for the second challenge. It supports default
5765   // credentials, but they shouldn't be used, since they were already tried.
5766   mock_handler = std::make_unique<HttpAuthHandlerMock>();
5767   mock_handler->set_allows_default_credentials(true);
5768   auth_handler_factory->AddMockHandler(std::move(mock_handler),
5769                                        HttpAuth::AUTH_PROXY);
5770   session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
5771 
5772   // Add NetLog just so can verify load timing information gets a NetLog ID.
5773   session_deps_.net_log = NetLog::Get();
5774   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
5775 
5776   // Should try to establish tunnel.
5777   MockWrite data_writes1[] = {
5778       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5779                 "Host: www.example.org:443\r\n"
5780                 "Proxy-Connection: keep-alive\r\n\r\n"),
5781   };
5782 
5783   // The proxy responds to the connect with a 407, using a non-persistent
5784   // connection.
5785   MockRead data_reads1[] = {
5786       // No credentials.
5787       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5788       MockRead("Proxy-Authenticate: Mock\r\n"),
5789       MockRead("Proxy-Connection: close\r\n\r\n"),
5790   };
5791 
5792   // Since the first connection was closed, need to establish another once given
5793   // credentials.
5794   MockWrite data_writes2[] = {
5795       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5796                 "Host: www.example.org:443\r\n"
5797                 "Proxy-Connection: keep-alive\r\n"
5798                 "Proxy-Authorization: auth_token\r\n\r\n"),
5799   };
5800 
5801   MockRead data_reads2[] = {
5802       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5803       MockRead("Proxy-Authenticate: Mock\r\n"),
5804       MockRead("Proxy-Connection: close\r\n\r\n"),
5805   };
5806 
5807   StaticSocketDataProvider data1(data_reads1, data_writes1);
5808   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5809   StaticSocketDataProvider data2(data_reads2, data_writes2);
5810   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5811   SSLSocketDataProvider ssl(ASYNC, OK);
5812   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5813 
5814   auto trans =
5815       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5816 
5817   TestCompletionCallback callback;
5818   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5819   EXPECT_THAT(callback.GetResult(rv), IsOk());
5820 
5821   const HttpResponseInfo* response = trans->GetResponseInfo();
5822   ASSERT_TRUE(response);
5823   ASSERT_TRUE(response->headers);
5824   EXPECT_EQ(407, response->headers->response_code());
5825   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5826   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5827   EXPECT_FALSE(response->auth_challenge.has_value());
5828 
5829   LoadTimingInfo load_timing_info;
5830   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
5831 
5832   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5833   EXPECT_THAT(callback.GetResult(rv), IsOk());
5834   response = trans->GetResponseInfo();
5835   ASSERT_TRUE(response);
5836   ASSERT_TRUE(response->headers);
5837   EXPECT_EQ(407, response->headers->response_code());
5838   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5839   EXPECT_TRUE(response->auth_challenge.has_value());
5840 
5841   trans.reset();
5842   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5843 }
5844 
5845 // A more nuanced test than GenerateAuthToken test which asserts that
5846 // ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
5847 // unnecessarily invalidated, and that if the server co-operates, the
5848 // authentication handshake can continue with the same scheme but with a
5849 // different identity.
TEST_P(HttpNetworkTransactionTest,NonPermanentGenerateAuthTokenError)5850 TEST_P(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
5851   HttpRequestInfo request;
5852   request.method = "GET";
5853   request.url = GURL("http://www.example.org/");
5854   request.traffic_annotation =
5855       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5856 
5857   auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
5858   auth_handler_factory->set_do_init_from_challenge(true);
5859 
5860   // First handler. Uses default credentials, but barfs at generate auth token.
5861   auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
5862   mock_handler->set_allows_default_credentials(true);
5863   mock_handler->set_allows_explicit_credentials(true);
5864   mock_handler->set_connection_based(true);
5865   mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
5866   auth_handler_factory->AddMockHandler(std::move(mock_handler),
5867                                        HttpAuth::AUTH_SERVER);
5868 
5869   // Add another handler for the second challenge. It supports default
5870   // credentials, but they shouldn't be used, since they were already tried.
5871   mock_handler = std::make_unique<HttpAuthHandlerMock>();
5872   mock_handler->set_allows_default_credentials(true);
5873   mock_handler->set_allows_explicit_credentials(true);
5874   mock_handler->set_connection_based(true);
5875   auth_handler_factory->AddMockHandler(std::move(mock_handler),
5876                                        HttpAuth::AUTH_SERVER);
5877   session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
5878 
5879   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
5880 
5881   MockWrite data_writes1[] = {
5882       MockWrite("GET / HTTP/1.1\r\n"
5883                 "Host: www.example.org\r\n"
5884                 "Connection: keep-alive\r\n\r\n"),
5885   };
5886 
5887   MockRead data_reads1[] = {
5888       MockRead("HTTP/1.1 401 Authentication Required\r\n"
5889                "WWW-Authenticate: Mock\r\n"
5890                "Connection: keep-alive\r\n\r\n"),
5891   };
5892 
5893   // Identical to data_writes1[]. The AuthHandler encounters a
5894   // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
5895   // transaction procceds without an authorization header.
5896   MockWrite data_writes2[] = {
5897       MockWrite("GET / HTTP/1.1\r\n"
5898                 "Host: www.example.org\r\n"
5899                 "Connection: keep-alive\r\n\r\n"),
5900   };
5901 
5902   MockRead data_reads2[] = {
5903       MockRead("HTTP/1.1 401 Authentication Required\r\n"
5904                "WWW-Authenticate: Mock\r\n"
5905                "Connection: keep-alive\r\n\r\n"),
5906   };
5907 
5908   MockWrite data_writes3[] = {
5909       MockWrite("GET / HTTP/1.1\r\n"
5910                 "Host: www.example.org\r\n"
5911                 "Connection: keep-alive\r\n"
5912                 "Authorization: auth_token\r\n\r\n"),
5913   };
5914 
5915   MockRead data_reads3[] = {
5916       MockRead("HTTP/1.1 200 OK\r\n"
5917                "Content-Length: 5\r\n"
5918                "Content-Type: text/plain\r\n"
5919                "Connection: keep-alive\r\n\r\n"
5920                "Hello"),
5921   };
5922 
5923   StaticSocketDataProvider data1(data_reads1, data_writes1);
5924   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5925 
5926   StaticSocketDataProvider data2(data_reads2, data_writes2);
5927   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5928 
5929   StaticSocketDataProvider data3(data_reads3, data_writes3);
5930   session_deps_.socket_factory->AddSocketDataProvider(&data3);
5931 
5932   auto trans =
5933       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5934 
5935   TestCompletionCallback callback;
5936   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5937   EXPECT_THAT(callback.GetResult(rv), IsOk());
5938 
5939   const HttpResponseInfo* response = trans->GetResponseInfo();
5940   ASSERT_TRUE(response);
5941   ASSERT_TRUE(response->headers);
5942   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5943 
5944   // The following three tests assert that an authentication challenge was
5945   // received and that the stack is ready to respond to the challenge using
5946   // ambient credentials.
5947   EXPECT_EQ(401, response->headers->response_code());
5948   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5949   EXPECT_FALSE(response->auth_challenge.has_value());
5950 
5951   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5952   EXPECT_THAT(callback.GetResult(rv), IsOk());
5953   response = trans->GetResponseInfo();
5954   ASSERT_TRUE(response);
5955   ASSERT_TRUE(response->headers);
5956 
5957   // The following three tests assert that an authentication challenge was
5958   // received and that the stack needs explicit credentials before it is ready
5959   // to respond to the challenge.
5960   EXPECT_EQ(401, response->headers->response_code());
5961   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5962   EXPECT_TRUE(response->auth_challenge.has_value());
5963 
5964   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5965   EXPECT_THAT(callback.GetResult(rv), IsOk());
5966   response = trans->GetResponseInfo();
5967   ASSERT_TRUE(response);
5968   ASSERT_TRUE(response->headers);
5969   EXPECT_EQ(200, response->headers->response_code());
5970 
5971   trans.reset();
5972   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5973 }
5974 
5975 // Proxy resolver that returns a proxy with the same host and port for different
5976 // schemes, based on the path of the URL being requests.
5977 class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
5978  public:
5979   SameProxyWithDifferentSchemesProxyResolver() = default;
5980 
5981   SameProxyWithDifferentSchemesProxyResolver(
5982       const SameProxyWithDifferentSchemesProxyResolver&) = delete;
5983   SameProxyWithDifferentSchemesProxyResolver& operator=(
5984       const SameProxyWithDifferentSchemesProxyResolver&) = delete;
5985 
5986   ~SameProxyWithDifferentSchemesProxyResolver() override = default;
5987 
5988   static constexpr uint16_t kProxyPort = 10000;
5989 
ProxyHostPortPair()5990   static HostPortPair ProxyHostPortPair() {
5991     return HostPortPair("proxy.test", kProxyPort);
5992   }
5993 
ProxyHostPortPairAsString()5994   static std::string ProxyHostPortPairAsString() {
5995     return ProxyHostPortPair().ToString();
5996   }
5997 
5998   // ProxyResolver implementation.
GetProxyForURL(const GURL & url,const NetworkAnonymizationKey & network_anonymization_key,ProxyInfo * results,CompletionOnceCallback callback,std::unique_ptr<Request> * request,const NetLogWithSource &)5999   int GetProxyForURL(const GURL& url,
6000                      const NetworkAnonymizationKey& network_anonymization_key,
6001                      ProxyInfo* results,
6002                      CompletionOnceCallback callback,
6003                      std::unique_ptr<Request>* request,
6004                      const NetLogWithSource& /*net_log*/) override {
6005     *results = ProxyInfo();
6006     results->set_traffic_annotation(
6007         MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
6008     if (url.path() == "/socks4") {
6009       results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
6010       return OK;
6011     }
6012     if (url.path() == "/socks5") {
6013       results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
6014       return OK;
6015     }
6016     if (url.path() == "/http") {
6017       results->UsePacString("PROXY " + ProxyHostPortPairAsString());
6018       return OK;
6019     }
6020     if (url.path() == "/https") {
6021       results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
6022       return OK;
6023     }
6024     NOTREACHED();
6025     return ERR_NOT_IMPLEMENTED;
6026   }
6027 };
6028 
6029 class SameProxyWithDifferentSchemesProxyResolverFactory
6030     : public ProxyResolverFactory {
6031  public:
SameProxyWithDifferentSchemesProxyResolverFactory()6032   SameProxyWithDifferentSchemesProxyResolverFactory()
6033       : ProxyResolverFactory(false) {}
6034 
6035   SameProxyWithDifferentSchemesProxyResolverFactory(
6036       const SameProxyWithDifferentSchemesProxyResolverFactory&) = delete;
6037   SameProxyWithDifferentSchemesProxyResolverFactory& operator=(
6038       const SameProxyWithDifferentSchemesProxyResolverFactory&) = delete;
6039 
CreateProxyResolver(const scoped_refptr<PacFileData> & pac_script,std::unique_ptr<ProxyResolver> * resolver,CompletionOnceCallback callback,std::unique_ptr<Request> * request)6040   int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
6041                           std::unique_ptr<ProxyResolver>* resolver,
6042                           CompletionOnceCallback callback,
6043                           std::unique_ptr<Request>* request) override {
6044     *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
6045     return OK;
6046   }
6047 };
6048 
6049 // Check that when different proxy schemes are all applied to a proxy at the
6050 // same address, the connections are not grouped together.  i.e., a request to
6051 // foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
6052 // request to foo.com using proxy.com as an HTTP proxy.
TEST_P(HttpNetworkTransactionTest,SameDestinationForDifferentProxyTypes)6053 TEST_P(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
6054   session_deps_.proxy_resolution_service =
6055       std::make_unique<ConfiguredProxyResolutionService>(
6056           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6057               ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
6058           std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
6059           nullptr, /*quick_check_enabled=*/true);
6060 
6061   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
6062 
6063   MockWrite socks_writes[] = {
6064       MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
6065                 kSOCKS4OkRequestLocalHostPort80Length),
6066       MockWrite(SYNCHRONOUS,
6067                 "GET /socks4 HTTP/1.1\r\n"
6068                 "Host: test\r\n"
6069                 "Connection: keep-alive\r\n\r\n"),
6070   };
6071   MockRead socks_reads[] = {
6072       MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
6073       MockRead("HTTP/1.0 200 OK\r\n"
6074                "Connection: keep-alive\r\n"
6075                "Content-Length: 15\r\n\r\n"
6076                "SOCKS4 Response"),
6077   };
6078   StaticSocketDataProvider socks_data(socks_reads, socks_writes);
6079   session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
6080 
6081   const char kSOCKS5Request[] = {
6082       0x05,                  // Version
6083       0x01,                  // Command (CONNECT)
6084       0x00,                  // Reserved
6085       0x03,                  // Address type (DOMAINNAME)
6086       0x04,                  // Length of domain (4)
6087       't',  'e',  's', 't',  // Domain string
6088       0x00, 0x50,            // 16-bit port (80)
6089   };
6090   MockWrite socks5_writes[] = {
6091       MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
6092       MockWrite(ASYNC, kSOCKS5Request, std::size(kSOCKS5Request)),
6093       MockWrite(SYNCHRONOUS,
6094                 "GET /socks5 HTTP/1.1\r\n"
6095                 "Host: test\r\n"
6096                 "Connection: keep-alive\r\n\r\n"),
6097   };
6098   MockRead socks5_reads[] = {
6099       MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
6100       MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
6101       MockRead("HTTP/1.0 200 OK\r\n"
6102                "Connection: keep-alive\r\n"
6103                "Content-Length: 15\r\n\r\n"
6104                "SOCKS5 Response"),
6105   };
6106   StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
6107   session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
6108 
6109   MockWrite http_writes[] = {
6110       MockWrite(SYNCHRONOUS,
6111                 "GET http://test/http HTTP/1.1\r\n"
6112                 "Host: test\r\n"
6113                 "Proxy-Connection: keep-alive\r\n\r\n"),
6114   };
6115   MockRead http_reads[] = {
6116       MockRead("HTTP/1.1 200 OK\r\n"
6117                "Proxy-Connection: keep-alive\r\n"
6118                "Content-Length: 13\r\n\r\n"
6119                "HTTP Response"),
6120   };
6121   StaticSocketDataProvider http_data(http_reads, http_writes);
6122   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
6123 
6124   MockWrite https_writes[] = {
6125       MockWrite(SYNCHRONOUS,
6126                 "GET http://test/https HTTP/1.1\r\n"
6127                 "Host: test\r\n"
6128                 "Proxy-Connection: keep-alive\r\n\r\n"),
6129   };
6130   MockRead https_reads[] = {
6131       MockRead("HTTP/1.1 200 OK\r\n"
6132                "Proxy-Connection: keep-alive\r\n"
6133                "Content-Length: 14\r\n\r\n"
6134                "HTTPS Response"),
6135   };
6136   StaticSocketDataProvider https_data(https_reads, https_writes);
6137   session_deps_.socket_factory->AddSocketDataProvider(&https_data);
6138   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
6139   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6140 
6141   SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
6142   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6143 
6144   struct TestCase {
6145     GURL url;
6146     std::string expected_response;
6147     // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
6148     // after the test.
6149     int expected_idle_socks4_sockets;
6150     int expected_idle_socks5_sockets;
6151     // How many idle sockets there should be in the HTTP/HTTPS proxy socket
6152     // pools after the test.
6153     int expected_idle_http_sockets;
6154     int expected_idle_https_sockets;
6155   } const kTestCases[] = {
6156       {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0},
6157       {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0},
6158       {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0},
6159       {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1},
6160   };
6161 
6162   for (const auto& test_case : kTestCases) {
6163     SCOPED_TRACE(test_case.url);
6164 
6165     HttpRequestInfo request;
6166     request.method = "GET";
6167     request.url = test_case.url;
6168     request.traffic_annotation =
6169         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6170     ConnectedHandler connected_handler;
6171 
6172     auto transaction = std::make_unique<HttpNetworkTransaction>(
6173         DEFAULT_PRIORITY, session.get());
6174 
6175     transaction->SetConnectedCallback(connected_handler.Callback());
6176 
6177     TestCompletionCallback callback;
6178     int rv =
6179         transaction->Start(&request, callback.callback(), NetLogWithSource());
6180     EXPECT_THAT(callback.GetResult(rv), IsOk());
6181 
6182     const HttpResponseInfo* response = transaction->GetResponseInfo();
6183     ASSERT_TRUE(response);
6184     ASSERT_TRUE(response->headers);
6185     EXPECT_EQ(200, response->headers->response_code());
6186     std::string response_data;
6187     EXPECT_THAT(ReadTransaction(transaction.get(), &response_data), IsOk());
6188     EXPECT_EQ(test_case.expected_response, response_data);
6189 
6190     TransportInfo expected_transport;
6191     expected_transport.type = TransportType::kProxied;
6192     expected_transport.endpoint =
6193         IPEndPoint(IPAddress::IPv4Localhost(),
6194                    SameProxyWithDifferentSchemesProxyResolver::kProxyPort);
6195     expected_transport.negotiated_protocol = kProtoUnknown;
6196     EXPECT_THAT(connected_handler.transports(),
6197                 ElementsAre(expected_transport));
6198 
6199     // Return the socket to the socket pool, so can make sure it's not used for
6200     // the next requests.
6201     transaction.reset();
6202     base::RunLoop().RunUntilIdle();
6203 
6204     // Check the number of idle sockets in the pool, to make sure that used
6205     // sockets are indeed being returned to the socket pool.  If each request
6206     // doesn't return an idle socket to the pool, the test would incorrectly
6207     // pass.
6208     EXPECT_EQ(test_case.expected_idle_socks4_sockets,
6209               session
6210                   ->GetSocketPool(
6211                       HttpNetworkSession::NORMAL_SOCKET_POOL,
6212                       ProxyChain(ProxyServer::SCHEME_SOCKS4,
6213                                  SameProxyWithDifferentSchemesProxyResolver::
6214                                      ProxyHostPortPair()))
6215                   ->IdleSocketCount());
6216     EXPECT_EQ(test_case.expected_idle_socks5_sockets,
6217               session
6218                   ->GetSocketPool(
6219                       HttpNetworkSession::NORMAL_SOCKET_POOL,
6220                       ProxyChain(ProxyServer::SCHEME_SOCKS5,
6221                                  SameProxyWithDifferentSchemesProxyResolver::
6222                                      ProxyHostPortPair()))
6223                   ->IdleSocketCount());
6224     EXPECT_EQ(test_case.expected_idle_http_sockets,
6225               session
6226                   ->GetSocketPool(
6227                       HttpNetworkSession::NORMAL_SOCKET_POOL,
6228                       ProxyChain(ProxyServer::SCHEME_HTTP,
6229                                  SameProxyWithDifferentSchemesProxyResolver::
6230                                      ProxyHostPortPair()))
6231                   ->IdleSocketCount());
6232     EXPECT_EQ(test_case.expected_idle_https_sockets,
6233               session
6234                   ->GetSocketPool(
6235                       HttpNetworkSession::NORMAL_SOCKET_POOL,
6236                       ProxyChain(ProxyServer::SCHEME_HTTPS,
6237                                  SameProxyWithDifferentSchemesProxyResolver::
6238                                      ProxyHostPortPair()))
6239                   ->IdleSocketCount());
6240   }
6241 }
6242 
6243 // Test the load timing for HTTPS requests with an HTTP proxy.
TEST_P(HttpNetworkTransactionTest,HttpProxyLoadTimingNoPacTwoRequests)6244 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
6245   HttpRequestInfo request1;
6246   request1.method = "GET";
6247   request1.url = GURL("https://www.example.org/1");
6248   request1.traffic_annotation =
6249       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6250 
6251   HttpRequestInfo request2;
6252   request2.method = "GET";
6253   request2.url = GURL("https://www.example.org/2");
6254   request2.traffic_annotation =
6255       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6256 
6257   // Configure against proxy server "myproxy:70".
6258   session_deps_.proxy_resolution_service =
6259       ConfiguredProxyResolutionService::CreateFixedForTest(
6260           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6261   NetLogWithSource net_log_with_source =
6262       NetLogWithSource::Make(NetLogSourceType::NONE);
6263   session_deps_.net_log = NetLog::Get();
6264   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6265 
6266   // Since we have proxy, should try to establish tunnel.
6267   MockWrite data_writes1[] = {
6268       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6269                 "Host: www.example.org:443\r\n"
6270                 "Proxy-Connection: keep-alive\r\n\r\n"),
6271 
6272       MockWrite("GET /1 HTTP/1.1\r\n"
6273                 "Host: www.example.org\r\n"
6274                 "Connection: keep-alive\r\n\r\n"),
6275 
6276       MockWrite("GET /2 HTTP/1.1\r\n"
6277                 "Host: www.example.org\r\n"
6278                 "Connection: keep-alive\r\n\r\n"),
6279   };
6280 
6281   // The proxy responds to the connect with a 407, using a persistent
6282   // connection.
6283   MockRead data_reads1[] = {
6284       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
6285 
6286       MockRead("HTTP/1.1 200 OK\r\n"),
6287       MockRead("Content-Length: 1\r\n\r\n"),
6288       MockRead(SYNCHRONOUS, "1"),
6289 
6290       MockRead("HTTP/1.1 200 OK\r\n"),
6291       MockRead("Content-Length: 2\r\n\r\n"),
6292       MockRead(SYNCHRONOUS, "22"),
6293   };
6294 
6295   StaticSocketDataProvider data1(data_reads1, data_writes1);
6296   session_deps_.socket_factory->AddSocketDataProvider(&data1);
6297   SSLSocketDataProvider ssl(ASYNC, OK);
6298   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6299 
6300   TestCompletionCallback callback1;
6301   auto trans1 =
6302       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
6303 
6304   int rv = trans1->Start(&request1, callback1.callback(), net_log_with_source);
6305   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6306 
6307   rv = callback1.WaitForResult();
6308   EXPECT_THAT(rv, IsOk());
6309 
6310   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
6311   ASSERT_TRUE(response1);
6312   ASSERT_EQ(1u, response1->proxy_chain.length());
6313   EXPECT_TRUE(response1->proxy_chain.GetProxyServer(0).is_http());
6314   ASSERT_TRUE(response1->headers);
6315   EXPECT_EQ(1, response1->headers->GetContentLength());
6316 
6317   LoadTimingInfo load_timing_info1;
6318   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
6319   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
6320 
6321   trans1.reset();
6322 
6323   TestCompletionCallback callback2;
6324   auto trans2 =
6325       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
6326 
6327   rv = trans2->Start(&request2, callback2.callback(), net_log_with_source);
6328   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6329 
6330   rv = callback2.WaitForResult();
6331   EXPECT_THAT(rv, IsOk());
6332 
6333   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
6334   ASSERT_TRUE(response2);
6335   ASSERT_EQ(1u, response2->proxy_chain.length());
6336   EXPECT_TRUE(response2->proxy_chain.GetProxyServer(0).is_http());
6337   ASSERT_TRUE(response2->headers);
6338   EXPECT_EQ(2, response2->headers->GetContentLength());
6339 
6340   LoadTimingInfo load_timing_info2;
6341   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6342   TestLoadTimingReused(load_timing_info2);
6343 
6344   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
6345 
6346   trans2.reset();
6347   session->CloseAllConnections(ERR_FAILED, "Very good reason");
6348 }
6349 
6350 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
TEST_P(HttpNetworkTransactionTest,HttpProxyLoadTimingWithPacTwoRequests)6351 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
6352   HttpRequestInfo request1;
6353   request1.method = "GET";
6354   request1.url = GURL("https://www.example.org/1");
6355   request1.traffic_annotation =
6356       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6357 
6358   HttpRequestInfo request2;
6359   request2.method = "GET";
6360   request2.url = GURL("https://www.example.org/2");
6361   request2.traffic_annotation =
6362       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6363 
6364   // Configure against proxy server "myproxy:70".
6365   session_deps_.proxy_resolution_service =
6366       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
6367           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6368   NetLogWithSource net_log_with_source =
6369       NetLogWithSource::Make(NetLogSourceType::NONE);
6370   session_deps_.net_log = NetLog::Get();
6371   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6372 
6373   // Since we have proxy, should try to establish tunnel.
6374   MockWrite data_writes1[] = {
6375       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6376                 "Host: www.example.org:443\r\n"
6377                 "Proxy-Connection: keep-alive\r\n\r\n"),
6378 
6379       MockWrite("GET /1 HTTP/1.1\r\n"
6380                 "Host: www.example.org\r\n"
6381                 "Connection: keep-alive\r\n\r\n"),
6382 
6383       MockWrite("GET /2 HTTP/1.1\r\n"
6384                 "Host: www.example.org\r\n"
6385                 "Connection: keep-alive\r\n\r\n"),
6386   };
6387 
6388   // The proxy responds to the connect with a 407, using a persistent
6389   // connection.
6390   MockRead data_reads1[] = {
6391       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
6392 
6393       MockRead("HTTP/1.1 200 OK\r\n"),
6394       MockRead("Content-Length: 1\r\n\r\n"),
6395       MockRead(SYNCHRONOUS, "1"),
6396 
6397       MockRead("HTTP/1.1 200 OK\r\n"),
6398       MockRead("Content-Length: 2\r\n\r\n"),
6399       MockRead(SYNCHRONOUS, "22"),
6400   };
6401 
6402   StaticSocketDataProvider data1(data_reads1, data_writes1);
6403   session_deps_.socket_factory->AddSocketDataProvider(&data1);
6404   SSLSocketDataProvider ssl(ASYNC, OK);
6405   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6406 
6407   TestCompletionCallback callback1;
6408   auto trans1 =
6409       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
6410 
6411   int rv = trans1->Start(&request1, callback1.callback(), net_log_with_source);
6412   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6413 
6414   rv = callback1.WaitForResult();
6415   EXPECT_THAT(rv, IsOk());
6416 
6417   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
6418   ASSERT_TRUE(response1);
6419   ASSERT_TRUE(response1->headers);
6420   EXPECT_EQ(1, response1->headers->GetContentLength());
6421 
6422   LoadTimingInfo load_timing_info1;
6423   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
6424   TestLoadTimingNotReusedWithPac(load_timing_info1,
6425                                  CONNECT_TIMING_HAS_SSL_TIMES);
6426 
6427   trans1.reset();
6428 
6429   TestCompletionCallback callback2;
6430   auto trans2 =
6431       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
6432 
6433   rv = trans2->Start(&request2, callback2.callback(), net_log_with_source);
6434   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6435 
6436   rv = callback2.WaitForResult();
6437   EXPECT_THAT(rv, IsOk());
6438 
6439   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
6440   ASSERT_TRUE(response2);
6441   ASSERT_TRUE(response2->headers);
6442   EXPECT_EQ(2, response2->headers->GetContentLength());
6443 
6444   LoadTimingInfo load_timing_info2;
6445   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6446   TestLoadTimingReusedWithPac(load_timing_info2);
6447 
6448   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
6449 
6450   trans2.reset();
6451   session->CloseAllConnections(ERR_FAILED, "Very good reason");
6452 }
6453 
6454 // Make sure that NetworkAnonymizationKeys are passed down to the proxy layer.
TEST_P(HttpNetworkTransactionTest,ProxyResolvedWithNetworkAnonymizationKey)6455 TEST_P(HttpNetworkTransactionTest, ProxyResolvedWithNetworkAnonymizationKey) {
6456   const SchemefulSite kSite(GURL("https://foo.test/"));
6457   const SchemefulSite kOtherSite(GURL("https://bar.test/"));
6458   const NetworkIsolationKey kNetworkIsolationKey =
6459       NetworkIsolationKey(kSite, kOtherSite);
6460   const NetworkAnonymizationKey kNetworkAnonymizationKey =
6461       NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
6462           kNetworkIsolationKey);
6463 
6464   ProxyConfig proxy_config;
6465   proxy_config.set_auto_detect(true);
6466   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6467 
6468   CapturingProxyResolver capturing_proxy_resolver;
6469   capturing_proxy_resolver.set_proxy_chain(ProxyChain::Direct());
6470   session_deps_.proxy_resolution_service =
6471       std::make_unique<ConfiguredProxyResolutionService>(
6472           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6473               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6474           std::make_unique<CapturingProxyResolverFactory>(
6475               &capturing_proxy_resolver),
6476           nullptr, /*quick_check_enabled=*/true);
6477 
6478   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6479 
6480   // No need to continue with the network request - proxy resolution occurs
6481   // before establishing a data.
6482   StaticSocketDataProvider data{base::span<MockRead>(),
6483                                 base::span<MockWrite>()};
6484   data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_FAILED));
6485   session_deps_.socket_factory->AddSocketDataProvider(&data);
6486 
6487   // Run first request until an auth challenge is observed.
6488   HttpRequestInfo request;
6489   request.method = "GET";
6490   request.url = GURL("http://foo.test/");
6491   request.traffic_annotation =
6492       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6493   request.network_isolation_key = kNetworkIsolationKey;
6494   request.network_anonymization_key = kNetworkAnonymizationKey;
6495   HttpNetworkTransaction trans(LOWEST, session.get());
6496   TestCompletionCallback callback;
6497   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
6498   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_FAILED));
6499 
6500   ASSERT_EQ(1u, capturing_proxy_resolver.lookup_info().size());
6501   ASSERT_EQ(
6502       kNetworkAnonymizationKey,
6503       capturing_proxy_resolver.lookup_info()[0].network_anonymization_key);
6504   ASSERT_EQ(request.url, capturing_proxy_resolver.lookup_info()[0].url);
6505 }
6506 
6507 // Test that a failure in resolving the proxy hostname is retrievable.
TEST_P(HttpNetworkTransactionTest,ProxyHostResolutionFailure)6508 TEST_P(HttpNetworkTransactionTest, ProxyHostResolutionFailure) {
6509   HttpRequestInfo request;
6510   request.method = "GET";
6511   request.url = GURL("http://www.example.org/");
6512   request.traffic_annotation =
6513       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6514 
6515   // Configure against https proxy server "proxy:70".
6516   session_deps_.proxy_resolution_service =
6517       ConfiguredProxyResolutionService::CreateFixedForTest(
6518           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6519   auto resolver = std::make_unique<MockHostResolver>();
6520   resolver->rules()->AddSimulatedTimeoutFailure("proxy");
6521   session_deps_.net_log = net::NetLog::Get();
6522   session_deps_.host_resolver = std::move(resolver);
6523   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
6524   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6525   TestCompletionCallback callback;
6526 
6527   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
6528   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6529   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_CONNECTION_FAILED));
6530 
6531   const HttpResponseInfo* response = trans.GetResponseInfo();
6532   ASSERT_TRUE(response);
6533   EXPECT_THAT(response->resolve_error_info.error, IsError(ERR_DNS_TIMED_OUT));
6534 }
6535 
6536 // Test a simple GET (for an HTTP endpoint) through an HTTPS Proxy
6537 // (HTTPS -> HTTP).
TEST_P(HttpNetworkTransactionTest,HttpsProxyGet)6538 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
6539   HttpRequestInfo request;
6540   request.method = "GET";
6541   request.url = GURL("http://www.example.org/");
6542   request.traffic_annotation =
6543       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6544 
6545   // Configure against https proxy server "proxy:70".
6546   session_deps_.proxy_resolution_service =
6547       ConfiguredProxyResolutionService::CreateFixedForTest(
6548           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6549   session_deps_.net_log = NetLog::Get();
6550   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6551 
6552   // Since we have proxy, should use full url
6553   MockWrite data_writes1[] = {
6554       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6555                 "Host: www.example.org\r\n"
6556                 "Proxy-Connection: keep-alive\r\n\r\n"),
6557   };
6558 
6559   MockRead data_reads1[] = {
6560       MockRead("HTTP/1.1 200 OK\r\n"),
6561       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6562       MockRead("Content-Length: 100\r\n\r\n"),
6563       MockRead(SYNCHRONOUS, OK),
6564   };
6565 
6566   StaticSocketDataProvider data1(data_reads1, data_writes1);
6567   session_deps_.socket_factory->AddSocketDataProvider(&data1);
6568   SSLSocketDataProvider ssl(ASYNC, OK);
6569   ssl.ssl_info.cert =
6570       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
6571   ASSERT_TRUE(ssl.ssl_info.cert);
6572   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6573 
6574   ConnectedHandler connected_handler;
6575   TestCompletionCallback callback;
6576 
6577   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6578 
6579   trans.SetConnectedCallback(connected_handler.Callback());
6580 
6581   int rv = trans.Start(&request, callback.callback(),
6582                        NetLogWithSource::Make(NetLogSourceType::NONE));
6583   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6584 
6585   rv = callback.WaitForResult();
6586   EXPECT_THAT(rv, IsOk());
6587 
6588   LoadTimingInfo load_timing_info;
6589   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
6590   TestLoadTimingNotReused(load_timing_info,
6591                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6592 
6593   const HttpResponseInfo* response = trans.GetResponseInfo();
6594   ASSERT_TRUE(response);
6595 
6596   ASSERT_EQ(1u, response->proxy_chain.length());
6597   EXPECT_TRUE(response->proxy_chain.GetProxyServer(0).is_https());
6598   EXPECT_TRUE(response->headers->IsKeepAlive());
6599   EXPECT_EQ(200, response->headers->response_code());
6600   EXPECT_EQ(100, response->headers->GetContentLength());
6601   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6602 
6603   // DNS aliases should be empty when using a proxy.
6604   EXPECT_TRUE(response->dns_aliases.empty());
6605 
6606   TransportInfo expected_transport;
6607   expected_transport.type = TransportType::kProxied;
6608   expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 70);
6609   expected_transport.negotiated_protocol = kProtoUnknown;
6610   EXPECT_THAT(connected_handler.transports(), ElementsAre(expected_transport));
6611 
6612   // The password prompt info should not be set.
6613   EXPECT_FALSE(response->auth_challenge.has_value());
6614 
6615   // Although we use an HTTPS proxy, the `SSLInfo` from that connection should
6616   // not be reported as a property of the origin.
6617   EXPECT_FALSE(response->ssl_info.cert);
6618 }
6619 
6620 // Test a simple GET (for an HTTP endpoint) through two HTTPS proxies
6621 // (HTTPS -> HTTPS -> HTTP). This should tunnel through both proxies.
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyGet)6622 TEST_P(HttpNetworkTransactionTest, HttpsNestedProxyGet) {
6623   HttpRequestInfo request;
6624   request.method = "GET";
6625   request.url = GURL("http://www.example.org/");
6626   request.traffic_annotation =
6627       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6628 
6629   // Configure a nested proxy.
6630   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
6631                                   HostPortPair("proxy1.test", 70)};
6632   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
6633                                   HostPortPair("proxy2.test", 71)};
6634   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
6635 
6636   ProxyList proxy_list;
6637   proxy_list.AddProxyChain(kNestedProxyChain);
6638   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
6639 
6640   session_deps_.proxy_resolution_service =
6641       ConfiguredProxyResolutionService::CreateFixedForTest(
6642           ProxyConfigWithAnnotation(proxy_config,
6643                                     TRAFFIC_ANNOTATION_FOR_TESTS));
6644   session_deps_.net_log = NetLog::Get();
6645   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6646 
6647   MockWrite data_writes1[] = {
6648       MockWrite("CONNECT proxy2.test:71 HTTP/1.1\r\n"
6649                 "Host: proxy2.test:71\r\n"
6650                 "Proxy-Connection: keep-alive\r\n\r\n"),
6651       MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
6652                 "Host: www.example.org:80\r\n"
6653                 "Proxy-Connection: keep-alive\r\n\r\n"),
6654       MockWrite("GET / HTTP/1.1\r\n"
6655                 "Host: www.example.org\r\n"
6656                 "Connection: keep-alive\r\n\r\n"),
6657   };
6658 
6659   MockRead data_reads1[] = {
6660       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
6661       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
6662       MockRead("HTTP/1.1 200 OK\r\n"),
6663       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6664       MockRead("Content-Length: 100\r\n\r\n"),
6665       MockRead(SYNCHRONOUS, OK),
6666   };
6667 
6668   StaticSocketDataProvider data1(data_reads1, data_writes1);
6669   session_deps_.socket_factory->AddSocketDataProvider(&data1);
6670 
6671   SSLSocketDataProvider ssl(ASYNC, OK);
6672   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6673 
6674   SSLSocketDataProvider ssl2(ASYNC, OK);
6675   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6676 
6677   ConnectedHandler connected_handler;
6678   TestCompletionCallback callback;
6679 
6680   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6681 
6682   trans.SetConnectedCallback(connected_handler.Callback());
6683 
6684   int rv = trans.Start(&request, callback.callback(),
6685                        NetLogWithSource::Make(NetLogSourceType::NONE));
6686   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6687 
6688   rv = callback.WaitForResult();
6689   EXPECT_THAT(rv, IsOk());
6690 
6691   LoadTimingInfo load_timing_info;
6692   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
6693   TestLoadTimingNotReused(load_timing_info,
6694                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6695 
6696   const HttpResponseInfo* response = trans.GetResponseInfo();
6697   ASSERT_TRUE(response);
6698 
6699   EXPECT_EQ(2u, response->proxy_chain.length());
6700   EXPECT_TRUE(response->proxy_chain.GetProxyServer(0).is_https());
6701   EXPECT_TRUE(response->proxy_chain.GetProxyServer(1).is_https());
6702   EXPECT_TRUE(response->headers->IsKeepAlive());
6703   EXPECT_EQ(200, response->headers->response_code());
6704   EXPECT_EQ(100, response->headers->GetContentLength());
6705   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6706 
6707   // DNS aliases should be empty when using a proxy.
6708   EXPECT_TRUE(response->dns_aliases.empty());
6709 
6710   TransportInfo expected_transport;
6711   expected_transport.type = TransportType::kProxied;
6712   expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 70);
6713   EXPECT_THAT(connected_handler.transports(), ElementsAre(expected_transport));
6714 
6715   // The password prompt info should not be set.
6716   EXPECT_FALSE(response->auth_challenge.has_value());
6717 
6718   // Although we use an HTTPS proxy, the `SSLInfo` from that connection should
6719   // not be reported as a property of the origin.
6720   EXPECT_FALSE(response->ssl_info.cert);
6721 }
6722 
6723 // Test a SPDY GET (for an HTTP endpoint) through an HTTPS (SPDY) proxy
6724 // (SPDY -> HTTP).
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyGet)6725 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
6726   HttpRequestInfo request;
6727   request.method = "GET";
6728   request.url = GURL("http://www.example.org/");
6729   request.traffic_annotation =
6730       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6731 
6732   // Configure against https proxy server "proxy:70".
6733   session_deps_.proxy_resolution_service =
6734       ConfiguredProxyResolutionService::CreateFixedForTest(
6735           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6736   session_deps_.net_log = NetLog::Get();
6737   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6738 
6739   // fetch http://www.example.org/ via SPDY
6740   spdy::SpdySerializedFrame req(
6741       spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
6742   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
6743 
6744   spdy::SpdySerializedFrame resp(
6745       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6746   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
6747   MockRead spdy_reads[] = {
6748       CreateMockRead(resp, 1),
6749       CreateMockRead(data, 2),
6750       MockRead(ASYNC, 0, 3),
6751   };
6752 
6753   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
6754   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6755 
6756   SSLSocketDataProvider ssl(ASYNC, OK);
6757   ssl.ssl_info.cert =
6758       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
6759   ASSERT_TRUE(ssl.ssl_info.cert);
6760   ssl.next_proto = kProtoHTTP2;
6761   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6762 
6763   ConnectedHandler connected_handler;
6764   TestCompletionCallback callback;
6765 
6766   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6767 
6768   trans.SetConnectedCallback(connected_handler.Callback());
6769 
6770   int rv = trans.Start(&request, callback.callback(),
6771                        NetLogWithSource::Make(NetLogSourceType::NONE));
6772   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6773 
6774   rv = callback.WaitForResult();
6775   EXPECT_THAT(rv, IsOk());
6776 
6777   LoadTimingInfo load_timing_info;
6778   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
6779   TestLoadTimingNotReused(load_timing_info,
6780                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6781 
6782   const HttpResponseInfo* response = trans.GetResponseInfo();
6783   ASSERT_TRUE(response);
6784   EXPECT_EQ(1u, response->proxy_chain.length());
6785   EXPECT_TRUE(response->proxy_chain.GetProxyServer(0).is_https());
6786   ASSERT_TRUE(response->headers);
6787   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6788 
6789   // DNS aliases should be empty when using a proxy.
6790   EXPECT_TRUE(response->dns_aliases.empty());
6791 
6792   TransportInfo expected_transport;
6793   expected_transport.type = TransportType::kProxied;
6794   expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 70);
6795   expected_transport.negotiated_protocol = kProtoHTTP2;
6796   EXPECT_THAT(connected_handler.transports(), ElementsAre(expected_transport));
6797 
6798   std::string response_data;
6799   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
6800   EXPECT_EQ(kUploadData, response_data);
6801 
6802   // Although we use an HTTPS proxy, the `SSLInfo` from that connection should
6803   // not be reported as a property of the origin.
6804   EXPECT_FALSE(response->ssl_info.cert);
6805 }
6806 
6807 // Test a SPDY GET (for an HTTP endpoint) through two HTTPS (SPDY) proxies
6808 // (SPDY -> SPDY -> HTTP).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxySpdyGet)6809 TEST_P(HttpNetworkTransactionTest, HttpsNestedProxySpdyGet) {
6810   HttpRequestInfo request;
6811   request.method = "GET";
6812   request.url = GURL("http://www.example.org/");
6813   request.traffic_annotation =
6814       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6815 
6816   // Configure a nested proxy.
6817   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
6818                                   HostPortPair("proxy1.test", 70)};
6819   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
6820                                   HostPortPair("proxy2.test", 71)};
6821   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
6822 
6823   ProxyList proxy_list;
6824   proxy_list.AddProxyChain(kNestedProxyChain);
6825   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
6826 
6827   session_deps_.proxy_resolution_service =
6828       ConfiguredProxyResolutionService::CreateFixedForTest(
6829           ProxyConfigWithAnnotation(proxy_config,
6830                                     TRAFFIC_ANNOTATION_FOR_TESTS));
6831   session_deps_.net_log = NetLog::Get();
6832   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6833 
6834   // CONNECT to proxy2.test:71 via SPDY.
6835   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
6836       /*extra_headers=*/nullptr, 0, 1,
6837       HttpProxyConnectJob::kH2QuicTunnelPriority,
6838       kProxyServer2.host_port_pair()));
6839 
6840   spdy::SpdySerializedFrame proxy2_connect_resp(
6841       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6842 
6843   // CONNECT to www.example.org:80 via SPDY.
6844   // Need to use a new `SpdyTestUtil()` so that the stream parent ID of this
6845   // request is calculated correctly.
6846   SpdyTestUtil spdy_util2(/*use_priority_header=*/true);
6847   spdy::SpdySerializedFrame endpoint_connect(spdy_util2.ConstructSpdyConnect(
6848       /*extra_headers=*/nullptr, 0, 1,
6849       HttpProxyConnectJob::kH2QuicTunnelPriority,
6850       HostPortPair("www.example.org", 80)));
6851   spdy::SpdySerializedFrame wrapped_endpoint_connect(
6852       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect, 1));
6853 
6854   spdy::SpdySerializedFrame endpoint_connect_resp(
6855       spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6856   spdy::SpdySerializedFrame wrapped_endpoint_connect_resp(
6857       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect_resp, 1));
6858 
6859   // fetch http://www.example.org/ via HTTP.
6860   // Since this request will go over two tunnels, it needs to be double-wrapped.
6861   const char kGet[] =
6862       "GET / HTTP/1.1\r\n"
6863       "Host: www.example.org\r\n"
6864       "Connection: keep-alive\r\n\r\n";
6865   spdy::SpdySerializedFrame wrapped_get(
6866       spdy_util2.ConstructSpdyDataFrame(1, kGet, false));
6867   spdy::SpdySerializedFrame wrapped_wrapped_get(
6868       spdy_util_.ConstructWrappedSpdyFrame(wrapped_get, 1));
6869 
6870   const char kResp[] =
6871       "HTTP/1.1 200 OK\r\n"
6872       "Content-Length: 10\r\n\r\n";
6873   spdy::SpdySerializedFrame wrapped_get_resp(
6874       spdy_util2.ConstructSpdyDataFrame(1, kResp, false));
6875   spdy::SpdySerializedFrame wrapped_wrapped_get_resp(
6876       spdy_util_.ConstructWrappedSpdyFrame(wrapped_get_resp, 1));
6877 
6878   const char kRespData[] = "1234567890";
6879   spdy::SpdySerializedFrame wrapped_body(
6880       spdy_util2.ConstructSpdyDataFrame(1, kRespData, false));
6881   spdy::SpdySerializedFrame wrapped_wrapped_body(
6882       spdy_util_.ConstructWrappedSpdyFrame(wrapped_body, 1));
6883 
6884   MockWrite spdy_writes[] = {
6885       CreateMockWrite(proxy2_connect, 0),
6886       CreateMockWrite(wrapped_endpoint_connect, 2),
6887       CreateMockWrite(wrapped_wrapped_get, 5),
6888   };
6889 
6890   MockRead spdy_reads[] = {
6891       CreateMockRead(proxy2_connect_resp, 1),
6892       // TODO(https://crbug.com/497228): We have to manually delay this read so
6893       // that the higher-level SPDY stream doesn't get notified of an available
6894       // read before the write it initiated (the second CONNECT) finishes,
6895       // triggering a DCHECK.
6896       MockRead(ASYNC, ERR_IO_PENDING, 3),
6897       CreateMockRead(wrapped_endpoint_connect_resp, 4, ASYNC),
6898       CreateMockRead(wrapped_wrapped_get_resp, 6, ASYNC),
6899       CreateMockRead(wrapped_wrapped_body, 7, ASYNC),
6900       MockRead(ASYNC, 0, 8),
6901   };
6902 
6903   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
6904   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6905 
6906   SSLSocketDataProvider ssl(ASYNC, OK);
6907   ssl.next_proto = kProtoHTTP2;
6908   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6909 
6910   SSLSocketDataProvider ssl2(ASYNC, OK);
6911   ssl2.next_proto = kProtoHTTP2;
6912   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6913 
6914   ConnectedHandler connected_handler;
6915   TestCompletionCallback callback;
6916 
6917   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6918 
6919   trans.SetConnectedCallback(connected_handler.Callback());
6920 
6921   int rv = trans.Start(&request, callback.callback(),
6922                        NetLogWithSource::Make(NetLogSourceType::NONE));
6923   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6924 
6925   spdy_data.RunUntilPaused();
6926   base::RunLoop().RunUntilIdle();
6927   spdy_data.Resume();
6928 
6929   rv = callback.WaitForResult();
6930   ASSERT_THAT(rv, IsOk());
6931 
6932   LoadTimingInfo load_timing_info;
6933   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
6934   TestLoadTimingNotReused(load_timing_info,
6935                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6936 
6937   const HttpResponseInfo* response = trans.GetResponseInfo();
6938   ASSERT_TRUE(response);
6939   EXPECT_EQ(response->proxy_chain.GetProxyServer(/*chain_index=*/0),
6940             kProxyServer1);
6941   EXPECT_EQ(response->proxy_chain.GetProxyServer(/*chain_index=*/1),
6942             kProxyServer2);
6943   ASSERT_TRUE(response->headers);
6944   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6945 
6946   // DNS aliases should be empty when using a proxy.
6947   EXPECT_TRUE(response->dns_aliases.empty());
6948 
6949   TransportInfo expected_transport;
6950   expected_transport.type = TransportType::kProxied;
6951   expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 70);
6952   expected_transport.negotiated_protocol = kProtoUnknown;
6953   EXPECT_THAT(connected_handler.transports(), ElementsAre(expected_transport));
6954 
6955   std::string response_data;
6956   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
6957   EXPECT_EQ(kRespData, response_data);
6958 
6959   // Although we use an HTTPS proxy, the `SSLInfo` from that connection should
6960   // not be reported as a property of the origin.
6961   EXPECT_FALSE(response->ssl_info.cert);
6962 }
6963 
6964 // Test a SPDY GET (for an HTTP endpoint) through the same HTTPS (SPDY) proxy
6965 // twice (SPDY -> SPDY -> HTTP).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxySameProxyTwiceSpdyGet)6966 TEST_P(HttpNetworkTransactionTest, HttpsNestedProxySameProxyTwiceSpdyGet) {
6967   HttpRequestInfo request;
6968   request.method = "GET";
6969   request.url = GURL("http://www.example.org/");
6970   request.traffic_annotation =
6971       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6972 
6973   // Configure a nested proxy.
6974   const ProxyServer kProxyServer{ProxyServer::SCHEME_HTTPS,
6975                                  HostPortPair("proxy.test", 70)};
6976   const ProxyChain kNestedProxyChain{{kProxyServer, kProxyServer}};
6977 
6978   ProxyList proxy_list;
6979   proxy_list.AddProxyChain(kNestedProxyChain);
6980   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
6981 
6982   session_deps_.proxy_resolution_service =
6983       ConfiguredProxyResolutionService::CreateFixedForTest(
6984           ProxyConfigWithAnnotation(proxy_config,
6985                                     TRAFFIC_ANNOTATION_FOR_TESTS));
6986 
6987   session_deps_.net_log = NetLog::Get();
6988   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6989 
6990   // CONNECT to proxy.test:70 via SPDY.
6991   spdy::SpdySerializedFrame proxy_connect(spdy_util_.ConstructSpdyConnect(
6992       /*extra_headers=*/nullptr, 0, 1,
6993       HttpProxyConnectJob::kH2QuicTunnelPriority,
6994       kProxyServer.host_port_pair()));
6995 
6996   spdy::SpdySerializedFrame proxy_connect_resp(
6997       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6998 
6999   // CONNECT to www.example.org:80 via SPDY.
7000   // Need to use a new `SpdyTestUtil()` so that the stream parent ID of this
7001   // request is calculated correctly.
7002   SpdyTestUtil new_spdy_util(/*use_priority_header=*/true);
7003   spdy::SpdySerializedFrame endpoint_connect(new_spdy_util.ConstructSpdyConnect(
7004       /*extra_headers=*/nullptr, 0, 1,
7005       HttpProxyConnectJob::kH2QuicTunnelPriority,
7006       HostPortPair("www.example.org", 80)));
7007   spdy::SpdySerializedFrame wrapped_endpoint_connect(
7008       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect, 1));
7009 
7010   spdy::SpdySerializedFrame endpoint_connect_resp(
7011       new_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
7012   spdy::SpdySerializedFrame wrapped_endpoint_connect_resp(
7013       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect_resp, 1));
7014 
7015   // fetch http://www.example.org/ via HTTP.
7016   // Since this request will go over two tunnels, it needs to be double-wrapped.
7017   const char kGet[] =
7018       "GET / HTTP/1.1\r\n"
7019       "Host: www.example.org\r\n"
7020       "Connection: keep-alive\r\n\r\n";
7021   spdy::SpdySerializedFrame wrapped_get(
7022       new_spdy_util.ConstructSpdyDataFrame(1, kGet, false));
7023   spdy::SpdySerializedFrame wrapped_wrapped_get(
7024       spdy_util_.ConstructWrappedSpdyFrame(wrapped_get, 1));
7025 
7026   const char kResp[] =
7027       "HTTP/1.1 200 OK\r\n"
7028       "Content-Length: 10\r\n\r\n";
7029   spdy::SpdySerializedFrame wrapped_get_resp(
7030       new_spdy_util.ConstructSpdyDataFrame(1, kResp, false));
7031   spdy::SpdySerializedFrame wrapped_wrapped_get_resp(
7032       spdy_util_.ConstructWrappedSpdyFrame(wrapped_get_resp, 1));
7033 
7034   const char kRespData[] = "1234567890";
7035   spdy::SpdySerializedFrame wrapped_body(
7036       new_spdy_util.ConstructSpdyDataFrame(1, kRespData, false));
7037   spdy::SpdySerializedFrame wrapped_wrapped_body(
7038       spdy_util_.ConstructWrappedSpdyFrame(wrapped_body, 1));
7039 
7040   MockWrite spdy_writes[] = {
7041       CreateMockWrite(proxy_connect, 0),
7042       CreateMockWrite(wrapped_endpoint_connect, 2),
7043       CreateMockWrite(wrapped_wrapped_get, 5),
7044   };
7045 
7046   MockRead spdy_reads[] = {
7047       CreateMockRead(proxy_connect_resp, 1),
7048       // TODO(https://crbug.com/497228): We have to manually delay this read so
7049       // that the higher-level SPDY stream doesn't get notified of an available
7050       // read before the write it initiated (the second CONNECT) finishes,
7051       // triggering a DCHECK.
7052       MockRead(ASYNC, ERR_IO_PENDING, 3),
7053       CreateMockRead(wrapped_endpoint_connect_resp, 4, ASYNC),
7054       CreateMockRead(wrapped_wrapped_get_resp, 6, ASYNC),
7055       CreateMockRead(wrapped_wrapped_body, 7, ASYNC),
7056       MockRead(ASYNC, 0, 8),
7057   };
7058 
7059   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
7060   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7061 
7062   SSLSocketDataProvider ssl(ASYNC, OK);
7063   ssl.next_proto = kProtoHTTP2;
7064   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7065 
7066   SSLSocketDataProvider ssl2(ASYNC, OK);
7067   ssl2.next_proto = kProtoHTTP2;
7068   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7069 
7070   ConnectedHandler connected_handler;
7071   TestCompletionCallback callback;
7072 
7073   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7074 
7075   trans.SetConnectedCallback(connected_handler.Callback());
7076 
7077   int rv = trans.Start(&request, callback.callback(),
7078                        NetLogWithSource::Make(NetLogSourceType::NONE));
7079   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7080 
7081   spdy_data.RunUntilPaused();
7082   base::RunLoop().RunUntilIdle();
7083   spdy_data.Resume();
7084 
7085   rv = callback.WaitForResult();
7086   ASSERT_THAT(rv, IsOk());
7087 
7088   LoadTimingInfo load_timing_info;
7089   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
7090   TestLoadTimingNotReused(load_timing_info,
7091                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7092 
7093   const HttpResponseInfo* response = trans.GetResponseInfo();
7094   ASSERT_TRUE(response);
7095   EXPECT_EQ(response->proxy_chain.GetProxyServer(/*chain_index=*/0),
7096             kProxyServer);
7097   EXPECT_EQ(response->proxy_chain.GetProxyServer(/*chain_index=*/1),
7098             kProxyServer);
7099   ASSERT_TRUE(response->headers);
7100   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7101 
7102   // DNS aliases should be empty when using a proxy.
7103   EXPECT_TRUE(response->dns_aliases.empty());
7104 
7105   TransportInfo expected_transport;
7106   expected_transport.type = TransportType::kProxied;
7107   expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 70);
7108   expected_transport.negotiated_protocol = kProtoUnknown;
7109   EXPECT_THAT(connected_handler.transports(), ElementsAre(expected_transport));
7110 
7111   std::string response_data;
7112   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
7113   EXPECT_EQ(kRespData, response_data);
7114 
7115   // Although we use an HTTPS proxy, the `SSLInfo` from that connection should
7116   // not be reported as a property of the origin.
7117   EXPECT_FALSE(response->ssl_info.cert);
7118 }
7119 
7120 // Test that a SPDY protocol error encountered when attempting to perform an
7121 // HTTP request over a multi-proxy chain is handled correctly.
TEST_P(HttpNetworkTransactionTest,NestedProxyHttpOverSpdyProtocolError)7122 TEST_P(HttpNetworkTransactionTest, NestedProxyHttpOverSpdyProtocolError) {
7123   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
7124                                   HostPortPair("proxy1.test", 70)};
7125   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
7126                                   HostPortPair("proxy2.test", 71)};
7127   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
7128 
7129   ProxyList proxy_list;
7130   proxy_list.AddProxyChain(kNestedProxyChain);
7131   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
7132 
7133   session_deps_.proxy_resolution_service =
7134       ConfiguredProxyResolutionService::CreateFixedForTest(
7135           ProxyConfigWithAnnotation(proxy_config,
7136                                     TRAFFIC_ANNOTATION_FOR_TESTS));
7137   session_deps_.net_log = NetLog::Get();
7138   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7139 
7140   // CONNECT to proxy2.test:71 via SPDY.
7141   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
7142       /*extra_headers=*/nullptr, 0, 1,
7143       HttpProxyConnectJob::kH2QuicTunnelPriority,
7144       kProxyServer2.host_port_pair()));
7145 
7146   spdy::SpdySerializedFrame proxy2_connect_resp(
7147       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7148 
7149   // CONNECT to www.example.org:80 via SPDY.
7150   // Need to use a new `SpdyTestUtil()` so that the stream parent ID of this
7151   // request is calculated correctly.
7152   SpdyTestUtil spdy_util2(/*use_priority_header=*/true);
7153   spdy::SpdySerializedFrame endpoint_connect(spdy_util2.ConstructSpdyConnect(
7154       /*extra_headers=*/nullptr, 0, 1,
7155       HttpProxyConnectJob::kH2QuicTunnelPriority,
7156       HostPortPair("www.example.org", 80)));
7157   spdy::SpdySerializedFrame wrapped_endpoint_connect(
7158       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect, 1));
7159 
7160   spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
7161   spdy::SpdySerializedFrame wrapped_data(
7162       spdy_util_.ConstructWrappedSpdyFrame(data, 1));
7163 
7164   MockWrite spdy_writes[] = {
7165       CreateMockWrite(proxy2_connect, 0),
7166       CreateMockWrite(wrapped_endpoint_connect, 2),
7167   };
7168 
7169   MockRead spdy_reads[] = {
7170       CreateMockRead(proxy2_connect_resp, 1),
7171       // TODO(https://crbug.com/497228): We have to manually delay this read so
7172       // that the higher-level SPDY stream doesn't get notified of an available
7173       // read before the write it initiated (the second CONNECT) finishes,
7174       // triggering a DCHECK.
7175       MockRead(ASYNC, ERR_IO_PENDING, 3),
7176       // Instead of returning a valid response, just return wrapped data. This
7177       // should trigger an HTTP2 protocol error and not CHECK when nested
7178       // proxies are in use.
7179       CreateMockRead(wrapped_data, 4),
7180       MockRead(ASYNC, 0, 5),
7181   };
7182 
7183   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
7184   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7185 
7186   SSLSocketDataProvider ssl(ASYNC, OK);
7187   ssl.next_proto = kProtoHTTP2;
7188   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7189 
7190   SSLSocketDataProvider ssl2(ASYNC, OK);
7191   ssl2.next_proto = kProtoHTTP2;
7192   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7193 
7194   HttpRequestInfo request;
7195   request.method = "GET";
7196   request.url = GURL("http://www.example.org/");
7197   request.traffic_annotation =
7198       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7199 
7200   TestCompletionCallback callback;
7201 
7202   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7203 
7204   int rv = trans.Start(&request, callback.callback(),
7205                        NetLogWithSource::Make(NetLogSourceType::NONE));
7206   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7207 
7208   spdy_data.RunUntilPaused();
7209   base::RunLoop().RunUntilIdle();
7210   spdy_data.Resume();
7211 
7212   rv = callback.WaitForResult();
7213   ASSERT_THAT(rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
7214 }
7215 
7216 // Test that a proxy server requesting a client auth cert doesn't cause a crash.
7217 // TODO(https://crbug.com/1491092): This test can be deleted once we no longer
7218 // need the multi-proxy chain version below, since this functionality should
7219 // be sufficiently tested elsewhere. For now this test just shows that
7220 // single-proxy and multi-proxy behavior is consistent (when a read returns
7221 // ERR_SSL_CLIENT_AUTH_CERT_NEEDED).
TEST_P(HttpNetworkTransactionTest,HttpsClientAuthCertNeededNoCrash)7222 TEST_P(HttpNetworkTransactionTest, HttpsClientAuthCertNeededNoCrash) {
7223   // Configure against https proxy server "proxy:70".
7224   session_deps_.proxy_resolution_service =
7225       ConfiguredProxyResolutionService::CreateFixedForTest(
7226           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
7227 
7228   session_deps_.net_log = NetLog::Get();
7229   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7230 
7231   // CONNECT to www.example.org:443 via SPDY.
7232   spdy::SpdySerializedFrame endpoint_connect(spdy_util_.ConstructSpdyConnect(
7233       /*extra_headers=*/nullptr, 0, 1,
7234       HttpProxyConnectJob::kH2QuicTunnelPriority,
7235       HostPortPair("www.example.org", 443)));
7236 
7237   spdy::SpdySerializedFrame spdy_response_go_away(
7238       spdy_util_.ConstructSpdyGoAway(0, spdy::ERROR_CODE_PROTOCOL_ERROR,
7239                                      "Error 110 reading from socket."));
7240 
7241   MockWrite spdy_writes[] = {
7242       CreateMockWrite(endpoint_connect, 0),
7243       CreateMockWrite(spdy_response_go_away, 2),
7244   };
7245 
7246   MockRead spdy_reads[] = {
7247       MockRead(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED, 1),
7248       MockRead(ASYNC, 0, 3),
7249   };
7250 
7251   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
7252   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7253 
7254   SSLSocketDataProvider ssl(ASYNC, OK);
7255   ssl.next_proto = kProtoHTTP2;
7256   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7257 
7258   HttpRequestInfo request;
7259   request.method = "GET";
7260   request.url = GURL("https://www.example.org/");
7261   request.traffic_annotation =
7262       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7263 
7264   TestCompletionCallback callback;
7265 
7266   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7267 
7268   int rv = trans.Start(&request, callback.callback(),
7269                        NetLogWithSource::Make(NetLogSourceType::NONE));
7270   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7271 
7272   rv = callback.WaitForResult();
7273   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
7274   SSLCertRequestInfo* cert_request_info =
7275       trans.GetResponseInfo()->cert_request_info.get();
7276   // In the case of a read returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED directly,
7277   // no `SSLCertRequestInfo` is available.
7278   EXPECT_FALSE(cert_request_info);
7279 }
7280 
7281 // Test that the first proxy server in a multi-proxy chain requesting a client
7282 // auth cert doesn't cause a crash.
7283 // TODO(https://crbug.com/1491092): Support client auth certificates for
7284 // multi-proxy chains and then replace this test with a more robust one (for
7285 // instance, a version of the AuthEverywhere test that uses a multi-proxy
7286 // chain).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyClientAuthCertNeededFirstProxyNoCrash)7287 TEST_P(HttpNetworkTransactionTest,
7288        HttpsNestedProxyClientAuthCertNeededFirstProxyNoCrash) {
7289   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
7290                                   HostPortPair("proxy1.test", 70)};
7291   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
7292                                   HostPortPair("proxy2.test", 71)};
7293   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
7294 
7295   ProxyList proxy_list;
7296   proxy_list.AddProxyChain(kNestedProxyChain);
7297   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
7298 
7299   session_deps_.proxy_resolution_service =
7300       ConfiguredProxyResolutionService::CreateFixedForTest(
7301           ProxyConfigWithAnnotation(proxy_config,
7302                                     TRAFFIC_ANNOTATION_FOR_TESTS));
7303   session_deps_.net_log = NetLog::Get();
7304   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7305 
7306   // CONNECT to proxy2.test:71 via SPDY.
7307   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
7308       /*extra_headers=*/nullptr, 0, 1,
7309       HttpProxyConnectJob::kH2QuicTunnelPriority,
7310       kProxyServer2.host_port_pair()));
7311 
7312   spdy::SpdySerializedFrame spdy_response_go_away(
7313       spdy_util_.ConstructSpdyGoAway(0, spdy::ERROR_CODE_PROTOCOL_ERROR,
7314                                      "Error 110 reading from socket."));
7315 
7316   MockWrite spdy_writes[] = {
7317       CreateMockWrite(proxy2_connect, 0),
7318       CreateMockWrite(spdy_response_go_away, 2),
7319   };
7320 
7321   MockRead spdy_reads[] = {
7322       MockRead(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED, 1),
7323       MockRead(ASYNC, 0, 3),
7324   };
7325 
7326   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
7327   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7328 
7329   SSLSocketDataProvider ssl(ASYNC, OK);
7330   ssl.next_proto = kProtoHTTP2;
7331   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7332 
7333   HttpRequestInfo request;
7334   request.method = "GET";
7335   request.url = GURL("https://www.example.org/");
7336   request.traffic_annotation =
7337       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7338 
7339   TestCompletionCallback callback;
7340 
7341   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7342 
7343   int rv = trans.Start(&request, callback.callback(),
7344                        NetLogWithSource::Make(NetLogSourceType::NONE));
7345   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7346 
7347   rv = callback.WaitForResult();
7348   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
7349   SSLCertRequestInfo* cert_request_info =
7350       trans.GetResponseInfo()->cert_request_info.get();
7351   // In the case of a read returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED directly,
7352   // no `SSLCertRequestInfo` is available.
7353   EXPECT_FALSE(cert_request_info);
7354 }
7355 
7356 // Same as above but using a different method to request the client auth
7357 // certificate.
7358 // TODO(https://crbug.com/1491092): Support client auth certificates for
7359 // multi-proxy chains and then replace this test with a more robust one (for
7360 // instance, a version of the AuthEverywhere test that uses a multi-proxy
7361 // chain).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyClientAuthCertNeededFirstProxyNoCrash2)7362 TEST_P(HttpNetworkTransactionTest,
7363        HttpsNestedProxyClientAuthCertNeededFirstProxyNoCrash2) {
7364   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
7365                                   HostPortPair("proxy1.test", 70)};
7366   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
7367                                   HostPortPair("proxy2.test", 71)};
7368   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
7369 
7370   ProxyList proxy_list;
7371   proxy_list.AddProxyChain(kNestedProxyChain);
7372   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
7373 
7374   session_deps_.proxy_resolution_service =
7375       ConfiguredProxyResolutionService::CreateFixedForTest(
7376           ProxyConfigWithAnnotation(proxy_config,
7377                                     TRAFFIC_ANNOTATION_FOR_TESTS));
7378   session_deps_.net_log = NetLog::Get();
7379   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7380 
7381   StaticSocketDataProvider spdy_data{base::span<MockRead>(),
7382                                      base::span<MockWrite>()};
7383   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7384 
7385   auto cert_request_info_proxy = base::MakeRefCounted<SSLCertRequestInfo>();
7386   cert_request_info_proxy->host_and_port = kProxyServer1.host_port_pair();
7387 
7388   SSLSocketDataProvider ssl(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
7389   ssl.cert_request_info = cert_request_info_proxy;
7390   ssl.expected_send_client_cert = false;
7391   ssl.next_proto = kProtoHTTP2;
7392   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7393 
7394   HttpRequestInfo request;
7395   request.method = "GET";
7396   request.url = GURL("https://www.example.org/");
7397   request.traffic_annotation =
7398       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7399 
7400   TestCompletionCallback callback;
7401 
7402   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7403 
7404   int rv = trans.Start(&request, callback.callback(),
7405                        NetLogWithSource::Make(NetLogSourceType::NONE));
7406   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7407 
7408   rv = callback.WaitForResult();
7409   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
7410   SSLCertRequestInfo* cert_request_info =
7411       trans.GetResponseInfo()->cert_request_info.get();
7412   ASSERT_TRUE(cert_request_info);
7413   EXPECT_TRUE(cert_request_info->is_proxy);
7414   EXPECT_EQ(cert_request_info->host_and_port, kProxyServer1.host_port_pair());
7415 }
7416 
7417 // Test that a read returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED after the first
7418 // CONNECT doesn't result in a crash when a multi-proxy chain is in use.
7419 // TODO(https://crbug.com/1491092): Support client auth certificates for
7420 // multi-proxy chains and then replace this test with a more robust one (for
7421 // instance, a version of the AuthEverywhere test that uses a multi-proxy
7422 // chain).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyClientAuthCertNeededAfterFirstConnectNoCrash2)7423 TEST_P(HttpNetworkTransactionTest,
7424        HttpsNestedProxyClientAuthCertNeededAfterFirstConnectNoCrash2) {
7425   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
7426                                   HostPortPair("proxy1.test", 70)};
7427   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
7428                                   HostPortPair("proxy2.test", 71)};
7429   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
7430 
7431   ProxyList proxy_list;
7432   proxy_list.AddProxyChain(kNestedProxyChain);
7433   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
7434 
7435   session_deps_.proxy_resolution_service =
7436       ConfiguredProxyResolutionService::CreateFixedForTest(
7437           ProxyConfigWithAnnotation(proxy_config,
7438                                     TRAFFIC_ANNOTATION_FOR_TESTS));
7439   session_deps_.net_log = NetLog::Get();
7440   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7441 
7442   // CONNECT to proxy2.test:71 via SPDY.
7443   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
7444       /*extra_headers=*/nullptr, 0, 1,
7445       HttpProxyConnectJob::kH2QuicTunnelPriority,
7446       kProxyServer2.host_port_pair()));
7447 
7448   spdy::SpdySerializedFrame proxy2_connect_resp(
7449       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7450 
7451   // CONNECT to www.example.org:80 via SPDY.
7452   // Need to use a new `SpdyTestUtil()` so that the stream parent ID of this
7453   // request is calculated correctly.
7454   SpdyTestUtil spdy_util2(/*use_priority_header=*/true);
7455   spdy::SpdySerializedFrame endpoint_connect(spdy_util2.ConstructSpdyConnect(
7456       /*extra_headers=*/nullptr, 0, 1,
7457       HttpProxyConnectJob::kH2QuicTunnelPriority,
7458       HostPortPair("www.example.org", 80)));
7459   spdy::SpdySerializedFrame wrapped_endpoint_connect(
7460       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect, 1));
7461 
7462   spdy::SpdySerializedFrame spdy_response_go_away(
7463       spdy_util_.ConstructSpdyGoAway(0, spdy::ERROR_CODE_PROTOCOL_ERROR,
7464                                      "Error 110 reading from socket."));
7465   MockWrite spdy_writes[] = {
7466       CreateMockWrite(proxy2_connect, 0),
7467       CreateMockWrite(wrapped_endpoint_connect, 2),
7468       CreateMockWrite(spdy_response_go_away, 5),
7469   };
7470 
7471   MockRead spdy_reads[] = {
7472       CreateMockRead(proxy2_connect_resp, 1),
7473       // TODO(https://crbug.com/497228): We have to manually delay this read so
7474       // that the higher-level SPDY stream doesn't get notified of an available
7475       // read before the write it initiated (the second CONNECT) finishes,
7476       // triggering a DCHECK.
7477       MockRead(ASYNC, ERR_IO_PENDING, 3),
7478       MockRead(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED, 4),
7479   };
7480 
7481   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
7482   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7483 
7484   SSLSocketDataProvider ssl(ASYNC, OK);
7485   ssl.next_proto = kProtoHTTP2;
7486   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7487 
7488   SSLSocketDataProvider ssl2(ASYNC, OK);
7489   ssl2.next_proto = kProtoHTTP2;
7490   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7491 
7492   HttpRequestInfo request;
7493   request.method = "GET";
7494   request.url = GURL("http://www.example.org/");
7495   request.traffic_annotation =
7496       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7497 
7498   TestCompletionCallback callback;
7499 
7500   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7501 
7502   int rv = trans.Start(&request, callback.callback(),
7503                        NetLogWithSource::Make(NetLogSourceType::NONE));
7504   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7505 
7506   spdy_data.RunUntilPaused();
7507   base::RunLoop().RunUntilIdle();
7508   spdy_data.Resume();
7509 
7510   rv = callback.WaitForResult();
7511   ASSERT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
7512   SSLCertRequestInfo* cert_request_info =
7513       trans.GetResponseInfo()->cert_request_info.get();
7514   EXPECT_FALSE(cert_request_info);
7515 }
7516 
7517 // Test that the second proxy server in a multi-proxy chain requesting a client
7518 // auth cert doesn't cause a crash.
7519 // TODO(https://crbug.com/1491092): Support client auth certificates for
7520 // multi-proxy chains and then replace this test with a more robust one (for
7521 // instance, a version of the AuthEverywhere test that uses a multi-proxy
7522 // chain).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyClientAuthCertNeededSecondProxyNoCrash)7523 TEST_P(HttpNetworkTransactionTest,
7524        HttpsNestedProxyClientAuthCertNeededSecondProxyNoCrash) {
7525   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
7526                                   HostPortPair("proxy1.test", 70)};
7527   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
7528                                   HostPortPair("proxy2.test", 71)};
7529   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
7530 
7531   ProxyList proxy_list;
7532   proxy_list.AddProxyChain(kNestedProxyChain);
7533   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
7534 
7535   session_deps_.proxy_resolution_service =
7536       ConfiguredProxyResolutionService::CreateFixedForTest(
7537           ProxyConfigWithAnnotation(proxy_config,
7538                                     TRAFFIC_ANNOTATION_FOR_TESTS));
7539   session_deps_.net_log = NetLog::Get();
7540   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7541 
7542   // CONNECT to proxy2.test:71 via SPDY.
7543   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
7544       /*extra_headers=*/nullptr, 0, 1,
7545       HttpProxyConnectJob::kH2QuicTunnelPriority,
7546       kProxyServer2.host_port_pair()));
7547 
7548   spdy::SpdySerializedFrame proxy2_connect_resp(
7549       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7550 
7551   spdy::SpdySerializedFrame rst(
7552       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
7553 
7554   MockWrite spdy_writes[] = {
7555       CreateMockWrite(proxy2_connect, 0),
7556       CreateMockWrite(rst, 2),
7557   };
7558 
7559   MockRead spdy_reads[] = {
7560       CreateMockRead(proxy2_connect_resp, 1),
7561       MockRead(ASYNC, 0, 3),
7562   };
7563 
7564   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
7565   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7566 
7567   SSLSocketDataProvider ssl(ASYNC, OK);
7568   ssl.next_proto = kProtoHTTP2;
7569   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7570 
7571   auto cert_request_info_proxy = base::MakeRefCounted<SSLCertRequestInfo>();
7572   cert_request_info_proxy->host_and_port = kProxyServer2.host_port_pair();
7573 
7574   SSLSocketDataProvider ssl2(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
7575   ssl2.cert_request_info = cert_request_info_proxy;
7576   ssl2.expected_send_client_cert = false;
7577   ssl2.next_proto = kProtoHTTP2;
7578   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7579 
7580   HttpRequestInfo request;
7581   request.method = "GET";
7582   request.url = GURL("http://www.example.org/");
7583   request.traffic_annotation =
7584       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7585 
7586   TestCompletionCallback callback;
7587 
7588   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7589 
7590   int rv = trans.Start(&request, callback.callback(),
7591                        NetLogWithSource::Make(NetLogSourceType::NONE));
7592   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7593 
7594   rv = callback.WaitForResult();
7595   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
7596   SSLCertRequestInfo* cert_request_info =
7597       trans.GetResponseInfo()->cert_request_info.get();
7598   ASSERT_TRUE(cert_request_info);
7599   EXPECT_TRUE(cert_request_info->is_proxy);
7600   EXPECT_EQ(cert_request_info->host_and_port, kProxyServer2.host_port_pair());
7601 }
7602 
7603 // Test that the endpoint requesting a client auth cert over a multi-proxy chain
7604 // tunnel doesn't cause a crash.
7605 // TODO(https://crbug.com/1491092): Support client auth certificates for
7606 // multi-proxy chains and then replace this test with a more robust one (for
7607 // instance, a version of the AuthEverywhere test that uses a multi-proxy
7608 // chain).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyClientAuthCertNeededEndpointNoCrash)7609 TEST_P(HttpNetworkTransactionTest,
7610        HttpsNestedProxyClientAuthCertNeededEndpointNoCrash) {
7611   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
7612                                   HostPortPair("proxy1.test", 70)};
7613   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
7614                                   HostPortPair("proxy2.test", 71)};
7615   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
7616 
7617   ProxyList proxy_list;
7618   proxy_list.AddProxyChain(kNestedProxyChain);
7619   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
7620 
7621   session_deps_.proxy_resolution_service =
7622       ConfiguredProxyResolutionService::CreateFixedForTest(
7623           ProxyConfigWithAnnotation(proxy_config,
7624                                     TRAFFIC_ANNOTATION_FOR_TESTS));
7625   session_deps_.net_log = NetLog::Get();
7626   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7627 
7628   // CONNECT to proxy2.test:71 via SPDY.
7629   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
7630       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
7631       kProxyServer2.host_port_pair()));
7632 
7633   spdy::SpdySerializedFrame proxy2_connect_resp(
7634       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7635 
7636   // CONNECT to www.example.org:443 via SPDY.
7637   // Need to use a new `SpdyTestUtil()` so that the stream parent ID of this
7638   // CONNECT is calculated correctly.
7639   SpdyTestUtil new_spdy_util;
7640   spdy::SpdySerializedFrame endpoint_connect(new_spdy_util.ConstructSpdyConnect(
7641       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
7642       HostPortPair("www.example.org", 443)));
7643 
7644   // Since this request and response are sent over the tunnel established
7645   // previously, from a socket-perspective these need to be wrapped as data
7646   // frames.
7647   spdy::SpdySerializedFrame wrapped_endpoint_connect(
7648       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect, 1));
7649 
7650   spdy::SpdySerializedFrame endpoint_connect_resp(
7651       new_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
7652   spdy::SpdySerializedFrame wrapped_endpoint_connect_resp(
7653       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect_resp, 1));
7654 
7655   spdy::SpdySerializedFrame rst(
7656       new_spdy_util.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
7657   spdy::SpdySerializedFrame wrapped_rst(
7658       spdy_util_.ConstructWrappedSpdyFrame(rst, 1));
7659 
7660   MockWrite spdy_writes[] = {
7661       CreateMockWrite(proxy2_connect, 0),
7662       CreateMockWrite(wrapped_endpoint_connect, 2),
7663       CreateMockWrite(wrapped_rst, 5),
7664   };
7665 
7666   MockRead spdy_reads[] = {
7667       CreateMockRead(proxy2_connect_resp, 1, ASYNC),
7668       // TODO(https://crbug.com/497228): We have to manually delay this read so
7669       // that the higher-level SPDY stream doesn't get notified of an available
7670       // read before the write it initiated (the second CONNECT) finishes,
7671       // triggering a DCHECK.
7672       MockRead(ASYNC, ERR_IO_PENDING, 3),
7673       CreateMockRead(wrapped_endpoint_connect_resp, 4, ASYNC),
7674       MockRead(ASYNC, ERR_IO_PENDING, 6),
7675       MockRead(ASYNC, 0, 7),
7676   };
7677 
7678   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
7679   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7680 
7681   SSLSocketDataProvider ssl(ASYNC, OK);
7682   ssl.next_proto = kProtoHTTP2;
7683   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7684 
7685   SSLSocketDataProvider ssl2(ASYNC, OK);
7686   ssl2.next_proto = kProtoHTTP2;
7687   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7688 
7689   auto cert_request_info_origin = base::MakeRefCounted<SSLCertRequestInfo>();
7690   cert_request_info_origin->host_and_port =
7691       HostPortPair("www.example.org", 443);
7692 
7693   SSLSocketDataProvider ssl3(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
7694   ssl3.cert_request_info = cert_request_info_origin;
7695   ssl3.expected_send_client_cert = false;
7696   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7697 
7698   HttpRequestInfo request;
7699   request.method = "GET";
7700   request.url = GURL("https://www.example.org/");
7701   request.traffic_annotation =
7702       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7703 
7704   TestCompletionCallback callback;
7705 
7706   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7707 
7708   int rv = trans.Start(&request, callback.callback(),
7709                        NetLogWithSource::Make(NetLogSourceType::NONE));
7710   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7711 
7712   spdy_data.RunUntilPaused();
7713   base::RunLoop().RunUntilIdle();
7714   spdy_data.Resume();
7715 
7716   rv = callback.WaitForResult();
7717   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
7718   SSLCertRequestInfo* cert_request_info =
7719       trans.GetResponseInfo()->cert_request_info.get();
7720   ASSERT_TRUE(cert_request_info);
7721   EXPECT_FALSE(cert_request_info->is_proxy);
7722   EXPECT_EQ(cert_request_info->host_and_port,
7723             HostPortPair("www.example.org", 443));
7724 }
7725 
7726 // Verifies that a session which races and wins against the owning transaction
7727 // (completing prior to host resolution), doesn't fail the transaction.
7728 // Regression test for crbug.com/334413.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyGetWithSessionRace)7729 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
7730   HttpRequestInfo request;
7731   request.method = "GET";
7732   request.url = GURL("http://www.example.org/");
7733   request.traffic_annotation =
7734       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7735 
7736   // Configure SPDY proxy server "proxy:70".
7737   session_deps_.proxy_resolution_service =
7738       ConfiguredProxyResolutionService::CreateFixedForTest(
7739           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
7740   NetLogWithSource net_log_with_source =
7741       NetLogWithSource::Make(NetLogSourceType::NONE);
7742   session_deps_.net_log = NetLog::Get();
7743   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7744 
7745   // Fetch http://www.example.org/ through the SPDY proxy.
7746   spdy::SpdySerializedFrame req(
7747       spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
7748   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
7749 
7750   spdy::SpdySerializedFrame resp(
7751       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7752   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
7753   MockRead spdy_reads[] = {
7754       CreateMockRead(resp, 1),
7755       CreateMockRead(data, 2),
7756       MockRead(ASYNC, 0, 3),
7757   };
7758 
7759   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
7760   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7761 
7762   SSLSocketDataProvider ssl(ASYNC, OK);
7763   ssl.next_proto = kProtoHTTP2;
7764   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7765 
7766   TestCompletionCallback callback1;
7767 
7768   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7769 
7770   // Stall the hostname resolution begun by the transaction.
7771   session_deps_.host_resolver->set_ondemand_mode(true);
7772 
7773   int rv = trans.Start(&request, callback1.callback(), net_log_with_source);
7774   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7775 
7776   // Race a session to the proxy, which completes first.
7777   session_deps_.host_resolver->set_ondemand_mode(false);
7778   SpdySessionKey key(HostPortPair("proxy", 70), PRIVACY_MODE_DISABLED,
7779                      ProxyChain::Direct(), SessionUsage::kProxy, SocketTag(),
7780                      NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
7781                      /*disable_cert_verification_network_fetches=*/true);
7782   base::WeakPtr<SpdySession> spdy_session =
7783       CreateSpdySession(session.get(), key, net_log_with_source);
7784 
7785   // Unstall the resolution begun by the transaction.
7786   session_deps_.host_resolver->set_ondemand_mode(true);
7787   session_deps_.host_resolver->ResolveAllPending();
7788 
7789   EXPECT_FALSE(callback1.have_result());
7790   rv = callback1.WaitForResult();
7791   EXPECT_THAT(rv, IsOk());
7792 
7793   const HttpResponseInfo* response = trans.GetResponseInfo();
7794   ASSERT_TRUE(response);
7795   ASSERT_TRUE(response->headers);
7796   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
7797 
7798   std::string response_data;
7799   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
7800   EXPECT_EQ(kUploadData, response_data);
7801 }
7802 
7803 // Test a SPDY GET through an HTTPS proxy that uses proxy auth.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyGetWithProxyAuth)7804 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
7805   HttpRequestInfo request;
7806   request.method = "GET";
7807   request.url = GURL("http://www.example.org/");
7808   request.traffic_annotation =
7809       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7810 
7811   // Configure against https proxy server "myproxy:70".
7812   session_deps_.proxy_resolution_service =
7813       ConfiguredProxyResolutionService::CreateFixedForTest(
7814           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
7815   session_deps_.net_log = NetLog::Get();
7816   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7817 
7818   // The first request will be a bare GET, the second request will be a
7819   // GET with a Proxy-Authorization header.
7820   spdy_util_.set_default_url(request.url);
7821   spdy::SpdySerializedFrame req_get(
7822       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
7823   spdy_util_.UpdateWithStreamDestruction(1);
7824   const char* const kExtraAuthorizationHeaders[] = {"proxy-authorization",
7825                                                     "Basic Zm9vOmJhcg=="};
7826   spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
7827       kExtraAuthorizationHeaders, std::size(kExtraAuthorizationHeaders) / 2, 3,
7828       LOWEST));
7829   MockWrite spdy_writes[] = {
7830       CreateMockWrite(req_get, 0),
7831       CreateMockWrite(req_get_authorization, 3),
7832   };
7833 
7834   // The first response is a 407 proxy authentication challenge, and the second
7835   // response will be a 200 response since the second request includes a valid
7836   // Authorization header.
7837   const char* const kExtraAuthenticationHeaders[] = {
7838       "proxy-authenticate", "Basic realm=\"MyRealm1\""};
7839   spdy::SpdySerializedFrame resp_authentication(
7840       spdy_util_.ConstructSpdyReplyError(
7841           "407", kExtraAuthenticationHeaders,
7842           std::size(kExtraAuthenticationHeaders) / 2, 1));
7843   spdy::SpdySerializedFrame body_authentication(
7844       spdy_util_.ConstructSpdyDataFrame(1, true));
7845   spdy::SpdySerializedFrame resp_data(
7846       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
7847   spdy::SpdySerializedFrame body_data(
7848       spdy_util_.ConstructSpdyDataFrame(3, true));
7849   MockRead spdy_reads[] = {
7850       CreateMockRead(resp_authentication, 1),
7851       CreateMockRead(body_authentication, 2, SYNCHRONOUS),
7852       CreateMockRead(resp_data, 4),
7853       CreateMockRead(body_data, 5),
7854       MockRead(ASYNC, 0, 6),
7855   };
7856 
7857   SequencedSocketData data(spdy_reads, spdy_writes);
7858   session_deps_.socket_factory->AddSocketDataProvider(&data);
7859 
7860   SSLSocketDataProvider ssl(ASYNC, OK);
7861   ssl.next_proto = kProtoHTTP2;
7862   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7863 
7864   TestCompletionCallback callback1;
7865 
7866   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7867 
7868   int rv = trans.Start(&request, callback1.callback(),
7869                        NetLogWithSource::Make(NetLogSourceType::NONE));
7870   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7871 
7872   rv = callback1.WaitForResult();
7873   EXPECT_THAT(rv, IsOk());
7874 
7875   const HttpResponseInfo* const response = trans.GetResponseInfo();
7876 
7877   ASSERT_TRUE(response);
7878   ASSERT_TRUE(response->headers);
7879   EXPECT_EQ(407, response->headers->response_code());
7880   EXPECT_TRUE(response->was_fetched_via_spdy);
7881   EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
7882 
7883   TestCompletionCallback callback2;
7884 
7885   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
7886   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7887 
7888   rv = callback2.WaitForResult();
7889   EXPECT_THAT(rv, IsOk());
7890 
7891   const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
7892 
7893   ASSERT_TRUE(response_restart);
7894   ASSERT_TRUE(response_restart->headers);
7895   EXPECT_EQ(200, response_restart->headers->response_code());
7896   // The password prompt info should not be set.
7897   EXPECT_FALSE(response_restart->auth_challenge.has_value());
7898 }
7899 
7900 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server
7901 // (SPDY -> HTTPS).
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyConnectHttps)7902 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
7903   HttpRequestInfo request;
7904   request.method = "GET";
7905   request.url = GURL("https://www.example.org/");
7906   request.traffic_annotation =
7907       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7908 
7909   // Configure against https proxy server "proxy:70".
7910   session_deps_.proxy_resolution_service =
7911       ConfiguredProxyResolutionService::CreateFixedForTest(
7912           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
7913   session_deps_.net_log = NetLog::Get();
7914   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7915 
7916   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7917 
7918   // CONNECT to www.example.org:443 via SPDY
7919   spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
7920       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
7921       HostPortPair("www.example.org", 443)));
7922   // fetch https://www.example.org/ via HTTP
7923 
7924   const char kGet[] =
7925       "GET / HTTP/1.1\r\n"
7926       "Host: www.example.org\r\n"
7927       "Connection: keep-alive\r\n\r\n";
7928   spdy::SpdySerializedFrame wrapped_get(
7929       spdy_util_.ConstructSpdyDataFrame(1, kGet, false));
7930   spdy::SpdySerializedFrame conn_resp(
7931       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7932   const char kResp[] =
7933       "HTTP/1.1 200 OK\r\n"
7934       "Content-Length: 10\r\n\r\n";
7935   spdy::SpdySerializedFrame wrapped_get_resp(
7936       spdy_util_.ConstructSpdyDataFrame(1, kResp, false));
7937   const char kRespData[] = "1234567890";
7938   spdy::SpdySerializedFrame wrapped_body(
7939       spdy_util_.ConstructSpdyDataFrame(1, kRespData, false));
7940 
7941   MockWrite spdy_writes[] = {
7942       CreateMockWrite(connect, 0),
7943       CreateMockWrite(wrapped_get, 2),
7944   };
7945 
7946   MockRead spdy_reads[] = {
7947       CreateMockRead(conn_resp, 1, ASYNC),
7948       CreateMockRead(wrapped_get_resp, 3, ASYNC),
7949       CreateMockRead(wrapped_body, 4, ASYNC),
7950       MockRead(ASYNC, 0, 5),
7951   };
7952 
7953   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
7954   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7955 
7956   SSLSocketDataProvider ssl(ASYNC, OK);
7957   ssl.next_proto = kProtoHTTP2;
7958   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7959   SSLSocketDataProvider ssl2(ASYNC, OK);
7960   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7961 
7962   TestCompletionCallback callback1;
7963 
7964   int rv = trans.Start(&request, callback1.callback(),
7965                        NetLogWithSource::Make(NetLogSourceType::NONE));
7966   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7967 
7968   rv = callback1.WaitForResult();
7969   ASSERT_THAT(rv, IsOk());
7970 
7971   LoadTimingInfo load_timing_info;
7972   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
7973   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
7974 
7975   const HttpResponseInfo* response = trans.GetResponseInfo();
7976   ASSERT_TRUE(response);
7977   ASSERT_TRUE(response->headers);
7978   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7979 
7980   std::string response_data;
7981   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
7982   EXPECT_EQ(kRespData, response_data);
7983 }
7984 
7985 // Test a SPDY CONNECT through two HTTPS (SPDY) proxies to an HTTPS (non-SPDY)
7986 // server (SPDY -> SPDY -> HTTPS).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxySpdyConnectHttps)7987 TEST_P(HttpNetworkTransactionTest, HttpsNestedProxySpdyConnectHttps) {
7988   HttpRequestInfo request;
7989   request.method = "GET";
7990   request.url = GURL("https://www.example.org/");
7991   request.traffic_annotation =
7992       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7993 
7994   // Configure a nested proxy.
7995   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
7996                                   HostPortPair("proxy1.test", 70)};
7997   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
7998                                   HostPortPair("proxy2.test", 71)};
7999   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
8000 
8001   ProxyList proxy_list;
8002   proxy_list.AddProxyChain(kNestedProxyChain);
8003   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
8004 
8005   session_deps_.proxy_resolution_service =
8006       ConfiguredProxyResolutionService::CreateFixedForTest(
8007           ProxyConfigWithAnnotation(proxy_config,
8008                                     TRAFFIC_ANNOTATION_FOR_TESTS));
8009 
8010   session_deps_.net_log = NetLog::Get();
8011   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8012 
8013   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8014 
8015   // CONNECT to proxy2.test:71 via SPDY.
8016   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
8017       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
8018       kProxyServer2.host_port_pair()));
8019 
8020   spdy::SpdySerializedFrame proxy2_connect_resp(
8021       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8022 
8023   // CONNECT to www.example.org:443 via SPDY.
8024   // Need to use a new `SpdyTestUtil()` so that the stream parent ID of this
8025   // CONNECT is calculated correctly.
8026   SpdyTestUtil new_spdy_util;
8027   spdy::SpdySerializedFrame endpoint_connect(new_spdy_util.ConstructSpdyConnect(
8028       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
8029       HostPortPair("www.example.org", 443)));
8030 
8031   // Since this request and response are sent over the tunnel established
8032   // previously, from a socket-perspective these need to be wrapped as data
8033   // frames.
8034   spdy::SpdySerializedFrame wrapped_endpoint_connect(
8035       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect, 1));
8036 
8037   spdy::SpdySerializedFrame endpoint_connect_resp(
8038       new_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
8039   spdy::SpdySerializedFrame wrapped_endpoint_connect_resp(
8040       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect_resp, 1));
8041 
8042   // fetch https://www.example.org/ via HTTP.
8043   // Since this request will go over two tunnels, it needs to be double-wrapped.
8044   const char kGet[] =
8045       "GET / HTTP/1.1\r\n"
8046       "Host: www.example.org\r\n"
8047       "Connection: keep-alive\r\n\r\n";
8048   spdy::SpdySerializedFrame wrapped_get(
8049       new_spdy_util.ConstructSpdyDataFrame(1, kGet, false));
8050   spdy::SpdySerializedFrame wrapped_wrapped_get(
8051       spdy_util_.ConstructWrappedSpdyFrame(wrapped_get, 1));
8052 
8053   const char kResp[] =
8054       "HTTP/1.1 200 OK\r\n"
8055       "Content-Length: 10\r\n\r\n";
8056   spdy::SpdySerializedFrame wrapped_get_resp(
8057       new_spdy_util.ConstructSpdyDataFrame(1, kResp, false));
8058   spdy::SpdySerializedFrame wrapped_wrapped_get_resp(
8059       spdy_util_.ConstructWrappedSpdyFrame(wrapped_get_resp, 1));
8060 
8061   const char kRespData[] = "1234567890";
8062   spdy::SpdySerializedFrame wrapped_body(
8063       new_spdy_util.ConstructSpdyDataFrame(1, kRespData, false));
8064   spdy::SpdySerializedFrame wrapped_wrapped_body(
8065       spdy_util_.ConstructWrappedSpdyFrame(wrapped_body, 1));
8066 
8067   MockWrite spdy_writes[] = {
8068       CreateMockWrite(proxy2_connect, 0),
8069       CreateMockWrite(wrapped_endpoint_connect, 2),
8070       CreateMockWrite(wrapped_wrapped_get, 5),
8071   };
8072 
8073   MockRead spdy_reads[] = {
8074       CreateMockRead(proxy2_connect_resp, 1, ASYNC),
8075       // TODO(https://crbug.com/497228): We have to manually delay this read so
8076       // that the higher-level SPDY stream doesn't get notified of an available
8077       // read before the write it initiated (the second CONNECT) finishes,
8078       // triggering a DCHECK.
8079       MockRead(ASYNC, ERR_IO_PENDING, 3),
8080       CreateMockRead(wrapped_endpoint_connect_resp, 4, ASYNC),
8081       CreateMockRead(wrapped_wrapped_get_resp, 6, ASYNC),
8082       CreateMockRead(wrapped_wrapped_body, 7, ASYNC),
8083       MockRead(ASYNC, 0, 8),
8084   };
8085 
8086   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
8087   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8088 
8089   SSLSocketDataProvider ssl(ASYNC, OK);
8090   ssl.next_proto = kProtoHTTP2;
8091   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8092   SSLSocketDataProvider ssl2(ASYNC, OK);
8093   ssl2.next_proto = kProtoHTTP2;
8094   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
8095   SSLSocketDataProvider ssl3(ASYNC, OK);
8096   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
8097 
8098   TestCompletionCallback callback1;
8099 
8100   int rv = trans.Start(&request, callback1.callback(),
8101                        NetLogWithSource::Make(NetLogSourceType::NONE));
8102   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8103 
8104   spdy_data.RunUntilPaused();
8105   base::RunLoop().RunUntilIdle();
8106   spdy_data.Resume();
8107 
8108   rv = callback1.WaitForResult();
8109   ASSERT_THAT(rv, IsOk());
8110 
8111   LoadTimingInfo load_timing_info;
8112   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
8113   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
8114 
8115   const HttpResponseInfo* response = trans.GetResponseInfo();
8116   ASSERT_TRUE(response);
8117   ASSERT_TRUE(response->headers);
8118   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8119 
8120   std::string response_data;
8121   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
8122   EXPECT_EQ(kRespData, response_data);
8123 }
8124 
8125 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server (SPDY -> SPDY).
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyConnectSpdy)8126 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
8127   SpdyTestUtil spdy_util_wrapped(/*use_priority_header=*/true);
8128 
8129   HttpRequestInfo request;
8130   request.method = "GET";
8131   request.url = GURL("https://www.example.org/");
8132   request.traffic_annotation =
8133       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8134 
8135   // Configure against https proxy server "proxy:70".
8136   session_deps_.proxy_resolution_service =
8137       ConfiguredProxyResolutionService::CreateFixedForTest(
8138           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8139   session_deps_.net_log = NetLog::Get();
8140   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8141 
8142   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8143 
8144   // CONNECT to www.example.org:443 via SPDY
8145   spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
8146       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
8147       HostPortPair("www.example.org", 443)));
8148   // fetch https://www.example.org/ via SPDY
8149   const char kMyUrl[] = "https://www.example.org/";
8150   spdy::SpdySerializedFrame get(
8151       spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
8152   spdy::SpdySerializedFrame wrapped_get(
8153       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
8154   spdy::SpdySerializedFrame conn_resp(
8155       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8156   spdy::SpdySerializedFrame get_resp(
8157       spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
8158   spdy::SpdySerializedFrame wrapped_get_resp(
8159       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
8160   spdy::SpdySerializedFrame body(
8161       spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
8162   spdy::SpdySerializedFrame wrapped_body(
8163       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
8164   spdy::SpdySerializedFrame window_update_get_resp(
8165       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
8166   spdy::SpdySerializedFrame window_update_body(
8167       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
8168 
8169   MockWrite spdy_writes[] = {
8170       CreateMockWrite(connect, 0),
8171       CreateMockWrite(wrapped_get, 2),
8172       CreateMockWrite(window_update_get_resp, 6),
8173       CreateMockWrite(window_update_body, 7),
8174   };
8175 
8176   MockRead spdy_reads[] = {
8177       CreateMockRead(conn_resp, 1, ASYNC),
8178       MockRead(ASYNC, ERR_IO_PENDING, 3),
8179       CreateMockRead(wrapped_get_resp, 4, ASYNC),
8180       CreateMockRead(wrapped_body, 5, ASYNC),
8181       MockRead(ASYNC, 0, 8),
8182   };
8183 
8184   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
8185   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8186 
8187   SSLSocketDataProvider ssl(ASYNC, OK);
8188   ssl.next_proto = kProtoHTTP2;
8189   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8190   SSLSocketDataProvider ssl2(ASYNC, OK);
8191   ssl2.next_proto = kProtoHTTP2;
8192   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
8193 
8194   TestCompletionCallback callback1;
8195 
8196   int rv = trans.Start(&request, callback1.callback(),
8197                        NetLogWithSource::Make(NetLogSourceType::NONE));
8198   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8199 
8200   // Allow the SpdyProxyClientSocket's write callback to complete.
8201   base::RunLoop().RunUntilIdle();
8202   // Now allow the read of the response to complete.
8203   spdy_data.Resume();
8204   rv = callback1.WaitForResult();
8205   EXPECT_THAT(rv, IsOk());
8206 
8207   LoadTimingInfo load_timing_info;
8208   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
8209   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
8210 
8211   const HttpResponseInfo* response = trans.GetResponseInfo();
8212   ASSERT_TRUE(response);
8213   ASSERT_TRUE(response->headers);
8214   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
8215 
8216   std::string response_data;
8217   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
8218   EXPECT_EQ(kUploadData, response_data);
8219 }
8220 
8221 // Test a SPDY CONNECT for an HTTPS (non-SPDY) endpoint through an HTTPS
8222 // (non-SPDY) proxy and HTTPS (SPDY) proxy chain (HTTPS -> SPDY -> HTTPS).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyMixedConnectSpdy)8223 TEST_P(HttpNetworkTransactionTest, HttpsNestedProxyMixedConnectSpdy) {
8224   HttpRequestInfo request;
8225   request.method = "GET";
8226   request.url = GURL("https://www.example.org/");
8227   request.traffic_annotation =
8228       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8229 
8230   // Configure a nested proxy.
8231   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
8232                                   HostPortPair("proxy1.test", 70)};
8233   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
8234                                   HostPortPair("proxy2.test", 71)};
8235   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
8236 
8237   ProxyList proxy_list;
8238   proxy_list.AddProxyChain(kNestedProxyChain);
8239   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
8240 
8241   session_deps_.proxy_resolution_service =
8242       ConfiguredProxyResolutionService::CreateFixedForTest(
8243           ProxyConfigWithAnnotation(proxy_config,
8244                                     TRAFFIC_ANNOTATION_FOR_TESTS));
8245   session_deps_.net_log = NetLog::Get();
8246   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8247 
8248   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8249 
8250   // CONNECT to proxy2.test:71 via HTTP.
8251   const char kProxy2Connect[] =
8252       "CONNECT proxy2.test:71 HTTP/1.1\r\n"
8253       "Host: proxy2.test:71\r\n"
8254       "Proxy-Connection: keep-alive\r\n\r\n";
8255 
8256   const char kProxy2ConnectResp[] =
8257       "HTTP/1.1 200 Connection Established\r\n\r\n";
8258 
8259   // CONNECT to www.example.org:443 via SPDY.
8260   spdy::SpdySerializedFrame endpoint_connect(spdy_util_.ConstructSpdyConnect(
8261       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
8262       HostPortPair("www.example.org", 443)));
8263 
8264   spdy::SpdySerializedFrame endpoint_connect_resp(
8265       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8266 
8267   // fetch https://www.example.org/ via HTTP.
8268   // Since this request and response are sent over the tunnel established
8269   // previously, from a socket-perspective these need to be wrapped as data
8270   // frames.
8271   const char kGet[] =
8272       "GET / HTTP/1.1\r\n"
8273       "Host: www.example.org\r\n"
8274       "Connection: keep-alive\r\n\r\n";
8275   spdy::SpdySerializedFrame wrapped_get(
8276       spdy_util_.ConstructSpdyDataFrame(1, kGet, false));
8277 
8278   const char kResp[] =
8279       "HTTP/1.1 200 OK\r\n"
8280       "Content-Length: 10\r\n\r\n";
8281   spdy::SpdySerializedFrame wrapped_get_resp(
8282       spdy_util_.ConstructSpdyDataFrame(1, kResp, false));
8283 
8284   const char kRespData[] = "1234567890";
8285   spdy::SpdySerializedFrame wrapped_body(
8286       spdy_util_.ConstructSpdyDataFrame(1, kRespData, false));
8287 
8288   MockWrite socket_writes[] = {
8289       MockWrite(ASYNC, 0, kProxy2Connect),
8290       CreateMockWrite(endpoint_connect, 2),
8291       CreateMockWrite(wrapped_get, 4),
8292   };
8293 
8294   MockRead socket_reads[] = {
8295       MockRead(ASYNC, 1, kProxy2ConnectResp),
8296       CreateMockRead(endpoint_connect_resp, 3, ASYNC),
8297       CreateMockRead(wrapped_get_resp, 5, ASYNC),
8298       CreateMockRead(wrapped_body, 6, ASYNC),
8299       MockRead(ASYNC, 0, 7),
8300   };
8301 
8302   SequencedSocketData socket_data(socket_reads, socket_writes);
8303   session_deps_.socket_factory->AddSocketDataProvider(&socket_data);
8304 
8305   SSLSocketDataProvider ssl(ASYNC, OK);
8306   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8307   SSLSocketDataProvider ssl2(ASYNC, OK);
8308   ssl2.next_proto = kProtoHTTP2;
8309   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
8310   SSLSocketDataProvider ssl3(ASYNC, OK);
8311   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
8312 
8313   TestCompletionCallback callback1;
8314 
8315   int rv = trans.Start(&request, callback1.callback(),
8316                        NetLogWithSource::Make(NetLogSourceType::NONE));
8317   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8318 
8319   rv = callback1.WaitForResult();
8320   ASSERT_THAT(rv, IsOk());
8321 
8322   LoadTimingInfo load_timing_info;
8323   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
8324   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
8325 
8326   const HttpResponseInfo* response = trans.GetResponseInfo();
8327   ASSERT_TRUE(response);
8328   ASSERT_TRUE(response->headers);
8329   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8330 
8331   std::string response_data;
8332   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
8333   EXPECT_EQ(kRespData, response_data);
8334 }
8335 
8336 // Test an HTTP CONNECT for an HTTPS (non-SPDY) endpoint through an HTTPS (SPDY)
8337 // proxy and HTTPS (non-SPDY) proxy chain (SPDY -> HTTPS -> HTTPS).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyMixedConnectHttps)8338 TEST_P(HttpNetworkTransactionTest, HttpsNestedProxyMixedConnectHttps) {
8339   HttpRequestInfo request;
8340   request.method = "GET";
8341   request.url = GURL("https://www.example.org/");
8342   request.traffic_annotation =
8343       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8344 
8345   // Configure a nested proxy.
8346   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
8347                                   HostPortPair("proxy1.test", 70)};
8348   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
8349                                   HostPortPair("proxy2.test", 71)};
8350   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
8351 
8352   ProxyList proxy_list;
8353   proxy_list.AddProxyChain(kNestedProxyChain);
8354   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
8355 
8356   session_deps_.proxy_resolution_service =
8357       ConfiguredProxyResolutionService::CreateFixedForTest(
8358           ProxyConfigWithAnnotation(proxy_config,
8359                                     TRAFFIC_ANNOTATION_FOR_TESTS));
8360   session_deps_.net_log = NetLog::Get();
8361   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8362 
8363   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8364 
8365   // CONNECT to proxy2.test:71 via SPDY.
8366   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
8367       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
8368       kProxyServer2.host_port_pair()));
8369 
8370   spdy::SpdySerializedFrame proxy2_connect_resp(
8371       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8372 
8373   // CONNECT to www.example.org:443 via HTTPS.
8374   const char kEndpointConnect[] =
8375       "CONNECT www.example.org:443 HTTP/1.1\r\n"
8376       "Host: www.example.org:443\r\n"
8377       "Proxy-Connection: keep-alive\r\n\r\n";
8378 
8379   const char kEndpointConnectResp[] =
8380       "HTTP/1.1 200 Connection Established\r\n\r\n";
8381 
8382   // Since this request and response are sent over the tunnel established
8383   // previously, from a socket-perspective these need to be wrapped as data
8384   // frames.
8385   spdy::SpdySerializedFrame wrapped_endpoint_connect(
8386       spdy_util_.ConstructSpdyDataFrame(1, kEndpointConnect, false));
8387   spdy::SpdySerializedFrame wrapped_endpoint_connect_resp(
8388       spdy_util_.ConstructSpdyDataFrame(1, kEndpointConnectResp, false));
8389 
8390   // fetch https://www.example.org/ via HTTP.
8391   // Since this request will go over the SPDY tunnel, it needs to be wrapped as
8392   // well.
8393   const char kGet[] =
8394       "GET / HTTP/1.1\r\n"
8395       "Host: www.example.org\r\n"
8396       "Connection: keep-alive\r\n\r\n";
8397   spdy::SpdySerializedFrame wrapped_get(
8398       spdy_util_.ConstructSpdyDataFrame(1, kGet, false));
8399 
8400   const char kResp[] =
8401       "HTTP/1.1 200 OK\r\n"
8402       "Content-Length: 10\r\n\r\n";
8403   spdy::SpdySerializedFrame wrapped_get_resp(
8404       spdy_util_.ConstructSpdyDataFrame(1, kResp, false));
8405 
8406   const char kRespData[] = "1234567890";
8407   spdy::SpdySerializedFrame wrapped_body(
8408       spdy_util_.ConstructSpdyDataFrame(1, kRespData, false));
8409 
8410   MockWrite spdy_writes[] = {
8411       CreateMockWrite(proxy2_connect, 0),
8412       CreateMockWrite(wrapped_endpoint_connect, 2),
8413       CreateMockWrite(wrapped_get, 4),
8414   };
8415 
8416   MockRead spdy_reads[] = {
8417       CreateMockRead(proxy2_connect_resp, 1, ASYNC),
8418       CreateMockRead(wrapped_endpoint_connect_resp, 3, ASYNC),
8419       CreateMockRead(wrapped_get_resp, 5, ASYNC),
8420       CreateMockRead(wrapped_body, 6, ASYNC),
8421       MockRead(ASYNC, 0, 7),
8422   };
8423 
8424   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
8425   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8426 
8427   SSLSocketDataProvider ssl(ASYNC, OK);
8428   ssl.next_proto = kProtoHTTP2;
8429   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8430   SSLSocketDataProvider ssl2(ASYNC, OK);
8431   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
8432   SSLSocketDataProvider ssl3(ASYNC, OK);
8433   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
8434 
8435   TestCompletionCallback callback1;
8436 
8437   int rv = trans.Start(&request, callback1.callback(),
8438                        NetLogWithSource::Make(NetLogSourceType::NONE));
8439   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8440 
8441   rv = callback1.WaitForResult();
8442   ASSERT_THAT(rv, IsOk());
8443 
8444   LoadTimingInfo load_timing_info;
8445   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
8446   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
8447 
8448   const HttpResponseInfo* response = trans.GetResponseInfo();
8449   ASSERT_TRUE(response);
8450   ASSERT_TRUE(response->headers);
8451   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8452 
8453   std::string response_data;
8454   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
8455   EXPECT_EQ(kRespData, response_data);
8456 }
8457 
8458 // Test a SPDY CONNECT failure through an HTTPS (SPDY) proxy
8459 // (SPDY -> HTTPS/SPDY).
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyConnectFailure)8460 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
8461   HttpRequestInfo request;
8462   request.method = "GET";
8463   request.url = GURL("https://www.example.org/");
8464   request.traffic_annotation =
8465       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8466 
8467   // Configure against https proxy server "proxy:70".
8468   session_deps_.proxy_resolution_service =
8469       ConfiguredProxyResolutionService::CreateFixedForTest(
8470           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8471   session_deps_.net_log = NetLog::Get();
8472   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8473 
8474   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8475 
8476   // CONNECT to www.example.org:443 via SPDY.
8477   spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
8478       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
8479       HostPortPair("www.example.org", 443)));
8480   spdy::SpdySerializedFrame rst(
8481       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
8482 
8483   MockWrite spdy_writes[] = {
8484       CreateMockWrite(connect, 0),
8485       CreateMockWrite(rst, 2),
8486   };
8487 
8488   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
8489   MockRead spdy_reads[] = {
8490       CreateMockRead(resp, 1, ASYNC),
8491       // Pause instead of triggering a connection close so that it's more clear
8492       // which action is causing the tunnel error (the endpoint connect error
8493       // above).
8494       MockRead(ASYNC, ERR_IO_PENDING, 3),
8495       MockRead(ASYNC, 0, 4),
8496   };
8497 
8498   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
8499   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8500 
8501   SSLSocketDataProvider ssl(ASYNC, OK);
8502   ssl.next_proto = kProtoHTTP2;
8503   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8504 
8505   TestCompletionCallback callback1;
8506 
8507   int rv = trans.Start(&request, callback1.callback(),
8508                        NetLogWithSource::Make(NetLogSourceType::NONE));
8509   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8510 
8511   rv = callback1.WaitForResult();
8512   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
8513 
8514   // TODO(juliatuttle): Anything else to check here?
8515 }
8516 
8517 // Test a SPDY CONNECT failure through two HTTPS (SPDY) proxies where the
8518 // connection to the first proxy fails (SPDY -> HTTPS/SPDY -> HTTPS/SPDY).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxySpdyConnectFirstProxyFailure)8519 TEST_P(HttpNetworkTransactionTest,
8520        HttpsNestedProxySpdyConnectFirstProxyFailure) {
8521   HttpRequestInfo request;
8522   request.method = "GET";
8523   request.url = GURL("https://www.example.org/");
8524   request.traffic_annotation =
8525       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8526 
8527   // Configure a nested proxy.
8528   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
8529                                   HostPortPair("proxy1.test", 70)};
8530   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
8531                                   HostPortPair("proxy2.test", 71)};
8532   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
8533 
8534   ProxyList proxy_list;
8535   proxy_list.AddProxyChain(kNestedProxyChain);
8536   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
8537 
8538   session_deps_.proxy_resolution_service =
8539       ConfiguredProxyResolutionService::CreateFixedForTest(
8540           ProxyConfigWithAnnotation(proxy_config,
8541                                     TRAFFIC_ANNOTATION_FOR_TESTS));
8542   session_deps_.net_log = NetLog::Get();
8543   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8544 
8545   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8546 
8547   // CONNECT to proxy2.test:71 via SPDY.
8548   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
8549       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
8550       kProxyServer2.host_port_pair()));
8551   spdy::SpdySerializedFrame proxy2_connect_error_resp(
8552       spdy_util_.ConstructSpdyReplyError(1));
8553 
8554   spdy::SpdySerializedFrame rst(
8555       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
8556 
8557   MockWrite spdy_writes[] = {
8558       CreateMockWrite(proxy2_connect, 0),
8559       CreateMockWrite(rst, 2),
8560   };
8561   MockRead spdy_reads[] = {
8562       CreateMockRead(proxy2_connect_error_resp, 1, ASYNC),
8563       // Pause instead of triggering a connection close so that it's more clear
8564       // which action is causing the tunnel error (the endpoint connect error
8565       // above).
8566       MockRead(ASYNC, ERR_IO_PENDING, 3),
8567       MockRead(ASYNC, 0, 4),
8568   };
8569 
8570   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
8571   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8572 
8573   SSLSocketDataProvider ssl(ASYNC, OK);
8574   ssl.next_proto = kProtoHTTP2;
8575   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8576 
8577   TestCompletionCallback callback1;
8578 
8579   int rv = trans.Start(&request, callback1.callback(),
8580                        NetLogWithSource::Make(NetLogSourceType::NONE));
8581   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8582 
8583   rv = callback1.WaitForResult();
8584   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
8585 }
8586 
8587 // Test a SPDY CONNECT failure through two HTTPS (SPDY) proxies where the
8588 // connection to the second proxy fails (SPDY -> SPDY -> HTTPS/SPDY).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxySpdyConnectSecondProxyFailure)8589 TEST_P(HttpNetworkTransactionTest,
8590        HttpsNestedProxySpdyConnectSecondProxyFailure) {
8591   HttpRequestInfo request;
8592   request.method = "GET";
8593   request.url = GURL("https://www.example.org/");
8594   request.traffic_annotation =
8595       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8596 
8597   // Configure a nested proxy.
8598   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
8599                                   HostPortPair("proxy1.test", 70)};
8600   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
8601                                   HostPortPair("proxy2.test", 71)};
8602   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
8603 
8604   ProxyList proxy_list;
8605   proxy_list.AddProxyChain(kNestedProxyChain);
8606   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
8607 
8608   session_deps_.proxy_resolution_service =
8609       std::make_unique<ConfiguredProxyResolutionService>(
8610           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
8611               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
8612           /*resolver_factory=*/nullptr,
8613           /*net_log=*/nullptr, /*quick_check_enabled=*/true);
8614   session_deps_.net_log = NetLog::Get();
8615   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8616 
8617   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8618 
8619   // CONNECT to proxy2.test:71 via SPDY.
8620   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
8621       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
8622       kProxyServer2.host_port_pair()));
8623 
8624   spdy::SpdySerializedFrame proxy2_connect_resp(
8625       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8626 
8627   // Need to use a new `SpdyTestUtil()` so that the stream parent ID of this
8628   // request is calculated correctly.
8629   SpdyTestUtil new_spdy_util;
8630   // CONNECT to www.example.org:443 via SPDY.
8631   spdy::SpdySerializedFrame endpoint_connect(new_spdy_util.ConstructSpdyConnect(
8632       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
8633       HostPortPair("www.example.org", 443)));
8634   spdy::SpdySerializedFrame rst(
8635       new_spdy_util.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
8636 
8637   // Since this request and response are sent over the tunnel established
8638   // previously, from a socket-perspective these need to be wrapped as data
8639   // frames.
8640   spdy::SpdySerializedFrame wrapped_endpoint_connect(
8641       spdy_util_.ConstructSpdyDataFrame(1, endpoint_connect, false));
8642   spdy::SpdySerializedFrame wrapped_rst(
8643       spdy_util_.ConstructSpdyDataFrame(1, rst, false));
8644 
8645   spdy::SpdySerializedFrame endpoint_connect_error_resp(
8646       new_spdy_util.ConstructSpdyReplyError(1));
8647   spdy::SpdySerializedFrame wrapped_endpoint_connect_error_resp(
8648       spdy_util_.ConstructSpdyDataFrame(1, endpoint_connect_error_resp, false));
8649 
8650   MockWrite spdy_writes[] = {
8651       CreateMockWrite(proxy2_connect, 0),
8652       CreateMockWrite(wrapped_endpoint_connect, 2),
8653       CreateMockWrite(wrapped_rst, 5),
8654   };
8655 
8656   MockRead spdy_reads[] = {
8657       CreateMockRead(proxy2_connect_resp, 1, ASYNC),
8658       // TODO(https://crbug.com/497228): We have to manually delay this read so
8659       // that the higher-level SPDY stream doesn't get notified of an available
8660       // read before the write it initiated (the second CONNECT) finishes,
8661       // triggering a DCHECK.
8662       MockRead(ASYNC, ERR_IO_PENDING, 3),
8663       CreateMockRead(wrapped_endpoint_connect_error_resp, 4, ASYNC),
8664       // Pause instead of triggering a connection close so that it's more clear
8665       // which action is causing the tunnel error (the endpoint connect error
8666       // above).
8667       MockRead(ASYNC, ERR_IO_PENDING, 6),
8668       MockRead(ASYNC, 0, 7),
8669   };
8670 
8671   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
8672   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8673 
8674   SSLSocketDataProvider ssl(ASYNC, OK);
8675   ssl.next_proto = kProtoHTTP2;
8676   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8677   SSLSocketDataProvider ssl2(ASYNC, OK);
8678   ssl2.next_proto = kProtoHTTP2;
8679   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
8680 
8681   TestCompletionCallback callback1;
8682 
8683   int rv = trans.Start(&request, callback1.callback(),
8684                        NetLogWithSource::Make(NetLogSourceType::NONE));
8685   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8686 
8687   spdy_data.RunUntilPaused();
8688   base::RunLoop().RunUntilIdle();
8689   spdy_data.Resume();
8690 
8691   rv = callback1.WaitForResult();
8692   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
8693 }
8694 
8695 // This method creates a tunnel using `chain1`, proxies an HTTP GET request
8696 // through it to ensure that it has been created successfully, and then creates
8697 // another tunnel using `chain2` to check whether a new socket is used for it.
8698 // This is used to test that no unexpected socket reuse occurs between different
8699 // proxy chains.
HttpsNestedProxyNoSocketReuseHelper(const net::ProxyChain & chain1,const net::ProxyChain & chain2)8700 void HttpNetworkTransactionTestBase::HttpsNestedProxyNoSocketReuseHelper(
8701     const net::ProxyChain& chain1,
8702     const net::ProxyChain& chain2) {
8703   ASSERT_NE(chain1, chain2);
8704 
8705   session_deps_.proxy_delegate = std::make_unique<TestProxyDelegate>();
8706   auto* proxy_delegate =
8707       static_cast<TestProxyDelegate*>(session_deps_.proxy_delegate.get());
8708   proxy_delegate->set_proxy_chain(chain1);
8709 
8710   HttpRequestInfo request;
8711   request.method = "GET";
8712   request.url = GURL("http://www.example.org/");
8713   request.traffic_annotation =
8714       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8715 
8716   session_deps_.proxy_resolution_service =
8717       ConfiguredProxyResolutionService::CreateFixedForTest(
8718           "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8719   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
8720   session_deps_.net_log = NetLog::Get();
8721   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8722 
8723   std::vector<SSLSocketDataProvider> ssl_socket_data_providers;
8724   std::vector<std::string> connects;
8725   // Allocate enough space in each of these so that the address of each entry
8726   // will not change after insertion.
8727   ssl_socket_data_providers.reserve(chain1.length() + chain2.length());
8728   connects.reserve(chain1.length() - 1 + chain2.length() - 1);
8729 
8730   std::vector<MockWrite> data_writes1;
8731   std::vector<MockRead> data_reads1;
8732 
8733   for (size_t proxy_index = 1; proxy_index < chain1.length(); ++proxy_index) {
8734     const auto& proxy_host_port_pair_string =
8735         chain1.GetProxyServer(proxy_index).host_port_pair().ToString();
8736     connects.push_back(
8737         base::StringPrintf("CONNECT %s HTTP/1.1\r\n"
8738                            "Host: %s\r\n"
8739                            "Proxy-Connection: keep-alive\r\n\r\n",
8740                            proxy_host_port_pair_string.c_str(),
8741                            proxy_host_port_pair_string.c_str()));
8742     data_writes1.emplace_back(connects.back().c_str());
8743     data_reads1.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
8744   }
8745 
8746   if (chain1.is_multi_proxy()) {
8747     // Since this is a multi-proxy chain, CONNECT to the endpoint.
8748     data_writes1.emplace_back(
8749         "CONNECT www.example.org:80 HTTP/1.1\r\n"
8750         "Host: www.example.org:80\r\n"
8751         "Proxy-Connection: keep-alive\r\n\r\n");
8752     data_reads1.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
8753 
8754     // Make the request to the endpoint.
8755     data_writes1.emplace_back(
8756         "GET / HTTP/1.1\r\n"
8757         "Host: www.example.org\r\n"
8758         "Connection: keep-alive\r\n\r\n");
8759   } else {
8760     // For a single-proxy chain, use GET.
8761     data_writes1.emplace_back(
8762         "GET http://www.example.org/ HTTP/1.1\r\n"
8763         "Host: www.example.org\r\n"
8764         "Proxy-Connection: keep-alive\r\n\r\n");
8765   }
8766 
8767   data_reads1.emplace_back("HTTP/1.1 200 OK\r\n");
8768   data_reads1.emplace_back(SYNCHRONOUS, OK);
8769 
8770   StaticSocketDataProvider data1(data_reads1, data_writes1);
8771   session_deps_.socket_factory->AddSocketDataProvider(&data1);
8772 
8773   for (size_t proxy_index = 0; proxy_index < chain1.length(); ++proxy_index) {
8774     ssl_socket_data_providers.emplace_back(ASYNC, OK);
8775     session_deps_.socket_factory->AddSSLSocketDataProvider(
8776         &ssl_socket_data_providers.back());
8777   }
8778 
8779   TestCompletionCallback callback1;
8780 
8781   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
8782 
8783   int rv = trans1.Start(&request, callback1.callback(),
8784                         NetLogWithSource::Make(NetLogSourceType::NONE));
8785   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8786 
8787   rv = callback1.WaitForResult();
8788   EXPECT_THAT(rv, IsOk());
8789 
8790   const HttpResponseInfo* response = trans1.GetResponseInfo();
8791   ASSERT_TRUE(response);
8792   EXPECT_EQ(200, response->headers->response_code());
8793   EXPECT_EQ(chain1, response->proxy_chain);
8794 
8795   // Now use the second proxy chain. We expect that it will use a new
8796   // socket, so to test this we will create a new socket data provider and
8797   // expect that this gets used instead of the one created above for the
8798   // first transaction.
8799   proxy_delegate->set_proxy_chain(chain2);
8800 
8801   std::vector<MockWrite> data_writes2;
8802   std::vector<MockRead> data_reads2;
8803 
8804   for (size_t proxy_index = 1; proxy_index < chain2.length(); ++proxy_index) {
8805     const auto& proxy_host_port_pair_string =
8806         chain2.GetProxyServer(proxy_index).host_port_pair().ToString();
8807     connects.push_back(
8808         base::StringPrintf("CONNECT %s HTTP/1.1\r\n"
8809                            "Host: %s\r\n"
8810                            "Proxy-Connection: keep-alive\r\n\r\n",
8811                            proxy_host_port_pair_string.c_str(),
8812                            proxy_host_port_pair_string.c_str()));
8813     data_writes2.emplace_back(connects.back().c_str());
8814     data_reads2.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
8815   }
8816 
8817   if (chain2.is_multi_proxy()) {
8818     // Since this is a multi-proxy chain, CONNECT to the endpoint.
8819     data_writes2.emplace_back(
8820         "CONNECT www.example.org:80 HTTP/1.1\r\n"
8821         "Host: www.example.org:80\r\n"
8822         "Proxy-Connection: keep-alive\r\n\r\n");
8823     data_reads2.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
8824 
8825     // Make the request to the endpoint.
8826     data_writes2.emplace_back(
8827         "GET / HTTP/1.1\r\n"
8828         "Host: www.example.org\r\n"
8829         "Connection: keep-alive\r\n\r\n");
8830   } else {
8831     // For a single-proxy chain, use GET.
8832     data_writes2.emplace_back(
8833         "GET http://www.example.org/ HTTP/1.1\r\n"
8834         "Host: www.example.org\r\n"
8835         "Proxy-Connection: keep-alive\r\n\r\n");
8836   }
8837   data_reads2.emplace_back("HTTP/1.1 200 OK\r\n");
8838   data_reads2.emplace_back(SYNCHRONOUS, OK);
8839 
8840   StaticSocketDataProvider data2(data_reads2, data_writes2);
8841   session_deps_.socket_factory->AddSocketDataProvider(&data2);
8842 
8843   for (size_t proxy_index = 0; proxy_index < chain2.length(); ++proxy_index) {
8844     ssl_socket_data_providers.emplace_back(ASYNC, OK);
8845     session_deps_.socket_factory->AddSSLSocketDataProvider(
8846         &ssl_socket_data_providers.back());
8847   }
8848 
8849   TestCompletionCallback callback2;
8850   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
8851 
8852   rv = trans2.Start(&request, callback2.callback(),
8853                     NetLogWithSource::Make(NetLogSourceType::NONE));
8854   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8855 
8856   rv = callback2.WaitForResult();
8857   EXPECT_THAT(rv, IsOk());
8858 
8859   response = trans2.GetResponseInfo();
8860   ASSERT_TRUE(response);
8861   EXPECT_EQ(200, response->headers->response_code());
8862   EXPECT_EQ(chain2, response->proxy_chain);
8863 
8864   EXPECT_TRUE(data1.AllReadDataConsumed());
8865   EXPECT_TRUE(data1.AllWriteDataConsumed());
8866   EXPECT_TRUE(data2.AllReadDataConsumed());
8867   EXPECT_TRUE(data2.AllWriteDataConsumed());
8868 }
8869 
8870 // If we have established a proxy tunnel through a two hop proxy and then
8871 // establish a tunnel through only the first hop, ensure that socket re-use does
8872 // not occur (HTTPS A -> HTTPS B != HTTPS A).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyNoSocketReuseFirstHop)8873 TEST_P(HttpNetworkTransactionTest, HttpsNestedProxyNoSocketReuseFirstHop) {
8874   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
8875                                   HostPortPair("proxy1.test", 70)};
8876   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
8877                                   HostPortPair("proxy2.test", 71)};
8878   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
8879 
8880   const ProxyChain kFirstHopOnlyChain{{kProxyServer1}};
8881   HttpsNestedProxyNoSocketReuseHelper(kNestedProxyChain, kFirstHopOnlyChain);
8882 }
8883 
8884 // If we have established a proxy tunnel through a two hop proxy and then
8885 // establish a tunnel through only the second hop, ensure that socket re-use
8886 // does not occur (HTTPS A -> HTTPS B != HTTPS B).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyNoSocketReuseSecondHop)8887 TEST_P(HttpNetworkTransactionTest, HttpsNestedProxyNoSocketReuseSecondHop) {
8888   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
8889                                   HostPortPair("proxy1.test", 70)};
8890   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
8891                                   HostPortPair("proxy2.test", 71)};
8892   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
8893 
8894   const ProxyChain kSecondHopOnlyChain{{kProxyServer2}};
8895 
8896   HttpsNestedProxyNoSocketReuseHelper(kNestedProxyChain, kSecondHopOnlyChain);
8897 }
8898 
8899 // If we have established a proxy tunnel through a two hop proxy and then
8900 // establish a tunnel through the same proxies with the order reversed, ensure
8901 // that socket re-use does not occur (HTTPS A -> HTTPS B != HTTPS B -> HTTPS A).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyNoSocketReuseReversedChain)8902 TEST_P(HttpNetworkTransactionTest, HttpsNestedProxyNoSocketReuseReversedChain) {
8903   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
8904                                   HostPortPair("proxy1.test", 70)};
8905   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
8906                                   HostPortPair("proxy2.test", 71)};
8907   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
8908 
8909   const ProxyChain kReversedChain{{kProxyServer2, kProxyServer1}};
8910 
8911   HttpsNestedProxyNoSocketReuseHelper(kNestedProxyChain, kReversedChain);
8912 }
8913 
8914 // If we have established a proxy tunnel through a two hop proxy using SPDY,
8915 // ensure that socket reuse occurs as expected. Specifically, for:
8916 // (SPDY A -> SPDY B -> HTTPS Endpoint),
8917 // (SPDY A -> HTTPS Endpoint) should send the endpoint CONNECT to
8918 // the existing SPDY A socket but for:
8919 // (SPDY B -> HTTPS Endpoint), the SPDY A -> SPDY B socket should not be used.
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxySpdySocketReuseDifferentChains)8920 TEST_P(HttpNetworkTransactionTest,
8921        HttpsNestedProxySpdySocketReuseDifferentChains) {
8922   HttpRequestInfo request;
8923   request.method = "GET";
8924   request.url = GURL("https://www.example.org/");
8925   request.traffic_annotation =
8926       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8927 
8928   // Configure a nested proxy.
8929   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
8930                                   HostPortPair("proxy1.test", 70)};
8931   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
8932                                   HostPortPair("proxy2.test", 71)};
8933   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
8934   const ProxyChain kFirstHopOnlyChain{{kProxyServer1}};
8935   const ProxyChain kSecondHopOnlyChain{{kProxyServer1}};
8936 
8937   session_deps_.proxy_delegate = std::make_unique<TestProxyDelegate>();
8938   auto* proxy_delegate =
8939       static_cast<TestProxyDelegate*>(session_deps_.proxy_delegate.get());
8940   proxy_delegate->set_proxy_chain(kNestedProxyChain);
8941 
8942   session_deps_.proxy_resolution_service =
8943       ConfiguredProxyResolutionService::CreateFixedForTest(
8944           "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8945   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
8946 
8947   session_deps_.net_log = NetLog::Get();
8948   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8949 
8950   // CONNECT to proxy2.test:71 via SPDY.
8951   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
8952       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
8953       kProxyServer2.host_port_pair()));
8954 
8955   spdy::SpdySerializedFrame proxy2_connect_resp(
8956       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8957 
8958   // CONNECT to www.example.org:443 via SPDY.
8959   // Need to use a new `SpdyTestUtil()` so that the stream parent ID of this
8960   // CONNECT is calculated correctly.
8961   SpdyTestUtil new_spdy_util;
8962   spdy::SpdySerializedFrame endpoint_connect(new_spdy_util.ConstructSpdyConnect(
8963       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
8964       HostPortPair("www.example.org", 443)));
8965 
8966   // Since this request and response are sent over the tunnel established
8967   // previously, from a socket-perspective these need to be wrapped as data
8968   // frames.
8969   spdy::SpdySerializedFrame wrapped_endpoint_connect(
8970       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect, 1));
8971 
8972   spdy::SpdySerializedFrame endpoint_connect_resp(
8973       new_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
8974   spdy::SpdySerializedFrame wrapped_endpoint_connect_resp(
8975       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect_resp, 1));
8976 
8977   // fetch https://www.example.org/ via HTTP.
8978   // Since this request will go over two tunnels, it needs to be double-wrapped.
8979   const char kGet[] =
8980       "GET / HTTP/1.1\r\n"
8981       "Host: www.example.org\r\n"
8982       "Connection: keep-alive\r\n\r\n";
8983   spdy::SpdySerializedFrame wrapped_get(
8984       new_spdy_util.ConstructSpdyDataFrame(1, kGet, false));
8985   spdy::SpdySerializedFrame wrapped_wrapped_get(
8986       spdy_util_.ConstructWrappedSpdyFrame(wrapped_get, 1));
8987 
8988   const char kResp[] =
8989       "HTTP/1.1 200 OK\r\n"
8990       "Content-Length: 10\r\n\r\n";
8991   spdy::SpdySerializedFrame wrapped_get_resp(
8992       new_spdy_util.ConstructSpdyDataFrame(1, kResp, false));
8993   spdy::SpdySerializedFrame wrapped_wrapped_get_resp(
8994       spdy_util_.ConstructWrappedSpdyFrame(wrapped_get_resp, 1));
8995 
8996   const char kTrans1RespData[] = "1234567890";
8997   spdy::SpdySerializedFrame wrapped_body(
8998       new_spdy_util.ConstructSpdyDataFrame(1, kTrans1RespData, false));
8999   spdy::SpdySerializedFrame wrapped_wrapped_body(
9000       spdy_util_.ConstructWrappedSpdyFrame(wrapped_body, 1));
9001 
9002   const char kTrans2RespData[] = "abcdefghij";
9003   spdy::SpdySerializedFrame second_trans_endpoint_connect(
9004       spdy_util_.ConstructSpdyConnect(
9005           nullptr, 0, 3, HttpProxyConnectJob::kH2QuicTunnelPriority,
9006           HostPortPair("www.example.org", 443)));
9007   spdy::SpdySerializedFrame second_trans_endpoint_connect_resp(
9008       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
9009   spdy::SpdySerializedFrame second_trans_wrapped_get(
9010       new_spdy_util.ConstructSpdyDataFrame(3, kGet, false));
9011   spdy::SpdySerializedFrame second_trans_wrapped_get_resp(
9012       new_spdy_util.ConstructSpdyDataFrame(3, kResp, false));
9013   spdy::SpdySerializedFrame second_trans_wrapped_body(
9014       new_spdy_util.ConstructSpdyDataFrame(3, kTrans2RespData, false));
9015 
9016   MockWrite spdy_writes1[] = {
9017       CreateMockWrite(proxy2_connect, 0),
9018       CreateMockWrite(wrapped_endpoint_connect, 2),
9019       CreateMockWrite(wrapped_wrapped_get, 5),
9020       // For the second transaction, we expect the endpoint connect on this
9021       // socket.
9022       CreateMockWrite(second_trans_endpoint_connect, 8),
9023       CreateMockWrite(second_trans_wrapped_get, 10),
9024 
9025   };
9026 
9027   MockRead spdy_reads1[] = {
9028       CreateMockRead(proxy2_connect_resp, 1, ASYNC),
9029       // TODO(https://crbug.com/497228): We have to manually delay this read so
9030       // that the higher-level SPDY stream doesn't get notified of an available
9031       // read before the write it initiated (the second CONNECT) finishes,
9032       // triggering a DCHECK.
9033       MockRead(ASYNC, ERR_IO_PENDING, 3),
9034       CreateMockRead(wrapped_endpoint_connect_resp, 4, ASYNC),
9035       CreateMockRead(wrapped_wrapped_get_resp, 6, ASYNC),
9036       CreateMockRead(wrapped_wrapped_body, 7, ASYNC),
9037       CreateMockRead(second_trans_endpoint_connect_resp, 9),
9038       CreateMockRead(second_trans_wrapped_get_resp, 11, ASYNC),
9039       CreateMockRead(second_trans_wrapped_body, 12, ASYNC),
9040       MockRead(ASYNC, 0, 13),
9041   };
9042 
9043   SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
9044   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
9045 
9046   SSLSocketDataProvider ssl(ASYNC, OK);
9047   ssl.next_proto = kProtoHTTP2;
9048   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9049   SSLSocketDataProvider ssl2(ASYNC, OK);
9050   ssl2.next_proto = kProtoHTTP2;
9051   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
9052   SSLSocketDataProvider ssl3(ASYNC, OK);
9053   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
9054 
9055   TestCompletionCallback callback1;
9056   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
9057 
9058   int rv = trans1.Start(&request, callback1.callback(),
9059                         NetLogWithSource::Make(NetLogSourceType::NONE));
9060   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9061 
9062   spdy_data1.RunUntilPaused();
9063   base::RunLoop().RunUntilIdle();
9064   spdy_data1.Resume();
9065 
9066   rv = callback1.WaitForResult();
9067   ASSERT_THAT(rv, IsOk());
9068 
9069   const HttpResponseInfo* response = trans1.GetResponseInfo();
9070   ASSERT_TRUE(response);
9071   ASSERT_TRUE(response->headers);
9072   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9073   EXPECT_EQ(kNestedProxyChain, response->proxy_chain);
9074 
9075   std::string response_data;
9076   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
9077   EXPECT_EQ(kTrans1RespData, response_data);
9078 
9079   // Now use a proxy chain consisting of only the first proxy. We expect that it
9080   // will re-use the existing socket to the proxy, so we will look for the reads
9081   // and writes associated with this in the same SocketDataProvider used by the
9082   // first transaction.
9083   proxy_delegate->set_proxy_chain(kFirstHopOnlyChain);
9084 
9085   SSLSocketDataProvider ssl4(ASYNC, OK);
9086   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl4);
9087 
9088   TestCompletionCallback callback2;
9089   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
9090 
9091   rv = trans2.Start(&request, callback2.callback(),
9092                     NetLogWithSource::Make(NetLogSourceType::NONE));
9093   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9094 
9095   rv = callback2.WaitForResult();
9096   ASSERT_THAT(rv, IsOk());
9097 
9098   response = trans2.GetResponseInfo();
9099   ASSERT_TRUE(response);
9100   ASSERT_TRUE(response->headers);
9101   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9102   EXPECT_EQ(kFirstHopOnlyChain, response->proxy_chain);
9103 
9104   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
9105   EXPECT_EQ(kTrans2RespData, response_data);
9106 
9107   // Now use a proxy chain consisting of only the second proxy. We expect that
9108   // it will not re-use the existing socket to the first proxy, so we will look
9109   // for the reads and writes associated with this in a new SocketDataProvider.
9110   proxy_delegate->set_proxy_chain(kSecondHopOnlyChain);
9111 
9112   // CONNECT to www.example.org:443 via SPDY.
9113   SpdyTestUtil third_spdy_util;
9114   spdy::SpdySerializedFrame third_trans_endpoint_connect(
9115       third_spdy_util.ConstructSpdyConnect(
9116           nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9117           HostPortPair("www.example.org", 443)));
9118 
9119   spdy::SpdySerializedFrame third_trans_endpoint_connect_resp(
9120       third_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
9121 
9122   // fetch https://www.example.org/ via HTTP.
9123   spdy::SpdySerializedFrame third_trans_wrapped_get(
9124       third_spdy_util.ConstructSpdyDataFrame(1, kGet, false));
9125 
9126   spdy::SpdySerializedFrame third_trans_wrapped_get_resp(
9127       third_spdy_util.ConstructSpdyDataFrame(1, kResp, false));
9128 
9129   const char kTrans3RespData[] = "!@#$%^&*()";
9130   spdy::SpdySerializedFrame third_trans_wrapped_body(
9131       third_spdy_util.ConstructSpdyDataFrame(1, kTrans3RespData, false));
9132 
9133   MockWrite spdy_writes2[] = {
9134       CreateMockWrite(third_trans_endpoint_connect, 0),
9135       CreateMockWrite(third_trans_wrapped_get, 2),
9136   };
9137 
9138   MockRead spdy_reads2[] = {
9139       CreateMockRead(third_trans_endpoint_connect_resp, 1, ASYNC),
9140       CreateMockRead(third_trans_wrapped_get_resp, 3, ASYNC),
9141       CreateMockRead(third_trans_wrapped_body, 4, ASYNC),
9142       MockRead(ASYNC, 0, 5),
9143   };
9144 
9145   SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
9146   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
9147 
9148   SSLSocketDataProvider ssl5(ASYNC, OK);
9149   ssl5.next_proto = kProtoHTTP2;
9150   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl5);
9151 
9152   SSLSocketDataProvider ssl6(ASYNC, OK);
9153   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl6);
9154 
9155   TestCompletionCallback callback3;
9156   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
9157 
9158   rv = trans3.Start(&request, callback3.callback(),
9159                     NetLogWithSource::Make(NetLogSourceType::NONE));
9160   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9161 
9162   rv = callback3.WaitForResult();
9163   ASSERT_THAT(rv, IsOk());
9164 
9165   response = trans3.GetResponseInfo();
9166   ASSERT_TRUE(response);
9167   ASSERT_TRUE(response->headers);
9168   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9169   EXPECT_EQ(kFirstHopOnlyChain, response->proxy_chain);
9170 
9171   ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
9172   EXPECT_EQ(kTrans3RespData, response_data);
9173 
9174   EXPECT_EQ(proxy_delegate->on_before_tunnel_request_call_count(), 4u);
9175 
9176   EXPECT_TRUE(spdy_data1.AllReadDataConsumed());
9177   EXPECT_TRUE(spdy_data1.AllWriteDataConsumed());
9178   EXPECT_TRUE(spdy_data2.AllReadDataConsumed());
9179   EXPECT_TRUE(spdy_data2.AllWriteDataConsumed());
9180 }
9181 
9182 // If we have established a proxy tunnel through a two-hop proxy using SPDY,
9183 // ensure that socket reuse occurs as expected for two different requests (test
9184 // that there is only one CONNECT for the second proxy in the chain).
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxySpdySocketReuseDifferentRequests)9185 TEST_P(HttpNetworkTransactionTest,
9186        HttpsNestedProxySpdySocketReuseDifferentRequests) {
9187   HttpRequestInfo request1;
9188   request1.method = "GET";
9189   request1.url = GURL("https://www.example.org/");
9190   request1.traffic_annotation =
9191       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9192 
9193   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
9194                                   HostPortPair("proxy1.test", 70)};
9195   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
9196                                   HostPortPair("proxy2.test", 71)};
9197   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
9198 
9199   session_deps_.proxy_delegate = std::make_unique<TestProxyDelegate>();
9200   auto* proxy_delegate =
9201       static_cast<TestProxyDelegate*>(session_deps_.proxy_delegate.get());
9202   proxy_delegate->set_proxy_chain(kNestedProxyChain);
9203 
9204   session_deps_.proxy_resolution_service =
9205       ConfiguredProxyResolutionService::CreateFixedForTest(
9206           "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9207   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
9208 
9209   session_deps_.net_log = NetLog::Get();
9210   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9211 
9212   // CONNECT to proxy2.test:71 via SPDY.
9213   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
9214       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9215       kProxyServer2.host_port_pair()));
9216 
9217   spdy::SpdySerializedFrame proxy2_connect_resp(
9218       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
9219 
9220   // CONNECT to www.example.org:443 via SPDY.
9221   // Need to use a new `SpdyTestUtil()` so that the stream parent ID of this
9222   // CONNECT is calculated correctly.
9223   SpdyTestUtil new_spdy_util;
9224   spdy::SpdySerializedFrame endpoint_connect(new_spdy_util.ConstructSpdyConnect(
9225       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9226       HostPortPair("www.example.org", 443)));
9227 
9228   // Since the first request and response are sent over the tunnel established
9229   // previously, from a socket-perspective these need to be wrapped as data
9230   // frames.
9231   spdy::SpdySerializedFrame wrapped_endpoint_connect(
9232       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect, 1));
9233 
9234   spdy::SpdySerializedFrame endpoint_connect_resp(
9235       new_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
9236   spdy::SpdySerializedFrame wrapped_endpoint_connect_resp(
9237       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect_resp, 1));
9238 
9239   // fetch https://www.example.org/ via HTTP.
9240   // Since the first request will go over two tunnels, it needs to be
9241   // double-wrapped.
9242   const char kGet1[] =
9243       "GET / HTTP/1.1\r\n"
9244       "Host: www.example.org\r\n"
9245       "Connection: keep-alive\r\n\r\n";
9246   spdy::SpdySerializedFrame wrapped_get(
9247       new_spdy_util.ConstructSpdyDataFrame(1, kGet1, false));
9248   spdy::SpdySerializedFrame wrapped_wrapped_get(
9249       spdy_util_.ConstructWrappedSpdyFrame(wrapped_get, 1));
9250 
9251   const char kResp[] =
9252       "HTTP/1.1 200 OK\r\n"
9253       "Content-Length: 10\r\n\r\n";
9254   spdy::SpdySerializedFrame wrapped_get_resp(
9255       new_spdy_util.ConstructSpdyDataFrame(1, kResp, false));
9256   spdy::SpdySerializedFrame wrapped_wrapped_get_resp(
9257       spdy_util_.ConstructWrappedSpdyFrame(wrapped_get_resp, 1));
9258 
9259   const char kTrans1RespData[] = "1234567890";
9260   spdy::SpdySerializedFrame wrapped_body(
9261       new_spdy_util.ConstructSpdyDataFrame(1, kTrans1RespData, false));
9262   spdy::SpdySerializedFrame wrapped_wrapped_body(
9263       spdy_util_.ConstructWrappedSpdyFrame(wrapped_body, 1));
9264 
9265   // CONNECT to www.example.com:443 via SPDY.
9266   spdy::SpdySerializedFrame second_trans_endpoint_connect(
9267       new_spdy_util.ConstructSpdyConnect(
9268           nullptr, 0, 3, HttpProxyConnectJob::kH2QuicTunnelPriority,
9269           HostPortPair("www.example.com", 443)));
9270   spdy::SpdySerializedFrame second_trans_wrapped_endpoint_connect(
9271       spdy_util_.ConstructWrappedSpdyFrame(second_trans_endpoint_connect, 1));
9272 
9273   spdy::SpdySerializedFrame second_trans_endpoint_connect_resp(
9274       new_spdy_util.ConstructSpdyGetReply(nullptr, 0, 3));
9275   spdy::SpdySerializedFrame second_trans_wrapped_endpoint_connect_resp(
9276       spdy_util_.ConstructWrappedSpdyFrame(second_trans_endpoint_connect_resp,
9277                                            1));
9278 
9279   // fetch https://www.example.com/2 via HTTP.
9280   const char kGet2[] =
9281       "GET /2 HTTP/1.1\r\n"
9282       "Host: www.example.com\r\n"
9283       "Connection: keep-alive\r\n\r\n";
9284   SpdyTestUtil second_trans_spdy_util;
9285   spdy::SpdySerializedFrame second_trans_wrapped_get(
9286       second_trans_spdy_util.ConstructSpdyDataFrame(3, kGet2, false));
9287   spdy::SpdySerializedFrame second_trans_wrapped_wrapped_get(
9288       spdy_util_.ConstructWrappedSpdyFrame(second_trans_wrapped_get, 1));
9289 
9290   spdy::SpdySerializedFrame second_trans_wrapped_get_resp(
9291       second_trans_spdy_util.ConstructSpdyDataFrame(3, kResp, false));
9292   spdy::SpdySerializedFrame second_trans_wrapped_wrapped_get_resp(
9293       spdy_util_.ConstructWrappedSpdyFrame(second_trans_wrapped_get_resp, 1));
9294 
9295   const char kTrans2RespData[] = "abcdefghij";
9296   spdy::SpdySerializedFrame second_trans_wrapped_body(
9297       second_trans_spdy_util.ConstructSpdyDataFrame(3, kTrans2RespData, false));
9298   spdy::SpdySerializedFrame second_trans_wrapped_wrapped_body(
9299       spdy_util_.ConstructWrappedSpdyFrame(second_trans_wrapped_body, 1));
9300 
9301   MockWrite spdy_writes1[] = {
9302       CreateMockWrite(proxy2_connect, 0),
9303       CreateMockWrite(wrapped_endpoint_connect, 2),
9304       CreateMockWrite(wrapped_wrapped_get, 5),
9305       // For the second transaction, we expect the endpoint connect on this
9306       // socket with no duplicated proxy2 CONNECT.
9307       CreateMockWrite(second_trans_wrapped_endpoint_connect, 8),
9308       CreateMockWrite(second_trans_wrapped_wrapped_get, 11),
9309   };
9310 
9311   MockRead spdy_reads1[] = {
9312       CreateMockRead(proxy2_connect_resp, 1, ASYNC),
9313       // TODO(https://crbug.com/497228): We have to manually delay this read so
9314       // that the higher-level SPDY stream doesn't get notified of an available
9315       // read before the write it initiated (the second CONNECT) finishes,
9316       // triggering a DCHECK.
9317       MockRead(ASYNC, ERR_IO_PENDING, 3),
9318       CreateMockRead(wrapped_endpoint_connect_resp, 4, ASYNC),
9319       CreateMockRead(wrapped_wrapped_get_resp, 6, ASYNC),
9320       CreateMockRead(wrapped_wrapped_body, 7, ASYNC),
9321       // TODO(https://crbug.com/497228): We have to manually delay this read so
9322       // that the higher-level SPDY stream doesn't get notified of an available
9323       // read before the write it initiated (the second CONNECT) finishes,
9324       // triggering a DCHECK.
9325       MockRead(ASYNC, ERR_IO_PENDING, 9),
9326       CreateMockRead(second_trans_wrapped_endpoint_connect_resp, 10),
9327       CreateMockRead(second_trans_wrapped_wrapped_get_resp, 12),
9328       CreateMockRead(second_trans_wrapped_wrapped_body, 13),
9329       MockRead(ASYNC, 0, 14),
9330   };
9331 
9332   SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
9333   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
9334 
9335   SSLSocketDataProvider ssl(ASYNC, OK);
9336   ssl.next_proto = kProtoHTTP2;
9337   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9338   SSLSocketDataProvider ssl2(ASYNC, OK);
9339   ssl2.next_proto = kProtoHTTP2;
9340   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
9341   SSLSocketDataProvider ssl3(ASYNC, OK);
9342   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
9343 
9344   TestCompletionCallback callback1;
9345   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
9346 
9347   int rv = trans1.Start(&request1, callback1.callback(),
9348                         NetLogWithSource::Make(NetLogSourceType::NONE));
9349   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9350 
9351   spdy_data1.RunUntilPaused();
9352   base::RunLoop().RunUntilIdle();
9353   spdy_data1.Resume();
9354 
9355   rv = callback1.WaitForResult();
9356   ASSERT_THAT(rv, IsOk());
9357 
9358   const HttpResponseInfo* response = trans1.GetResponseInfo();
9359   ASSERT_TRUE(response);
9360   ASSERT_TRUE(response->headers);
9361   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9362   EXPECT_EQ(kNestedProxyChain, response->proxy_chain);
9363 
9364   std::string response_data;
9365   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
9366   EXPECT_EQ(kTrans1RespData, response_data);
9367 
9368   HttpRequestInfo request2;
9369   request2.method = "GET";
9370   request2.url = GURL("https://www.example.com/2");
9371   request2.traffic_annotation =
9372       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9373 
9374   SSLSocketDataProvider ssl4(ASYNC, OK);
9375   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl4);
9376 
9377   TestCompletionCallback callback2;
9378   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
9379 
9380   rv = trans2.Start(&request2, callback2.callback(),
9381                     NetLogWithSource::Make(NetLogSourceType::NONE));
9382   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9383 
9384   spdy_data1.RunUntilPaused();
9385   base::RunLoop().RunUntilIdle();
9386   spdy_data1.Resume();
9387 
9388   rv = callback2.WaitForResult();
9389   ASSERT_THAT(rv, IsOk());
9390 
9391   response = trans2.GetResponseInfo();
9392   ASSERT_TRUE(response);
9393   ASSERT_TRUE(response->headers);
9394   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9395   EXPECT_EQ(kNestedProxyChain, response->proxy_chain);
9396 
9397   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
9398   EXPECT_EQ(kTrans2RespData, response_data);
9399 }
9400 
9401 // Ensure that socket reuse occurs after an error from a SPDY connection through
9402 // the nested proxy.
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxySpdySocketReuseAfterError)9403 TEST_P(HttpNetworkTransactionTest, HttpsNestedProxySpdySocketReuseAfterError) {
9404   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
9405                                   HostPortPair("proxy1.test", 70)};
9406   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
9407                                   HostPortPair("proxy2.test", 71)};
9408   const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
9409 
9410   ProxyList proxy_list;
9411   proxy_list.AddProxyChain(kNestedProxyChain);
9412   ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
9413 
9414   session_deps_.proxy_resolution_service =
9415       ConfiguredProxyResolutionService::CreateFixedForTest(
9416           ProxyConfigWithAnnotation(proxy_config,
9417                                     TRAFFIC_ANNOTATION_FOR_TESTS));
9418   session_deps_.net_log = NetLog::Get();
9419   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9420 
9421   // CONNECT to proxy2.test:71 via SPDY.
9422   spdy::SpdySerializedFrame proxy2_connect(spdy_util_.ConstructSpdyConnect(
9423       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9424       kProxyServer2.host_port_pair()));
9425 
9426   spdy::SpdySerializedFrame proxy2_connect_resp(
9427       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
9428 
9429   // CONNECT to www.example.org:443 via SPDY.
9430   // Need to use a new `SpdyTestUtil()` so that the stream parent ID of this
9431   // CONNECT is calculated correctly.
9432   SpdyTestUtil new_spdy_util;
9433   spdy::SpdySerializedFrame endpoint_connect(new_spdy_util.ConstructSpdyConnect(
9434       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9435       HostPortPair("www.example.org", 443)));
9436 
9437   // Since this request and response are sent over the tunnel established
9438   // previously, from a socket-perspective these need to be wrapped as data
9439   // frames.
9440   spdy::SpdySerializedFrame wrapped_endpoint_connect(
9441       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect, 1));
9442 
9443   spdy::SpdySerializedFrame endpoint_connect_resp(
9444       new_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
9445   spdy::SpdySerializedFrame wrapped_endpoint_connect_resp(
9446       spdy_util_.ConstructWrappedSpdyFrame(endpoint_connect_resp, 1));
9447 
9448   spdy::SpdySerializedFrame rst(
9449       new_spdy_util.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
9450   spdy::SpdySerializedFrame wrapped_rst(
9451       spdy_util_.ConstructWrappedSpdyFrame(rst, 1));
9452 
9453   new_spdy_util.UpdateWithStreamDestruction(1);
9454   spdy::SpdySerializedFrame attempt2_endpoint_connect(
9455       new_spdy_util.ConstructSpdyConnect(
9456           nullptr, 0, 3, HttpProxyConnectJob::kH2QuicTunnelPriority,
9457           HostPortPair("www.example.org", 443)));
9458   spdy::SpdySerializedFrame attempt2_wrapped_endpoint_connect(
9459       spdy_util_.ConstructWrappedSpdyFrame(attempt2_endpoint_connect, 1));
9460 
9461   spdy::SpdySerializedFrame attempt2_endpoint_connect_resp(
9462       new_spdy_util.ConstructSpdyGetReply(nullptr, 0, 3));
9463   spdy::SpdySerializedFrame attempt2_wrapped_endpoint_connect_resp(
9464       spdy_util_.ConstructWrappedSpdyFrame(attempt2_endpoint_connect_resp, 1));
9465 
9466   // fetch https://www.example.org/ via HTTPS.
9467   // Since this request will go over two tunnels, it needs to be double-wrapped.
9468   const char kGet[] =
9469       "GET / HTTP/1.1\r\n"
9470       "Host: www.example.org\r\n"
9471       "Connection: keep-alive\r\n\r\n";
9472   SpdyTestUtil attempt2_spdy_util(/*use_priority_header=*/true);
9473   spdy::SpdySerializedFrame attempt2_wrapped_get(
9474       attempt2_spdy_util.ConstructSpdyDataFrame(3, kGet, false));
9475   spdy::SpdySerializedFrame attempt2_wrapped_wrapped_get(
9476       spdy_util_.ConstructWrappedSpdyFrame(attempt2_wrapped_get, 1));
9477 
9478   const char kResp[] =
9479       "HTTP/1.1 200 OK\r\n"
9480       "Content-Length: 10\r\n\r\n";
9481   spdy::SpdySerializedFrame attempt2_wrapped_get_resp(
9482       attempt2_spdy_util.ConstructSpdyDataFrame(3, kResp, false));
9483   spdy::SpdySerializedFrame attempt2_wrapped_wrapped_get_resp(
9484       spdy_util_.ConstructWrappedSpdyFrame(attempt2_wrapped_get_resp, 1));
9485 
9486   const char kRespData[] = "1234567890";
9487   spdy::SpdySerializedFrame attempt2_wrapped_body(
9488       attempt2_spdy_util.ConstructSpdyDataFrame(3, kRespData, false));
9489   spdy::SpdySerializedFrame attempt2_wrapped_wrapped_body(
9490       spdy_util_.ConstructWrappedSpdyFrame(attempt2_wrapped_body, 1));
9491 
9492   MockWrite spdy_writes[] = {
9493       CreateMockWrite(proxy2_connect, 0),
9494       CreateMockWrite(wrapped_endpoint_connect, 2),
9495       CreateMockWrite(wrapped_rst, 5),
9496       CreateMockWrite(attempt2_wrapped_endpoint_connect, 6),
9497       CreateMockWrite(attempt2_wrapped_wrapped_get, 9),
9498   };
9499 
9500   MockRead spdy_reads[] = {
9501       CreateMockRead(proxy2_connect_resp, 1, ASYNC),
9502       // TODO(https://crbug.com/497228): We have to manually delay this read so
9503       // that the higher-level SPDY stream doesn't get notified of an available
9504       // read before the write it initiated (the second CONNECT) finishes,
9505       // triggering a DCHECK.
9506       MockRead(ASYNC, ERR_IO_PENDING, 3),
9507       CreateMockRead(wrapped_endpoint_connect_resp, 4, ASYNC),
9508       // The SSL socket error should occur here.
9509       MockRead(ASYNC, ERR_IO_PENDING, 7),
9510       CreateMockRead(attempt2_wrapped_endpoint_connect_resp, 8, ASYNC),
9511       CreateMockRead(attempt2_wrapped_wrapped_get_resp, 10, ASYNC),
9512       CreateMockRead(attempt2_wrapped_wrapped_body, 11, ASYNC),
9513       MockRead(ASYNC, 0, 12),
9514   };
9515 
9516   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
9517   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9518 
9519   SSLSocketDataProvider ssl(ASYNC, OK);
9520   ssl.next_proto = kProtoHTTP2;
9521   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9522 
9523   SSLSocketDataProvider ssl2(ASYNC, OK);
9524   ssl2.next_proto = kProtoHTTP2;
9525   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
9526 
9527   auto cert_request_info_proxy = base::MakeRefCounted<SSLCertRequestInfo>();
9528   cert_request_info_proxy->host_and_port = kProxyServer1.host_port_pair();
9529 
9530   SSLSocketDataProvider ssl3(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
9531   ssl3.cert_request_info = cert_request_info_proxy;
9532   ssl3.expected_send_client_cert = false;
9533   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
9534 
9535   HttpRequestInfo request1;
9536   request1.method = "GET";
9537   request1.url = GURL("https://www.example.org/");
9538   request1.traffic_annotation =
9539       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9540 
9541   TestCompletionCallback callback1;
9542 
9543   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
9544 
9545   int rv = trans1.Start(&request1, callback1.callback(),
9546                         NetLogWithSource::Make(NetLogSourceType::NONE));
9547   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9548 
9549   spdy_data.RunUntilPaused();
9550   base::RunLoop().RunUntilIdle();
9551   spdy_data.Resume();
9552 
9553   rv = callback1.WaitForResult();
9554   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
9555 
9556   SSLSocketDataProvider ssl4(ASYNC, OK);
9557   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl4);
9558 
9559   TestCompletionCallback callback2;
9560 
9561   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
9562 
9563   rv = trans2.Start(&request1, callback2.callback(),
9564                     NetLogWithSource::Make(NetLogSourceType::NONE));
9565   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9566 
9567   spdy_data.RunUntilPaused();
9568   base::RunLoop().RunUntilIdle();
9569   spdy_data.Resume();
9570 
9571   rv = callback2.WaitForResult();
9572   ASSERT_THAT(rv, IsOk());
9573 
9574   const HttpResponseInfo* response = trans2.GetResponseInfo();
9575   ASSERT_TRUE(response);
9576   ASSERT_TRUE(response->headers);
9577   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9578 
9579   std::string response_data;
9580   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
9581   EXPECT_EQ(kRespData, response_data);
9582 }
9583 
9584 // Test the case where a proxied H2 session doesn't exist when an auth challenge
9585 // is observed, but does exist by the time auth credentials are provided. In
9586 // this case, auth and SSL are fully negotated on the second request, but then
9587 // the socket is discarded to use the shared session.
TEST_P(HttpNetworkTransactionTest,ProxiedH2SessionAppearsDuringAuth)9588 TEST_P(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
9589   ProxyConfig proxy_config;
9590   proxy_config.set_auto_detect(true);
9591   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
9592 
9593   CapturingProxyResolver capturing_proxy_resolver;
9594   capturing_proxy_resolver.set_proxy_chain(
9595       ProxyChain(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
9596   session_deps_.proxy_resolution_service =
9597       std::make_unique<ConfiguredProxyResolutionService>(
9598           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
9599               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
9600           std::make_unique<CapturingProxyResolverFactory>(
9601               &capturing_proxy_resolver),
9602           nullptr, /*quick_check_enabled=*/true);
9603 
9604   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9605 
9606   const char kMyUrl[] = "https://www.example.org/";
9607   spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
9608   spdy::SpdySerializedFrame get_resp(
9609       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
9610   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
9611 
9612   spdy_util_.UpdateWithStreamDestruction(1);
9613   spdy::SpdySerializedFrame get2(
9614       spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
9615   spdy::SpdySerializedFrame get_resp2(
9616       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
9617   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
9618 
9619   MockWrite auth_challenge_writes[] = {
9620       MockWrite(ASYNC, 0,
9621                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9622                 "Host: www.example.org:443\r\n"
9623                 "Proxy-Connection: keep-alive\r\n\r\n"),
9624       MockWrite(ASYNC, 2,
9625                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9626                 "Host: www.example.org:443\r\n"
9627                 "Proxy-Connection: keep-alive\r\n\r\n"),
9628   };
9629 
9630   MockRead auth_challenge_reads[] = {
9631       MockRead(ASYNC, 1,
9632                "HTTP/1.1 407 Authentication Required\r\n"
9633                "Content-Length: 0\r\n"
9634                "Proxy-Connection: close\r\n"
9635                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
9636   };
9637 
9638   MockWrite spdy_writes[] = {
9639       MockWrite(ASYNC, 0,
9640                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9641                 "Host: www.example.org:443\r\n"
9642                 "Proxy-Connection: keep-alive\r\n"
9643                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
9644       CreateMockWrite(get, 2),
9645       CreateMockWrite(get2, 5),
9646   };
9647 
9648   MockRead spdy_reads[] = {
9649       MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
9650       CreateMockRead(get_resp, 3, ASYNC),
9651       CreateMockRead(body, 4, ASYNC),
9652       CreateMockRead(get_resp2, 6, ASYNC),
9653       CreateMockRead(body2, 7, ASYNC),
9654 
9655       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
9656   };
9657 
9658   MockWrite auth_response_writes_discarded_socket[] = {
9659       MockWrite(ASYNC, 0,
9660                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9661                 "Host: www.example.org:443\r\n"
9662                 "Proxy-Connection: keep-alive\r\n"
9663                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
9664   };
9665 
9666   MockRead auth_response_reads_discarded_socket[] = {
9667       MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
9668   };
9669 
9670   SequencedSocketData auth_challenge1(auth_challenge_reads,
9671                                       auth_challenge_writes);
9672   session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
9673 
9674   SequencedSocketData auth_challenge2(auth_challenge_reads,
9675                                       auth_challenge_writes);
9676   session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
9677 
9678   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
9679   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9680 
9681   SequencedSocketData auth_response_discarded_socket(
9682       auth_response_reads_discarded_socket,
9683       auth_response_writes_discarded_socket);
9684   session_deps_.socket_factory->AddSocketDataProvider(
9685       &auth_response_discarded_socket);
9686 
9687   SSLSocketDataProvider ssl(ASYNC, OK);
9688   ssl.next_proto = kProtoHTTP2;
9689   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9690 
9691   SSLSocketDataProvider ssl2(ASYNC, OK);
9692   ssl2.next_proto = kProtoHTTP2;
9693   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
9694 
9695   TestCompletionCallback callback;
9696   std::string response_data;
9697 
9698   // Run first request until an auth challenge is observed.
9699   HttpRequestInfo request1;
9700   request1.method = "GET";
9701   request1.url = GURL(kMyUrl);
9702   request1.traffic_annotation =
9703       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9704   HttpNetworkTransaction trans1(LOWEST, session.get());
9705   int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9706   EXPECT_THAT(callback.GetResult(rv), IsOk());
9707   const HttpResponseInfo* response = trans1.GetResponseInfo();
9708   ASSERT_TRUE(response);
9709   ASSERT_TRUE(response->headers);
9710   EXPECT_EQ(407, response->headers->response_code());
9711   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9712   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
9713 
9714   // Run second request until an auth challenge is observed.
9715   HttpRequestInfo request2;
9716   request2.method = "GET";
9717   request2.url = GURL(kMyUrl);
9718   request2.traffic_annotation =
9719       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9720   HttpNetworkTransaction trans2(LOWEST, session.get());
9721   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9722   EXPECT_THAT(callback.GetResult(rv), IsOk());
9723   response = trans2.GetResponseInfo();
9724   ASSERT_TRUE(response);
9725   ASSERT_TRUE(response->headers);
9726   EXPECT_EQ(407, response->headers->response_code());
9727   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9728   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
9729 
9730   // Now provide credentials for the first request, and wait for it to complete.
9731   rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
9732   rv = callback.GetResult(rv);
9733   EXPECT_THAT(rv, IsOk());
9734   response = trans1.GetResponseInfo();
9735   ASSERT_TRUE(response);
9736   ASSERT_TRUE(response->headers);
9737   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
9738   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
9739   EXPECT_EQ(kUploadData, response_data);
9740 
9741   // Now provide credentials for the second request. It should notice the
9742   // existing session, and reuse it.
9743   rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
9744   EXPECT_THAT(callback.GetResult(rv), IsOk());
9745   response = trans2.GetResponseInfo();
9746   ASSERT_TRUE(response);
9747   ASSERT_TRUE(response->headers);
9748   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
9749   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
9750   EXPECT_EQ(kUploadData, response_data);
9751 }
9752 
9753 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
9754 // HTTPS Proxy to different servers.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers)9755 TEST_P(HttpNetworkTransactionTest,
9756        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
9757   // Configure against https proxy server "proxy:70".
9758   session_deps_.proxy_resolution_service =
9759       ConfiguredProxyResolutionService::CreateFixedForTest(
9760           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9761   session_deps_.net_log = NetLog::Get();
9762   std::unique_ptr<HttpNetworkSession> session(
9763       SpdySessionDependencies::SpdyCreateSession(&session_deps_));
9764 
9765   HttpRequestInfo request1;
9766   request1.method = "GET";
9767   request1.url = GURL("https://www.example.org/");
9768   request1.load_flags = 0;
9769   request1.traffic_annotation =
9770       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9771 
9772   HttpRequestInfo request2;
9773   request2.method = "GET";
9774   request2.url = GURL("https://mail.example.org/");
9775   request2.load_flags = 0;
9776   request2.traffic_annotation =
9777       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9778 
9779   // CONNECT to www.example.org:443 via SPDY.
9780   spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
9781       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9782       HostPortPair("www.example.org", 443)));
9783   spdy::SpdySerializedFrame conn_resp1(
9784       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
9785 
9786   // Fetch https://www.example.org/ via HTTP.
9787   const char kGet1[] =
9788       "GET / HTTP/1.1\r\n"
9789       "Host: www.example.org\r\n"
9790       "Connection: keep-alive\r\n\r\n";
9791   spdy::SpdySerializedFrame wrapped_get1(
9792       spdy_util_.ConstructSpdyDataFrame(1, kGet1, false));
9793   const char kResp1[] =
9794       "HTTP/1.1 200 OK\r\n"
9795       "Content-Length: 1\r\n\r\n";
9796   spdy::SpdySerializedFrame wrapped_get_resp1(
9797       spdy_util_.ConstructSpdyDataFrame(1, kResp1, false));
9798   spdy::SpdySerializedFrame wrapped_body1(
9799       spdy_util_.ConstructSpdyDataFrame(1, "1", false));
9800 
9801   // CONNECT to mail.example.org:443 via SPDY.
9802   spdy::Http2HeaderBlock connect2_block;
9803   connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
9804   connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
9805   spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
9806       3, std::move(connect2_block), HttpProxyConnectJob::kH2QuicTunnelPriority,
9807       false));
9808 
9809   spdy::SpdySerializedFrame conn_resp2(
9810       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
9811 
9812   // Fetch https://mail.example.org/ via HTTP.
9813   const char kGet2[] =
9814       "GET / HTTP/1.1\r\n"
9815       "Host: mail.example.org\r\n"
9816       "Connection: keep-alive\r\n\r\n";
9817   spdy::SpdySerializedFrame wrapped_get2(
9818       spdy_util_.ConstructSpdyDataFrame(3, kGet2, false));
9819   const char kResp2[] =
9820       "HTTP/1.1 200 OK\r\n"
9821       "Content-Length: 2\r\n\r\n";
9822   spdy::SpdySerializedFrame wrapped_get_resp2(
9823       spdy_util_.ConstructSpdyDataFrame(3, kResp2, false));
9824   spdy::SpdySerializedFrame wrapped_body2(
9825       spdy_util_.ConstructSpdyDataFrame(3, "22", false));
9826 
9827   MockWrite spdy_writes[] = {
9828       CreateMockWrite(connect1, 0),
9829       CreateMockWrite(wrapped_get1, 2),
9830       CreateMockWrite(connect2, 5),
9831       CreateMockWrite(wrapped_get2, 7),
9832   };
9833 
9834   MockRead spdy_reads[] = {
9835       CreateMockRead(conn_resp1, 1, ASYNC),
9836       CreateMockRead(wrapped_get_resp1, 3, ASYNC),
9837       CreateMockRead(wrapped_body1, 4, ASYNC),
9838       CreateMockRead(conn_resp2, 6, ASYNC),
9839       CreateMockRead(wrapped_get_resp2, 8, ASYNC),
9840       CreateMockRead(wrapped_body2, 9, ASYNC),
9841       MockRead(ASYNC, 0, 10),
9842   };
9843 
9844   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
9845   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9846 
9847   SSLSocketDataProvider ssl(ASYNC, OK);
9848   ssl.next_proto = kProtoHTTP2;
9849   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9850   SSLSocketDataProvider ssl2(ASYNC, OK);
9851   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
9852   SSLSocketDataProvider ssl3(ASYNC, OK);
9853   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
9854 
9855   TestCompletionCallback callback;
9856 
9857   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9858   int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
9859   EXPECT_THAT(callback.GetResult(rv), IsOk());
9860 
9861   LoadTimingInfo load_timing_info;
9862   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
9863   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
9864 
9865   const HttpResponseInfo* response = trans.GetResponseInfo();
9866   ASSERT_TRUE(response);
9867   ASSERT_TRUE(response->headers);
9868   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9869 
9870   std::string response_data;
9871   auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
9872   rv = trans.Read(buf.get(), 256, callback.callback());
9873   EXPECT_EQ(1, callback.GetResult(rv));
9874 
9875   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
9876   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9877   EXPECT_THAT(callback.GetResult(rv), IsOk());
9878 
9879   LoadTimingInfo load_timing_info2;
9880   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
9881   // Even though the SPDY connection is reused, a new tunnelled connection has
9882   // to be created, so the socket's load timing looks like a fresh connection.
9883   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
9884 
9885   // The requests should have different IDs, since they each are using their own
9886   // separate stream.
9887   EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
9888 
9889   rv = trans2.Read(buf.get(), 256, callback.callback());
9890   EXPECT_EQ(2, callback.GetResult(rv));
9891 }
9892 
9893 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
9894 // HTTPS Proxy to the same server.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer)9895 TEST_P(HttpNetworkTransactionTest,
9896        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
9897   // Configure against https proxy server "proxy:70".
9898   session_deps_.proxy_resolution_service =
9899       ConfiguredProxyResolutionService::CreateFixedForTest(
9900           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9901   session_deps_.net_log = NetLog::Get();
9902   std::unique_ptr<HttpNetworkSession> session(
9903       SpdySessionDependencies::SpdyCreateSession(&session_deps_));
9904 
9905   HttpRequestInfo request1;
9906   request1.method = "GET";
9907   request1.url = GURL("https://www.example.org/");
9908   request1.load_flags = 0;
9909   request1.traffic_annotation =
9910       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9911 
9912   HttpRequestInfo request2;
9913   request2.method = "GET";
9914   request2.url = GURL("https://www.example.org/2");
9915   request2.load_flags = 0;
9916   request2.traffic_annotation =
9917       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9918 
9919   // CONNECT to www.example.org:443 via SPDY.
9920   spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
9921       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9922       HostPortPair("www.example.org", 443)));
9923   spdy::SpdySerializedFrame conn_resp1(
9924       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
9925 
9926   // Fetch https://www.example.org/ via HTTP.
9927   const char kGet1[] =
9928       "GET / HTTP/1.1\r\n"
9929       "Host: www.example.org\r\n"
9930       "Connection: keep-alive\r\n\r\n";
9931   spdy::SpdySerializedFrame wrapped_get1(
9932       spdy_util_.ConstructSpdyDataFrame(1, kGet1, false));
9933   const char kResp1[] =
9934       "HTTP/1.1 200 OK\r\n"
9935       "Content-Length: 1\r\n\r\n";
9936   spdy::SpdySerializedFrame wrapped_get_resp1(
9937       spdy_util_.ConstructSpdyDataFrame(1, kResp1, false));
9938   spdy::SpdySerializedFrame wrapped_body1(
9939       spdy_util_.ConstructSpdyDataFrame(1, "1", false));
9940 
9941   // Fetch https://www.example.org/2 via HTTP.
9942   const char kGet2[] =
9943       "GET /2 HTTP/1.1\r\n"
9944       "Host: www.example.org\r\n"
9945       "Connection: keep-alive\r\n\r\n";
9946   spdy::SpdySerializedFrame wrapped_get2(
9947       spdy_util_.ConstructSpdyDataFrame(1, kGet2, false));
9948   const char kResp2[] =
9949       "HTTP/1.1 200 OK\r\n"
9950       "Content-Length: 2\r\n\r\n";
9951   spdy::SpdySerializedFrame wrapped_get_resp2(
9952       spdy_util_.ConstructSpdyDataFrame(1, kResp2, false));
9953   spdy::SpdySerializedFrame wrapped_body2(
9954       spdy_util_.ConstructSpdyDataFrame(1, "22", false));
9955 
9956   MockWrite spdy_writes[] = {
9957       CreateMockWrite(connect1, 0),
9958       CreateMockWrite(wrapped_get1, 2),
9959       CreateMockWrite(wrapped_get2, 5),
9960   };
9961 
9962   MockRead spdy_reads[] = {
9963       CreateMockRead(conn_resp1, 1, ASYNC),
9964       CreateMockRead(wrapped_get_resp1, 3, ASYNC),
9965       CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
9966       CreateMockRead(wrapped_get_resp2, 6, ASYNC),
9967       CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
9968       MockRead(ASYNC, 0, 8),
9969   };
9970 
9971   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
9972   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9973 
9974   SSLSocketDataProvider ssl(ASYNC, OK);
9975   ssl.next_proto = kProtoHTTP2;
9976   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9977   SSLSocketDataProvider ssl2(ASYNC, OK);
9978   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
9979 
9980   TestCompletionCallback callback;
9981 
9982   auto trans =
9983       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
9984   int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
9985   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9986 
9987   rv = callback.WaitForResult();
9988   EXPECT_THAT(rv, IsOk());
9989 
9990   LoadTimingInfo load_timing_info;
9991   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9992   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
9993 
9994   const HttpResponseInfo* response = trans->GetResponseInfo();
9995   ASSERT_TRUE(response);
9996   ASSERT_TRUE(response->headers);
9997   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9998 
9999   std::string response_data;
10000   auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
10001   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
10002   trans.reset();
10003 
10004   auto trans2 =
10005       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
10006   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
10007   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10008 
10009   rv = callback.WaitForResult();
10010   EXPECT_THAT(rv, IsOk());
10011 
10012   LoadTimingInfo load_timing_info2;
10013   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
10014   TestLoadTimingReused(load_timing_info2);
10015 
10016   // The requests should have the same ID.
10017   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
10018 
10019   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
10020 }
10021 
10022 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS
10023 // Proxy to different servers.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyLoadTimingTwoHttpRequests)10024 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
10025   // Configure against https proxy server "proxy:70".
10026   session_deps_.proxy_resolution_service =
10027       ConfiguredProxyResolutionService::CreateFixedForTest(
10028           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10029   session_deps_.net_log = NetLog::Get();
10030   std::unique_ptr<HttpNetworkSession> session(
10031       SpdySessionDependencies::SpdyCreateSession(&session_deps_));
10032 
10033   HttpRequestInfo request1;
10034   request1.method = "GET";
10035   request1.url = GURL("http://www.example.org/");
10036   request1.load_flags = 0;
10037   request1.traffic_annotation =
10038       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10039 
10040   HttpRequestInfo request2;
10041   request2.method = "GET";
10042   request2.url = GURL("http://mail.example.org/");
10043   request2.load_flags = 0;
10044   request2.traffic_annotation =
10045       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10046 
10047   // http://www.example.org/
10048   spdy::Http2HeaderBlock headers(
10049       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
10050   spdy::SpdySerializedFrame get1(
10051       spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
10052   spdy::SpdySerializedFrame get_resp1(
10053       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
10054   spdy::SpdySerializedFrame body1(
10055       spdy_util_.ConstructSpdyDataFrame(1, "1", true));
10056   spdy_util_.UpdateWithStreamDestruction(1);
10057 
10058   // http://mail.example.org/
10059   spdy::Http2HeaderBlock headers2(
10060       spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
10061   spdy::SpdySerializedFrame get2(
10062       spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
10063   spdy::SpdySerializedFrame get_resp2(
10064       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
10065   spdy::SpdySerializedFrame body2(
10066       spdy_util_.ConstructSpdyDataFrame(3, "22", true));
10067 
10068   MockWrite spdy_writes[] = {
10069       CreateMockWrite(get1, 0),
10070       CreateMockWrite(get2, 3),
10071   };
10072 
10073   MockRead spdy_reads[] = {
10074       CreateMockRead(get_resp1, 1, ASYNC),
10075       CreateMockRead(body1, 2, ASYNC),
10076       CreateMockRead(get_resp2, 4, ASYNC),
10077       CreateMockRead(body2, 5, ASYNC),
10078       MockRead(ASYNC, 0, 6),
10079   };
10080 
10081   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
10082   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10083 
10084   SSLSocketDataProvider ssl(ASYNC, OK);
10085   ssl.next_proto = kProtoHTTP2;
10086   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10087 
10088   TestCompletionCallback callback;
10089 
10090   auto trans =
10091       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
10092   int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
10093   EXPECT_THAT(callback.GetResult(rv), IsOk());
10094 
10095   LoadTimingInfo load_timing_info;
10096   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10097   TestLoadTimingNotReused(load_timing_info,
10098                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10099 
10100   const HttpResponseInfo* response = trans->GetResponseInfo();
10101   ASSERT_TRUE(response);
10102   ASSERT_TRUE(response->headers);
10103   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
10104 
10105   std::string response_data;
10106   auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
10107   rv = trans->Read(buf.get(), 256, callback.callback());
10108   EXPECT_EQ(1, callback.GetResult(rv));
10109   // Delete the first request, so the second one can reuse the socket.
10110   trans.reset();
10111 
10112   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
10113   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
10114   EXPECT_THAT(callback.GetResult(rv), IsOk());
10115 
10116   LoadTimingInfo load_timing_info2;
10117   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
10118   TestLoadTimingReused(load_timing_info2);
10119 
10120   // The requests should have the same ID.
10121   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
10122 
10123   rv = trans2.Read(buf.get(), 256, callback.callback());
10124   EXPECT_EQ(2, callback.GetResult(rv));
10125 }
10126 
10127 // Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
10128 // direct (non-proxied) request to the proxy server are not pooled, as that
10129 // would break socket pool isolation.
TEST_P(HttpNetworkTransactionTest,SpdyProxyIsolation1)10130 TEST_P(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
10131   ProxyConfig proxy_config;
10132   proxy_config.set_auto_detect(true);
10133   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
10134 
10135   CapturingProxyResolver capturing_proxy_resolver;
10136   session_deps_.proxy_resolution_service =
10137       std::make_unique<ConfiguredProxyResolutionService>(
10138           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
10139               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
10140           std::make_unique<CapturingProxyResolverFactory>(
10141               &capturing_proxy_resolver),
10142           nullptr, /*quick_check_enabled=*/true);
10143 
10144   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10145 
10146   SpdyTestUtil spdy_util1(/*use_priority_header=*/true);
10147   // CONNECT to www.example.org:443 via HTTP/2.
10148   spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
10149       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
10150       HostPortPair("www.example.org", 443)));
10151   // fetch https://www.example.org/ via HTTP/2.
10152   const char kMyUrl[] = "https://www.example.org/";
10153   spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
10154   spdy::SpdySerializedFrame wrapped_get(
10155       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
10156   spdy::SpdySerializedFrame conn_resp(
10157       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
10158   spdy::SpdySerializedFrame get_resp(
10159       spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
10160   spdy::SpdySerializedFrame wrapped_get_resp(
10161       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
10162   spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
10163   spdy::SpdySerializedFrame wrapped_body(
10164       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
10165   spdy::SpdySerializedFrame window_update_get_resp(
10166       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
10167   spdy::SpdySerializedFrame window_update_body(
10168       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
10169 
10170   MockWrite spdy_writes1[] = {
10171       CreateMockWrite(connect, 0),
10172       CreateMockWrite(wrapped_get, 2),
10173       CreateMockWrite(window_update_get_resp, 6),
10174       CreateMockWrite(window_update_body, 7),
10175   };
10176 
10177   MockRead spdy_reads1[] = {
10178       CreateMockRead(conn_resp, 1, ASYNC),
10179       MockRead(ASYNC, ERR_IO_PENDING, 3),
10180       CreateMockRead(wrapped_get_resp, 4, ASYNC),
10181       CreateMockRead(wrapped_body, 5, ASYNC),
10182       MockRead(ASYNC, 0, 8),
10183   };
10184 
10185   SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
10186   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
10187 
10188   // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
10189   // a new pipe.
10190   SpdyTestUtil spdy_util2(/*use_priority_header=*/true);
10191   spdy::SpdySerializedFrame req(
10192       spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
10193   MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
10194 
10195   spdy::SpdySerializedFrame resp(
10196       spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
10197   spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
10198   MockRead spdy_reads2[] = {
10199       CreateMockRead(resp, 1),
10200       CreateMockRead(data, 2),
10201       MockRead(ASYNC, 0, 3),
10202   };
10203   SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
10204   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
10205 
10206   SSLSocketDataProvider ssl(ASYNC, OK);
10207   ssl.next_proto = kProtoHTTP2;
10208   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10209   SSLSocketDataProvider ssl2(ASYNC, OK);
10210   ssl2.next_proto = kProtoHTTP2;
10211   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
10212   SSLSocketDataProvider ssl3(ASYNC, OK);
10213   ssl3.next_proto = kProtoHTTP2;
10214   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
10215 
10216   TestCompletionCallback callback;
10217   std::string response_data;
10218 
10219   // Make a request using proxy:70 as a HTTP/2 proxy.
10220   capturing_proxy_resolver.set_proxy_chain(
10221       ProxyChain(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
10222   HttpRequestInfo request1;
10223   request1.method = "GET";
10224   request1.url = GURL("https://www.example.org/");
10225   request1.traffic_annotation =
10226       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10227 
10228   HttpNetworkTransaction trans1(LOWEST, session.get());
10229   int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
10230   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10231 
10232   // Allow the SpdyProxyClientSocket's write callback to complete.
10233   base::RunLoop().RunUntilIdle();
10234   // Now allow the read of the response to complete.
10235   spdy_data1.Resume();
10236   rv = callback.WaitForResult();
10237   EXPECT_THAT(rv, IsOk());
10238 
10239   const HttpResponseInfo* response = trans1.GetResponseInfo();
10240   ASSERT_TRUE(response);
10241   ASSERT_TRUE(response->headers);
10242   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
10243 
10244   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
10245   EXPECT_EQ(kUploadData, response_data);
10246   RunUntilIdle();
10247 
10248   // Make a direct HTTP/2 request to proxy:70.
10249   capturing_proxy_resolver.set_proxy_chain(ProxyChain::Direct());
10250   HttpRequestInfo request2;
10251   request2.method = "GET";
10252   request2.url = GURL("https://proxy:70/");
10253   request2.traffic_annotation =
10254       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10255   HttpNetworkTransaction trans2(LOWEST, session.get());
10256   EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
10257                                               NetLogWithSource())),
10258               IsOk());
10259   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
10260 }
10261 
10262 // Same as above, but reverse request order, since the code to check for an
10263 // existing session is different for tunnels and direct connections.
TEST_P(HttpNetworkTransactionTest,SpdyProxyIsolation2)10264 TEST_P(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
10265   // Configure against https proxy server "myproxy:80".
10266   ProxyConfig proxy_config;
10267   proxy_config.set_auto_detect(true);
10268   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
10269 
10270   CapturingProxyResolver capturing_proxy_resolver;
10271   session_deps_.proxy_resolution_service =
10272       std::make_unique<ConfiguredProxyResolutionService>(
10273           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
10274               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
10275           std::make_unique<CapturingProxyResolverFactory>(
10276               &capturing_proxy_resolver),
10277           nullptr, /*quick_check_enabled=*/true);
10278 
10279   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10280   // Fetch https://proxy:70/ via HTTP/2.
10281   SpdyTestUtil spdy_util1(/*use_priority_header=*/true);
10282   spdy::SpdySerializedFrame req(
10283       spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
10284   MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
10285 
10286   spdy::SpdySerializedFrame resp(
10287       spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
10288   spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
10289   MockRead spdy_reads1[] = {
10290       CreateMockRead(resp, 1),
10291       CreateMockRead(data, 2),
10292       MockRead(ASYNC, 0, 3),
10293   };
10294   SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
10295   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
10296 
10297   SpdyTestUtil spdy_util2(/*use_priority_header=*/true);
10298   // CONNECT to www.example.org:443 via HTTP/2.
10299   spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
10300       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
10301       HostPortPair("www.example.org", 443)));
10302   // fetch https://www.example.org/ via HTTP/2.
10303   const char kMyUrl[] = "https://www.example.org/";
10304   spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
10305   spdy::SpdySerializedFrame wrapped_get(
10306       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
10307   spdy::SpdySerializedFrame conn_resp(
10308       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
10309   spdy::SpdySerializedFrame get_resp(
10310       spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
10311   spdy::SpdySerializedFrame wrapped_get_resp(
10312       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
10313   spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
10314   spdy::SpdySerializedFrame wrapped_body(
10315       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
10316   spdy::SpdySerializedFrame window_update_get_resp(
10317       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
10318   spdy::SpdySerializedFrame window_update_body(
10319       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
10320 
10321   MockWrite spdy_writes2[] = {
10322       CreateMockWrite(connect, 0),
10323       CreateMockWrite(wrapped_get, 2),
10324       CreateMockWrite(window_update_get_resp, 6),
10325       CreateMockWrite(window_update_body, 7),
10326   };
10327 
10328   MockRead spdy_reads2[] = {
10329       CreateMockRead(conn_resp, 1, ASYNC),
10330       MockRead(ASYNC, ERR_IO_PENDING, 3),
10331       CreateMockRead(wrapped_get_resp, 4, ASYNC),
10332       CreateMockRead(wrapped_body, 5, ASYNC),
10333       MockRead(ASYNC, 0, 8),
10334   };
10335 
10336   SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
10337   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
10338 
10339   SSLSocketDataProvider ssl(ASYNC, OK);
10340   ssl.next_proto = kProtoHTTP2;
10341   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10342   SSLSocketDataProvider ssl2(ASYNC, OK);
10343   ssl2.next_proto = kProtoHTTP2;
10344   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
10345   SSLSocketDataProvider ssl3(ASYNC, OK);
10346   ssl3.next_proto = kProtoHTTP2;
10347   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
10348 
10349   TestCompletionCallback callback;
10350   std::string response_data;
10351 
10352   // Make a direct HTTP/2 request to proxy:70.
10353   capturing_proxy_resolver.set_proxy_chain(ProxyChain::Direct());
10354   HttpRequestInfo request1;
10355   request1.method = "GET";
10356   request1.url = GURL("https://proxy:70/");
10357   request1.traffic_annotation =
10358       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10359   HttpNetworkTransaction trans1(LOWEST, session.get());
10360   EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
10361                                               NetLogWithSource())),
10362               IsOk());
10363   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
10364   RunUntilIdle();
10365 
10366   // Make a request using proxy:70 as a HTTP/2 proxy.
10367   capturing_proxy_resolver.set_proxy_chain(
10368       ProxyChain(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
10369   HttpRequestInfo request2;
10370   request2.method = "GET";
10371   request2.url = GURL("https://www.example.org/");
10372   request2.traffic_annotation =
10373       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10374 
10375   HttpNetworkTransaction trans2(LOWEST, session.get());
10376   int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
10377   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10378 
10379   // Allow the SpdyProxyClientSocket's write callback to complete.
10380   base::RunLoop().RunUntilIdle();
10381   // Now allow the read of the response to complete.
10382   spdy_data2.Resume();
10383   rv = callback.WaitForResult();
10384   EXPECT_THAT(rv, IsOk());
10385 
10386   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
10387   ASSERT_TRUE(response2);
10388   ASSERT_TRUE(response2->headers);
10389   EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
10390 
10391   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
10392   EXPECT_EQ(kUploadData, response_data);
10393 }
10394 
10395 // Test the challenge-response-retry sequence through an HTTPS Proxy
TEST_P(HttpNetworkTransactionTest,HttpsProxyAuthRetry)10396 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
10397   HttpRequestInfo request;
10398   request.method = "GET";
10399   request.url = GURL("http://www.example.org/");
10400   // when the no authentication data flag is set.
10401   request.privacy_mode = PRIVACY_MODE_ENABLED;
10402   request.traffic_annotation =
10403       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10404 
10405   // Configure against https proxy server "myproxy:70".
10406   session_deps_.proxy_resolution_service =
10407       ConfiguredProxyResolutionService::CreateFixedForTest(
10408           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10409   session_deps_.net_log = NetLog::Get();
10410   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10411 
10412   // Since we have proxy, should use full url
10413   MockWrite data_writes1[] = {
10414       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
10415                 "Host: www.example.org\r\n"
10416                 "Proxy-Connection: keep-alive\r\n\r\n"),
10417 
10418       // After calling trans.RestartWithAuth(), this is the request we should
10419       // be issuing -- the final header line contains the credentials.
10420       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
10421                 "Host: www.example.org\r\n"
10422                 "Proxy-Connection: keep-alive\r\n"
10423                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
10424   };
10425 
10426   // The proxy responds to the GET with a 407, using a persistent
10427   // connection.
10428   MockRead data_reads1[] = {
10429       // No credentials.
10430       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10431       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10432       MockRead("Proxy-Connection: keep-alive\r\n"),
10433       MockRead("Content-Length: 0\r\n\r\n"),
10434 
10435       MockRead("HTTP/1.1 200 OK\r\n"),
10436       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10437       MockRead("Content-Length: 100\r\n\r\n"),
10438       MockRead(SYNCHRONOUS, OK),
10439   };
10440 
10441   StaticSocketDataProvider data1(data_reads1, data_writes1);
10442   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10443   SSLSocketDataProvider ssl(ASYNC, OK);
10444   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10445 
10446   TestCompletionCallback callback1;
10447 
10448   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10449 
10450   int rv = trans.Start(&request, callback1.callback(),
10451                        NetLogWithSource::Make(NetLogSourceType::NONE));
10452   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10453 
10454   rv = callback1.WaitForResult();
10455   EXPECT_THAT(rv, IsOk());
10456 
10457   LoadTimingInfo load_timing_info;
10458   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
10459   TestLoadTimingNotReused(load_timing_info,
10460                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10461 
10462   const HttpResponseInfo* response = trans.GetResponseInfo();
10463   ASSERT_TRUE(response);
10464   ASSERT_TRUE(response->headers);
10465   EXPECT_EQ(407, response->headers->response_code());
10466   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10467   EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
10468   EXPECT_FALSE(response->did_use_http_auth);
10469   EXPECT_EQ(PacResultElementToProxyChain("HTTPS myproxy:70"),
10470             response->proxy_chain);
10471 
10472   TestCompletionCallback callback2;
10473 
10474   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
10475   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10476 
10477   rv = callback2.WaitForResult();
10478   EXPECT_THAT(rv, IsOk());
10479 
10480   load_timing_info = LoadTimingInfo();
10481   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
10482   // Retrying with HTTP AUTH is considered to be reusing a socket.
10483   TestLoadTimingReused(load_timing_info);
10484 
10485   response = trans.GetResponseInfo();
10486   ASSERT_TRUE(response);
10487 
10488   EXPECT_TRUE(response->headers->IsKeepAlive());
10489   EXPECT_EQ(200, response->headers->response_code());
10490   EXPECT_EQ(100, response->headers->GetContentLength());
10491   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10492   EXPECT_TRUE(response->did_use_http_auth);
10493   EXPECT_EQ(PacResultElementToProxyChain("HTTPS myproxy:70"),
10494             response->proxy_chain);
10495 
10496   // The password prompt info should not be set.
10497   EXPECT_FALSE(response->auth_challenge.has_value());
10498 }
10499 
10500 // Test the challenge-response-retry sequence through an HTTPS Proxy over a
10501 // connection that requires a restart.
TEST_P(HttpNetworkTransactionTest,HttpsProxyAuthRetryNoKeepAlive)10502 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetryNoKeepAlive) {
10503   HttpRequestInfo request;
10504   request.method = "GET";
10505   request.url = GURL("http://www.example.org/");
10506   // when the no authentication data flag is set.
10507   request.privacy_mode = PRIVACY_MODE_ENABLED;
10508   request.traffic_annotation =
10509       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10510 
10511   // Configure against https proxy server "myproxy:70".
10512   session_deps_.proxy_resolution_service =
10513       ConfiguredProxyResolutionService::CreateFixedForTest(
10514           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10515   session_deps_.net_log = NetLog::Get();
10516   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10517 
10518   // Since we have proxy, should use full url
10519   MockWrite data_writes1[] = {
10520       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
10521                 "Host: www.example.org\r\n"
10522                 "Proxy-Connection: keep-alive\r\n\r\n"),
10523   };
10524 
10525   // The proxy responds to the GET with a 407, using a non-persistent
10526   // connection.
10527   MockRead data_reads1[] = {
10528       // No credentials.
10529       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10530       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10531       MockRead("Proxy-Connection: close\r\n"),
10532       MockRead("Content-Length: 0\r\n\r\n"),
10533   };
10534 
10535   MockWrite data_writes2[] = {
10536       // After calling trans.RestartWithAuth(), this is the request we should
10537       // be issuing -- the final header line contains the credentials.
10538       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
10539                 "Host: www.example.org\r\n"
10540                 "Proxy-Connection: keep-alive\r\n"
10541                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
10542   };
10543 
10544   MockRead data_reads2[] = {
10545       MockRead("HTTP/1.1 200 OK\r\n"),
10546       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10547       MockRead("Content-Length: 100\r\n\r\n"),
10548       MockRead(SYNCHRONOUS, OK),
10549   };
10550 
10551   StaticSocketDataProvider data1(data_reads1, data_writes1);
10552   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10553   StaticSocketDataProvider data2(data_reads2, data_writes2);
10554   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10555 
10556   // One per each proxy connection.
10557   SSLSocketDataProvider ssl1(ASYNC, OK);
10558   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
10559   SSLSocketDataProvider ssl2(ASYNC, OK);
10560   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
10561 
10562   TestCompletionCallback callback1;
10563 
10564   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10565 
10566   int rv = trans.Start(&request, callback1.callback(),
10567                        NetLogWithSource::Make(NetLogSourceType::NONE));
10568   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10569 
10570   rv = callback1.WaitForResult();
10571   EXPECT_THAT(rv, IsOk());
10572 
10573   LoadTimingInfo load_timing_info;
10574   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
10575   TestLoadTimingNotReused(load_timing_info,
10576                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10577 
10578   const HttpResponseInfo* response = trans.GetResponseInfo();
10579   ASSERT_TRUE(response);
10580   ASSERT_TRUE(response->headers);
10581   EXPECT_EQ(407, response->headers->response_code());
10582   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10583   EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
10584   EXPECT_FALSE(response->did_use_http_auth);
10585   EXPECT_EQ(PacResultElementToProxyChain("HTTPS myproxy:70"),
10586             response->proxy_chain);
10587 
10588   TestCompletionCallback callback2;
10589 
10590   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
10591   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10592 
10593   rv = callback2.WaitForResult();
10594   EXPECT_THAT(rv, IsOk());
10595 
10596   load_timing_info = LoadTimingInfo();
10597   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
10598   TestLoadTimingNotReused(load_timing_info,
10599                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10600 
10601   response = trans.GetResponseInfo();
10602   ASSERT_TRUE(response);
10603 
10604   EXPECT_TRUE(response->headers->IsKeepAlive());
10605   EXPECT_EQ(200, response->headers->response_code());
10606   EXPECT_EQ(100, response->headers->GetContentLength());
10607   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10608   EXPECT_TRUE(response->did_use_http_auth);
10609   EXPECT_EQ(PacResultElementToProxyChain("HTTPS myproxy:70"),
10610             response->proxy_chain);
10611 
10612   // The password prompt info should not be set.
10613   EXPECT_FALSE(response->auth_challenge.has_value());
10614 }
10615 
10616 // Test the challenge-response-retry sequence through an HTTPS Proxy over a
10617 // connection that requires a restart, with a proxy change occurring over the
10618 // restart.
TEST_P(HttpNetworkTransactionTest,HttpsProxyAuthRetryNoKeepAliveChangeProxy)10619 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetryNoKeepAliveChangeProxy) {
10620   const auto proxy_chain1 = PacResultElementToProxyChain("HTTPS myproxy:70");
10621   const auto proxy_chain2 = PacResultElementToProxyChain("HTTPS myproxy2:70");
10622 
10623   session_deps_.proxy_delegate = std::make_unique<TestProxyDelegate>();
10624   auto* proxy_delegate =
10625       static_cast<TestProxyDelegate*>(session_deps_.proxy_delegate.get());
10626   proxy_delegate->set_proxy_chain(proxy_chain1);
10627 
10628   HttpRequestInfo request;
10629   request.method = "GET";
10630   request.url = GURL("http://www.example.org/");
10631   // when the no authentication data flag is set.
10632   request.privacy_mode = PRIVACY_MODE_ENABLED;
10633   request.traffic_annotation =
10634       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10635 
10636   // Configure against https proxy server "myproxy:70".
10637   session_deps_.proxy_resolution_service =
10638       ConfiguredProxyResolutionService::CreateFixedForTest(
10639           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10640   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
10641   session_deps_.net_log = NetLog::Get();
10642   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10643 
10644   // Since we have proxy, should use full url
10645   MockWrite data_writes1[] = {
10646       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
10647                 "Host: www.example.org\r\n"
10648                 "Proxy-Connection: keep-alive\r\n\r\n"),
10649   };
10650 
10651   // The proxy responds to the GET with a 407, using a non-persistent
10652   // connection.
10653   MockRead data_reads1[] = {
10654       // No credentials.
10655       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10656       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10657       MockRead("Proxy-Connection: close\r\n"),
10658       MockRead("Content-Length: 0\r\n\r\n"),
10659   };
10660 
10661   MockWrite data_writes2[] = {
10662       // After calling trans.RestartWithAuth(), this is the request we should
10663       // be issuing -- the final header line contains the credentials.
10664       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
10665                 "Host: www.example.org\r\n"
10666                 "Proxy-Connection: keep-alive\r\n"
10667                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
10668   };
10669 
10670   MockRead data_reads2[] = {
10671       MockRead("HTTP/1.1 200 OK\r\n"),
10672       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10673       MockRead("Content-Length: 100\r\n\r\n"),
10674       MockRead(SYNCHRONOUS, OK),
10675   };
10676 
10677   StaticSocketDataProvider data1(data_reads1, data_writes1);
10678   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10679   StaticSocketDataProvider data2(data_reads2, data_writes2);
10680   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10681 
10682   // One per each proxy connection.
10683   SSLSocketDataProvider ssl1(ASYNC, OK);
10684   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
10685   SSLSocketDataProvider ssl2(ASYNC, OK);
10686   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
10687 
10688   TestCompletionCallback callback1;
10689 
10690   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10691 
10692   int rv = trans.Start(&request, callback1.callback(),
10693                        NetLogWithSource::Make(NetLogSourceType::NONE));
10694   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10695 
10696   rv = callback1.WaitForResult();
10697   EXPECT_THAT(rv, IsOk());
10698 
10699   LoadTimingInfo load_timing_info;
10700   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
10701   TestLoadTimingNotReused(load_timing_info,
10702                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10703 
10704   const HttpResponseInfo* response = trans.GetResponseInfo();
10705   ASSERT_TRUE(response);
10706   ASSERT_TRUE(response->headers);
10707   EXPECT_EQ(407, response->headers->response_code());
10708   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10709   EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
10710   EXPECT_FALSE(response->did_use_http_auth);
10711   EXPECT_EQ(proxy_chain1, response->proxy_chain);
10712 
10713   TestCompletionCallback callback2;
10714 
10715   // Configure against https proxy server "myproxy2:70".
10716   proxy_delegate->set_proxy_chain(proxy_chain2);
10717 
10718   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
10719   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10720 
10721   rv = callback2.WaitForResult();
10722   EXPECT_THAT(rv, IsOk());
10723 
10724   load_timing_info = LoadTimingInfo();
10725   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
10726   TestLoadTimingNotReused(load_timing_info,
10727                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10728 
10729   response = trans.GetResponseInfo();
10730   ASSERT_TRUE(response);
10731 
10732   EXPECT_TRUE(response->headers->IsKeepAlive());
10733   EXPECT_EQ(200, response->headers->response_code());
10734   EXPECT_EQ(100, response->headers->GetContentLength());
10735   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10736   EXPECT_TRUE(response->did_use_http_auth);
10737   EXPECT_EQ(proxy_chain2, response->proxy_chain);
10738 
10739   // The password prompt info should not be set.
10740   EXPECT_FALSE(response->auth_challenge.has_value());
10741 }
10742 
10743 // Test the challenge-response-retry sequence through an HTTPS Proxy over a
10744 // connection that requires a restart, with a change to a direct connection
10745 // occurring over the restart.
TEST_P(HttpNetworkTransactionTest,HttpsProxyAuthRetryNoKeepAliveChangeToDirect)10746 TEST_P(HttpNetworkTransactionTest,
10747        HttpsProxyAuthRetryNoKeepAliveChangeToDirect) {
10748   const auto proxy_chain = PacResultElementToProxyChain("HTTPS myproxy:70");
10749   const auto direct = ProxyChain::Direct();
10750 
10751   session_deps_.proxy_delegate = std::make_unique<TestProxyDelegate>();
10752   auto* proxy_delegate =
10753       static_cast<TestProxyDelegate*>(session_deps_.proxy_delegate.get());
10754   proxy_delegate->set_proxy_chain(proxy_chain);
10755 
10756   HttpRequestInfo request;
10757   request.method = "GET";
10758   request.url = GURL("http://www.example.org/");
10759   // when the no authentication data flag is set.
10760   request.privacy_mode = PRIVACY_MODE_ENABLED;
10761   request.traffic_annotation =
10762       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10763 
10764   // Configure against https proxy server "myproxy:70".
10765   session_deps_.proxy_resolution_service =
10766       ConfiguredProxyResolutionService::CreateFixedForTest(
10767           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10768   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
10769   session_deps_.net_log = NetLog::Get();
10770   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10771 
10772   // Since we have proxy, should use full url
10773   MockWrite data_writes1[] = {
10774       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
10775                 "Host: www.example.org\r\n"
10776                 "Proxy-Connection: keep-alive\r\n\r\n"),
10777   };
10778 
10779   // The proxy responds to the GET with a 407, using a non-persistent
10780   // connection.
10781   MockRead data_reads1[] = {
10782       // No credentials.
10783       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10784       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10785       MockRead("Proxy-Connection: close\r\n"),
10786       MockRead("Content-Length: 0\r\n\r\n"),
10787   };
10788 
10789   MockWrite data_writes2[] = {
10790       // After calling trans.RestartWithAuth(), this is the request we should
10791       // be issuing.
10792       MockWrite("GET / HTTP/1.1\r\n"
10793                 "Host: www.example.org\r\n"
10794                 "Connection: keep-alive\r\n\r\n"),
10795   };
10796 
10797   MockRead data_reads2[] = {
10798       MockRead("HTTP/1.1 200 OK\r\n"),
10799       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10800       MockRead("Content-Length: 100\r\n\r\n"),
10801       MockRead(SYNCHRONOUS, OK),
10802   };
10803 
10804   StaticSocketDataProvider data1(data_reads1, data_writes1);
10805   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10806   StaticSocketDataProvider data2(data_reads2, data_writes2);
10807   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10808 
10809   // One per each connection.
10810   SSLSocketDataProvider ssl1(ASYNC, OK);
10811   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
10812   SSLSocketDataProvider ssl2(ASYNC, OK);
10813   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
10814 
10815   TestCompletionCallback callback1;
10816 
10817   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10818 
10819   int rv = trans.Start(&request, callback1.callback(),
10820                        NetLogWithSource::Make(NetLogSourceType::NONE));
10821   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10822 
10823   rv = callback1.WaitForResult();
10824   EXPECT_THAT(rv, IsOk());
10825 
10826   LoadTimingInfo load_timing_info;
10827   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
10828   TestLoadTimingNotReused(load_timing_info,
10829                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10830 
10831   const HttpResponseInfo* response = trans.GetResponseInfo();
10832   ASSERT_TRUE(response);
10833   ASSERT_TRUE(response->headers);
10834   EXPECT_EQ(407, response->headers->response_code());
10835   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10836   EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
10837   EXPECT_FALSE(response->did_use_http_auth);
10838   EXPECT_EQ(proxy_chain, response->proxy_chain);
10839 
10840   TestCompletionCallback callback2;
10841 
10842   // Configure to use a direct connection.
10843   proxy_delegate->set_proxy_chain(direct);
10844 
10845   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
10846   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10847 
10848   rv = callback2.WaitForResult();
10849   EXPECT_THAT(rv, IsOk());
10850 
10851   load_timing_info = LoadTimingInfo();
10852   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
10853   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
10854 
10855   response = trans.GetResponseInfo();
10856   ASSERT_TRUE(response);
10857 
10858   EXPECT_TRUE(response->headers->IsKeepAlive());
10859   EXPECT_EQ(200, response->headers->response_code());
10860   EXPECT_EQ(100, response->headers->GetContentLength());
10861   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10862   EXPECT_FALSE(response->did_use_http_auth);
10863   EXPECT_EQ(direct, response->proxy_chain);
10864 
10865   // The password prompt info should not be set.
10866   EXPECT_FALSE(response->auth_challenge.has_value());
10867 }
10868 
ConnectStatusHelperWithExpectedStatus(const MockRead & status,int expected_status)10869 void HttpNetworkTransactionTestBase::ConnectStatusHelperWithExpectedStatus(
10870     const MockRead& status,
10871     int expected_status) {
10872   HttpRequestInfo request;
10873   request.method = "GET";
10874   request.url = GURL("https://www.example.org/");
10875   request.traffic_annotation =
10876       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10877 
10878   // Configure against proxy server "myproxy:70".
10879   session_deps_.proxy_resolution_service =
10880       ConfiguredProxyResolutionService::CreateFixedForTest(
10881           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10882   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10883 
10884   // Since we have proxy, should try to establish tunnel.
10885   MockWrite data_writes[] = {
10886       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10887                 "Host: www.example.org:443\r\n"
10888                 "Proxy-Connection: keep-alive\r\n\r\n"),
10889   };
10890 
10891   MockRead data_reads[] = {
10892       status,
10893       MockRead("Content-Length: 10\r\n\r\n"),
10894       // No response body because the test stops reading here.
10895       MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
10896   };
10897 
10898   StaticSocketDataProvider data(data_reads, data_writes);
10899   session_deps_.socket_factory->AddSocketDataProvider(&data);
10900 
10901   TestCompletionCallback callback;
10902 
10903   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10904 
10905   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10906   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10907 
10908   rv = callback.WaitForResult();
10909   EXPECT_EQ(expected_status, rv);
10910 }
10911 
ConnectStatusHelper(const MockRead & status)10912 void HttpNetworkTransactionTestBase::ConnectStatusHelper(
10913     const MockRead& status) {
10914   ConnectStatusHelperWithExpectedStatus(status, ERR_TUNNEL_CONNECTION_FAILED);
10915 }
10916 
TEST_P(HttpNetworkTransactionTest,ConnectStatus100)10917 TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
10918   ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
10919 }
10920 
TEST_P(HttpNetworkTransactionTest,ConnectStatus101)10921 TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
10922   ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
10923 }
10924 
TEST_P(HttpNetworkTransactionTest,ConnectStatus201)10925 TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
10926   ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
10927 }
10928 
TEST_P(HttpNetworkTransactionTest,ConnectStatus202)10929 TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
10930   ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
10931 }
10932 
TEST_P(HttpNetworkTransactionTest,ConnectStatus203)10933 TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
10934   ConnectStatusHelper(
10935       MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
10936 }
10937 
TEST_P(HttpNetworkTransactionTest,ConnectStatus204)10938 TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
10939   ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
10940 }
10941 
TEST_P(HttpNetworkTransactionTest,ConnectStatus205)10942 TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
10943   ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
10944 }
10945 
TEST_P(HttpNetworkTransactionTest,ConnectStatus206)10946 TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
10947   ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
10948 }
10949 
TEST_P(HttpNetworkTransactionTest,ConnectStatus300)10950 TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
10951   ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
10952 }
10953 
TEST_P(HttpNetworkTransactionTest,ConnectStatus301)10954 TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
10955   ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
10956 }
10957 
TEST_P(HttpNetworkTransactionTest,ConnectStatus302)10958 TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
10959   ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
10960 }
10961 
TEST_P(HttpNetworkTransactionTest,ConnectStatus303)10962 TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
10963   ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
10964 }
10965 
TEST_P(HttpNetworkTransactionTest,ConnectStatus304)10966 TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
10967   ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
10968 }
10969 
TEST_P(HttpNetworkTransactionTest,ConnectStatus305)10970 TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
10971   ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
10972 }
10973 
TEST_P(HttpNetworkTransactionTest,ConnectStatus306)10974 TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
10975   ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
10976 }
10977 
TEST_P(HttpNetworkTransactionTest,ConnectStatus307)10978 TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
10979   ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
10980 }
10981 
TEST_P(HttpNetworkTransactionTest,ConnectStatus308)10982 TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
10983   ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
10984 }
10985 
TEST_P(HttpNetworkTransactionTest,ConnectStatus400)10986 TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
10987   ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
10988 }
10989 
TEST_P(HttpNetworkTransactionTest,ConnectStatus401)10990 TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
10991   ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
10992 }
10993 
TEST_P(HttpNetworkTransactionTest,ConnectStatus402)10994 TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
10995   ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
10996 }
10997 
TEST_P(HttpNetworkTransactionTest,ConnectStatus403)10998 TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
10999   ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
11000 }
11001 
TEST_P(HttpNetworkTransactionTest,ConnectStatus404)11002 TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
11003   ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
11004 }
11005 
TEST_P(HttpNetworkTransactionTest,ConnectStatus405)11006 TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
11007   ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
11008 }
11009 
TEST_P(HttpNetworkTransactionTest,ConnectStatus406)11010 TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
11011   ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
11012 }
11013 
TEST_P(HttpNetworkTransactionTest,ConnectStatus407)11014 TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
11015   ConnectStatusHelperWithExpectedStatus(
11016       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
11017       ERR_PROXY_AUTH_UNSUPPORTED);
11018 }
11019 
TEST_P(HttpNetworkTransactionTest,ConnectStatus408)11020 TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
11021   ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
11022 }
11023 
TEST_P(HttpNetworkTransactionTest,ConnectStatus409)11024 TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
11025   ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
11026 }
11027 
TEST_P(HttpNetworkTransactionTest,ConnectStatus410)11028 TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
11029   ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
11030 }
11031 
TEST_P(HttpNetworkTransactionTest,ConnectStatus411)11032 TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
11033   ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
11034 }
11035 
TEST_P(HttpNetworkTransactionTest,ConnectStatus412)11036 TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
11037   ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
11038 }
11039 
TEST_P(HttpNetworkTransactionTest,ConnectStatus413)11040 TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
11041   ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
11042 }
11043 
TEST_P(HttpNetworkTransactionTest,ConnectStatus414)11044 TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
11045   ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
11046 }
11047 
TEST_P(HttpNetworkTransactionTest,ConnectStatus415)11048 TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
11049   ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
11050 }
11051 
TEST_P(HttpNetworkTransactionTest,ConnectStatus416)11052 TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
11053   ConnectStatusHelper(
11054       MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
11055 }
11056 
TEST_P(HttpNetworkTransactionTest,ConnectStatus417)11057 TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
11058   ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
11059 }
11060 
TEST_P(HttpNetworkTransactionTest,ConnectStatus500)11061 TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
11062   ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
11063 }
11064 
TEST_P(HttpNetworkTransactionTest,ConnectStatus501)11065 TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
11066   ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
11067 }
11068 
TEST_P(HttpNetworkTransactionTest,ConnectStatus502)11069 TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
11070   ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
11071 }
11072 
TEST_P(HttpNetworkTransactionTest,ConnectStatus503)11073 TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
11074   ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
11075 }
11076 
TEST_P(HttpNetworkTransactionTest,ConnectStatus504)11077 TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
11078   ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
11079 }
11080 
TEST_P(HttpNetworkTransactionTest,ConnectStatus505)11081 TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
11082   ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
11083 }
11084 
11085 // Test the flow when both the proxy server AND origin server require
11086 // authentication. Again, this uses basic auth for both since that is
11087 // the simplest to mock.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyThenServer)11088 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
11089   HttpRequestInfo request;
11090   request.method = "GET";
11091   request.url = GURL("http://www.example.org/");
11092   request.traffic_annotation =
11093       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11094 
11095   // Configure against proxy server "myproxy:70".
11096   session_deps_.proxy_resolution_service =
11097       ConfiguredProxyResolutionService::CreateFixedForTest(
11098           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
11099   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11100 
11101   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11102 
11103   MockWrite data_writes1[] = {
11104       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
11105                 "Host: www.example.org\r\n"
11106                 "Proxy-Connection: keep-alive\r\n\r\n"),
11107   };
11108 
11109   MockRead data_reads1[] = {
11110       MockRead("HTTP/1.0 407 Unauthorized\r\n"),
11111       // Give a couple authenticate options (only the middle one is actually
11112       // supported).
11113       MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
11114       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11115       MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
11116       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11117       // Large content-length -- won't matter, as connection will be reset.
11118       MockRead("Content-Length: 10000\r\n\r\n"),
11119       MockRead(SYNCHRONOUS, ERR_FAILED),
11120   };
11121 
11122   // After calling trans.RestartWithAuth() the first time, this is the
11123   // request we should be issuing -- the final header line contains the
11124   // proxy's credentials.
11125   MockWrite data_writes2[] = {
11126       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
11127                 "Host: www.example.org\r\n"
11128                 "Proxy-Connection: keep-alive\r\n"
11129                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
11130   };
11131 
11132   // Now the proxy server lets the request pass through to origin server.
11133   // The origin server responds with a 401.
11134   MockRead data_reads2[] = {
11135       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
11136       // Note: We are using the same realm-name as the proxy server. This is
11137       // completely valid, as realms are unique across hosts.
11138       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11139       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11140       MockRead("Content-Length: 2000\r\n\r\n"),
11141       MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
11142   };
11143 
11144   // After calling trans.RestartWithAuth() the second time, we should send
11145   // the credentials for both the proxy and origin server.
11146   MockWrite data_writes3[] = {
11147       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
11148                 "Host: www.example.org\r\n"
11149                 "Proxy-Connection: keep-alive\r\n"
11150                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
11151                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
11152   };
11153 
11154   // Lastly we get the desired content.
11155   MockRead data_reads3[] = {
11156       MockRead("HTTP/1.0 200 OK\r\n"),
11157       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11158       MockRead("Content-Length: 100\r\n\r\n"),
11159       MockRead(SYNCHRONOUS, OK),
11160   };
11161 
11162   StaticSocketDataProvider data1(data_reads1, data_writes1);
11163   StaticSocketDataProvider data2(data_reads2, data_writes2);
11164   StaticSocketDataProvider data3(data_reads3, data_writes3);
11165   session_deps_.socket_factory->AddSocketDataProvider(&data1);
11166   session_deps_.socket_factory->AddSocketDataProvider(&data2);
11167   session_deps_.socket_factory->AddSocketDataProvider(&data3);
11168 
11169   TestCompletionCallback callback1;
11170 
11171   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
11172   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11173 
11174   rv = callback1.WaitForResult();
11175   EXPECT_THAT(rv, IsOk());
11176 
11177   const HttpResponseInfo* response = trans.GetResponseInfo();
11178   ASSERT_TRUE(response);
11179   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
11180 
11181   TestCompletionCallback callback2;
11182 
11183   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
11184   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11185 
11186   rv = callback2.WaitForResult();
11187   EXPECT_THAT(rv, IsOk());
11188 
11189   response = trans.GetResponseInfo();
11190   ASSERT_TRUE(response);
11191   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
11192 
11193   TestCompletionCallback callback3;
11194 
11195   rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
11196                              callback3.callback());
11197   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11198 
11199   rv = callback3.WaitForResult();
11200   EXPECT_THAT(rv, IsOk());
11201 
11202   response = trans.GetResponseInfo();
11203   EXPECT_FALSE(response->auth_challenge.has_value());
11204   EXPECT_EQ(100, response->headers->GetContentLength());
11205 }
11206 
11207 // For the NTLM implementation using SSPI, we skip the NTLM tests since we
11208 // can't hook into its internals to cause it to generate predictable NTLM
11209 // authorization headers.
11210 #if defined(NTLM_PORTABLE)
11211 // The NTLM authentication unit tests are based on known test data from the
11212 // [MS-NLMP] Specification [1]. These tests are primarily of the authentication
11213 // flow rather than the implementation of the NTLM protocol. See net/ntlm
11214 // for the implementation and testing of the protocol.
11215 //
11216 // [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
11217 
11218 // Enter the correct password and authenticate successfully.
TEST_P(HttpNetworkTransactionTest,NTLMAuthV2)11219 TEST_P(HttpNetworkTransactionTest, NTLMAuthV2) {
11220   HttpRequestInfo request;
11221   request.method = "GET";
11222   request.url = GURL("https://server/kids/login.aspx");
11223   request.traffic_annotation =
11224       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11225 
11226   // Ensure load is not disrupted by flags which suppress behaviour specific
11227   // to other auth schemes.
11228   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
11229 
11230   HttpAuthNtlmMechanism::ScopedProcSetter proc_setter(
11231       MockGetMSTime, MockGenerateRandom, MockGetHostName);
11232   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11233 
11234   // Generate the NTLM messages based on known test data.
11235   std::string negotiate_msg = base::Base64Encode(std::string_view(
11236       reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
11237       std::size(ntlm::test::kExpectedNegotiateMsg)));
11238   std::string challenge_msg = base::Base64Encode(std::string_view(
11239       reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
11240       std::size(ntlm::test::kChallengeMsgFromSpecV2)));
11241   std::string authenticate_msg = base::Base64Encode(std::string_view(
11242       reinterpret_cast<const char*>(
11243           ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
11244       std::size(ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)));
11245 
11246   MockWrite data_writes1[] = {
11247       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
11248                 "Host: server\r\n"
11249                 "Connection: keep-alive\r\n\r\n"),
11250   };
11251 
11252   MockRead data_reads1[] = {
11253       MockRead("HTTP/1.1 401 Access Denied\r\n"),
11254       // Negotiate and NTLM are often requested together.  However, we only want
11255       // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
11256       // the header that requests Negotiate for this test.
11257       MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
11258       MockRead("Content-Length: 42\r\n"),
11259       MockRead("Content-Type: text/html\r\n\r\n"),
11260       // Missing content -- won't matter, as connection will be reset.
11261   };
11262 
11263   MockWrite data_writes2[] = {
11264       // After restarting with a null identity, this is the
11265       // request we should be issuing -- the final header line contains a Type
11266       // 1 message.
11267       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
11268                 "Host: server\r\n"
11269                 "Connection: keep-alive\r\n"
11270                 "Authorization: NTLM "),
11271       MockWrite(negotiate_msg.c_str()),
11272       MockWrite("\r\n\r\n"),
11273 
11274       // After calling trans.RestartWithAuth(), we should send a Type 3 message
11275       // (using correct credentials).  The second request continues on the
11276       // same connection.
11277       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
11278                 "Host: server\r\n"
11279                 "Connection: keep-alive\r\n"
11280                 "Authorization: NTLM "),
11281       MockWrite(authenticate_msg.c_str()),
11282       MockWrite("\r\n\r\n"),
11283   };
11284 
11285   MockRead data_reads2[] = {
11286       // The origin server responds with a Type 2 message.
11287       MockRead("HTTP/1.1 401 Access Denied\r\n"),
11288       MockRead("WWW-Authenticate: NTLM "),
11289       MockRead(challenge_msg.c_str()),
11290       MockRead("\r\n"),
11291       MockRead("Content-Length: 42\r\n"),
11292       MockRead("Content-Type: text/html\r\n\r\n"),
11293       MockRead("You are not authorized to view this page\r\n"),
11294 
11295       // Lastly we get the desired content.
11296       MockRead("HTTP/1.1 200 OK\r\n"),
11297       MockRead("Content-Type: text/html; charset=utf-8\r\n"),
11298       MockRead("Content-Length: 14\r\n\r\n"),
11299       MockRead("Please Login\r\n"),
11300   };
11301 
11302   StaticSocketDataProvider data1(data_reads1, data_writes1);
11303   StaticSocketDataProvider data2(data_reads2, data_writes2);
11304   session_deps_.socket_factory->AddSocketDataProvider(&data1);
11305   session_deps_.socket_factory->AddSocketDataProvider(&data2);
11306 
11307   SSLSocketDataProvider ssl1(ASYNC, OK);
11308   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11309   SSLSocketDataProvider ssl2(ASYNC, OK);
11310   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11311 
11312   TestCompletionCallback callback1;
11313 
11314   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11315 
11316   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
11317   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11318 
11319   rv = callback1.WaitForResult();
11320   EXPECT_THAT(rv, IsOk());
11321 
11322   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
11323 
11324   const HttpResponseInfo* response = trans.GetResponseInfo();
11325   ASSERT_TRUE(response);
11326   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
11327 
11328   TestCompletionCallback callback2;
11329 
11330   rv = trans.RestartWithAuth(
11331       AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
11332       callback2.callback());
11333   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11334 
11335   rv = callback2.WaitForResult();
11336   EXPECT_THAT(rv, IsOk());
11337 
11338   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
11339 
11340   response = trans.GetResponseInfo();
11341   ASSERT_TRUE(response);
11342   EXPECT_FALSE(response->auth_challenge.has_value());
11343 
11344   TestCompletionCallback callback3;
11345 
11346   rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
11347   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11348 
11349   rv = callback3.WaitForResult();
11350   EXPECT_THAT(rv, IsOk());
11351 
11352   response = trans.GetResponseInfo();
11353   ASSERT_TRUE(response);
11354   EXPECT_FALSE(response->auth_challenge.has_value());
11355   EXPECT_EQ(14, response->headers->GetContentLength());
11356 
11357   std::string response_data;
11358   rv = ReadTransaction(&trans, &response_data);
11359   EXPECT_THAT(rv, IsOk());
11360   EXPECT_EQ("Please Login\r\n", response_data);
11361 
11362   EXPECT_TRUE(data1.AllReadDataConsumed());
11363   EXPECT_TRUE(data1.AllWriteDataConsumed());
11364   EXPECT_TRUE(data2.AllReadDataConsumed());
11365   EXPECT_TRUE(data2.AllWriteDataConsumed());
11366 }
11367 
11368 // Enter a wrong password, and then the correct one.
TEST_P(HttpNetworkTransactionTest,NTLMAuthV2WrongThenRightPassword)11369 TEST_P(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
11370   HttpRequestInfo request;
11371   request.method = "GET";
11372   request.url = GURL("https://server/kids/login.aspx");
11373   request.traffic_annotation =
11374       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11375 
11376   HttpAuthNtlmMechanism::ScopedProcSetter proc_setter(
11377       MockGetMSTime, MockGenerateRandom, MockGetHostName);
11378   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11379 
11380   // Generate the NTLM messages based on known test data.
11381   std::string negotiate_msg = base::Base64Encode(std::string_view(
11382       reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
11383       std::size(ntlm::test::kExpectedNegotiateMsg)));
11384   std::string challenge_msg = base::Base64Encode(std::string_view(
11385       reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
11386       std::size(ntlm::test::kChallengeMsgFromSpecV2)));
11387   std::string authenticate_msg = base::Base64Encode(std::string_view(
11388       reinterpret_cast<const char*>(
11389           ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
11390       std::size(ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)));
11391 
11392   // The authenticate message when |kWrongPassword| is sent.
11393   std::string wrong_password_authenticate_msg(
11394       "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
11395       "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
11396       "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
11397       "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
11398       "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
11399       "QwBPAE0AUABVAFQARQBSAA==");
11400 
11401   // Sanity check that it's the same length as the correct authenticate message
11402   // and that it's different.
11403   ASSERT_EQ(authenticate_msg.length(),
11404             wrong_password_authenticate_msg.length());
11405   ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
11406 
11407   MockWrite data_writes1[] = {
11408       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
11409                 "Host: server\r\n"
11410                 "Connection: keep-alive\r\n\r\n"),
11411   };
11412 
11413   MockRead data_reads1[] = {
11414       MockRead("HTTP/1.1 401 Access Denied\r\n"),
11415       // Negotiate and NTLM are often requested together.  However, we only want
11416       // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
11417       // the header that requests Negotiate for this test.
11418       MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
11419       MockRead("Content-Length: 42\r\n"),
11420       MockRead("Content-Type: text/html\r\n\r\n"),
11421       // Missing content -- won't matter, as connection will be reset.
11422   };
11423 
11424   MockWrite data_writes2[] = {
11425       // After restarting with a null identity, this is the
11426       // request we should be issuing -- the final header line contains a Type
11427       // 1 message.
11428       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
11429                 "Host: server\r\n"
11430                 "Connection: keep-alive\r\n"
11431                 "Authorization: NTLM "),
11432       MockWrite(negotiate_msg.c_str()),
11433       MockWrite("\r\n\r\n"),
11434 
11435       // After calling trans.RestartWithAuth(), we should send a Type 3 message
11436       // (using incorrect credentials).  The second request continues on the
11437       // same connection.
11438       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
11439                 "Host: server\r\n"
11440                 "Connection: keep-alive\r\n"
11441                 "Authorization: NTLM "),
11442       MockWrite(wrong_password_authenticate_msg.c_str()),
11443       MockWrite("\r\n\r\n"),
11444   };
11445 
11446   MockRead data_reads2[] = {
11447       // The origin server responds with a Type 2 message.
11448       MockRead("HTTP/1.1 401 Access Denied\r\n"),
11449       MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
11450       MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
11451       MockRead("Content-Type: text/html\r\n\r\n"),
11452       MockRead("You are not authorized to view this page\r\n"),
11453 
11454       // Wrong password.
11455       MockRead("HTTP/1.1 401 Access Denied\r\n"),
11456       MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
11457       MockRead("Content-Length: 42\r\n"),
11458       MockRead("Content-Type: text/html\r\n\r\n"),
11459       // Missing content -- won't matter, as connection will be reset.
11460   };
11461 
11462   MockWrite data_writes3[] = {
11463       // After restarting with a null identity, this is the
11464       // request we should be issuing -- the final header line contains a Type
11465       // 1 message.
11466       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
11467                 "Host: server\r\n"
11468                 "Connection: keep-alive\r\n"
11469                 "Authorization: NTLM "),
11470       MockWrite(negotiate_msg.c_str()),
11471       MockWrite("\r\n\r\n"),
11472 
11473       // After calling trans.RestartWithAuth(), we should send a Type 3 message
11474       // (the credentials for the origin server).  The second request continues
11475       // on the same connection.
11476       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
11477                 "Host: server\r\n"
11478                 "Connection: keep-alive\r\n"
11479                 "Authorization: NTLM "),
11480       MockWrite(authenticate_msg.c_str()),
11481       MockWrite("\r\n\r\n"),
11482   };
11483 
11484   MockRead data_reads3[] = {
11485       // The origin server responds with a Type 2 message.
11486       MockRead("HTTP/1.1 401 Access Denied\r\n"),
11487       MockRead("WWW-Authenticate: NTLM "),
11488       MockRead(challenge_msg.c_str()),
11489       MockRead("\r\n"),
11490       MockRead("Content-Length: 42\r\n"),
11491       MockRead("Content-Type: text/html\r\n\r\n"),
11492       MockRead("You are not authorized to view this page\r\n"),
11493 
11494       // Lastly we get the desired content.
11495       MockRead("HTTP/1.1 200 OK\r\n"),
11496       MockRead("Content-Type: text/html; charset=utf-8\r\n"),
11497       MockRead("Content-Length: 14\r\n\r\n"),
11498       MockRead("Please Login\r\n"),
11499   };
11500 
11501   StaticSocketDataProvider data1(data_reads1, data_writes1);
11502   StaticSocketDataProvider data2(data_reads2, data_writes2);
11503   StaticSocketDataProvider data3(data_reads3, data_writes3);
11504   session_deps_.socket_factory->AddSocketDataProvider(&data1);
11505   session_deps_.socket_factory->AddSocketDataProvider(&data2);
11506   session_deps_.socket_factory->AddSocketDataProvider(&data3);
11507 
11508   SSLSocketDataProvider ssl1(ASYNC, OK);
11509   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11510   SSLSocketDataProvider ssl2(ASYNC, OK);
11511   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11512   SSLSocketDataProvider ssl3(ASYNC, OK);
11513   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
11514 
11515   TestCompletionCallback callback1;
11516 
11517   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11518 
11519   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
11520   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11521 
11522   rv = callback1.WaitForResult();
11523   EXPECT_THAT(rv, IsOk());
11524 
11525   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
11526 
11527   const HttpResponseInfo* response = trans.GetResponseInfo();
11528   ASSERT_TRUE(response);
11529   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
11530 
11531   TestCompletionCallback callback2;
11532 
11533   // Enter the wrong password.
11534   rv = trans.RestartWithAuth(
11535       AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
11536       callback2.callback());
11537   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11538 
11539   rv = callback2.WaitForResult();
11540   EXPECT_THAT(rv, IsOk());
11541 
11542   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
11543   TestCompletionCallback callback3;
11544   rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
11545   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11546   rv = callback3.WaitForResult();
11547   EXPECT_THAT(rv, IsOk());
11548   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
11549 
11550   response = trans.GetResponseInfo();
11551   ASSERT_TRUE(response);
11552   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
11553 
11554   TestCompletionCallback callback4;
11555 
11556   // Now enter the right password.
11557   rv = trans.RestartWithAuth(
11558       AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
11559       callback4.callback());
11560   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11561 
11562   rv = callback4.WaitForResult();
11563   EXPECT_THAT(rv, IsOk());
11564 
11565   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
11566 
11567   TestCompletionCallback callback5;
11568 
11569   // One more roundtrip
11570   rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
11571   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11572 
11573   rv = callback5.WaitForResult();
11574   EXPECT_THAT(rv, IsOk());
11575 
11576   response = trans.GetResponseInfo();
11577   EXPECT_FALSE(response->auth_challenge.has_value());
11578   EXPECT_EQ(14, response->headers->GetContentLength());
11579 
11580   std::string response_data;
11581   rv = ReadTransaction(&trans, &response_data);
11582   EXPECT_THAT(rv, IsOk());
11583   EXPECT_EQ("Please Login\r\n", response_data);
11584 
11585   EXPECT_TRUE(data1.AllReadDataConsumed());
11586   EXPECT_TRUE(data1.AllWriteDataConsumed());
11587   EXPECT_TRUE(data2.AllReadDataConsumed());
11588   EXPECT_TRUE(data2.AllWriteDataConsumed());
11589   EXPECT_TRUE(data3.AllReadDataConsumed());
11590   EXPECT_TRUE(data3.AllWriteDataConsumed());
11591 }
11592 
11593 // Server requests NTLM authentication, which is not supported over HTTP/2.
11594 // Subsequent request with authorization header should be sent over HTTP/1.1.
TEST_P(HttpNetworkTransactionTest,NTLMOverHttp2)11595 TEST_P(HttpNetworkTransactionTest, NTLMOverHttp2) {
11596   HttpAuthNtlmMechanism::ScopedProcSetter proc_setter(
11597       MockGetMSTime, MockGenerateRandom, MockGetHostName);
11598 
11599   const char kUrl[] = "https://server/kids/login.aspx";
11600 
11601   HttpRequestInfo request;
11602   request.method = "GET";
11603   request.url = GURL(kUrl);
11604   request.traffic_annotation =
11605       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11606 
11607   // First request without credentials.
11608   spdy::Http2HeaderBlock request_headers0(
11609       spdy_util_.ConstructGetHeaderBlock(kUrl));
11610   spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
11611       1, std::move(request_headers0), LOWEST, true));
11612 
11613   spdy::Http2HeaderBlock response_headers0;
11614   response_headers0[spdy::kHttp2StatusHeader] = "401";
11615   response_headers0["www-authenticate"] = "NTLM";
11616   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
11617       1, std::move(response_headers0), true));
11618 
11619   // Stream 1 is closed.
11620   spdy_util_.UpdateWithStreamDestruction(1);
11621 
11622   // Generate the NTLM messages based on known test data.
11623   std::string negotiate_msg = base::Base64Encode(std::string_view(
11624       reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
11625       std::size(ntlm::test::kExpectedNegotiateMsg)));
11626   std::string challenge_msg = base::Base64Encode(std::string_view(
11627       reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
11628       std::size(ntlm::test::kChallengeMsgFromSpecV2)));
11629   std::string authenticate_msg = base::Base64Encode(std::string_view(
11630       reinterpret_cast<const char*>(
11631           ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
11632       std::size(ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)));
11633 
11634   MockWrite writes0[] = {CreateMockWrite(request0, 0)};
11635   MockRead reads0[] = {CreateMockRead(resp, 1),
11636                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2)};
11637 
11638   // Retry yet again using HTTP/1.1.
11639   MockWrite writes1[] = {
11640       // After restarting with a null identity, this is the
11641       // request we should be issuing -- the final header line contains a Type
11642       // 1 message.
11643       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
11644                 "Host: server\r\n"
11645                 "Connection: keep-alive\r\n"
11646                 "Authorization: NTLM "),
11647       MockWrite(negotiate_msg.c_str()),
11648       MockWrite("\r\n\r\n"),
11649 
11650       // After calling trans.RestartWithAuth(), we should send a Type 3 message
11651       // (the credentials for the origin server).  The second request continues
11652       // on the same connection.
11653       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
11654                 "Host: server\r\n"
11655                 "Connection: keep-alive\r\n"
11656                 "Authorization: NTLM "),
11657       MockWrite(authenticate_msg.c_str()),
11658       MockWrite("\r\n\r\n"),
11659   };
11660 
11661   MockRead reads1[] = {
11662       // The origin server responds with a Type 2 message.
11663       MockRead("HTTP/1.1 401 Access Denied\r\n"),
11664       MockRead("WWW-Authenticate: NTLM "),
11665       MockRead(challenge_msg.c_str()),
11666       MockRead("\r\n"),
11667       MockRead("Content-Length: 42\r\n"),
11668       MockRead("Content-Type: text/html\r\n\r\n"),
11669       MockRead("You are not authorized to view this page\r\n"),
11670 
11671       // Lastly we get the desired content.
11672       MockRead("HTTP/1.1 200 OK\r\n"),
11673       MockRead("Content-Type: text/html; charset=utf-8\r\n"),
11674       MockRead("Content-Length: 14\r\n\r\n"),
11675       MockRead("Please Login\r\n"),
11676   };
11677   SequencedSocketData data0(reads0, writes0);
11678   StaticSocketDataProvider data1(reads1, writes1);
11679   session_deps_.socket_factory->AddSocketDataProvider(&data0);
11680   session_deps_.socket_factory->AddSocketDataProvider(&data1);
11681 
11682   SSLSocketDataProvider ssl0(ASYNC, OK);
11683   ssl0.next_proto = kProtoHTTP2;
11684   ssl0.next_protos_expected_in_ssl_config =
11685       NextProtoVector{kProtoHTTP2, kProtoHTTP11};
11686   SSLSocketDataProvider ssl1(ASYNC, OK);
11687   // When creating the second connection, only HTTP/1.1 should be allowed.
11688   ssl1.next_protos_expected_in_ssl_config = NextProtoVector{kProtoHTTP11};
11689   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
11690   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11691 
11692   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11693   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11694 
11695   TestCompletionCallback callback1;
11696   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
11697   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11698 
11699   rv = callback1.WaitForResult();
11700   EXPECT_THAT(rv, IsOk());
11701 
11702   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
11703 
11704   const HttpResponseInfo* response = trans.GetResponseInfo();
11705   ASSERT_TRUE(response);
11706   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
11707 
11708   TestCompletionCallback callback2;
11709 
11710   rv = trans.RestartWithAuth(
11711       AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
11712       callback2.callback());
11713   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11714 
11715   rv = callback2.WaitForResult();
11716   EXPECT_THAT(rv, IsOk());
11717 
11718   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
11719 
11720   response = trans.GetResponseInfo();
11721   ASSERT_TRUE(response);
11722   EXPECT_FALSE(response->auth_challenge.has_value());
11723 
11724   TestCompletionCallback callback3;
11725 
11726   rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
11727   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11728 
11729   rv = callback3.WaitForResult();
11730   EXPECT_THAT(rv, IsOk());
11731 
11732   response = trans.GetResponseInfo();
11733   ASSERT_TRUE(response);
11734   EXPECT_FALSE(response->auth_challenge.has_value());
11735   EXPECT_EQ(14, response->headers->GetContentLength());
11736 
11737   std::string response_data;
11738   rv = ReadTransaction(&trans, &response_data);
11739   EXPECT_THAT(rv, IsOk());
11740   EXPECT_EQ("Please Login\r\n", response_data);
11741 
11742   EXPECT_TRUE(data0.AllReadDataConsumed());
11743   EXPECT_TRUE(data0.AllWriteDataConsumed());
11744   EXPECT_TRUE(data1.AllReadDataConsumed());
11745   EXPECT_TRUE(data1.AllWriteDataConsumed());
11746 
11747   EXPECT_TRUE(session->http_server_properties()->RequiresHTTP11(
11748       url::SchemeHostPort(request.url), NetworkAnonymizationKey()));
11749 }
11750 
11751 // Same as above, but with a host mapping in place. The mapped host is the one
11752 // that should be tagged as requiring HTTP11.
TEST_P(HttpNetworkTransactionTest,NTLMOverHttp2WithHostMapping)11753 TEST_P(HttpNetworkTransactionTest, NTLMOverHttp2WithHostMapping) {
11754   HttpAuthNtlmMechanism::ScopedProcSetter proc_setter(
11755       MockGetMSTime, MockGenerateRandom, MockGetHostName);
11756 
11757   const char kUrl[] = "https://server/kids/login.aspx";
11758   const char kMappedUrl[] = "https://server2:12345/kids/login.aspx";
11759   session_deps_.host_mapping_rules.AddRuleFromString(
11760       "MAP server server2:12345");
11761 
11762   HttpRequestInfo request;
11763   request.method = "GET";
11764   request.url = GURL(kUrl);
11765   request.traffic_annotation =
11766       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11767 
11768   // First request without credentials.
11769   spdy::Http2HeaderBlock request_headers0(
11770       spdy_util_.ConstructGetHeaderBlock(kUrl));
11771   spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
11772       1, std::move(request_headers0), LOWEST, true));
11773 
11774   spdy::Http2HeaderBlock response_headers0;
11775   response_headers0[spdy::kHttp2StatusHeader] = "401";
11776   response_headers0["www-authenticate"] = "NTLM";
11777   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
11778       1, std::move(response_headers0), true));
11779 
11780   // Stream 1 is closed.
11781   spdy_util_.UpdateWithStreamDestruction(1);
11782 
11783   // Generate the NTLM messages based on known test data.
11784   std::string negotiate_msg = base::Base64Encode(std::string_view(
11785       reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
11786       std::size(ntlm::test::kExpectedNegotiateMsg)));
11787   std::string challenge_msg = base::Base64Encode(std::string_view(
11788       reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
11789       std::size(ntlm::test::kChallengeMsgFromSpecV2)));
11790   std::string authenticate_msg = base::Base64Encode(std::string_view(
11791       reinterpret_cast<const char*>(
11792           ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
11793       std::size(ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)));
11794 
11795   MockWrite writes0[] = {CreateMockWrite(request0, 0)};
11796   MockRead reads0[] = {CreateMockRead(resp, 1),
11797                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2)};
11798 
11799   // Retry yet again using HTTP/1.1.
11800   MockWrite writes1[] = {
11801       // After restarting with a null identity, this is the
11802       // request we should be issuing -- the final header line contains a Type
11803       // 1 message.
11804       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
11805                 "Host: server\r\n"
11806                 "Connection: keep-alive\r\n"
11807                 "Authorization: NTLM "),
11808       MockWrite(negotiate_msg.c_str()),
11809       MockWrite("\r\n\r\n"),
11810 
11811       // After calling trans.RestartWithAuth(), we should send a Type 3 message
11812       // (the credentials for the origin server).  The second request continues
11813       // on the same connection.
11814       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
11815                 "Host: server\r\n"
11816                 "Connection: keep-alive\r\n"
11817                 "Authorization: NTLM "),
11818       MockWrite(authenticate_msg.c_str()),
11819       MockWrite("\r\n\r\n"),
11820   };
11821 
11822   MockRead reads1[] = {
11823       // The origin server responds with a Type 2 message.
11824       MockRead("HTTP/1.1 401 Access Denied\r\n"),
11825       MockRead("WWW-Authenticate: NTLM "),
11826       MockRead(challenge_msg.c_str()),
11827       MockRead("\r\n"),
11828       MockRead("Content-Length: 42\r\n"),
11829       MockRead("Content-Type: text/html\r\n\r\n"),
11830       MockRead("You are not authorized to view this page\r\n"),
11831 
11832       // Lastly we get the desired content.
11833       MockRead("HTTP/1.1 200 OK\r\n"),
11834       MockRead("Content-Type: text/html; charset=utf-8\r\n"),
11835       MockRead("Content-Length: 14\r\n\r\n"),
11836       MockRead("Please Login\r\n"),
11837   };
11838   SequencedSocketData data0(reads0, writes0);
11839   StaticSocketDataProvider data1(reads1, writes1);
11840   session_deps_.socket_factory->AddSocketDataProvider(&data0);
11841   session_deps_.socket_factory->AddSocketDataProvider(&data1);
11842 
11843   SSLSocketDataProvider ssl0(ASYNC, OK);
11844   ssl0.next_proto = kProtoHTTP2;
11845   ssl0.next_protos_expected_in_ssl_config =
11846       NextProtoVector{kProtoHTTP2, kProtoHTTP11};
11847   SSLSocketDataProvider ssl1(ASYNC, OK);
11848   // When creating the second connection, only HTTP/1.1 should be allowed.
11849   ssl1.next_protos_expected_in_ssl_config = NextProtoVector{kProtoHTTP11};
11850   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
11851   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11852 
11853   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11854   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11855 
11856   TestCompletionCallback callback1;
11857   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
11858   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11859 
11860   rv = callback1.WaitForResult();
11861   EXPECT_THAT(rv, IsOk());
11862 
11863   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
11864 
11865   const HttpResponseInfo* response = trans.GetResponseInfo();
11866   ASSERT_TRUE(response);
11867   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
11868 
11869   TestCompletionCallback callback2;
11870 
11871   rv = trans.RestartWithAuth(
11872       AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
11873       callback2.callback());
11874   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11875 
11876   rv = callback2.WaitForResult();
11877   EXPECT_THAT(rv, IsOk());
11878 
11879   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
11880 
11881   response = trans.GetResponseInfo();
11882   ASSERT_TRUE(response);
11883   EXPECT_FALSE(response->auth_challenge.has_value());
11884 
11885   TestCompletionCallback callback3;
11886 
11887   rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
11888   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11889 
11890   rv = callback3.WaitForResult();
11891   EXPECT_THAT(rv, IsOk());
11892 
11893   response = trans.GetResponseInfo();
11894   ASSERT_TRUE(response);
11895   EXPECT_FALSE(response->auth_challenge.has_value());
11896   EXPECT_EQ(14, response->headers->GetContentLength());
11897 
11898   std::string response_data;
11899   rv = ReadTransaction(&trans, &response_data);
11900   EXPECT_THAT(rv, IsOk());
11901   EXPECT_EQ("Please Login\r\n", response_data);
11902 
11903   EXPECT_TRUE(data0.AllReadDataConsumed());
11904   EXPECT_TRUE(data0.AllWriteDataConsumed());
11905   EXPECT_TRUE(data1.AllReadDataConsumed());
11906   EXPECT_TRUE(data1.AllWriteDataConsumed());
11907 
11908   EXPECT_FALSE(session->http_server_properties()->RequiresHTTP11(
11909       url::SchemeHostPort(request.url), NetworkAnonymizationKey()));
11910   EXPECT_TRUE(session->http_server_properties()->RequiresHTTP11(
11911       url::SchemeHostPort(GURL(kMappedUrl)), NetworkAnonymizationKey()));
11912 }
11913 
11914 #if BUILDFLAG(ENABLE_WEBSOCKETS)
11915 
11916 // Variant of above test using WebSockets.
TEST_P(HttpNetworkTransactionTest,NTLMOverHttp2WithWebsockets)11917 TEST_P(HttpNetworkTransactionTest, NTLMOverHttp2WithWebsockets) {
11918   const GURL kInitialUrl("https://server/");
11919   const GURL kWebSocketUrl("wss://server/");
11920   HttpAuthNtlmMechanism::ScopedProcSetter proc_setter(
11921       MockGetMSTime, MockGenerateRandom, MockGetHostName);
11922 
11923   // Initial request establishes an H2 connection, which will then be reused for
11924   // WebSockets. This is needed since WebSockets will reuse H2 connections, but
11925   // it won't create a new one.
11926   spdy::Http2HeaderBlock initial_request_headers(
11927       spdy_util_.ConstructGetHeaderBlock(kInitialUrl.spec()));
11928   spdy::SpdySerializedFrame initial_request(spdy_util_.ConstructSpdyHeaders(
11929       1, std::move(initial_request_headers), DEFAULT_PRIORITY, true));
11930   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
11931 
11932   // Settings frame, indicating WebSockets is supported.
11933   spdy::SettingsMap settings;
11934   settings[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
11935   spdy::SpdySerializedFrame settings_frame(
11936       spdy_util_.ConstructSpdySettings(settings));
11937 
11938   // Response headers for first request. Body is never received, but that
11939   // shouldn't matter for the purposes of this test.
11940   spdy::SpdySerializedFrame initial_response(
11941       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11942 
11943   // First WebSocket request, which has no credentials.
11944   spdy::Http2HeaderBlock websocket_request_headers;
11945   websocket_request_headers[spdy::kHttp2MethodHeader] = "CONNECT";
11946   websocket_request_headers[spdy::kHttp2AuthorityHeader] = "server";
11947   websocket_request_headers[spdy::kHttp2SchemeHeader] = "https";
11948   websocket_request_headers[spdy::kHttp2PathHeader] = "/";
11949   websocket_request_headers[spdy::kHttp2ProtocolHeader] = "websocket";
11950   websocket_request_headers["origin"] = "http://server";
11951   websocket_request_headers["sec-websocket-version"] = "13";
11952   websocket_request_headers["sec-websocket-extensions"] =
11953       "permessage-deflate; client_max_window_bits";
11954   spdy::SpdySerializedFrame websocket_request(spdy_util_.ConstructSpdyHeaders(
11955       3, std::move(websocket_request_headers), MEDIUM, false));
11956 
11957   // Auth challenge to WebSocket request.
11958   spdy::Http2HeaderBlock auth_challenge_headers;
11959   auth_challenge_headers[spdy::kHttp2StatusHeader] = "401";
11960   auth_challenge_headers["www-authenticate"] = "NTLM";
11961   spdy::SpdySerializedFrame websocket_auth_challenge(
11962       spdy_util_.ConstructSpdyResponseHeaders(
11963           3, std::move(auth_challenge_headers), true));
11964 
11965   MockWrite writes0[] = {CreateMockWrite(initial_request, 0),
11966                          CreateMockWrite(settings_ack, 2),
11967                          CreateMockWrite(websocket_request, 4),
11968                          MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 7)};
11969   MockRead reads0[] = {CreateMockRead(settings_frame, 1),
11970                        CreateMockRead(initial_response, 3),
11971                        CreateMockRead(websocket_auth_challenge, 5),
11972                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6)};
11973 
11974   // Generate the NTLM messages based on known test data.
11975   std::string negotiate_msg = base::Base64Encode(std::string_view(
11976       reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
11977       std::size(ntlm::test::kExpectedNegotiateMsg)));
11978   std::string challenge_msg = base::Base64Encode(std::string_view(
11979       reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
11980       std::size(ntlm::test::kChallengeMsgFromSpecV2)));
11981   std::string authenticate_msg = base::Base64Encode(std::string_view(
11982       reinterpret_cast<const char*>(
11983           ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
11984       std::size(ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)));
11985 
11986   // Retry yet again using HTTP/1.1.
11987   MockWrite writes1[] = {
11988       // After restarting with a null identity, this is the
11989       // request we should be issuing -- the final header line contains a Type
11990       // 1 message.
11991       MockWrite("GET / HTTP/1.1\r\n"
11992                 "Host: server\r\n"
11993                 "Connection: Upgrade\r\n"
11994                 "Authorization: NTLM "),
11995       MockWrite(negotiate_msg.c_str()),
11996       MockWrite("\r\n"),
11997       MockWrite("Origin: http://server\r\n"
11998                 "Sec-WebSocket-Version: 13\r\n"
11999                 "Upgrade: websocket\r\n"
12000                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
12001                 "Sec-WebSocket-Extensions: permessage-deflate; "
12002                 "client_max_window_bits\r\n\r\n"),
12003 
12004       // After calling trans.RestartWithAuth(), we should send a Type 3 message
12005       // (the credentials for the origin server).  The second request continues
12006       // on the same connection.
12007       MockWrite("GET / HTTP/1.1\r\n"
12008                 "Host: server\r\n"
12009                 "Connection: Upgrade\r\n"
12010                 "Authorization: NTLM "),
12011       MockWrite(authenticate_msg.c_str()),
12012       MockWrite("\r\n"),
12013       MockWrite("Origin: http://server\r\n"
12014                 "Sec-WebSocket-Version: 13\r\n"
12015                 "Upgrade: websocket\r\n"
12016                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
12017                 "Sec-WebSocket-Extensions: permessage-deflate; "
12018                 "client_max_window_bits\r\n\r\n"),
12019   };
12020 
12021   MockRead reads1[] = {
12022       // The origin server responds with a Type 2 message.
12023       MockRead("HTTP/1.1 401 Access Denied\r\n"),
12024       MockRead("WWW-Authenticate: NTLM "),
12025       MockRead(challenge_msg.c_str()),
12026       MockRead("\r\n"),
12027       MockRead("Content-Length: 42\r\n"),
12028       MockRead("Content-Type: text/html\r\n\r\n"),
12029       MockRead("You are not authorized to view this page\r\n"),
12030 
12031       // Lastly we get the desired content.
12032       MockRead("HTTP/1.1 101 Switching Protocols\r\n"
12033                "Upgrade: websocket\r\n"
12034                "Connection: Upgrade\r\n"
12035                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
12036   };
12037   SequencedSocketData data0(reads0, writes0);
12038   session_deps_.socket_factory->AddSocketDataProvider(&data0);
12039   SSLSocketDataProvider ssl0(ASYNC, OK);
12040   ssl0.next_proto = kProtoHTTP2;
12041   ssl0.next_protos_expected_in_ssl_config =
12042       NextProtoVector{kProtoHTTP2, kProtoHTTP11};
12043   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
12044 
12045   StaticSocketDataProvider data1(reads1, writes1);
12046   session_deps_.socket_factory->AddSocketDataProvider(&data1);
12047   SSLSocketDataProvider ssl1(ASYNC, OK);
12048   // When creating the second connection, only HTTP/1.1 should be allowed.
12049   ssl1.next_protos_expected_in_ssl_config = NextProtoVector{kProtoHTTP11};
12050   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12051 
12052   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12053 
12054   HttpRequestInfo initial_request_info;
12055   initial_request_info.method = "GET";
12056   initial_request_info.url = kInitialUrl;
12057   initial_request_info.traffic_annotation =
12058       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12059   HttpNetworkTransaction initial_trans(DEFAULT_PRIORITY, session.get());
12060   TestCompletionCallback initial_callback;
12061   int rv = initial_trans.Start(&initial_request_info,
12062                                initial_callback.callback(), NetLogWithSource());
12063   EXPECT_THAT(initial_callback.GetResult(rv), IsOk());
12064 
12065   EXPECT_FALSE(session->http_server_properties()->RequiresHTTP11(
12066       url::SchemeHostPort(kInitialUrl), NetworkAnonymizationKey()));
12067 
12068   HttpRequestInfo websocket_request_info;
12069   websocket_request_info.method = "GET";
12070   websocket_request_info.url = kWebSocketUrl;
12071   websocket_request_info.traffic_annotation =
12072       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12073   EXPECT_TRUE(HostPortPair::FromURL(initial_request_info.url)
12074                   .Equals(HostPortPair::FromURL(websocket_request_info.url)));
12075   websocket_request_info.extra_headers.SetHeader("Origin", "http://server");
12076   websocket_request_info.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
12077   // The following two headers must be removed by WebSocketHttp2HandshakeStream.
12078   websocket_request_info.extra_headers.SetHeader("Connection", "Upgrade");
12079   websocket_request_info.extra_headers.SetHeader("Upgrade", "websocket");
12080 
12081   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
12082 
12083   HttpNetworkTransaction websocket_trans(MEDIUM, session.get());
12084   websocket_trans.SetWebSocketHandshakeStreamCreateHelper(
12085       &websocket_stream_create_helper);
12086 
12087   TestCompletionCallback websocket_callback;
12088   rv = websocket_trans.Start(&websocket_request_info,
12089                              websocket_callback.callback(), NetLogWithSource());
12090   EXPECT_THAT(websocket_callback.GetResult(rv), IsOk());
12091 
12092   EXPECT_FALSE(websocket_trans.IsReadyToRestartForAuth());
12093 
12094   const HttpResponseInfo* response = websocket_trans.GetResponseInfo();
12095   ASSERT_TRUE(response);
12096   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
12097 
12098   rv = websocket_trans.RestartWithAuth(
12099       AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
12100       websocket_callback.callback());
12101   EXPECT_THAT(websocket_callback.GetResult(rv), IsOk());
12102 
12103   EXPECT_TRUE(websocket_trans.IsReadyToRestartForAuth());
12104 
12105   response = websocket_trans.GetResponseInfo();
12106   ASSERT_TRUE(response);
12107   EXPECT_FALSE(response->auth_challenge.has_value());
12108 
12109   rv = websocket_trans.RestartWithAuth(AuthCredentials(),
12110                                        websocket_callback.callback());
12111   EXPECT_THAT(websocket_callback.GetResult(rv), IsOk());
12112 
12113   // The server should have been marked as requiring HTTP/1.1. The important
12114   // part here is that the scheme that requires HTTP/1.1 should be HTTPS, not
12115   // WSS.
12116   EXPECT_TRUE(session->http_server_properties()->RequiresHTTP11(
12117       url::SchemeHostPort(kInitialUrl), NetworkAnonymizationKey()));
12118 }
12119 
12120 #endif  // BUILDFLAG(ENABLE_WEBSOCKETS)
12121 
12122 // Test that, if we have an NTLM proxy and the origin resets the connection, we
12123 // do no retry forever as a result of TLS retries. This is a regression test for
12124 // https://crbug.com/823387. The version interference probe has since been
12125 // removed, but we now have a legacy crypto fallback. (If that fallback is
12126 // removed, this test should be kept but with the expectations tweaked, in case
12127 // future fallbacks are added.)
TEST_P(HttpNetworkTransactionTest,NTLMProxyTLSHandshakeReset)12128 TEST_P(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
12129   // The NTLM test data expects the proxy to be named 'server'. The origin is
12130   // https://origin/.
12131   session_deps_.proxy_resolution_service =
12132       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
12133           "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
12134 
12135   SSLContextConfig config;
12136   session_deps_.ssl_config_service =
12137       std::make_unique<TestSSLConfigService>(config);
12138 
12139   HttpRequestInfo request;
12140   request.method = "GET";
12141   request.url = GURL("https://origin/");
12142   request.traffic_annotation =
12143       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12144 
12145   // Ensure load is not disrupted by flags which suppress behaviour specific
12146   // to other auth schemes.
12147   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
12148 
12149   HttpAuthNtlmMechanism::ScopedProcSetter proc_setter(
12150       MockGetMSTime, MockGenerateRandom, MockGetHostName);
12151   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12152 
12153   // Generate the NTLM messages based on known test data.
12154   std::string negotiate_msg = base::Base64Encode(std::string_view(
12155       reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
12156       std::size(ntlm::test::kExpectedNegotiateMsg)));
12157   std::string challenge_msg = base::Base64Encode(std::string_view(
12158       reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
12159       std::size(ntlm::test::kChallengeMsgFromSpecV2)));
12160   std::string authenticate_msg = base::Base64Encode(std::string_view(
12161       reinterpret_cast<const char*>(
12162           ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
12163       std::size(ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)));
12164 
12165   MockWrite data_writes[] = {
12166       // The initial CONNECT request.
12167       MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
12168                 "Host: origin:443\r\n"
12169                 "Proxy-Connection: keep-alive\r\n\r\n"),
12170 
12171       // After restarting with an identity.
12172       MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
12173                 "Host: origin:443\r\n"
12174                 "Proxy-Connection: keep-alive\r\n"
12175                 "Proxy-Authorization: NTLM "),
12176       MockWrite(negotiate_msg.c_str()),
12177       // End headers.
12178       MockWrite("\r\n\r\n"),
12179 
12180       // The second restart.
12181       MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
12182                 "Host: origin:443\r\n"
12183                 "Proxy-Connection: keep-alive\r\n"
12184                 "Proxy-Authorization: NTLM "),
12185       MockWrite(authenticate_msg.c_str()),
12186       // End headers.
12187       MockWrite("\r\n\r\n"),
12188   };
12189 
12190   MockRead data_reads[] = {
12191       // The initial NTLM response.
12192       MockRead("HTTP/1.1 407 Access Denied\r\n"
12193                "Content-Length: 0\r\n"
12194                "Proxy-Authenticate: NTLM\r\n\r\n"),
12195 
12196       // The NTLM challenge message.
12197       MockRead("HTTP/1.1 407 Access Denied\r\n"
12198                "Content-Length: 0\r\n"
12199                "Proxy-Authenticate: NTLM "),
12200       MockRead(challenge_msg.c_str()),
12201       // End headers.
12202       MockRead("\r\n\r\n"),
12203 
12204       // Finally the tunnel is established.
12205       MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
12206   };
12207 
12208   StaticSocketDataProvider data(data_reads, data_writes);
12209   SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
12210   session_deps_.socket_factory->AddSocketDataProvider(&data);
12211   session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
12212 
12213   StaticSocketDataProvider data2(data_reads, data_writes);
12214   SSLSocketDataProvider data2_ssl(ASYNC, ERR_CONNECTION_RESET);
12215   session_deps_.socket_factory->AddSocketDataProvider(&data2);
12216   session_deps_.socket_factory->AddSSLSocketDataProvider(&data2_ssl);
12217 
12218   // Start the transaction. The proxy responds with an NTLM authentication
12219   // request.
12220   TestCompletionCallback callback;
12221   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12222   int rv = callback.GetResult(
12223       trans.Start(&request, callback.callback(), NetLogWithSource()));
12224 
12225   EXPECT_THAT(rv, IsOk());
12226   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
12227   const HttpResponseInfo* response = trans.GetResponseInfo();
12228   ASSERT_TRUE(response);
12229   EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge));
12230 
12231   // Configure credentials and restart. The proxy responds with the challenge
12232   // message.
12233   rv = callback.GetResult(trans.RestartWithAuth(
12234       AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
12235       callback.callback()));
12236   EXPECT_THAT(rv, IsOk());
12237   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
12238   response = trans.GetResponseInfo();
12239   ASSERT_TRUE(response);
12240   EXPECT_FALSE(response->auth_challenge.has_value());
12241 
12242   // Restart once more. The tunnel will be established and the the SSL handshake
12243   // will reset. The fallback will then kick in and restart the process. The
12244   // proxy responds with another NTLM authentiation request, but we don't need
12245   // to provide credentials as the cached ones work.
12246   rv = callback.GetResult(
12247       trans.RestartWithAuth(AuthCredentials(), callback.callback()));
12248   EXPECT_THAT(rv, IsOk());
12249   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
12250   response = trans.GetResponseInfo();
12251   ASSERT_TRUE(response);
12252   EXPECT_FALSE(response->auth_challenge.has_value());
12253 
12254   // The proxy responds with the NTLM challenge message.
12255   rv = callback.GetResult(
12256       trans.RestartWithAuth(AuthCredentials(), callback.callback()));
12257   EXPECT_THAT(rv, IsOk());
12258   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
12259   response = trans.GetResponseInfo();
12260   ASSERT_TRUE(response);
12261   EXPECT_FALSE(response->auth_challenge.has_value());
12262 
12263   // Send the NTLM authenticate message. The tunnel is established and the
12264   // handshake resets again. We should not retry again.
12265   rv = callback.GetResult(
12266       trans.RestartWithAuth(AuthCredentials(), callback.callback()));
12267   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
12268 }
12269 
12270 #endif  // NTLM_PORTABLE
12271 
12272 // Test reading a server response which has only headers, and no body.
12273 // After some maximum number of bytes is consumed, the transaction should
12274 // fail with ERR_RESPONSE_HEADERS_TOO_BIG.
TEST_P(HttpNetworkTransactionTest,LargeHeadersNoBody)12275 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
12276   HttpRequestInfo request;
12277   request.method = "GET";
12278   request.url = GURL("http://www.example.org/");
12279   request.traffic_annotation =
12280       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12281 
12282   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12283   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12284 
12285   // Respond with 300 kb of headers (we should fail after 256 kb).
12286   std::string large_headers_string;
12287   FillLargeHeadersString(&large_headers_string, 300 * 1024);
12288 
12289   MockRead data_reads[] = {
12290       MockRead("HTTP/1.0 200 OK\r\n"),
12291       MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
12292       MockRead("\r\nBODY"),
12293       MockRead(SYNCHRONOUS, OK),
12294   };
12295   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
12296   session_deps_.socket_factory->AddSocketDataProvider(&data);
12297 
12298   TestCompletionCallback callback;
12299 
12300   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12301   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12302 
12303   rv = callback.WaitForResult();
12304   EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
12305 }
12306 
12307 // Make sure that we don't try to reuse a TCPClientSocket when failing to
12308 // establish tunnel.
12309 // http://code.google.com/p/chromium/issues/detail?id=3772
TEST_P(HttpNetworkTransactionTest,DontRecycleTransportSocketForSSLTunnel)12310 TEST_P(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
12311   HttpRequestInfo request;
12312   request.method = "GET";
12313   request.url = GURL("https://www.example.org/");
12314   request.traffic_annotation =
12315       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12316 
12317   // Configure against proxy server "myproxy:70".
12318   session_deps_.proxy_resolution_service =
12319       ConfiguredProxyResolutionService::CreateFixedForTest(
12320           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
12321 
12322   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12323 
12324   auto trans =
12325       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
12326 
12327   // Since we have proxy, should try to establish tunnel.
12328   MockWrite data_writes1[] = {
12329       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12330                 "Host: www.example.org:443\r\n"
12331                 "Proxy-Connection: keep-alive\r\n\r\n"),
12332   };
12333 
12334   // The proxy responds to the connect with a 404, using a persistent
12335   // connection. Usually a proxy would return 501 (not implemented),
12336   // or 200 (tunnel established).
12337   MockRead data_reads1[] = {
12338       MockRead("HTTP/1.1 404 Not Found\r\n"),
12339       MockRead("Content-Length: 10\r\n\r\n"),
12340       MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
12341   };
12342 
12343   StaticSocketDataProvider data1(data_reads1, data_writes1);
12344   session_deps_.socket_factory->AddSocketDataProvider(&data1);
12345 
12346   TestCompletionCallback callback1;
12347 
12348   int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
12349   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12350 
12351   rv = callback1.WaitForResult();
12352   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
12353 
12354   // Empty the current queue.  This is necessary because idle sockets are
12355   // added to the connection pool asynchronously with a PostTask.
12356   base::RunLoop().RunUntilIdle();
12357 
12358   // We now check to make sure the TCPClientSocket was not added back to
12359   // the pool.
12360   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12361   trans.reset();
12362   base::RunLoop().RunUntilIdle();
12363   // Make sure that the socket didn't get recycled after calling the destructor.
12364   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12365 }
12366 
12367 // Make sure that we recycle a socket after reading all of the response body.
TEST_P(HttpNetworkTransactionTest,RecycleSocket)12368 TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
12369   HttpRequestInfo request;
12370   request.method = "GET";
12371   request.url = GURL("http://www.example.org/");
12372   request.traffic_annotation =
12373       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12374 
12375   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12376 
12377   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12378 
12379   MockRead data_reads[] = {
12380       // A part of the response body is received with the response headers.
12381       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
12382       // The rest of the response body is received in two parts.
12383       MockRead("lo"),
12384       MockRead(" world"),
12385       MockRead("junk"),  // Should not be read!!
12386       MockRead(SYNCHRONOUS, OK),
12387   };
12388 
12389   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
12390   session_deps_.socket_factory->AddSocketDataProvider(&data);
12391 
12392   TestCompletionCallback callback;
12393 
12394   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12395   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12396 
12397   rv = callback.WaitForResult();
12398   EXPECT_THAT(rv, IsOk());
12399 
12400   const HttpResponseInfo* response = trans.GetResponseInfo();
12401   ASSERT_TRUE(response);
12402 
12403   EXPECT_TRUE(response->headers);
12404   std::string status_line = response->headers->GetStatusLine();
12405   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
12406 
12407   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12408 
12409   std::string response_data;
12410   rv = ReadTransaction(&trans, &response_data);
12411   EXPECT_THAT(rv, IsOk());
12412   EXPECT_EQ("hello world", response_data);
12413 
12414   // Empty the current queue.  This is necessary because idle sockets are
12415   // added to the connection pool asynchronously with a PostTask.
12416   base::RunLoop().RunUntilIdle();
12417 
12418   // We now check to make sure the socket was added back to the pool.
12419   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12420 }
12421 
12422 // Make sure that we recycle a SSL socket after reading all of the response
12423 // body.
TEST_P(HttpNetworkTransactionTest,RecycleSSLSocket)12424 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
12425   HttpRequestInfo request;
12426   request.method = "GET";
12427   request.url = GURL("https://www.example.org/");
12428   request.traffic_annotation =
12429       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12430 
12431   MockWrite data_writes[] = {
12432       MockWrite("GET / HTTP/1.1\r\n"
12433                 "Host: www.example.org\r\n"
12434                 "Connection: keep-alive\r\n\r\n"),
12435   };
12436 
12437   MockRead data_reads[] = {
12438       MockRead("HTTP/1.1 200 OK\r\n"),
12439       MockRead("Content-Length: 11\r\n\r\n"),
12440       MockRead("hello world"),
12441       MockRead(SYNCHRONOUS, OK),
12442   };
12443 
12444   SSLSocketDataProvider ssl(ASYNC, OK);
12445   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12446 
12447   StaticSocketDataProvider data(data_reads, data_writes);
12448   session_deps_.socket_factory->AddSocketDataProvider(&data);
12449 
12450   TestCompletionCallback callback;
12451 
12452   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12453   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12454 
12455   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12456 
12457   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12458   EXPECT_THAT(callback.WaitForResult(), IsOk());
12459 
12460   const HttpResponseInfo* response = trans.GetResponseInfo();
12461   ASSERT_TRUE(response);
12462   ASSERT_TRUE(response->headers);
12463   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12464 
12465   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12466 
12467   std::string response_data;
12468   rv = ReadTransaction(&trans, &response_data);
12469   EXPECT_THAT(rv, IsOk());
12470   EXPECT_EQ("hello world", response_data);
12471 
12472   // Empty the current queue.  This is necessary because idle sockets are
12473   // added to the connection pool asynchronously with a PostTask.
12474   base::RunLoop().RunUntilIdle();
12475 
12476   // We now check to make sure the socket was added back to the pool.
12477   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12478 }
12479 
12480 // Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
12481 // from the pool and make sure that we recover okay.
TEST_P(HttpNetworkTransactionTest,RecycleDeadSSLSocket)12482 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
12483   HttpRequestInfo request;
12484   request.method = "GET";
12485   request.url = GURL("https://www.example.org/");
12486   request.traffic_annotation =
12487       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12488 
12489   MockWrite data_writes[] = {
12490       MockWrite("GET / HTTP/1.1\r\n"
12491                 "Host: www.example.org\r\n"
12492                 "Connection: keep-alive\r\n\r\n"),
12493       MockWrite("GET / HTTP/1.1\r\n"
12494                 "Host: www.example.org\r\n"
12495                 "Connection: keep-alive\r\n\r\n"),
12496   };
12497 
12498   MockRead data_reads[] = {
12499       MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
12500       MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
12501 
12502   SSLSocketDataProvider ssl(ASYNC, OK);
12503   SSLSocketDataProvider ssl2(ASYNC, OK);
12504   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12505   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12506 
12507   StaticSocketDataProvider data(data_reads, data_writes);
12508   StaticSocketDataProvider data2(data_reads, data_writes);
12509   session_deps_.socket_factory->AddSocketDataProvider(&data);
12510   session_deps_.socket_factory->AddSocketDataProvider(&data2);
12511 
12512   TestCompletionCallback callback;
12513 
12514   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12515   auto trans =
12516       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
12517 
12518   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12519 
12520   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12521   EXPECT_THAT(callback.WaitForResult(), IsOk());
12522 
12523   const HttpResponseInfo* response = trans->GetResponseInfo();
12524   ASSERT_TRUE(response);
12525   ASSERT_TRUE(response->headers);
12526   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12527 
12528   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12529 
12530   std::string response_data;
12531   rv = ReadTransaction(trans.get(), &response_data);
12532   EXPECT_THAT(rv, IsOk());
12533   EXPECT_EQ("hello world", response_data);
12534 
12535   // Empty the current queue.  This is necessary because idle sockets are
12536   // added to the connection pool asynchronously with a PostTask.
12537   base::RunLoop().RunUntilIdle();
12538 
12539   // We now check to make sure the socket was added back to the pool.
12540   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12541 
12542   // Now start the second transaction, which should reuse the previous socket.
12543 
12544   trans =
12545       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
12546 
12547   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12548 
12549   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12550   EXPECT_THAT(callback.WaitForResult(), IsOk());
12551 
12552   response = trans->GetResponseInfo();
12553   ASSERT_TRUE(response);
12554   ASSERT_TRUE(response->headers);
12555   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12556 
12557   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12558 
12559   rv = ReadTransaction(trans.get(), &response_data);
12560   EXPECT_THAT(rv, IsOk());
12561   EXPECT_EQ("hello world", response_data);
12562 
12563   // Empty the current queue.  This is necessary because idle sockets are
12564   // added to the connection pool asynchronously with a PostTask.
12565   base::RunLoop().RunUntilIdle();
12566 
12567   // We now check to make sure the socket was added back to the pool.
12568   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12569 }
12570 
TEST_P(HttpNetworkTransactionTest,CloseConnectionOnDestruction)12571 TEST_P(HttpNetworkTransactionTest, CloseConnectionOnDestruction) {
12572   enum class TestCase {
12573     kReadHeaders,
12574     kReadPartOfBodyRead,
12575     kReadAllOfBody,
12576   };
12577 
12578   for (auto test_case : {TestCase::kReadHeaders, TestCase::kReadPartOfBodyRead,
12579                          TestCase::kReadAllOfBody}) {
12580     SCOPED_TRACE(testing::Message()
12581                  << "Test case: " << static_cast<int>(test_case));
12582     for (bool close_connection : {false, true}) {
12583       if (test_case != TestCase::kReadAllOfBody || close_connection == false) {
12584         continue;
12585       }
12586       SCOPED_TRACE(testing::Message()
12587                    << "Close connection: " << close_connection);
12588 
12589       HttpRequestInfo request;
12590       request.method = "GET";
12591       request.url = GURL("http://foo.test/");
12592       request.traffic_annotation =
12593           net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12594 
12595       std::unique_ptr<HttpNetworkSession> session(
12596           CreateSession(&session_deps_));
12597 
12598       std::unique_ptr<HttpNetworkTransaction> trans =
12599           std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
12600                                                    session.get());
12601 
12602       MockRead data_reads[] = {
12603           // A part of the response body is received with the response headers.
12604           MockRead("HTTP/1.1 200 OK\r\n"
12605                    "Content-Length: 11\r\n\r\n"
12606                    "hello world"),
12607           MockRead(SYNCHRONOUS, OK),
12608       };
12609 
12610       StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
12611       session_deps_.socket_factory->AddSocketDataProvider(&data);
12612 
12613       TestCompletionCallback callback;
12614 
12615       int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12616       EXPECT_THAT(callback.GetResult(rv), IsOk());
12617 
12618       const HttpResponseInfo* response = trans->GetResponseInfo();
12619       ASSERT_TRUE(response);
12620 
12621       EXPECT_TRUE(response->headers);
12622       std::string status_line = response->headers->GetStatusLine();
12623       EXPECT_EQ("HTTP/1.1 200 OK", status_line);
12624 
12625       EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12626 
12627       std::string response_data;
12628       switch (test_case) {
12629         case TestCase::kReadHeaders: {
12630           // Already read the headers, nothing else to do.
12631           break;
12632         }
12633 
12634         case TestCase::kReadPartOfBodyRead: {
12635           auto buf = base::MakeRefCounted<IOBufferWithSize>(5);
12636           rv = trans->Read(buf.get(), 5, callback.callback());
12637           ASSERT_EQ(5, callback.GetResult(rv));
12638           response_data.assign(buf->data(), 5);
12639           EXPECT_EQ("hello", response_data);
12640           break;
12641         }
12642 
12643         case TestCase::kReadAllOfBody: {
12644           rv = ReadTransaction(trans.get(), &response_data);
12645           EXPECT_THAT(rv, IsOk());
12646           EXPECT_EQ("hello world", response_data);
12647           break;
12648         }
12649       }
12650 
12651       if (close_connection) {
12652         trans->CloseConnectionOnDestruction();
12653       }
12654       trans.reset();
12655 
12656       // Wait for the socket to be drained and added to the socket pool or
12657       // destroyed.
12658       base::RunLoop().RunUntilIdle();
12659 
12660       // In the case all the body was read, the socket will have been released
12661       // before the CloseConnectionOnDestruction() call, so will not be
12662       // destroyed.
12663       if (close_connection && test_case != TestCase::kReadAllOfBody) {
12664         EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12665       } else {
12666         EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12667       }
12668     }
12669   }
12670 }
12671 
12672 // Grab a socket, use it, and put it back into the pool. Then, make
12673 // low memory notification and ensure the socket pool is flushed.
TEST_P(HttpNetworkTransactionTest,FlushSocketPoolOnLowMemoryNotifications)12674 TEST_P(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
12675   HttpRequestInfo request;
12676   request.method = "GET";
12677   request.url = GURL("http://www.example.org/");
12678   request.load_flags = 0;
12679   request.traffic_annotation =
12680       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12681 
12682   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12683 
12684   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12685 
12686   MockRead data_reads[] = {
12687       // A part of the response body is received with the response headers.
12688       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
12689       // The rest of the response body is received in two parts.
12690       MockRead("lo"),
12691       MockRead(" world"),
12692       MockRead("junk"),  // Should not be read!!
12693       MockRead(SYNCHRONOUS, OK),
12694   };
12695 
12696   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
12697   session_deps_.socket_factory->AddSocketDataProvider(&data);
12698 
12699   TestCompletionCallback callback;
12700 
12701   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12702   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12703 
12704   EXPECT_THAT(callback.GetResult(rv), IsOk());
12705 
12706   const HttpResponseInfo* response = trans.GetResponseInfo();
12707   ASSERT_TRUE(response);
12708   EXPECT_TRUE(response->headers);
12709   std::string status_line = response->headers->GetStatusLine();
12710   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
12711 
12712   // Make memory critical notification and ensure the transaction still has been
12713   // operating right.
12714   base::MemoryPressureListener::NotifyMemoryPressure(
12715       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
12716   base::RunLoop().RunUntilIdle();
12717 
12718   // Socket should not be flushed as long as it is not idle.
12719   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12720 
12721   std::string response_data;
12722   rv = ReadTransaction(&trans, &response_data);
12723   EXPECT_THAT(rv, IsOk());
12724   EXPECT_EQ("hello world", response_data);
12725 
12726   // Empty the current queue.  This is necessary because idle sockets are
12727   // added to the connection pool asynchronously with a PostTask.
12728   base::RunLoop().RunUntilIdle();
12729 
12730   // We now check to make sure the socket was added back to the pool.
12731   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12732 
12733   // Idle sockets should be flushed now.
12734   base::MemoryPressureListener::NotifyMemoryPressure(
12735       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
12736   base::RunLoop().RunUntilIdle();
12737 
12738   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12739 }
12740 
12741 // Disable idle socket closing on memory pressure.
12742 // Grab a socket, use it, and put it back into the pool. Then, make
12743 // low memory notification and ensure the socket pool is NOT flushed.
TEST_P(HttpNetworkTransactionTest,NoFlushSocketPoolOnLowMemoryNotifications)12744 TEST_P(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
12745   HttpRequestInfo request;
12746   request.method = "GET";
12747   request.url = GURL("http://www.example.org/");
12748   request.load_flags = 0;
12749   request.traffic_annotation =
12750       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12751 
12752   // Disable idle socket closing on memory pressure.
12753   session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
12754   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12755 
12756   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12757 
12758   MockRead data_reads[] = {
12759       // A part of the response body is received with the response headers.
12760       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
12761       // The rest of the response body is received in two parts.
12762       MockRead("lo"),
12763       MockRead(" world"),
12764       MockRead("junk"),  // Should not be read!!
12765       MockRead(SYNCHRONOUS, OK),
12766   };
12767 
12768   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
12769   session_deps_.socket_factory->AddSocketDataProvider(&data);
12770 
12771   TestCompletionCallback callback;
12772 
12773   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12774   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12775 
12776   EXPECT_THAT(callback.GetResult(rv), IsOk());
12777 
12778   const HttpResponseInfo* response = trans.GetResponseInfo();
12779   ASSERT_TRUE(response);
12780   EXPECT_TRUE(response->headers);
12781   std::string status_line = response->headers->GetStatusLine();
12782   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
12783 
12784   // Make memory critical notification and ensure the transaction still has been
12785   // operating right.
12786   base::MemoryPressureListener::NotifyMemoryPressure(
12787       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
12788   base::RunLoop().RunUntilIdle();
12789 
12790   // Socket should not be flushed as long as it is not idle.
12791   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12792 
12793   std::string response_data;
12794   rv = ReadTransaction(&trans, &response_data);
12795   EXPECT_THAT(rv, IsOk());
12796   EXPECT_EQ("hello world", response_data);
12797 
12798   // Empty the current queue.  This is necessary because idle sockets are
12799   // added to the connection pool asynchronously with a PostTask.
12800   base::RunLoop().RunUntilIdle();
12801 
12802   // We now check to make sure the socket was added back to the pool.
12803   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12804 
12805   // Idle sockets should NOT be flushed on moderate memory pressure.
12806   base::MemoryPressureListener::NotifyMemoryPressure(
12807       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
12808   base::RunLoop().RunUntilIdle();
12809 
12810   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12811 
12812   // Idle sockets should NOT be flushed on critical memory pressure.
12813   base::MemoryPressureListener::NotifyMemoryPressure(
12814       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
12815   base::RunLoop().RunUntilIdle();
12816 
12817   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12818 }
12819 
12820 // Grab an SSL socket, use it, and put it back into the pool. Then, make
12821 // low memory notification and ensure the socket pool is flushed.
TEST_P(HttpNetworkTransactionTest,FlushSSLSocketPoolOnLowMemoryNotifications)12822 TEST_P(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
12823   HttpRequestInfo request;
12824   request.method = "GET";
12825   request.url = GURL("https://www.example.org/");
12826   request.load_flags = 0;
12827   request.traffic_annotation =
12828       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12829 
12830   MockWrite data_writes[] = {
12831       MockWrite("GET / HTTP/1.1\r\n"
12832                 "Host: www.example.org\r\n"
12833                 "Connection: keep-alive\r\n\r\n"),
12834   };
12835 
12836   MockRead data_reads[] = {
12837       MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
12838       MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
12839 
12840   SSLSocketDataProvider ssl(ASYNC, OK);
12841   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12842 
12843   StaticSocketDataProvider data(data_reads, data_writes);
12844   session_deps_.socket_factory->AddSocketDataProvider(&data);
12845 
12846   TestCompletionCallback callback;
12847 
12848   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12849   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12850 
12851   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12852   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12853 
12854   EXPECT_THAT(callback.GetResult(rv), IsOk());
12855 
12856   const HttpResponseInfo* response = trans.GetResponseInfo();
12857   ASSERT_TRUE(response);
12858   ASSERT_TRUE(response->headers);
12859   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12860 
12861   // Make memory critical notification and ensure the transaction still has been
12862   // operating right.
12863   base::MemoryPressureListener::NotifyMemoryPressure(
12864       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
12865   base::RunLoop().RunUntilIdle();
12866 
12867   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12868 
12869   std::string response_data;
12870   rv = ReadTransaction(&trans, &response_data);
12871   EXPECT_THAT(rv, IsOk());
12872   EXPECT_EQ("hello world", response_data);
12873 
12874   // Empty the current queue.  This is necessary because idle sockets are
12875   // added to the connection pool asynchronously with a PostTask.
12876   base::RunLoop().RunUntilIdle();
12877 
12878   // We now check to make sure the socket was added back to the pool.
12879   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12880 
12881   // Make memory notification once again and ensure idle socket is closed.
12882   base::MemoryPressureListener::NotifyMemoryPressure(
12883       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
12884   base::RunLoop().RunUntilIdle();
12885 
12886   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12887 }
12888 
12889 // Make sure that we recycle a socket after a zero-length response.
12890 // http://crbug.com/9880
TEST_P(HttpNetworkTransactionTest,RecycleSocketAfterZeroContentLength)12891 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
12892   HttpRequestInfo request;
12893   request.method = "GET";
12894   request.url = GURL(
12895       "http://www.example.org/csi?v=3&s=web&action=&"
12896       "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
12897       "e=17259,18167,19592,19773,19981,20133,20173,20233&"
12898       "rt=prt.2642,ol.2649,xjs.2951");
12899   request.traffic_annotation =
12900       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12901 
12902   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12903 
12904   MockRead data_reads[] = {
12905       MockRead("HTTP/1.1 204 No Content\r\n"
12906                "Content-Length: 0\r\n"
12907                "Content-Type: text/html\r\n\r\n"),
12908       MockRead("junk"),  // Should not be read!!
12909       MockRead(SYNCHRONOUS, OK),
12910   };
12911 
12912   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
12913   session_deps_.socket_factory->AddSocketDataProvider(&data);
12914 
12915   // Transaction must be created after the MockReads, so it's destroyed before
12916   // them.
12917   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12918 
12919   TestCompletionCallback callback;
12920 
12921   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12922   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12923 
12924   rv = callback.WaitForResult();
12925   EXPECT_THAT(rv, IsOk());
12926 
12927   const HttpResponseInfo* response = trans.GetResponseInfo();
12928   ASSERT_TRUE(response);
12929 
12930   EXPECT_TRUE(response->headers);
12931   std::string status_line = response->headers->GetStatusLine();
12932   EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
12933 
12934   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
12935 
12936   std::string response_data;
12937   rv = ReadTransaction(&trans, &response_data);
12938   EXPECT_THAT(rv, IsOk());
12939   EXPECT_EQ("", response_data);
12940 
12941   // Empty the current queue.  This is necessary because idle sockets are
12942   // added to the connection pool asynchronously with a PostTask.
12943   base::RunLoop().RunUntilIdle();
12944 
12945   // We now check to make sure the socket was added back to the pool.
12946   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12947 }
12948 
TEST_P(HttpNetworkTransactionTest,ResendRequestOnWriteBodyError)12949 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
12950   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
12951   element_readers.push_back(
12952       std::make_unique<UploadBytesElementReader>("foo", 3));
12953   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
12954 
12955   HttpRequestInfo request[2];
12956   // Transaction 1: a GET request that succeeds.  The socket is recycled
12957   // after use.
12958   request[0].method = "GET";
12959   request[0].url = GURL("http://www.google.com/");
12960   request[0].load_flags = 0;
12961   request[0].traffic_annotation =
12962       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12963   // Transaction 2: a POST request.  Reuses the socket kept alive from
12964   // transaction 1.  The first attempts fails when writing the POST data.
12965   // This causes the transaction to retry with a new socket.  The second
12966   // attempt succeeds.
12967   request[1].method = "POST";
12968   request[1].url = GURL("http://www.google.com/login.cgi");
12969   request[1].upload_data_stream = &upload_data_stream;
12970   request[1].load_flags = 0;
12971   request[1].traffic_annotation =
12972       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12973 
12974   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12975 
12976   // The first socket is used for transaction 1 and the first attempt of
12977   // transaction 2.
12978 
12979   // The response of transaction 1.
12980   MockRead data_reads1[] = {
12981       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
12982       MockRead("hello world"),
12983       MockRead(SYNCHRONOUS, OK),
12984   };
12985   // The mock write results of transaction 1 and the first attempt of
12986   // transaction 2.
12987   MockWrite data_writes1[] = {
12988       MockWrite(SYNCHRONOUS, 64),                      // GET
12989       MockWrite(SYNCHRONOUS, 93),                      // POST
12990       MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
12991   };
12992   StaticSocketDataProvider data1(data_reads1, data_writes1);
12993 
12994   // The second socket is used for the second attempt of transaction 2.
12995 
12996   // The response of transaction 2.
12997   MockRead data_reads2[] = {
12998       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
12999       MockRead("welcome"),
13000       MockRead(SYNCHRONOUS, OK),
13001   };
13002   // The mock write results of the second attempt of transaction 2.
13003   MockWrite data_writes2[] = {
13004       MockWrite(SYNCHRONOUS, 93),  // POST
13005       MockWrite(SYNCHRONOUS, 3),   // POST data
13006   };
13007   StaticSocketDataProvider data2(data_reads2, data_writes2);
13008 
13009   session_deps_.socket_factory->AddSocketDataProvider(&data1);
13010   session_deps_.socket_factory->AddSocketDataProvider(&data2);
13011 
13012   const char* const kExpectedResponseData[] = {"hello world", "welcome"};
13013 
13014   for (int i = 0; i < 2; ++i) {
13015     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13016 
13017     TestCompletionCallback callback;
13018 
13019     int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
13020     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13021 
13022     rv = callback.WaitForResult();
13023     EXPECT_THAT(rv, IsOk());
13024 
13025     const HttpResponseInfo* response = trans.GetResponseInfo();
13026     ASSERT_TRUE(response);
13027 
13028     EXPECT_TRUE(response->headers);
13029     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13030 
13031     std::string response_data;
13032     rv = ReadTransaction(&trans, &response_data);
13033     EXPECT_THAT(rv, IsOk());
13034     EXPECT_EQ(kExpectedResponseData[i], response_data);
13035   }
13036 }
13037 
13038 // Test the request-challenge-retry sequence for basic auth when there is
13039 // an identity in the URL. The request should be sent as normal, but when
13040 // it fails the identity from the URL is used to answer the challenge.
TEST_P(HttpNetworkTransactionTest,AuthIdentityInURL)13041 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
13042   HttpRequestInfo request;
13043   request.method = "GET";
13044   request.url = GURL("http://foo:b@[email protected]/");
13045   request.load_flags = LOAD_NORMAL;
13046   request.traffic_annotation =
13047       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13048 
13049   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13050   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13051 
13052   // The password contains an escaped character -- for this test to pass it
13053   // will need to be unescaped by HttpNetworkTransaction.
13054   EXPECT_EQ("b%40r", request.url.password());
13055 
13056   MockWrite data_writes1[] = {
13057       MockWrite("GET / HTTP/1.1\r\n"
13058                 "Host: www.example.org\r\n"
13059                 "Connection: keep-alive\r\n\r\n"),
13060   };
13061 
13062   MockRead data_reads1[] = {
13063       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
13064       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
13065       MockRead("Content-Length: 10\r\n\r\n"),
13066       MockRead(SYNCHRONOUS, ERR_FAILED),
13067   };
13068 
13069   // After the challenge above, the transaction will be restarted using the
13070   // identity from the url (foo, b@r) to answer the challenge.
13071   MockWrite data_writes2[] = {
13072       MockWrite("GET / HTTP/1.1\r\n"
13073                 "Host: www.example.org\r\n"
13074                 "Connection: keep-alive\r\n"
13075                 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
13076   };
13077 
13078   MockRead data_reads2[] = {
13079       MockRead("HTTP/1.0 200 OK\r\n"),
13080       MockRead("Content-Length: 100\r\n\r\n"),
13081       MockRead(SYNCHRONOUS, OK),
13082   };
13083 
13084   StaticSocketDataProvider data1(data_reads1, data_writes1);
13085   StaticSocketDataProvider data2(data_reads2, data_writes2);
13086   session_deps_.socket_factory->AddSocketDataProvider(&data1);
13087   session_deps_.socket_factory->AddSocketDataProvider(&data2);
13088 
13089   TestCompletionCallback callback1;
13090   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
13091   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13092   rv = callback1.WaitForResult();
13093   EXPECT_THAT(rv, IsOk());
13094   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
13095 
13096   TestCompletionCallback callback2;
13097   rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
13098   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13099   rv = callback2.WaitForResult();
13100   EXPECT_THAT(rv, IsOk());
13101   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
13102 
13103   const HttpResponseInfo* response = trans.GetResponseInfo();
13104   ASSERT_TRUE(response);
13105 
13106   // There is no challenge info, since the identity in URL worked.
13107   EXPECT_FALSE(response->auth_challenge.has_value());
13108 
13109   EXPECT_EQ(100, response->headers->GetContentLength());
13110 
13111   // Empty the current queue.
13112   base::RunLoop().RunUntilIdle();
13113 }
13114 
13115 // Test the request-challenge-retry sequence for basic auth when there is an
13116 // incorrect identity in the URL. The identity from the URL should be used only
13117 // once.
TEST_P(HttpNetworkTransactionTest,WrongAuthIdentityInURL)13118 TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
13119   HttpRequestInfo request;
13120   request.method = "GET";
13121   // Note: the URL has a username:password in it.  The password "baz" is
13122   // wrong (should be "bar").
13123   request.url = GURL("http://foo:[email protected]/");
13124 
13125   request.load_flags = LOAD_NORMAL;
13126   request.traffic_annotation =
13127       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13128 
13129   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13130   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13131 
13132   MockWrite data_writes1[] = {
13133       MockWrite("GET / HTTP/1.1\r\n"
13134                 "Host: www.example.org\r\n"
13135                 "Connection: keep-alive\r\n\r\n"),
13136   };
13137 
13138   MockRead data_reads1[] = {
13139       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
13140       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
13141       MockRead("Content-Length: 10\r\n\r\n"),
13142       MockRead(SYNCHRONOUS, ERR_FAILED),
13143   };
13144 
13145   // After the challenge above, the transaction will be restarted using the
13146   // identity from the url (foo, baz) to answer the challenge.
13147   MockWrite data_writes2[] = {
13148       MockWrite("GET / HTTP/1.1\r\n"
13149                 "Host: www.example.org\r\n"
13150                 "Connection: keep-alive\r\n"
13151                 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
13152   };
13153 
13154   MockRead data_reads2[] = {
13155       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
13156       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
13157       MockRead("Content-Length: 10\r\n\r\n"),
13158       MockRead(SYNCHRONOUS, ERR_FAILED),
13159   };
13160 
13161   // After the challenge above, the transaction will be restarted using the
13162   // identity supplied by the user (foo, bar) to answer the challenge.
13163   MockWrite data_writes3[] = {
13164       MockWrite("GET / HTTP/1.1\r\n"
13165                 "Host: www.example.org\r\n"
13166                 "Connection: keep-alive\r\n"
13167                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13168   };
13169 
13170   MockRead data_reads3[] = {
13171       MockRead("HTTP/1.0 200 OK\r\n"),
13172       MockRead("Content-Length: 100\r\n\r\n"),
13173       MockRead(SYNCHRONOUS, OK),
13174   };
13175 
13176   StaticSocketDataProvider data1(data_reads1, data_writes1);
13177   StaticSocketDataProvider data2(data_reads2, data_writes2);
13178   StaticSocketDataProvider data3(data_reads3, data_writes3);
13179   session_deps_.socket_factory->AddSocketDataProvider(&data1);
13180   session_deps_.socket_factory->AddSocketDataProvider(&data2);
13181   session_deps_.socket_factory->AddSocketDataProvider(&data3);
13182 
13183   TestCompletionCallback callback1;
13184 
13185   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
13186   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13187 
13188   rv = callback1.WaitForResult();
13189   EXPECT_THAT(rv, IsOk());
13190 
13191   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
13192   TestCompletionCallback callback2;
13193   rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
13194   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13195   rv = callback2.WaitForResult();
13196   EXPECT_THAT(rv, IsOk());
13197   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
13198 
13199   const HttpResponseInfo* response = trans.GetResponseInfo();
13200   ASSERT_TRUE(response);
13201   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
13202 
13203   TestCompletionCallback callback3;
13204   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
13205   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13206   rv = callback3.WaitForResult();
13207   EXPECT_THAT(rv, IsOk());
13208   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
13209 
13210   response = trans.GetResponseInfo();
13211   ASSERT_TRUE(response);
13212 
13213   // There is no challenge info, since the identity worked.
13214   EXPECT_FALSE(response->auth_challenge.has_value());
13215 
13216   EXPECT_EQ(100, response->headers->GetContentLength());
13217 
13218   // Empty the current queue.
13219   base::RunLoop().RunUntilIdle();
13220 }
13221 
13222 // Test the request-challenge-retry sequence for basic auth when there is a
13223 // correct identity in the URL, but its use is being suppressed. The identity
13224 // from the URL should never be used.
TEST_P(HttpNetworkTransactionTest,AuthIdentityInURLSuppressed)13225 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
13226   HttpRequestInfo request;
13227   request.method = "GET";
13228   request.url = GURL("http://foo:[email protected]/");
13229   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
13230   request.traffic_annotation =
13231       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13232 
13233   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13234   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13235 
13236   MockWrite data_writes1[] = {
13237       MockWrite("GET / HTTP/1.1\r\n"
13238                 "Host: www.example.org\r\n"
13239                 "Connection: keep-alive\r\n\r\n"),
13240   };
13241 
13242   MockRead data_reads1[] = {
13243       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
13244       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
13245       MockRead("Content-Length: 10\r\n\r\n"),
13246       MockRead(SYNCHRONOUS, ERR_FAILED),
13247   };
13248 
13249   // After the challenge above, the transaction will be restarted using the
13250   // identity supplied by the user, not the one in the URL, to answer the
13251   // challenge.
13252   MockWrite data_writes3[] = {
13253       MockWrite("GET / HTTP/1.1\r\n"
13254                 "Host: www.example.org\r\n"
13255                 "Connection: keep-alive\r\n"
13256                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13257   };
13258 
13259   MockRead data_reads3[] = {
13260       MockRead("HTTP/1.0 200 OK\r\n"),
13261       MockRead("Content-Length: 100\r\n\r\n"),
13262       MockRead(SYNCHRONOUS, OK),
13263   };
13264 
13265   StaticSocketDataProvider data1(data_reads1, data_writes1);
13266   StaticSocketDataProvider data3(data_reads3, data_writes3);
13267   session_deps_.socket_factory->AddSocketDataProvider(&data1);
13268   session_deps_.socket_factory->AddSocketDataProvider(&data3);
13269 
13270   TestCompletionCallback callback1;
13271   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
13272   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13273   rv = callback1.WaitForResult();
13274   EXPECT_THAT(rv, IsOk());
13275   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
13276 
13277   const HttpResponseInfo* response = trans.GetResponseInfo();
13278   ASSERT_TRUE(response);
13279   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
13280 
13281   TestCompletionCallback callback3;
13282   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
13283   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13284   rv = callback3.WaitForResult();
13285   EXPECT_THAT(rv, IsOk());
13286   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
13287 
13288   response = trans.GetResponseInfo();
13289   ASSERT_TRUE(response);
13290 
13291   // There is no challenge info, since the identity worked.
13292   EXPECT_FALSE(response->auth_challenge.has_value());
13293   EXPECT_EQ(100, response->headers->GetContentLength());
13294 
13295   // Empty the current queue.
13296   base::RunLoop().RunUntilIdle();
13297 }
13298 
13299 // Test that previously tried username/passwords for a realm get re-used.
TEST_P(HttpNetworkTransactionTest,BasicAuthCacheAndPreauth)13300 TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
13301   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13302 
13303   // Transaction 1: authenticate (foo, bar) on MyRealm1
13304   {
13305     HttpRequestInfo request;
13306     request.method = "GET";
13307     request.url = GURL("http://www.example.org/x/y/z");
13308     request.traffic_annotation =
13309         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13310 
13311     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13312 
13313     MockWrite data_writes1[] = {
13314         MockWrite("GET /x/y/z HTTP/1.1\r\n"
13315                   "Host: www.example.org\r\n"
13316                   "Connection: keep-alive\r\n\r\n"),
13317     };
13318 
13319     MockRead data_reads1[] = {
13320         MockRead("HTTP/1.0 401 Unauthorized\r\n"),
13321         MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
13322         MockRead("Content-Length: 10000\r\n\r\n"),
13323         MockRead(SYNCHRONOUS, ERR_FAILED),
13324     };
13325 
13326     // Resend with authorization (username=foo, password=bar)
13327     MockWrite data_writes2[] = {
13328         MockWrite("GET /x/y/z HTTP/1.1\r\n"
13329                   "Host: www.example.org\r\n"
13330                   "Connection: keep-alive\r\n"
13331                   "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13332     };
13333 
13334     // Sever accepts the authorization.
13335     MockRead data_reads2[] = {
13336         MockRead("HTTP/1.0 200 OK\r\n"),
13337         MockRead("Content-Length: 100\r\n\r\n"),
13338         MockRead(SYNCHRONOUS, OK),
13339     };
13340 
13341     StaticSocketDataProvider data1(data_reads1, data_writes1);
13342     StaticSocketDataProvider data2(data_reads2, data_writes2);
13343     session_deps_.socket_factory->AddSocketDataProvider(&data1);
13344     session_deps_.socket_factory->AddSocketDataProvider(&data2);
13345 
13346     TestCompletionCallback callback1;
13347 
13348     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
13349     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13350 
13351     rv = callback1.WaitForResult();
13352     EXPECT_THAT(rv, IsOk());
13353 
13354     const HttpResponseInfo* response = trans.GetResponseInfo();
13355     ASSERT_TRUE(response);
13356     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
13357 
13358     TestCompletionCallback callback2;
13359 
13360     rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
13361                                callback2.callback());
13362     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13363 
13364     rv = callback2.WaitForResult();
13365     EXPECT_THAT(rv, IsOk());
13366 
13367     response = trans.GetResponseInfo();
13368     ASSERT_TRUE(response);
13369     EXPECT_FALSE(response->auth_challenge.has_value());
13370     EXPECT_EQ(100, response->headers->GetContentLength());
13371   }
13372 
13373   // ------------------------------------------------------------------------
13374 
13375   // Transaction 2: authenticate (foo2, bar2) on MyRealm2
13376   {
13377     HttpRequestInfo request;
13378     request.method = "GET";
13379     // Note that Transaction 1 was at /x/y/z, so this is in the same
13380     // protection space as MyRealm1.
13381     request.url = GURL("http://www.example.org/x/y/a/b");
13382     request.traffic_annotation =
13383         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13384 
13385     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13386 
13387     MockWrite data_writes1[] = {
13388         MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
13389                   "Host: www.example.org\r\n"
13390                   "Connection: keep-alive\r\n"
13391                   // Send preemptive authorization for MyRealm1
13392                   "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13393     };
13394 
13395     // The server didn't like the preemptive authorization, and
13396     // challenges us for a different realm (MyRealm2).
13397     MockRead data_reads1[] = {
13398         MockRead("HTTP/1.0 401 Unauthorized\r\n"),
13399         MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
13400         MockRead("Content-Length: 10000\r\n\r\n"),
13401         MockRead(SYNCHRONOUS, ERR_FAILED),
13402     };
13403 
13404     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
13405     MockWrite data_writes2[] = {
13406         MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
13407                   "Host: www.example.org\r\n"
13408                   "Connection: keep-alive\r\n"
13409                   "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
13410     };
13411 
13412     // Sever accepts the authorization.
13413     MockRead data_reads2[] = {
13414         MockRead("HTTP/1.0 200 OK\r\n"),
13415         MockRead("Content-Length: 100\r\n\r\n"),
13416         MockRead(SYNCHRONOUS, OK),
13417     };
13418 
13419     StaticSocketDataProvider data1(data_reads1, data_writes1);
13420     StaticSocketDataProvider data2(data_reads2, data_writes2);
13421     session_deps_.socket_factory->AddSocketDataProvider(&data1);
13422     session_deps_.socket_factory->AddSocketDataProvider(&data2);
13423 
13424     TestCompletionCallback callback1;
13425 
13426     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
13427     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13428 
13429     rv = callback1.WaitForResult();
13430     EXPECT_THAT(rv, IsOk());
13431 
13432     const HttpResponseInfo* response = trans.GetResponseInfo();
13433     ASSERT_TRUE(response);
13434     ASSERT_TRUE(response->auth_challenge);
13435     EXPECT_FALSE(response->auth_challenge->is_proxy);
13436     EXPECT_EQ("http://www.example.org",
13437               response->auth_challenge->challenger.Serialize());
13438     EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
13439     EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
13440 
13441     TestCompletionCallback callback2;
13442 
13443     rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
13444                                callback2.callback());
13445     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13446 
13447     rv = callback2.WaitForResult();
13448     EXPECT_THAT(rv, IsOk());
13449 
13450     response = trans.GetResponseInfo();
13451     ASSERT_TRUE(response);
13452     EXPECT_FALSE(response->auth_challenge.has_value());
13453     EXPECT_EQ(100, response->headers->GetContentLength());
13454   }
13455 
13456   // ------------------------------------------------------------------------
13457 
13458   // Transaction 3: Resend a request in MyRealm's protection space --
13459   // succeed with preemptive authorization.
13460   {
13461     HttpRequestInfo request;
13462     request.method = "GET";
13463     request.url = GURL("http://www.example.org/x/y/z2");
13464     request.traffic_annotation =
13465         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13466 
13467     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13468 
13469     MockWrite data_writes1[] = {
13470         MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
13471                   "Host: www.example.org\r\n"
13472                   "Connection: keep-alive\r\n"
13473                   // The authorization for MyRealm1 gets sent preemptively
13474                   // (since the url is in the same protection space)
13475                   "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13476     };
13477 
13478     // Sever accepts the preemptive authorization
13479     MockRead data_reads1[] = {
13480         MockRead("HTTP/1.0 200 OK\r\n"),
13481         MockRead("Content-Length: 100\r\n\r\n"),
13482         MockRead(SYNCHRONOUS, OK),
13483     };
13484 
13485     StaticSocketDataProvider data1(data_reads1, data_writes1);
13486     session_deps_.socket_factory->AddSocketDataProvider(&data1);
13487 
13488     TestCompletionCallback callback1;
13489 
13490     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
13491     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13492 
13493     rv = callback1.WaitForResult();
13494     EXPECT_THAT(rv, IsOk());
13495 
13496     const HttpResponseInfo* response = trans.GetResponseInfo();
13497     ASSERT_TRUE(response);
13498 
13499     EXPECT_FALSE(response->auth_challenge.has_value());
13500     EXPECT_EQ(100, response->headers->GetContentLength());
13501   }
13502 
13503   // ------------------------------------------------------------------------
13504 
13505   // Transaction 4: request another URL in MyRealm (however the
13506   // url is not known to belong to the protection space, so no pre-auth).
13507   {
13508     HttpRequestInfo request;
13509     request.method = "GET";
13510     request.url = GURL("http://www.example.org/x/1");
13511     request.traffic_annotation =
13512         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13513 
13514     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13515 
13516     MockWrite data_writes1[] = {
13517         MockWrite("GET /x/1 HTTP/1.1\r\n"
13518                   "Host: www.example.org\r\n"
13519                   "Connection: keep-alive\r\n\r\n"),
13520     };
13521 
13522     MockRead data_reads1[] = {
13523         MockRead("HTTP/1.0 401 Unauthorized\r\n"),
13524         MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
13525         MockRead("Content-Length: 10000\r\n\r\n"),
13526         MockRead(SYNCHRONOUS, ERR_FAILED),
13527     };
13528 
13529     // Resend with authorization from MyRealm's cache.
13530     MockWrite data_writes2[] = {
13531         MockWrite("GET /x/1 HTTP/1.1\r\n"
13532                   "Host: www.example.org\r\n"
13533                   "Connection: keep-alive\r\n"
13534                   "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13535     };
13536 
13537     // Sever accepts the authorization.
13538     MockRead data_reads2[] = {
13539         MockRead("HTTP/1.0 200 OK\r\n"),
13540         MockRead("Content-Length: 100\r\n\r\n"),
13541         MockRead(SYNCHRONOUS, OK),
13542     };
13543 
13544     StaticSocketDataProvider data1(data_reads1, data_writes1);
13545     StaticSocketDataProvider data2(data_reads2, data_writes2);
13546     session_deps_.socket_factory->AddSocketDataProvider(&data1);
13547     session_deps_.socket_factory->AddSocketDataProvider(&data2);
13548 
13549     TestCompletionCallback callback1;
13550 
13551     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
13552     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13553 
13554     rv = callback1.WaitForResult();
13555     EXPECT_THAT(rv, IsOk());
13556 
13557     EXPECT_TRUE(trans.IsReadyToRestartForAuth());
13558     TestCompletionCallback callback2;
13559     rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
13560     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13561     rv = callback2.WaitForResult();
13562     EXPECT_THAT(rv, IsOk());
13563     EXPECT_FALSE(trans.IsReadyToRestartForAuth());
13564 
13565     const HttpResponseInfo* response = trans.GetResponseInfo();
13566     ASSERT_TRUE(response);
13567     EXPECT_FALSE(response->auth_challenge.has_value());
13568     EXPECT_EQ(100, response->headers->GetContentLength());
13569   }
13570 
13571   // ------------------------------------------------------------------------
13572 
13573   // Transaction 5: request a URL in MyRealm, but the server rejects the
13574   // cached identity. Should invalidate and re-prompt.
13575   {
13576     HttpRequestInfo request;
13577     request.method = "GET";
13578     request.url = GURL("http://www.example.org/p/q/t");
13579     request.traffic_annotation =
13580         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13581 
13582     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13583 
13584     MockWrite data_writes1[] = {
13585         MockWrite("GET /p/q/t HTTP/1.1\r\n"
13586                   "Host: www.example.org\r\n"
13587                   "Connection: keep-alive\r\n\r\n"),
13588     };
13589 
13590     MockRead data_reads1[] = {
13591         MockRead("HTTP/1.0 401 Unauthorized\r\n"),
13592         MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
13593         MockRead("Content-Length: 10000\r\n\r\n"),
13594         MockRead(SYNCHRONOUS, ERR_FAILED),
13595     };
13596 
13597     // Resend with authorization from cache for MyRealm.
13598     MockWrite data_writes2[] = {
13599         MockWrite("GET /p/q/t HTTP/1.1\r\n"
13600                   "Host: www.example.org\r\n"
13601                   "Connection: keep-alive\r\n"
13602                   "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13603     };
13604 
13605     // Sever rejects the authorization.
13606     MockRead data_reads2[] = {
13607         MockRead("HTTP/1.0 401 Unauthorized\r\n"),
13608         MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
13609         MockRead("Content-Length: 10000\r\n\r\n"),
13610         MockRead(SYNCHRONOUS, ERR_FAILED),
13611     };
13612 
13613     // At this point we should prompt for new credentials for MyRealm.
13614     // Restart with username=foo3, password=foo4.
13615     MockWrite data_writes3[] = {
13616         MockWrite("GET /p/q/t HTTP/1.1\r\n"
13617                   "Host: www.example.org\r\n"
13618                   "Connection: keep-alive\r\n"
13619                   "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
13620     };
13621 
13622     // Sever accepts the authorization.
13623     MockRead data_reads3[] = {
13624         MockRead("HTTP/1.0 200 OK\r\n"),
13625         MockRead("Content-Length: 100\r\n\r\n"),
13626         MockRead(SYNCHRONOUS, OK),
13627     };
13628 
13629     StaticSocketDataProvider data1(data_reads1, data_writes1);
13630     StaticSocketDataProvider data2(data_reads2, data_writes2);
13631     StaticSocketDataProvider data3(data_reads3, data_writes3);
13632     session_deps_.socket_factory->AddSocketDataProvider(&data1);
13633     session_deps_.socket_factory->AddSocketDataProvider(&data2);
13634     session_deps_.socket_factory->AddSocketDataProvider(&data3);
13635 
13636     TestCompletionCallback callback1;
13637 
13638     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
13639     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13640 
13641     rv = callback1.WaitForResult();
13642     EXPECT_THAT(rv, IsOk());
13643 
13644     EXPECT_TRUE(trans.IsReadyToRestartForAuth());
13645     TestCompletionCallback callback2;
13646     rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
13647     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13648     rv = callback2.WaitForResult();
13649     EXPECT_THAT(rv, IsOk());
13650     EXPECT_FALSE(trans.IsReadyToRestartForAuth());
13651 
13652     const HttpResponseInfo* response = trans.GetResponseInfo();
13653     ASSERT_TRUE(response);
13654     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
13655 
13656     TestCompletionCallback callback3;
13657 
13658     rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
13659                                callback3.callback());
13660     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13661 
13662     rv = callback3.WaitForResult();
13663     EXPECT_THAT(rv, IsOk());
13664 
13665     response = trans.GetResponseInfo();
13666     ASSERT_TRUE(response);
13667     EXPECT_FALSE(response->auth_challenge.has_value());
13668     EXPECT_EQ(100, response->headers->GetContentLength());
13669   }
13670 }
13671 
13672 // Tests that nonce count increments when multiple auth attempts
13673 // are started with the same nonce.
TEST_P(HttpNetworkTransactionTest,DigestPreAuthNonceCount)13674 TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
13675   auto digest_factory = std::make_unique<HttpAuthHandlerDigest::Factory>();
13676   auto nonce_generator =
13677       std::make_unique<HttpAuthHandlerDigest::FixedNonceGenerator>(
13678           "0123456789abcdef");
13679   digest_factory->set_nonce_generator(std::move(nonce_generator));
13680   session_deps_.http_auth_handler_factory = std::move(digest_factory);
13681   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13682 
13683   // Transaction 1: authenticate (foo, bar) on MyRealm1
13684   {
13685     HttpRequestInfo request;
13686     request.method = "GET";
13687     request.url = GURL("http://www.example.org/x/y/z");
13688     request.traffic_annotation =
13689         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13690 
13691     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13692 
13693     MockWrite data_writes1[] = {
13694         MockWrite("GET /x/y/z HTTP/1.1\r\n"
13695                   "Host: www.example.org\r\n"
13696                   "Connection: keep-alive\r\n\r\n"),
13697     };
13698 
13699     MockRead data_reads1[] = {
13700         MockRead("HTTP/1.0 401 Unauthorized\r\n"),
13701         MockRead(
13702             "WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
13703             "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
13704         MockRead(SYNCHRONOUS, OK),
13705     };
13706 
13707     // Resend with authorization (username=foo, password=bar)
13708     MockWrite data_writes2[] = {
13709         MockWrite(
13710             "GET /x/y/z HTTP/1.1\r\n"
13711             "Host: www.example.org\r\n"
13712             "Connection: keep-alive\r\n"
13713             "Authorization: Digest username=\"foo\", realm=\"digestive\", "
13714             "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
13715             "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
13716             "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
13717     };
13718 
13719     // Sever accepts the authorization.
13720     MockRead data_reads2[] = {
13721         MockRead("HTTP/1.0 200 OK\r\n"),
13722         MockRead(SYNCHRONOUS, OK),
13723     };
13724 
13725     StaticSocketDataProvider data1(data_reads1, data_writes1);
13726     StaticSocketDataProvider data2(data_reads2, data_writes2);
13727     session_deps_.socket_factory->AddSocketDataProvider(&data1);
13728     session_deps_.socket_factory->AddSocketDataProvider(&data2);
13729 
13730     TestCompletionCallback callback1;
13731 
13732     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
13733     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13734 
13735     rv = callback1.WaitForResult();
13736     EXPECT_THAT(rv, IsOk());
13737 
13738     const HttpResponseInfo* response = trans.GetResponseInfo();
13739     ASSERT_TRUE(response);
13740     EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge));
13741 
13742     TestCompletionCallback callback2;
13743 
13744     rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
13745                                callback2.callback());
13746     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13747 
13748     rv = callback2.WaitForResult();
13749     EXPECT_THAT(rv, IsOk());
13750 
13751     response = trans.GetResponseInfo();
13752     ASSERT_TRUE(response);
13753     EXPECT_FALSE(response->auth_challenge.has_value());
13754   }
13755 
13756   // ------------------------------------------------------------------------
13757 
13758   // Transaction 2: Request another resource in digestive's protection space.
13759   // This will preemptively add an Authorization header which should have an
13760   // "nc" value of 2 (as compared to 1 in the first use.
13761   {
13762     HttpRequestInfo request;
13763     request.method = "GET";
13764     // Note that Transaction 1 was at /x/y/z, so this is in the same
13765     // protection space as digest.
13766     request.url = GURL("http://www.example.org/x/y/a/b");
13767     request.traffic_annotation =
13768         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13769 
13770     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13771 
13772     MockWrite data_writes1[] = {
13773         MockWrite(
13774             "GET /x/y/a/b HTTP/1.1\r\n"
13775             "Host: www.example.org\r\n"
13776             "Connection: keep-alive\r\n"
13777             "Authorization: Digest username=\"foo\", realm=\"digestive\", "
13778             "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
13779             "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
13780             "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
13781     };
13782 
13783     // Sever accepts the authorization.
13784     MockRead data_reads1[] = {
13785         MockRead("HTTP/1.0 200 OK\r\n"),
13786         MockRead("Content-Length: 100\r\n\r\n"),
13787         MockRead(SYNCHRONOUS, OK),
13788     };
13789 
13790     StaticSocketDataProvider data1(data_reads1, data_writes1);
13791     session_deps_.socket_factory->AddSocketDataProvider(&data1);
13792 
13793     TestCompletionCallback callback1;
13794 
13795     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
13796     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13797 
13798     rv = callback1.WaitForResult();
13799     EXPECT_THAT(rv, IsOk());
13800 
13801     const HttpResponseInfo* response = trans.GetResponseInfo();
13802     ASSERT_TRUE(response);
13803     EXPECT_FALSE(response->auth_challenge.has_value());
13804   }
13805 }
13806 
13807 // Test the ResetStateForRestart() private method.
TEST_P(HttpNetworkTransactionTest,ResetStateForRestart)13808 TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
13809   // Create a transaction (the dependencies aren't important).
13810   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13811   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13812 
13813   // Setup some state (which we expect ResetStateForRestart() will clear).
13814   trans.read_buf_ = base::MakeRefCounted<IOBufferWithSize>(15);
13815   trans.read_buf_len_ = 15;
13816   trans.request_headers_.SetHeader("Authorization", "NTLM");
13817 
13818   // Setup state in response_
13819   HttpResponseInfo* response = &trans.response_;
13820   response->auth_challenge = std::nullopt;
13821   response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
13822   response->response_time = base::Time::Now();
13823   response->was_cached = true;  // (Wouldn't ever actually be true...)
13824 
13825   // Cause the above state to be reset.
13826   trans.ResetStateForRestart();
13827 
13828   // Verify that the state that needed to be reset, has been reset.
13829   EXPECT_FALSE(trans.read_buf_);
13830   EXPECT_EQ(0, trans.read_buf_len_);
13831   EXPECT_TRUE(trans.request_headers_.IsEmpty());
13832   EXPECT_FALSE(response->auth_challenge.has_value());
13833   EXPECT_FALSE(response->headers);
13834   EXPECT_FALSE(response->was_cached);
13835   EXPECT_EQ(0U, response->ssl_info.cert_status);
13836 }
13837 
13838 // Test HTTPS connections to a site with a bad certificate
TEST_P(HttpNetworkTransactionTest,HTTPSBadCertificate)13839 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
13840   HttpRequestInfo request;
13841   request.method = "GET";
13842   request.url = GURL("https://www.example.org/");
13843   request.traffic_annotation =
13844       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13845 
13846   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13847   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13848 
13849   MockWrite data_writes[] = {
13850       MockWrite("GET / HTTP/1.1\r\n"
13851                 "Host: www.example.org\r\n"
13852                 "Connection: keep-alive\r\n\r\n"),
13853   };
13854 
13855   MockRead data_reads[] = {
13856       MockRead("HTTP/1.0 200 OK\r\n"),
13857       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13858       MockRead("Content-Length: 100\r\n\r\n"),
13859       MockRead(SYNCHRONOUS, OK),
13860   };
13861 
13862   StaticSocketDataProvider ssl_bad_certificate;
13863   StaticSocketDataProvider data(data_reads, data_writes);
13864   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
13865   SSLSocketDataProvider ssl(ASYNC, OK);
13866 
13867   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
13868   session_deps_.socket_factory->AddSocketDataProvider(&data);
13869   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
13870   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13871 
13872   TestCompletionCallback callback;
13873 
13874   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
13875   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13876 
13877   rv = callback.WaitForResult();
13878   EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
13879 
13880   rv = trans.RestartIgnoringLastError(callback.callback());
13881   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13882 
13883   rv = callback.WaitForResult();
13884   EXPECT_THAT(rv, IsOk());
13885 
13886   const HttpResponseInfo* response = trans.GetResponseInfo();
13887 
13888   ASSERT_TRUE(response);
13889   EXPECT_EQ(100, response->headers->GetContentLength());
13890 }
13891 
13892 // Test HTTPS connections to a site with a bad certificate, going through a
13893 // proxy
TEST_P(HttpNetworkTransactionTest,HTTPSBadCertificateViaProxy)13894 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
13895   session_deps_.proxy_resolution_service =
13896       ConfiguredProxyResolutionService::CreateFixedForTest(
13897           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
13898 
13899   HttpRequestInfo request;
13900   request.method = "GET";
13901   request.url = GURL("https://www.example.org/");
13902   request.traffic_annotation =
13903       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13904 
13905   MockWrite proxy_writes[] = {
13906       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13907                 "Host: www.example.org:443\r\n"
13908                 "Proxy-Connection: keep-alive\r\n\r\n"),
13909   };
13910 
13911   MockRead proxy_reads[] = {MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
13912                             MockRead(SYNCHRONOUS, OK)};
13913 
13914   MockWrite data_writes[] = {
13915       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13916                 "Host: www.example.org:443\r\n"
13917                 "Proxy-Connection: keep-alive\r\n\r\n"),
13918       MockWrite("GET / HTTP/1.1\r\n"
13919                 "Host: www.example.org\r\n"
13920                 "Connection: keep-alive\r\n\r\n"),
13921   };
13922 
13923   MockRead data_reads[] = {
13924       MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
13925       MockRead("HTTP/1.0 200 OK\r\n"),
13926       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13927       MockRead("Content-Length: 100\r\n\r\n"),
13928       MockRead(SYNCHRONOUS, OK),
13929   };
13930 
13931   StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
13932   StaticSocketDataProvider data(data_reads, data_writes);
13933   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
13934   SSLSocketDataProvider ssl(ASYNC, OK);
13935 
13936   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
13937   session_deps_.socket_factory->AddSocketDataProvider(&data);
13938   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
13939   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13940 
13941   TestCompletionCallback callback;
13942 
13943   for (int i = 0; i < 2; i++) {
13944     session_deps_.socket_factory->ResetNextMockIndexes();
13945 
13946     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13947     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13948 
13949     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
13950     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13951 
13952     rv = callback.WaitForResult();
13953     EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
13954 
13955     rv = trans.RestartIgnoringLastError(callback.callback());
13956     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13957 
13958     rv = callback.WaitForResult();
13959     EXPECT_THAT(rv, IsOk());
13960 
13961     const HttpResponseInfo* response = trans.GetResponseInfo();
13962 
13963     ASSERT_TRUE(response);
13964     EXPECT_EQ(100, response->headers->GetContentLength());
13965   }
13966 }
13967 
13968 // Test HTTPS connections to a site, going through an HTTPS proxy
TEST_P(HttpNetworkTransactionTest,HTTPSViaHttpsProxy)13969 TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
13970   session_deps_.proxy_resolution_service =
13971       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
13972           "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
13973   session_deps_.net_log = net::NetLog::Get();
13974 
13975   HttpRequestInfo request;
13976   request.method = "GET";
13977   request.url = GURL("https://www.example.org/");
13978   request.traffic_annotation =
13979       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13980 
13981   MockWrite data_writes[] = {
13982       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13983                 "Host: www.example.org:443\r\n"
13984                 "Proxy-Connection: keep-alive\r\n\r\n"),
13985       MockWrite("GET / HTTP/1.1\r\n"
13986                 "Host: www.example.org\r\n"
13987                 "Connection: keep-alive\r\n\r\n"),
13988   };
13989 
13990   MockRead data_reads[] = {
13991       MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
13992       MockRead("HTTP/1.1 200 OK\r\n"),
13993       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13994       MockRead("Content-Length: 100\r\n\r\n"),
13995       MockRead(SYNCHRONOUS, OK),
13996   };
13997 
13998   StaticSocketDataProvider data(data_reads, data_writes);
13999   SSLSocketDataProvider proxy_ssl(ASYNC, OK);   // SSL to the proxy
14000   SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
14001 
14002   session_deps_.socket_factory->AddSocketDataProvider(&data);
14003   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
14004   session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
14005 
14006   TestCompletionCallback callback;
14007 
14008   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14009   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14010 
14011   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14012   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14013 
14014   rv = callback.WaitForResult();
14015   EXPECT_THAT(rv, IsOk());
14016   const HttpResponseInfo* response = trans.GetResponseInfo();
14017 
14018   ASSERT_TRUE(response);
14019 
14020   ASSERT_EQ(1u, response->proxy_chain.length());
14021   EXPECT_TRUE(response->proxy_chain.GetProxyServer(0).is_https());
14022   EXPECT_TRUE(response->headers->IsKeepAlive());
14023   EXPECT_EQ(200, response->headers->response_code());
14024   EXPECT_EQ(100, response->headers->GetContentLength());
14025   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14026 
14027   LoadTimingInfo load_timing_info;
14028   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
14029   TestLoadTimingNotReusedWithPac(load_timing_info,
14030                                  CONNECT_TIMING_HAS_SSL_TIMES);
14031 }
14032 
14033 // Test that an HTTPS Proxy cannot redirect a CONNECT request for main frames.
TEST_P(HttpNetworkTransactionTest,RedirectOfHttpsConnectViaHttpsProxy)14034 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
14035   session_deps_.proxy_resolution_service =
14036       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
14037           "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
14038   session_deps_.net_log = net::NetLog::Get();
14039 
14040   const base::TimeDelta kTimeIncrement = base::Seconds(4);
14041   session_deps_.host_resolver->set_ondemand_mode(true);
14042 
14043   HttpRequestInfo request;
14044   request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
14045   request.method = "GET";
14046   request.url = GURL("https://www.example.org/");
14047   request.traffic_annotation =
14048       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14049 
14050   MockWrite data_writes[] = {
14051       MockWrite(ASYNC, 0,
14052                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14053                 "Host: www.example.org:443\r\n"
14054                 "Proxy-Connection: keep-alive\r\n\r\n"),
14055   };
14056 
14057   MockRead data_reads[] = {
14058       // Pause on first read.
14059       MockRead(ASYNC, ERR_IO_PENDING, 1),
14060       MockRead(ASYNC, 2, "HTTP/1.1 302 Redirect\r\n"),
14061       MockRead(ASYNC, 3, "Location: http://login.example.com/\r\n"),
14062       MockRead(ASYNC, 4, "Content-Length: 0\r\n\r\n"),
14063   };
14064 
14065   SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
14066   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
14067 
14068   session_deps_.socket_factory->AddSocketDataProvider(&data);
14069   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
14070 
14071   TestCompletionCallback callback;
14072 
14073   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14074   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14075 
14076   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14077   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14078   EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
14079 
14080   // Host resolution takes |kTimeIncrement|.
14081   FastForwardBy(kTimeIncrement);
14082   // Resolving the current request with |ResolveNow| will cause the pending
14083   // request to instantly complete, and the async connect will start as well.
14084   session_deps_.host_resolver->ResolveOnlyRequestNow();
14085 
14086   // Connecting takes |kTimeIncrement|.
14087   FastForwardBy(kTimeIncrement);
14088   data.RunUntilPaused();
14089 
14090   // The server takes |kTimeIncrement| to respond.
14091   FastForwardBy(kTimeIncrement);
14092   data.Resume();
14093 
14094   rv = callback.WaitForResult();
14095   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
14096 }
14097 
14098 // Test that an HTTPS Proxy cannot redirect a CONNECT request for subresources.
TEST_P(HttpNetworkTransactionTest,RedirectOfHttpsConnectSubresourceViaHttpsProxy)14099 TEST_P(HttpNetworkTransactionTest,
14100        RedirectOfHttpsConnectSubresourceViaHttpsProxy) {
14101   base::HistogramTester histograms;
14102   session_deps_.proxy_resolution_service =
14103       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
14104           "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
14105   session_deps_.net_log = net::NetLog::Get();
14106 
14107   HttpRequestInfo request;
14108   request.method = "GET";
14109   request.url = GURL("https://www.example.org/");
14110   request.traffic_annotation =
14111       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14112 
14113   MockWrite data_writes[] = {
14114       MockWrite(ASYNC, 0,
14115                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14116                 "Host: www.example.org:443\r\n"
14117                 "Proxy-Connection: keep-alive\r\n\r\n"),
14118   };
14119 
14120   MockRead data_reads[] = {
14121       MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
14122       MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
14123       MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
14124   };
14125 
14126   SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
14127   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
14128 
14129   session_deps_.socket_factory->AddSocketDataProvider(&data);
14130   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
14131 
14132   TestCompletionCallback callback;
14133 
14134   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14135   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14136 
14137   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14138   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14139 
14140   rv = callback.WaitForResult();
14141   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
14142 }
14143 
14144 // Test that an HTTPS Proxy which was auto-detected cannot redirect a CONNECT
14145 // request for main frames.
TEST_P(HttpNetworkTransactionTest,RedirectOfHttpsConnectViaAutoDetectedHttpsProxy)14146 TEST_P(HttpNetworkTransactionTest,
14147        RedirectOfHttpsConnectViaAutoDetectedHttpsProxy) {
14148   base::HistogramTester histograms;
14149   session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::
14150       CreateFixedFromAutoDetectedPacResultForTest("HTTPS proxy:70",
14151                                                   TRAFFIC_ANNOTATION_FOR_TESTS);
14152   session_deps_.net_log = net::NetLog::Get();
14153 
14154   HttpRequestInfo request;
14155   request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
14156   request.method = "GET";
14157   request.url = GURL("https://www.example.org/");
14158   request.traffic_annotation =
14159       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14160 
14161   MockWrite data_writes[] = {
14162       MockWrite(ASYNC, 0,
14163                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14164                 "Host: www.example.org:443\r\n"
14165                 "Proxy-Connection: keep-alive\r\n\r\n"),
14166   };
14167 
14168   MockRead data_reads[] = {
14169       MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
14170       MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
14171       MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
14172   };
14173 
14174   SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
14175   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
14176 
14177   session_deps_.socket_factory->AddSocketDataProvider(&data);
14178   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
14179 
14180   TestCompletionCallback callback;
14181 
14182   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14183   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14184 
14185   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14186   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14187 
14188   rv = callback.WaitForResult();
14189   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
14190 }
14191 
14192 // Tests that an HTTPS (SPDY) Proxy's cannot redirect a CONNECT request for main
14193 // frames.
TEST_P(HttpNetworkTransactionTest,RedirectOfHttpsConnectViaSpdyProxy)14194 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
14195   base::HistogramTester histograms;
14196   session_deps_.proxy_resolution_service =
14197       ConfiguredProxyResolutionService::CreateFixedForTest(
14198           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
14199   session_deps_.net_log = net::NetLog::Get();
14200 
14201   const base::TimeDelta kTimeIncrement = base::Seconds(4);
14202   session_deps_.host_resolver->set_ondemand_mode(true);
14203 
14204   HttpRequestInfo request;
14205   request.method = "GET";
14206   request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
14207   request.url = GURL("https://www.example.org/");
14208   request.traffic_annotation =
14209       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14210 
14211   spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
14212       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
14213       HostPortPair("www.example.org", 443)));
14214   spdy::SpdySerializedFrame goaway(
14215       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
14216   MockWrite data_writes[] = {
14217       CreateMockWrite(conn, 0, SYNCHRONOUS),
14218       CreateMockWrite(goaway, 3, SYNCHRONOUS),
14219   };
14220 
14221   static const char* const kExtraHeaders[] = {
14222       "location",
14223       "http://login.example.com/",
14224   };
14225   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
14226       "302", kExtraHeaders, std::size(kExtraHeaders) / 2, 1));
14227   MockRead data_reads[] = {
14228       // Pause on first read.
14229       MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
14230       MockRead(ASYNC, 0, 4),  // EOF
14231   };
14232 
14233   SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
14234   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
14235   proxy_ssl.next_proto = kProtoHTTP2;
14236 
14237   session_deps_.socket_factory->AddSocketDataProvider(&data);
14238   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
14239 
14240   TestCompletionCallback callback;
14241 
14242   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14243   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14244 
14245   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14246   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14247   EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
14248 
14249   // Host resolution takes |kTimeIncrement|.
14250   FastForwardBy(kTimeIncrement);
14251   // Resolving the current request with |ResolveNow| will cause the pending
14252   // request to instantly complete, and the async connect will start as well.
14253   session_deps_.host_resolver->ResolveOnlyRequestNow();
14254 
14255   // Connecting takes |kTimeIncrement|.
14256   FastForwardBy(kTimeIncrement);
14257   data.RunUntilPaused();
14258 
14259   FastForwardBy(kTimeIncrement);
14260   data.Resume();
14261   rv = callback.WaitForResult();
14262   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
14263 }
14264 
14265 // Test that an HTTPS proxy's response to a CONNECT request is filtered.
TEST_P(HttpNetworkTransactionTest,ErrorResponseToHttpsConnectViaHttpsProxy)14266 TEST_P(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
14267   session_deps_.proxy_resolution_service =
14268       ConfiguredProxyResolutionService::CreateFixedForTest(
14269           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
14270 
14271   HttpRequestInfo request;
14272   request.method = "GET";
14273   request.url = GURL("https://www.example.org/");
14274   request.traffic_annotation =
14275       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14276 
14277   MockWrite data_writes[] = {
14278       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14279                 "Host: www.example.org:443\r\n"
14280                 "Proxy-Connection: keep-alive\r\n\r\n"),
14281   };
14282 
14283   MockRead data_reads[] = {
14284       MockRead("HTTP/1.1 404 Not Found\r\n"),
14285       MockRead("Content-Length: 23\r\n\r\n"),
14286       MockRead("The host does not exist"),
14287       MockRead(SYNCHRONOUS, OK),
14288   };
14289 
14290   StaticSocketDataProvider data(data_reads, data_writes);
14291   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
14292 
14293   session_deps_.socket_factory->AddSocketDataProvider(&data);
14294   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
14295 
14296   TestCompletionCallback callback;
14297 
14298   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14299   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14300 
14301   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14302   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14303 
14304   rv = callback.WaitForResult();
14305   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
14306 
14307   // TODO(juliatuttle): Anything else to check here?
14308 }
14309 
14310 // Test that a SPDY proxy's response to a CONNECT request is filtered.
TEST_P(HttpNetworkTransactionTest,ErrorResponseToHttpsConnectViaSpdyProxy)14311 TEST_P(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
14312   session_deps_.proxy_resolution_service =
14313       ConfiguredProxyResolutionService::CreateFixedForTest(
14314           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
14315 
14316   HttpRequestInfo request;
14317   request.method = "GET";
14318   request.url = GURL("https://www.example.org/");
14319   request.traffic_annotation =
14320       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14321 
14322   spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
14323       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
14324       HostPortPair("www.example.org", 443)));
14325   spdy::SpdySerializedFrame rst(
14326       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
14327   MockWrite data_writes[] = {
14328       CreateMockWrite(conn, 0),
14329       CreateMockWrite(rst, 3),
14330   };
14331 
14332   static const char* const kExtraHeaders[] = {
14333       "location",
14334       "http://login.example.com/",
14335   };
14336   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
14337       "404", kExtraHeaders, std::size(kExtraHeaders) / 2, 1));
14338   spdy::SpdySerializedFrame body(
14339       spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
14340   MockRead data_reads[] = {
14341       CreateMockRead(resp, 1), CreateMockRead(body, 2),
14342       MockRead(ASYNC, 0, 4),  // EOF
14343   };
14344 
14345   SequencedSocketData data(data_reads, data_writes);
14346   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
14347   proxy_ssl.next_proto = kProtoHTTP2;
14348 
14349   session_deps_.socket_factory->AddSocketDataProvider(&data);
14350   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
14351 
14352   TestCompletionCallback callback;
14353 
14354   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14355   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14356 
14357   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14358   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14359 
14360   rv = callback.WaitForResult();
14361   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
14362 
14363   // TODO(juliatuttle): Anything else to check here?
14364 }
14365 
14366 // Test the request-challenge-retry sequence for basic auth, through
14367 // a SPDY proxy over a single SPDY session.
TEST_P(HttpNetworkTransactionTest,BasicAuthSpdyProxy)14368 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
14369   HttpRequestInfo request;
14370   request.method = "GET";
14371   request.url = GURL("https://www.example.org/");
14372   // when the no authentication data flag is set.
14373   request.privacy_mode = PRIVACY_MODE_ENABLED;
14374   request.traffic_annotation =
14375       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14376 
14377   // Configure against https proxy server "myproxy:70".
14378   session_deps_.proxy_resolution_service =
14379       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
14380           "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
14381   RecordingNetLogObserver net_log_observer;
14382   session_deps_.net_log = NetLog::Get();
14383   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14384 
14385   // Since we have proxy, should try to establish tunnel.
14386   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
14387       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
14388       HostPortPair("www.example.org", 443)));
14389   spdy::SpdySerializedFrame rst(
14390       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
14391   spdy_util_.UpdateWithStreamDestruction(1);
14392 
14393   // After calling trans.RestartWithAuth(), this is the request we should
14394   // be issuing -- the final header line contains the credentials.
14395   const char* const kAuthCredentials[] = {
14396       "proxy-authorization",
14397       "Basic Zm9vOmJhcg==",
14398   };
14399   spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
14400       kAuthCredentials, std::size(kAuthCredentials) / 2, 3,
14401       HttpProxyConnectJob::kH2QuicTunnelPriority,
14402       HostPortPair("www.example.org", 443)));
14403   // fetch https://www.example.org/ via HTTP
14404   const char kGet[] =
14405       "GET / HTTP/1.1\r\n"
14406       "Host: www.example.org\r\n"
14407       "Connection: keep-alive\r\n\r\n";
14408   spdy::SpdySerializedFrame wrapped_get(
14409       spdy_util_.ConstructSpdyDataFrame(3, kGet, false));
14410 
14411   MockWrite spdy_writes[] = {
14412       CreateMockWrite(req, 0, ASYNC),
14413       CreateMockWrite(rst, 2, ASYNC),
14414       CreateMockWrite(connect2, 3),
14415       CreateMockWrite(wrapped_get, 5),
14416   };
14417 
14418   // The proxy responds to the connect with a 407, using a persistent
14419   // connection.
14420   const char kAuthStatus[] = "407";
14421   const char* const kAuthChallenge[] = {
14422       "proxy-authenticate",
14423       "Basic realm=\"MyRealm1\"",
14424   };
14425   spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
14426       kAuthStatus, kAuthChallenge, std::size(kAuthChallenge) / 2, 1));
14427 
14428   spdy::SpdySerializedFrame conn_resp(
14429       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
14430   const char kResp[] =
14431       "HTTP/1.1 200 OK\r\n"
14432       "Content-Length: 5\r\n\r\n";
14433 
14434   spdy::SpdySerializedFrame wrapped_get_resp(
14435       spdy_util_.ConstructSpdyDataFrame(3, kResp, false));
14436   spdy::SpdySerializedFrame wrapped_body(
14437       spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
14438   MockRead spdy_reads[] = {
14439       CreateMockRead(conn_auth_resp, 1, ASYNC),
14440       CreateMockRead(conn_resp, 4, ASYNC),
14441       CreateMockRead(wrapped_get_resp, 6, ASYNC),
14442       CreateMockRead(wrapped_body, 7, ASYNC),
14443       MockRead(ASYNC, OK, 8),  // EOF.  May or may not be read.
14444   };
14445 
14446   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
14447   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
14448   // Negotiate SPDY to the proxy
14449   SSLSocketDataProvider proxy(ASYNC, OK);
14450   proxy.next_proto = kProtoHTTP2;
14451   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
14452   // Vanilla SSL to the server
14453   SSLSocketDataProvider server(ASYNC, OK);
14454   session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
14455 
14456   TestCompletionCallback callback1;
14457 
14458   auto trans =
14459       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
14460 
14461   int rv = trans->Start(&request, callback1.callback(),
14462                         NetLogWithSource::Make(NetLogSourceType::NONE));
14463   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14464 
14465   rv = callback1.WaitForResult();
14466   EXPECT_THAT(rv, IsOk());
14467   auto entries = net_log_observer.GetEntries();
14468   size_t pos = ExpectLogContainsSomewhere(
14469       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14470       NetLogEventPhase::NONE);
14471   ExpectLogContainsSomewhere(
14472       entries, pos,
14473       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14474       NetLogEventPhase::NONE);
14475 
14476   const HttpResponseInfo* response = trans->GetResponseInfo();
14477   ASSERT_TRUE(response);
14478   ASSERT_TRUE(response->headers);
14479   EXPECT_EQ(407, response->headers->response_code());
14480   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14481   EXPECT_TRUE(response->auth_challenge.has_value());
14482   EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
14483 
14484   TestCompletionCallback callback2;
14485 
14486   rv =
14487       trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
14488   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14489 
14490   rv = callback2.WaitForResult();
14491   EXPECT_THAT(rv, IsOk());
14492 
14493   response = trans->GetResponseInfo();
14494   ASSERT_TRUE(response);
14495 
14496   EXPECT_TRUE(response->headers->IsKeepAlive());
14497   EXPECT_EQ(200, response->headers->response_code());
14498   EXPECT_EQ(5, response->headers->GetContentLength());
14499   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14500 
14501   // The password prompt info should not be set.
14502   EXPECT_FALSE(response->auth_challenge.has_value());
14503 
14504   LoadTimingInfo load_timing_info;
14505   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
14506   TestLoadTimingNotReusedWithPac(load_timing_info,
14507                                  CONNECT_TIMING_HAS_SSL_TIMES);
14508 
14509   trans.reset();
14510   session->CloseAllConnections(ERR_FAILED, "Very good reason");
14511 }
14512 
14513 // Test HTTPS connections to a site with a bad certificate, going through an
14514 // HTTPS proxy
TEST_P(HttpNetworkTransactionTest,HTTPSBadCertificateViaHttpsProxy)14515 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
14516   session_deps_.proxy_resolution_service =
14517       ConfiguredProxyResolutionService::CreateFixedForTest(
14518           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
14519 
14520   HttpRequestInfo request;
14521   request.method = "GET";
14522   request.url = GURL("https://www.example.org/");
14523   request.traffic_annotation =
14524       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14525 
14526   // Attempt to fetch the URL from a server with a bad cert
14527   MockWrite bad_cert_writes[] = {
14528       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14529                 "Host: www.example.org:443\r\n"
14530                 "Proxy-Connection: keep-alive\r\n\r\n"),
14531   };
14532 
14533   MockRead bad_cert_reads[] = {MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
14534                                MockRead(SYNCHRONOUS, OK)};
14535 
14536   // Attempt to fetch the URL with a good cert
14537   MockWrite good_data_writes[] = {
14538       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14539                 "Host: www.example.org:443\r\n"
14540                 "Proxy-Connection: keep-alive\r\n\r\n"),
14541       MockWrite("GET / HTTP/1.1\r\n"
14542                 "Host: www.example.org\r\n"
14543                 "Connection: keep-alive\r\n\r\n"),
14544   };
14545 
14546   MockRead good_cert_reads[] = {
14547       MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
14548       MockRead("HTTP/1.0 200 OK\r\n"),
14549       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14550       MockRead("Content-Length: 100\r\n\r\n"),
14551       MockRead(SYNCHRONOUS, OK),
14552   };
14553 
14554   StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
14555   StaticSocketDataProvider data(good_cert_reads, good_data_writes);
14556   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
14557   SSLSocketDataProvider ssl(ASYNC, OK);
14558 
14559   // SSL to the proxy, then CONNECT request, then SSL with bad certificate
14560   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14561   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
14562   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
14563 
14564   // SSL to the proxy, then CONNECT request, then valid SSL certificate
14565   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14566   session_deps_.socket_factory->AddSocketDataProvider(&data);
14567   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14568 
14569   TestCompletionCallback callback;
14570 
14571   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14572   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14573 
14574   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14575   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14576 
14577   rv = callback.WaitForResult();
14578   EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
14579 
14580   rv = trans.RestartIgnoringLastError(callback.callback());
14581   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14582 
14583   rv = callback.WaitForResult();
14584   EXPECT_THAT(rv, IsOk());
14585 
14586   const HttpResponseInfo* response = trans.GetResponseInfo();
14587 
14588   ASSERT_TRUE(response);
14589   EXPECT_EQ(100, response->headers->GetContentLength());
14590 }
14591 
TEST_P(HttpNetworkTransactionTest,BuildRequest_UserAgent)14592 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
14593   HttpRequestInfo request;
14594   request.method = "GET";
14595   request.url = GURL("http://www.example.org/");
14596   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
14597                                   "Chromium Ultra Awesome X Edition");
14598   request.traffic_annotation =
14599       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14600 
14601   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14602   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14603 
14604   MockWrite data_writes[] = {
14605       MockWrite("GET / HTTP/1.1\r\n"
14606                 "Host: www.example.org\r\n"
14607                 "Connection: keep-alive\r\n"
14608                 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
14609   };
14610 
14611   // Lastly, the server responds with the actual content.
14612   MockRead data_reads[] = {
14613       MockRead("HTTP/1.0 200 OK\r\n"),
14614       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14615       MockRead("Content-Length: 100\r\n\r\n"),
14616       MockRead(SYNCHRONOUS, OK),
14617   };
14618 
14619   StaticSocketDataProvider data(data_reads, data_writes);
14620   session_deps_.socket_factory->AddSocketDataProvider(&data);
14621 
14622   TestCompletionCallback callback;
14623 
14624   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14625   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14626 
14627   rv = callback.WaitForResult();
14628   EXPECT_THAT(rv, IsOk());
14629 }
14630 
TEST_P(HttpNetworkTransactionTest,BuildRequest_UserAgentOverTunnel)14631 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
14632   // Test user agent values, used both for the request header of the original
14633   // request, and the value returned by the HttpUserAgentSettings. nullptr means
14634   // no request header / no HttpUserAgentSettings object.
14635   const char* kTestUserAgents[] = {nullptr, "", "Foopy"};
14636 
14637   for (const char* setting_user_agent : kTestUserAgents) {
14638     if (!setting_user_agent) {
14639       session_deps_.http_user_agent_settings.reset();
14640     } else {
14641       session_deps_.http_user_agent_settings =
14642           std::make_unique<StaticHttpUserAgentSettings>(
14643               std::string() /* accept-language */, setting_user_agent);
14644     }
14645     session_deps_.proxy_resolution_service =
14646         ConfiguredProxyResolutionService::CreateFixedForTest(
14647             "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
14648     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14649     for (const char* request_user_agent : kTestUserAgents) {
14650       HttpRequestInfo request;
14651       request.method = "GET";
14652       request.url = GURL("https://www.example.org/");
14653       if (request_user_agent) {
14654         request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
14655                                         request_user_agent);
14656       }
14657       request.traffic_annotation =
14658           net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14659 
14660       HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14661 
14662       std::string expected_request;
14663       if (!setting_user_agent || strlen(setting_user_agent) == 0) {
14664         expected_request =
14665             "CONNECT www.example.org:443 HTTP/1.1\r\n"
14666             "Host: www.example.org:443\r\n"
14667             "Proxy-Connection: keep-alive\r\n\r\n";
14668       } else {
14669         expected_request = base::StringPrintf(
14670             "CONNECT www.example.org:443 HTTP/1.1\r\n"
14671             "Host: www.example.org:443\r\n"
14672             "Proxy-Connection: keep-alive\r\n"
14673             "User-Agent: %s\r\n\r\n",
14674             setting_user_agent);
14675       }
14676       MockWrite data_writes[] = {
14677           MockWrite(expected_request.c_str()),
14678       };
14679       MockRead data_reads[] = {
14680           // Return an error, so the transaction stops here (this test isn't
14681           // interested in the rest).
14682           MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
14683           MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
14684           MockRead("Proxy-Connection: close\r\n\r\n"),
14685       };
14686 
14687       StaticSocketDataProvider data(data_reads, data_writes);
14688       session_deps_.socket_factory->AddSocketDataProvider(&data);
14689 
14690       TestCompletionCallback callback;
14691 
14692       int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14693       EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14694 
14695       rv = callback.WaitForResult();
14696       EXPECT_THAT(rv, IsOk());
14697     }
14698   }
14699 }
14700 
TEST_P(HttpNetworkTransactionTest,BuildRequest_Referer)14701 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
14702   HttpRequestInfo request;
14703   request.method = "GET";
14704   request.url = GURL("http://www.example.org/");
14705   request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
14706                                   "http://the.previous.site.com/");
14707   request.traffic_annotation =
14708       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14709 
14710   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14711   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14712 
14713   MockWrite data_writes[] = {
14714       MockWrite("GET / HTTP/1.1\r\n"
14715                 "Host: www.example.org\r\n"
14716                 "Connection: keep-alive\r\n"
14717                 "Referer: http://the.previous.site.com/\r\n\r\n"),
14718   };
14719 
14720   // Lastly, the server responds with the actual content.
14721   MockRead data_reads[] = {
14722       MockRead("HTTP/1.0 200 OK\r\n"),
14723       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14724       MockRead("Content-Length: 100\r\n\r\n"),
14725       MockRead(SYNCHRONOUS, OK),
14726   };
14727 
14728   StaticSocketDataProvider data(data_reads, data_writes);
14729   session_deps_.socket_factory->AddSocketDataProvider(&data);
14730 
14731   TestCompletionCallback callback;
14732 
14733   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14734   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14735 
14736   rv = callback.WaitForResult();
14737   EXPECT_THAT(rv, IsOk());
14738 }
14739 
TEST_P(HttpNetworkTransactionTest,BuildRequest_PostContentLengthZero)14740 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
14741   HttpRequestInfo request;
14742   request.method = "POST";
14743   request.url = GURL("http://www.example.org/");
14744   request.traffic_annotation =
14745       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14746 
14747   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14748   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14749 
14750   MockWrite data_writes[] = {
14751       MockWrite("POST / HTTP/1.1\r\n"
14752                 "Host: www.example.org\r\n"
14753                 "Connection: keep-alive\r\n"
14754                 "Content-Length: 0\r\n\r\n"),
14755   };
14756 
14757   // Lastly, the server responds with the actual content.
14758   MockRead data_reads[] = {
14759       MockRead("HTTP/1.0 200 OK\r\n"),
14760       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14761       MockRead("Content-Length: 100\r\n\r\n"),
14762       MockRead(SYNCHRONOUS, OK),
14763   };
14764 
14765   StaticSocketDataProvider data(data_reads, data_writes);
14766   session_deps_.socket_factory->AddSocketDataProvider(&data);
14767 
14768   TestCompletionCallback callback;
14769 
14770   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14771   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14772 
14773   rv = callback.WaitForResult();
14774   EXPECT_THAT(rv, IsOk());
14775 }
14776 
TEST_P(HttpNetworkTransactionTest,BuildRequest_PutContentLengthZero)14777 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
14778   HttpRequestInfo request;
14779   request.method = "PUT";
14780   request.url = GURL("http://www.example.org/");
14781   request.traffic_annotation =
14782       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14783 
14784   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14785   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14786 
14787   MockWrite data_writes[] = {
14788       MockWrite("PUT / HTTP/1.1\r\n"
14789                 "Host: www.example.org\r\n"
14790                 "Connection: keep-alive\r\n"
14791                 "Content-Length: 0\r\n\r\n"),
14792   };
14793 
14794   // Lastly, the server responds with the actual content.
14795   MockRead data_reads[] = {
14796       MockRead("HTTP/1.0 200 OK\r\n"),
14797       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14798       MockRead("Content-Length: 100\r\n\r\n"),
14799       MockRead(SYNCHRONOUS, OK),
14800   };
14801 
14802   StaticSocketDataProvider data(data_reads, data_writes);
14803   session_deps_.socket_factory->AddSocketDataProvider(&data);
14804 
14805   TestCompletionCallback callback;
14806 
14807   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14808   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14809 
14810   rv = callback.WaitForResult();
14811   EXPECT_THAT(rv, IsOk());
14812 }
14813 
TEST_P(HttpNetworkTransactionTest,BuildRequest_HeadContentLengthZero)14814 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
14815   HttpRequestInfo request;
14816   request.method = "HEAD";
14817   request.url = GURL("http://www.example.org/");
14818   request.traffic_annotation =
14819       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14820 
14821   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14822   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14823 
14824   MockWrite data_writes[] = {
14825       MockWrite("HEAD / HTTP/1.1\r\n"
14826                 "Host: www.example.org\r\n"
14827                 "Connection: keep-alive\r\n\r\n"),
14828   };
14829 
14830   // Lastly, the server responds with the actual content.
14831   MockRead data_reads[] = {
14832       MockRead("HTTP/1.0 200 OK\r\n"),
14833       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14834       MockRead("Content-Length: 100\r\n\r\n"),
14835       MockRead(SYNCHRONOUS, OK),
14836   };
14837 
14838   StaticSocketDataProvider data(data_reads, data_writes);
14839   session_deps_.socket_factory->AddSocketDataProvider(&data);
14840 
14841   TestCompletionCallback callback;
14842 
14843   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14844   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14845 
14846   rv = callback.WaitForResult();
14847   EXPECT_THAT(rv, IsOk());
14848 }
14849 
TEST_P(HttpNetworkTransactionTest,BuildRequest_CacheControlNoCache)14850 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
14851   HttpRequestInfo request;
14852   request.method = "GET";
14853   request.url = GURL("http://www.example.org/");
14854   request.load_flags = LOAD_BYPASS_CACHE;
14855   request.traffic_annotation =
14856       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14857 
14858   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14859   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14860 
14861   MockWrite data_writes[] = {
14862       MockWrite("GET / HTTP/1.1\r\n"
14863                 "Host: www.example.org\r\n"
14864                 "Connection: keep-alive\r\n"
14865                 "Pragma: no-cache\r\n"
14866                 "Cache-Control: no-cache\r\n\r\n"),
14867   };
14868 
14869   // Lastly, the server responds with the actual content.
14870   MockRead data_reads[] = {
14871       MockRead("HTTP/1.0 200 OK\r\n"),
14872       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14873       MockRead("Content-Length: 100\r\n\r\n"),
14874       MockRead(SYNCHRONOUS, OK),
14875   };
14876 
14877   StaticSocketDataProvider data(data_reads, data_writes);
14878   session_deps_.socket_factory->AddSocketDataProvider(&data);
14879 
14880   TestCompletionCallback callback;
14881 
14882   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14883   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14884 
14885   rv = callback.WaitForResult();
14886   EXPECT_THAT(rv, IsOk());
14887 }
14888 
TEST_P(HttpNetworkTransactionTest,BuildRequest_CacheControlValidateCache)14889 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
14890   HttpRequestInfo request;
14891   request.method = "GET";
14892   request.url = GURL("http://www.example.org/");
14893   request.load_flags = LOAD_VALIDATE_CACHE;
14894   request.traffic_annotation =
14895       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14896 
14897   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14898   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14899 
14900   MockWrite data_writes[] = {
14901       MockWrite("GET / HTTP/1.1\r\n"
14902                 "Host: www.example.org\r\n"
14903                 "Connection: keep-alive\r\n"
14904                 "Cache-Control: max-age=0\r\n\r\n"),
14905   };
14906 
14907   // Lastly, the server responds with the actual content.
14908   MockRead data_reads[] = {
14909       MockRead("HTTP/1.0 200 OK\r\n"),
14910       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14911       MockRead("Content-Length: 100\r\n\r\n"),
14912       MockRead(SYNCHRONOUS, OK),
14913   };
14914 
14915   StaticSocketDataProvider data(data_reads, data_writes);
14916   session_deps_.socket_factory->AddSocketDataProvider(&data);
14917 
14918   TestCompletionCallback callback;
14919 
14920   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14921   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14922 
14923   rv = callback.WaitForResult();
14924   EXPECT_THAT(rv, IsOk());
14925 }
14926 
TEST_P(HttpNetworkTransactionTest,BuildRequest_ExtraHeaders)14927 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
14928   HttpRequestInfo request;
14929   request.method = "GET";
14930   request.url = GURL("http://www.example.org/");
14931   request.extra_headers.SetHeader("FooHeader", "Bar");
14932   request.traffic_annotation =
14933       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14934 
14935   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14936   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14937 
14938   MockWrite data_writes[] = {
14939       MockWrite("GET / HTTP/1.1\r\n"
14940                 "Host: www.example.org\r\n"
14941                 "Connection: keep-alive\r\n"
14942                 "FooHeader: Bar\r\n\r\n"),
14943   };
14944 
14945   // Lastly, the server responds with the actual content.
14946   MockRead data_reads[] = {
14947       MockRead("HTTP/1.0 200 OK\r\n"),
14948       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14949       MockRead("Content-Length: 100\r\n\r\n"),
14950       MockRead(SYNCHRONOUS, OK),
14951   };
14952 
14953   StaticSocketDataProvider data(data_reads, data_writes);
14954   session_deps_.socket_factory->AddSocketDataProvider(&data);
14955 
14956   TestCompletionCallback callback;
14957 
14958   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14959   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14960 
14961   rv = callback.WaitForResult();
14962   EXPECT_THAT(rv, IsOk());
14963 }
14964 
TEST_P(HttpNetworkTransactionTest,BuildRequest_ExtraHeadersStripped)14965 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
14966   HttpRequestInfo request;
14967   request.method = "GET";
14968   request.url = GURL("http://www.example.org/");
14969   request.extra_headers.SetHeader("referer", "www.foo.com");
14970   request.extra_headers.SetHeader("hEllo", "Kitty");
14971   request.extra_headers.SetHeader("FoO", "bar");
14972   request.traffic_annotation =
14973       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14974 
14975   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14976   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14977 
14978   MockWrite data_writes[] = {
14979       MockWrite("GET / HTTP/1.1\r\n"
14980                 "Host: www.example.org\r\n"
14981                 "Connection: keep-alive\r\n"
14982                 "referer: www.foo.com\r\n"
14983                 "hEllo: Kitty\r\n"
14984                 "FoO: bar\r\n\r\n"),
14985   };
14986 
14987   // Lastly, the server responds with the actual content.
14988   MockRead data_reads[] = {
14989       MockRead("HTTP/1.0 200 OK\r\n"),
14990       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14991       MockRead("Content-Length: 100\r\n\r\n"),
14992       MockRead(SYNCHRONOUS, OK),
14993   };
14994 
14995   StaticSocketDataProvider data(data_reads, data_writes);
14996   session_deps_.socket_factory->AddSocketDataProvider(&data);
14997 
14998   TestCompletionCallback callback;
14999 
15000   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15001   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15002 
15003   rv = callback.WaitForResult();
15004   EXPECT_THAT(rv, IsOk());
15005 }
15006 
TEST_P(HttpNetworkTransactionTest,SOCKS4_HTTP_GET)15007 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
15008   HttpRequestInfo request;
15009   request.method = "GET";
15010   request.url = GURL("http://www.example.org/");
15011   request.traffic_annotation =
15012       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15013 
15014   session_deps_.proxy_resolution_service =
15015       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
15016           "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
15017   session_deps_.net_log = net::NetLog::Get();
15018 
15019   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15020   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15021 
15022   char write_buffer[] = {0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0};
15023   char read_buffer[] = {0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0};
15024 
15025   MockWrite data_writes[] = {
15026       MockWrite(ASYNC, write_buffer, std::size(write_buffer)),
15027       MockWrite("GET / HTTP/1.1\r\n"
15028                 "Host: www.example.org\r\n"
15029                 "Connection: keep-alive\r\n\r\n")};
15030 
15031   MockRead data_reads[] = {
15032       MockRead(ASYNC, read_buffer, std::size(read_buffer)),
15033       MockRead("HTTP/1.0 200 OK\r\n"),
15034       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
15035       MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
15036 
15037   StaticSocketDataProvider data(data_reads, data_writes);
15038   session_deps_.socket_factory->AddSocketDataProvider(&data);
15039 
15040   TestCompletionCallback callback;
15041 
15042   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15043   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15044 
15045   rv = callback.WaitForResult();
15046   EXPECT_THAT(rv, IsOk());
15047 
15048   const HttpResponseInfo* response = trans.GetResponseInfo();
15049   ASSERT_TRUE(response);
15050 
15051   ASSERT_EQ(1u, response->proxy_chain.length());
15052   EXPECT_EQ(ProxyServer::SCHEME_SOCKS4,
15053             response->proxy_chain.GetProxyServer(0).scheme());
15054   LoadTimingInfo load_timing_info;
15055   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
15056   TestLoadTimingNotReusedWithPac(load_timing_info,
15057                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
15058 
15059   std::string response_text;
15060   rv = ReadTransaction(&trans, &response_text);
15061   EXPECT_THAT(rv, IsOk());
15062   EXPECT_EQ("Payload", response_text);
15063 }
15064 
TEST_P(HttpNetworkTransactionTest,SOCKS4_SSL_GET)15065 TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
15066   HttpRequestInfo request;
15067   request.method = "GET";
15068   request.url = GURL("https://www.example.org/");
15069   request.traffic_annotation =
15070       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15071 
15072   session_deps_.proxy_resolution_service =
15073       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
15074           "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
15075   session_deps_.net_log = net::NetLog::Get();
15076 
15077   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15078   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15079 
15080   unsigned char write_buffer[] = {0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0};
15081   unsigned char read_buffer[] = {0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0};
15082 
15083   MockWrite data_writes[] = {
15084       MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
15085                 std::size(write_buffer)),
15086       MockWrite("GET / HTTP/1.1\r\n"
15087                 "Host: www.example.org\r\n"
15088                 "Connection: keep-alive\r\n\r\n")};
15089 
15090   MockRead data_reads[] = {
15091       MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
15092                std::size(read_buffer)),
15093       MockRead("HTTP/1.0 200 OK\r\n"),
15094       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
15095       MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
15096 
15097   StaticSocketDataProvider data(data_reads, data_writes);
15098   session_deps_.socket_factory->AddSocketDataProvider(&data);
15099 
15100   SSLSocketDataProvider ssl(ASYNC, OK);
15101   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15102 
15103   TestCompletionCallback callback;
15104 
15105   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15106   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15107 
15108   rv = callback.WaitForResult();
15109   EXPECT_THAT(rv, IsOk());
15110 
15111   LoadTimingInfo load_timing_info;
15112   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
15113   TestLoadTimingNotReusedWithPac(load_timing_info,
15114                                  CONNECT_TIMING_HAS_SSL_TIMES);
15115 
15116   const HttpResponseInfo* response = trans.GetResponseInfo();
15117   ASSERT_TRUE(response);
15118   ASSERT_EQ(1u, response->proxy_chain.length());
15119   EXPECT_EQ(ProxyServer::SCHEME_SOCKS4,
15120             response->proxy_chain.GetProxyServer(0).scheme());
15121 
15122   std::string response_text;
15123   rv = ReadTransaction(&trans, &response_text);
15124   EXPECT_THAT(rv, IsOk());
15125   EXPECT_EQ("Payload", response_text);
15126 }
15127 
TEST_P(HttpNetworkTransactionTest,SOCKS4_HTTP_GET_no_PAC)15128 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
15129   HttpRequestInfo request;
15130   request.method = "GET";
15131   request.url = GURL("http://www.example.org/");
15132   request.traffic_annotation =
15133       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15134 
15135   session_deps_.proxy_resolution_service =
15136       ConfiguredProxyResolutionService::CreateFixedForTest(
15137           "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
15138   session_deps_.net_log = net::NetLog::Get();
15139 
15140   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15141   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15142 
15143   char write_buffer[] = {0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0};
15144   char read_buffer[] = {0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0};
15145 
15146   MockWrite data_writes[] = {
15147       MockWrite(ASYNC, write_buffer, std::size(write_buffer)),
15148       MockWrite("GET / HTTP/1.1\r\n"
15149                 "Host: www.example.org\r\n"
15150                 "Connection: keep-alive\r\n\r\n")};
15151 
15152   MockRead data_reads[] = {
15153       MockRead(ASYNC, read_buffer, std::size(read_buffer)),
15154       MockRead("HTTP/1.0 200 OK\r\n"),
15155       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
15156       MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
15157 
15158   StaticSocketDataProvider data(data_reads, data_writes);
15159   session_deps_.socket_factory->AddSocketDataProvider(&data);
15160 
15161   TestCompletionCallback callback;
15162 
15163   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15164   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15165 
15166   rv = callback.WaitForResult();
15167   EXPECT_THAT(rv, IsOk());
15168 
15169   const HttpResponseInfo* response = trans.GetResponseInfo();
15170   ASSERT_TRUE(response);
15171 
15172   LoadTimingInfo load_timing_info;
15173   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
15174   TestLoadTimingNotReused(load_timing_info,
15175                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
15176 
15177   std::string response_text;
15178   rv = ReadTransaction(&trans, &response_text);
15179   EXPECT_THAT(rv, IsOk());
15180   EXPECT_EQ("Payload", response_text);
15181 }
15182 
TEST_P(HttpNetworkTransactionTest,SOCKS5_HTTP_GET)15183 TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
15184   HttpRequestInfo request;
15185   request.method = "GET";
15186   request.url = GURL("http://www.example.org/");
15187   request.traffic_annotation =
15188       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15189 
15190   session_deps_.proxy_resolution_service =
15191       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
15192           "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
15193   session_deps_.net_log = net::NetLog::Get();
15194 
15195   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15196   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15197 
15198   const char kSOCKS5ExampleOkRequest[] = {
15199       0x05,  // Version
15200       0x01,  // Command (CONNECT)
15201       0x00,  // Reserved.
15202       0x03,  // Address type (DOMAINNAME).
15203       0x0F,  // Length of domain (15)
15204       'w',  'w', 'w', '.', 'e',  'x',
15205       'a',  'm', 'p', 'l', 'e',         // Domain string
15206       '.',  'o', 'r', 'g', 0x00, 0x50,  // 16-bit port (80)
15207   };
15208 
15209   MockWrite data_writes[] = {
15210       MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
15211       MockWrite(ASYNC, kSOCKS5ExampleOkRequest,
15212                 std::size(kSOCKS5ExampleOkRequest)),
15213       MockWrite("GET / HTTP/1.1\r\n"
15214                 "Host: www.example.org\r\n"
15215                 "Connection: keep-alive\r\n\r\n")};
15216 
15217   MockRead data_reads[] = {
15218       MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
15219       MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
15220       MockRead("HTTP/1.0 200 OK\r\n"),
15221       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
15222       MockRead("Payload"),
15223       MockRead(SYNCHRONOUS, OK)};
15224 
15225   StaticSocketDataProvider data(data_reads, data_writes);
15226   session_deps_.socket_factory->AddSocketDataProvider(&data);
15227 
15228   TestCompletionCallback callback;
15229 
15230   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15231   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15232 
15233   rv = callback.WaitForResult();
15234   EXPECT_THAT(rv, IsOk());
15235 
15236   const HttpResponseInfo* response = trans.GetResponseInfo();
15237   ASSERT_TRUE(response);
15238   ASSERT_EQ(1u, response->proxy_chain.length());
15239   EXPECT_EQ(ProxyServer::SCHEME_SOCKS5,
15240             response->proxy_chain.GetProxyServer(0).scheme());
15241 
15242   LoadTimingInfo load_timing_info;
15243   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
15244   TestLoadTimingNotReusedWithPac(load_timing_info,
15245                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
15246 
15247   std::string response_text;
15248   rv = ReadTransaction(&trans, &response_text);
15249   EXPECT_THAT(rv, IsOk());
15250   EXPECT_EQ("Payload", response_text);
15251 }
15252 
TEST_P(HttpNetworkTransactionTest,SOCKS5_SSL_GET)15253 TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
15254   HttpRequestInfo request;
15255   request.method = "GET";
15256   request.url = GURL("https://www.example.org/");
15257   request.traffic_annotation =
15258       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15259 
15260   session_deps_.proxy_resolution_service =
15261       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
15262           "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
15263   session_deps_.net_log = net::NetLog::Get();
15264 
15265   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15266   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15267 
15268   const unsigned char kSOCKS5ExampleOkRequest[] = {
15269       0x05,  // Version
15270       0x01,  // Command (CONNECT)
15271       0x00,  // Reserved.
15272       0x03,  // Address type (DOMAINNAME).
15273       0x0F,  // Length of domain (15)
15274       'w',  'w', 'w', '.', 'e',  'x',
15275       'a',  'm', 'p', 'l', 'e',         // Domain string
15276       '.',  'o', 'r', 'g', 0x01, 0xBB,  // 16-bit port (443)
15277   };
15278 
15279   const char kSOCKS5SslOkResponse[] = {0x05, 0x00, 0x00, 0x01, 0,
15280                                        0,    0,    0,    0x00, 0x00};
15281 
15282   MockWrite data_writes[] = {
15283       MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
15284       MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5ExampleOkRequest),
15285                 std::size(kSOCKS5ExampleOkRequest)),
15286       MockWrite("GET / HTTP/1.1\r\n"
15287                 "Host: www.example.org\r\n"
15288                 "Connection: keep-alive\r\n\r\n")};
15289 
15290   MockRead data_reads[] = {
15291       MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
15292       MockRead(ASYNC, kSOCKS5SslOkResponse, std::size(kSOCKS5SslOkResponse)),
15293       MockRead("HTTP/1.0 200 OK\r\n"),
15294       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
15295       MockRead("Payload"),
15296       MockRead(SYNCHRONOUS, OK)};
15297 
15298   StaticSocketDataProvider data(data_reads, data_writes);
15299   session_deps_.socket_factory->AddSocketDataProvider(&data);
15300 
15301   SSLSocketDataProvider ssl(ASYNC, OK);
15302   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15303 
15304   TestCompletionCallback callback;
15305 
15306   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15307   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15308 
15309   rv = callback.WaitForResult();
15310   EXPECT_THAT(rv, IsOk());
15311 
15312   const HttpResponseInfo* response = trans.GetResponseInfo();
15313   ASSERT_TRUE(response);
15314   ASSERT_EQ(1u, response->proxy_chain.length());
15315   EXPECT_EQ(ProxyServer::SCHEME_SOCKS5,
15316             response->proxy_chain.GetProxyServer(0).scheme());
15317 
15318   LoadTimingInfo load_timing_info;
15319   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
15320   TestLoadTimingNotReusedWithPac(load_timing_info,
15321                                  CONNECT_TIMING_HAS_SSL_TIMES);
15322 
15323   std::string response_text;
15324   rv = ReadTransaction(&trans, &response_text);
15325   EXPECT_THAT(rv, IsOk());
15326   EXPECT_EQ("Payload", response_text);
15327 }
15328 
15329 namespace {
15330 
15331 // Tests that for connection endpoints the group ids are correctly set.
15332 
15333 struct GroupIdTest {
15334   std::string proxy_chain;
15335   std::string url;
15336   ClientSocketPool::GroupId expected_group_id;
15337   bool ssl;
15338 };
15339 
SetupSessionForGroupIdTests(SpdySessionDependencies * session_deps_)15340 std::unique_ptr<HttpNetworkSession> SetupSessionForGroupIdTests(
15341     SpdySessionDependencies* session_deps_) {
15342   std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
15343 
15344   HttpServerProperties* http_server_properties =
15345       session->http_server_properties();
15346   AlternativeService alternative_service(kProtoHTTP2, "", 444);
15347   base::Time expiration = base::Time::Now() + base::Days(1);
15348   http_server_properties->SetHttp2AlternativeService(
15349       url::SchemeHostPort("https", "host.with.alternate", 443),
15350       NetworkAnonymizationKey(), alternative_service, expiration);
15351 
15352   return session;
15353 }
15354 
GroupIdTransactionHelper(const std::string & url,HttpNetworkSession * session)15355 int GroupIdTransactionHelper(const std::string& url,
15356                              HttpNetworkSession* session) {
15357   HttpRequestInfo request;
15358   request.method = "GET";
15359   request.url = GURL(url);
15360   request.traffic_annotation =
15361       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15362 
15363   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
15364 
15365   TestCompletionCallback callback;
15366 
15367   // We do not complete this request, the dtor will clean the transaction up.
15368   return trans.Start(&request, callback.callback(), NetLogWithSource());
15369 }
15370 
15371 }  // namespace
15372 
TEST_P(HttpNetworkTransactionTest,GroupIdForDirectConnections)15373 TEST_P(HttpNetworkTransactionTest, GroupIdForDirectConnections) {
15374   const GroupIdTest tests[] = {
15375       {
15376           "",  // unused
15377           "http://www.example.org/direct",
15378           ClientSocketPool::GroupId(
15379               url::SchemeHostPort(url::kHttpScheme, "www.example.org", 80),
15380               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15381               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15382           false,
15383       },
15384       {
15385           "",  // unused
15386           "http://[2001:1418:13:1::25]/direct",
15387           ClientSocketPool::GroupId(
15388               url::SchemeHostPort(url::kHttpScheme, "[2001:1418:13:1::25]", 80),
15389               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15390               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15391           false,
15392       },
15393 
15394       // SSL Tests
15395       {
15396           "",  // unused
15397           "https://www.example.org/direct_ssl",
15398           ClientSocketPool::GroupId(
15399               url::SchemeHostPort(url::kHttpsScheme, "www.example.org", 443),
15400               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15401               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15402           true,
15403       },
15404       {
15405           "",  // unused
15406           "https://[2001:1418:13:1::25]/direct",
15407           ClientSocketPool::GroupId(
15408               url::SchemeHostPort(url::kHttpsScheme, "[2001:1418:13:1::25]",
15409                                   443),
15410               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15411               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15412           true,
15413       },
15414       {
15415           "",  // unused
15416           "https://host.with.alternate/direct",
15417           ClientSocketPool::GroupId(
15418               url::SchemeHostPort(url::kHttpsScheme, "host.with.alternate",
15419                                   443),
15420               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15421               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15422           true,
15423       },
15424   };
15425 
15426   for (const auto& test : tests) {
15427     session_deps_.proxy_resolution_service =
15428         ConfiguredProxyResolutionService::CreateFixedForTest(
15429             test.proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS);
15430     std::unique_ptr<HttpNetworkSession> session(
15431         SetupSessionForGroupIdTests(&session_deps_));
15432 
15433     HttpNetworkSessionPeer peer(session.get());
15434     auto transport_conn_pool =
15435         std::make_unique<CaptureGroupIdTransportSocketPool>(
15436             &dummy_connect_job_params_);
15437     auto* transport_conn_pool_ptr = transport_conn_pool.get();
15438     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
15439     mock_pool_manager->SetSocketPool(ProxyChain::Direct(),
15440                                      std::move(transport_conn_pool));
15441     peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
15442 
15443     EXPECT_EQ(ERR_IO_PENDING,
15444               GroupIdTransactionHelper(test.url, session.get()));
15445     EXPECT_EQ(test.expected_group_id,
15446               transport_conn_pool_ptr->last_group_id_received());
15447     EXPECT_TRUE(transport_conn_pool_ptr->socket_requested());
15448   }
15449 }
15450 
TEST_P(HttpNetworkTransactionTest,GroupIdForHTTPProxyConnections)15451 TEST_P(HttpNetworkTransactionTest, GroupIdForHTTPProxyConnections) {
15452   const GroupIdTest tests[] = {
15453       {
15454           "http_proxy",
15455           "http://www.example.org/http_proxy_normal",
15456           ClientSocketPool::GroupId(
15457               url::SchemeHostPort(url::kHttpScheme, "www.example.org", 80),
15458               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15459               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15460           false,
15461       },
15462 
15463       // SSL Tests
15464       {
15465           "http_proxy",
15466           "https://www.example.org/http_connect_ssl",
15467           ClientSocketPool::GroupId(
15468               url::SchemeHostPort(url::kHttpsScheme, "www.example.org", 443),
15469               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15470               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15471           true,
15472       },
15473 
15474       {
15475           "http_proxy",
15476           "https://host.with.alternate/direct",
15477           ClientSocketPool::GroupId(
15478               url::SchemeHostPort(url::kHttpsScheme, "host.with.alternate",
15479                                   443),
15480               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15481               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15482           true,
15483       },
15484   };
15485 
15486   for (const auto& test : tests) {
15487     session_deps_.proxy_resolution_service =
15488         ConfiguredProxyResolutionService::CreateFixedForTest(
15489             test.proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS);
15490     std::unique_ptr<HttpNetworkSession> session(
15491         SetupSessionForGroupIdTests(&session_deps_));
15492 
15493     HttpNetworkSessionPeer peer(session.get());
15494 
15495     ProxyChain proxy_chain(ProxyServer::SCHEME_HTTP,
15496                            HostPortPair("http_proxy", 80));
15497     auto http_proxy_pool = std::make_unique<CaptureGroupIdTransportSocketPool>(
15498         &dummy_connect_job_params_);
15499     auto* http_proxy_pool_ptr = http_proxy_pool.get();
15500     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
15501     mock_pool_manager->SetSocketPool(proxy_chain, std::move(http_proxy_pool));
15502     peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
15503 
15504     EXPECT_EQ(ERR_IO_PENDING,
15505               GroupIdTransactionHelper(test.url, session.get()));
15506     EXPECT_EQ(test.expected_group_id,
15507               http_proxy_pool_ptr->last_group_id_received());
15508   }
15509 }
15510 
TEST_P(HttpNetworkTransactionTest,GroupIdForSOCKSConnections)15511 TEST_P(HttpNetworkTransactionTest, GroupIdForSOCKSConnections) {
15512   const GroupIdTest tests[] = {
15513       {
15514           "socks4://socks_proxy:1080",
15515           "http://www.example.org/socks4_direct",
15516           ClientSocketPool::GroupId(
15517               url::SchemeHostPort(url::kHttpScheme, "www.example.org", 80),
15518               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15519               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15520           false,
15521       },
15522       {
15523           "socks5://socks_proxy:1080",
15524           "http://www.example.org/socks5_direct",
15525           ClientSocketPool::GroupId(
15526               url::SchemeHostPort(url::kHttpScheme, "www.example.org", 80),
15527               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15528               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15529           false,
15530       },
15531 
15532       // SSL Tests
15533       {
15534           "socks4://socks_proxy:1080",
15535           "https://www.example.org/socks4_ssl",
15536           ClientSocketPool::GroupId(
15537               url::SchemeHostPort(url::kHttpsScheme, "www.example.org", 443),
15538               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15539               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15540           true,
15541       },
15542       {
15543           "socks5://socks_proxy:1080",
15544           "https://www.example.org/socks5_ssl",
15545           ClientSocketPool::GroupId(
15546               url::SchemeHostPort(url::kHttpsScheme, "www.example.org", 443),
15547               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15548               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15549           true,
15550       },
15551 
15552       {
15553           "socks4://socks_proxy:1080",
15554           "https://host.with.alternate/direct",
15555           ClientSocketPool::GroupId(
15556               url::SchemeHostPort(url::kHttpsScheme, "host.with.alternate",
15557                                   443),
15558               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
15559               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
15560           true,
15561       },
15562   };
15563 
15564   for (const auto& test : tests) {
15565     session_deps_.proxy_resolution_service =
15566         ConfiguredProxyResolutionService::CreateFixedForTest(
15567             test.proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS);
15568     std::unique_ptr<HttpNetworkSession> session(
15569         SetupSessionForGroupIdTests(&session_deps_));
15570 
15571     HttpNetworkSessionPeer peer(session.get());
15572 
15573     ProxyChain proxy_chain =
15574         ProxyUriToProxyChain(test.proxy_chain, ProxyServer::SCHEME_HTTP);
15575     ASSERT_TRUE(proxy_chain.IsValid());
15576     auto socks_conn_pool = std::make_unique<CaptureGroupIdTransportSocketPool>(
15577         &dummy_connect_job_params_);
15578     auto* socks_conn_pool_ptr = socks_conn_pool.get();
15579     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
15580     mock_pool_manager->SetSocketPool(proxy_chain, std::move(socks_conn_pool));
15581     peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
15582 
15583     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15584 
15585     EXPECT_EQ(ERR_IO_PENDING,
15586               GroupIdTransactionHelper(test.url, session.get()));
15587     EXPECT_EQ(test.expected_group_id,
15588               socks_conn_pool_ptr->last_group_id_received());
15589   }
15590 }
15591 
TEST_P(HttpNetworkTransactionTest,ReconsiderProxyAfterFailedConnection)15592 TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
15593   HttpRequestInfo request;
15594   request.method = "GET";
15595   request.url = GURL("http://www.example.org/");
15596   request.traffic_annotation =
15597       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15598 
15599   session_deps_.proxy_resolution_service =
15600       ConfiguredProxyResolutionService::CreateFixedForTest(
15601           "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
15602 
15603   // This simulates failure resolving all hostnames; that means we will fail
15604   // connecting to both proxies (myproxy:70 and foobar:80).
15605   session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
15606 
15607   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15608   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15609 
15610   TestCompletionCallback callback;
15611 
15612   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15613   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15614 
15615   rv = callback.WaitForResult();
15616   EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
15617 }
15618 
15619 // Make sure we can handle an error when writing the request.
TEST_P(HttpNetworkTransactionTest,RequestWriteError)15620 TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
15621   HttpRequestInfo request;
15622   request.method = "GET";
15623   request.url = GURL("http://www.foo.com/");
15624   request.traffic_annotation =
15625       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15626 
15627   MockWrite write_failure[] = {
15628       MockWrite(ASYNC, ERR_CONNECTION_RESET),
15629   };
15630   StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
15631   session_deps_.socket_factory->AddSocketDataProvider(&data);
15632   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15633 
15634   TestCompletionCallback callback;
15635 
15636   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15637 
15638   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15639   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15640 
15641   rv = callback.WaitForResult();
15642   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
15643 
15644   IPEndPoint endpoint;
15645   EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
15646   EXPECT_LT(0u, endpoint.address().size());
15647 }
15648 
15649 // Check that a connection closed after the start of the headers finishes ok.
TEST_P(HttpNetworkTransactionTest,ConnectionClosedAfterStartOfHeaders)15650 TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
15651   HttpRequestInfo request;
15652   request.method = "GET";
15653   request.url = GURL("http://www.foo.com/");
15654   request.traffic_annotation =
15655       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15656 
15657   MockRead data_reads[] = {
15658       MockRead("HTTP/1."),
15659       MockRead(SYNCHRONOUS, OK),
15660   };
15661 
15662   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
15663   session_deps_.socket_factory->AddSocketDataProvider(&data);
15664   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15665 
15666   TestCompletionCallback callback;
15667 
15668   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15669 
15670   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15671   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15672 
15673   rv = callback.WaitForResult();
15674   EXPECT_THAT(rv, IsOk());
15675 
15676   const HttpResponseInfo* response = trans.GetResponseInfo();
15677   ASSERT_TRUE(response);
15678 
15679   EXPECT_TRUE(response->headers);
15680   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
15681 
15682   std::string response_data;
15683   rv = ReadTransaction(&trans, &response_data);
15684   EXPECT_THAT(rv, IsOk());
15685   EXPECT_EQ("", response_data);
15686 
15687   IPEndPoint endpoint;
15688   EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
15689   EXPECT_LT(0u, endpoint.address().size());
15690 }
15691 
15692 // Make sure that a dropped connection while draining the body for auth
15693 // restart does the right thing.
TEST_P(HttpNetworkTransactionTest,DrainResetOK)15694 TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
15695   HttpRequestInfo request;
15696   request.method = "GET";
15697   request.url = GURL("http://www.example.org/");
15698   request.traffic_annotation =
15699       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15700 
15701   MockWrite data_writes1[] = {
15702       MockWrite("GET / HTTP/1.1\r\n"
15703                 "Host: www.example.org\r\n"
15704                 "Connection: keep-alive\r\n\r\n"),
15705   };
15706 
15707   MockRead data_reads1[] = {
15708       MockRead("HTTP/1.1 401 Unauthorized\r\n"),
15709       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
15710       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15711       MockRead("Content-Length: 14\r\n\r\n"),
15712       MockRead("Unauth"),
15713       MockRead(ASYNC, ERR_CONNECTION_RESET),
15714   };
15715 
15716   StaticSocketDataProvider data1(data_reads1, data_writes1);
15717   session_deps_.socket_factory->AddSocketDataProvider(&data1);
15718 
15719   // After calling trans.RestartWithAuth(), this is the request we should
15720   // be issuing -- the final header line contains the credentials.
15721   MockWrite data_writes2[] = {
15722       MockWrite("GET / HTTP/1.1\r\n"
15723                 "Host: www.example.org\r\n"
15724                 "Connection: keep-alive\r\n"
15725                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15726   };
15727 
15728   // Lastly, the server responds with the actual content.
15729   MockRead data_reads2[] = {
15730       MockRead("HTTP/1.1 200 OK\r\n"),
15731       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15732       MockRead("Content-Length: 100\r\n\r\n"),
15733       MockRead(SYNCHRONOUS, OK),
15734   };
15735 
15736   StaticSocketDataProvider data2(data_reads2, data_writes2);
15737   session_deps_.socket_factory->AddSocketDataProvider(&data2);
15738   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15739 
15740   TestCompletionCallback callback1;
15741 
15742   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15743 
15744   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
15745   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15746 
15747   rv = callback1.WaitForResult();
15748   EXPECT_THAT(rv, IsOk());
15749 
15750   const HttpResponseInfo* response = trans.GetResponseInfo();
15751   ASSERT_TRUE(response);
15752   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
15753 
15754   TestCompletionCallback callback2;
15755 
15756   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
15757   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15758 
15759   rv = callback2.WaitForResult();
15760   EXPECT_THAT(rv, IsOk());
15761 
15762   response = trans.GetResponseInfo();
15763   ASSERT_TRUE(response);
15764   EXPECT_FALSE(response->auth_challenge.has_value());
15765   EXPECT_EQ(100, response->headers->GetContentLength());
15766 }
15767 
15768 // Test HTTPS connections going through a proxy that sends extra data.
TEST_P(HttpNetworkTransactionTest,HTTPSViaProxyWithExtraData)15769 TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
15770   session_deps_.proxy_resolution_service =
15771       ConfiguredProxyResolutionService::CreateFixedForTest(
15772           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
15773 
15774   HttpRequestInfo request;
15775   request.method = "GET";
15776   request.url = GURL("https://www.example.org/");
15777   request.traffic_annotation =
15778       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15779 
15780   MockRead proxy_reads[] = {
15781       MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
15782       MockRead(SYNCHRONOUS, OK)};
15783 
15784   StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
15785   SSLSocketDataProvider ssl(ASYNC, OK);
15786 
15787   session_deps_.socket_factory->AddSocketDataProvider(&data);
15788   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15789 
15790   TestCompletionCallback callback;
15791 
15792   session_deps_.socket_factory->ResetNextMockIndexes();
15793 
15794   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15795   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15796 
15797   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15798   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15799 
15800   rv = callback.WaitForResult();
15801   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
15802 }
15803 
TEST_P(HttpNetworkTransactionTest,LargeContentLengthThenClose)15804 TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
15805   HttpRequestInfo request;
15806   request.method = "GET";
15807   request.url = GURL("http://www.example.org/");
15808   request.traffic_annotation =
15809       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15810 
15811   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15812   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15813 
15814   MockRead data_reads[] = {
15815       MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
15816       MockRead(SYNCHRONOUS, OK),
15817   };
15818 
15819   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
15820   session_deps_.socket_factory->AddSocketDataProvider(&data);
15821 
15822   TestCompletionCallback callback;
15823 
15824   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15825   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15826 
15827   EXPECT_THAT(callback.WaitForResult(), IsOk());
15828 
15829   const HttpResponseInfo* response = trans.GetResponseInfo();
15830   ASSERT_TRUE(response);
15831 
15832   EXPECT_TRUE(response->headers);
15833   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
15834 
15835   std::string response_data;
15836   rv = ReadTransaction(&trans, &response_data);
15837   EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
15838 }
15839 
TEST_P(HttpNetworkTransactionTest,UploadFileSmallerThanLength)15840 TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
15841   base::FilePath temp_file_path;
15842   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
15843   const uint64_t kFakeSize = 100000;  // file is actually blank
15844   UploadFileElementReader::ScopedOverridingContentLengthForTests
15845       overriding_content_length(kFakeSize);
15846 
15847   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
15848   element_readers.push_back(std::make_unique<UploadFileElementReader>(
15849       base::SingleThreadTaskRunner::GetCurrentDefault().get(), temp_file_path,
15850       0, std::numeric_limits<uint64_t>::max(), base::Time()));
15851   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
15852 
15853   HttpRequestInfo request;
15854   request.method = "POST";
15855   request.url = GURL("http://www.example.org/upload");
15856   request.upload_data_stream = &upload_data_stream;
15857   request.traffic_annotation =
15858       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15859 
15860   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15861   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15862 
15863   MockRead data_reads[] = {
15864       MockRead("HTTP/1.0 200 OK\r\n\r\n"),
15865       MockRead("hello world"),
15866       MockRead(SYNCHRONOUS, OK),
15867   };
15868   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
15869   session_deps_.socket_factory->AddSocketDataProvider(&data);
15870 
15871   TestCompletionCallback callback;
15872 
15873   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15874   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15875 
15876   rv = callback.WaitForResult();
15877   EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
15878 
15879   const HttpResponseInfo* response = trans.GetResponseInfo();
15880   ASSERT_TRUE(response);
15881 
15882   EXPECT_FALSE(response->headers);
15883 
15884   base::DeleteFile(temp_file_path);
15885 }
15886 
TEST_P(HttpNetworkTransactionTest,UploadUnreadableFile)15887 TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
15888   base::FilePath temp_file;
15889   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
15890   std::string temp_file_content("Unreadable file.");
15891   ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content));
15892   ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
15893 
15894   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
15895   element_readers.push_back(std::make_unique<UploadFileElementReader>(
15896       base::SingleThreadTaskRunner::GetCurrentDefault().get(), temp_file, 0,
15897       std::numeric_limits<uint64_t>::max(), base::Time()));
15898   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
15899 
15900   HttpRequestInfo request;
15901   request.method = "POST";
15902   request.url = GURL("http://www.example.org/upload");
15903   request.upload_data_stream = &upload_data_stream;
15904   request.traffic_annotation =
15905       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15906 
15907   // If we try to upload an unreadable file, the transaction should fail.
15908   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15909   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15910 
15911   StaticSocketDataProvider data;
15912   session_deps_.socket_factory->AddSocketDataProvider(&data);
15913 
15914   TestCompletionCallback callback;
15915 
15916   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15917   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15918 
15919   rv = callback.WaitForResult();
15920   EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
15921 
15922   base::DeleteFile(temp_file);
15923 }
15924 
TEST_P(HttpNetworkTransactionTest,CancelDuringInitRequestBody)15925 TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
15926   class FakeUploadElementReader : public UploadElementReader {
15927    public:
15928     FakeUploadElementReader() = default;
15929     ~FakeUploadElementReader() override = default;
15930 
15931     CompletionOnceCallback TakeCallback() { return std::move(callback_); }
15932 
15933     // UploadElementReader overrides:
15934     int Init(CompletionOnceCallback callback) override {
15935       callback_ = std::move(callback);
15936       return ERR_IO_PENDING;
15937     }
15938     uint64_t GetContentLength() const override { return 0; }
15939     uint64_t BytesRemaining() const override { return 0; }
15940     int Read(IOBuffer* buf,
15941              int buf_length,
15942              CompletionOnceCallback callback) override {
15943       return ERR_FAILED;
15944     }
15945 
15946    private:
15947     CompletionOnceCallback callback_;
15948   };
15949 
15950   auto fake_reader = std::make_unique<FakeUploadElementReader>();
15951   auto* fake_reader_ptr = fake_reader.get();
15952   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
15953   element_readers.push_back(std::move(fake_reader));
15954   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
15955 
15956   HttpRequestInfo request;
15957   request.method = "POST";
15958   request.url = GURL("http://www.example.org/upload");
15959   request.upload_data_stream = &upload_data_stream;
15960   request.traffic_annotation =
15961       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15962 
15963   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15964   auto trans =
15965       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
15966 
15967   StaticSocketDataProvider data;
15968   session_deps_.socket_factory->AddSocketDataProvider(&data);
15969 
15970   TestCompletionCallback callback;
15971   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
15972   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15973   base::RunLoop().RunUntilIdle();
15974 
15975   // Transaction is pending on request body initialization.
15976   CompletionOnceCallback init_callback = fake_reader_ptr->TakeCallback();
15977   ASSERT_FALSE(init_callback.is_null());
15978 
15979   // Return Init()'s result after the transaction gets destroyed.
15980   trans.reset();
15981   std::move(init_callback).Run(OK);  // Should not crash.
15982 }
15983 
15984 // Tests that changes to Auth realms are treated like auth rejections.
TEST_P(HttpNetworkTransactionTest,ChangeAuthRealms)15985 TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
15986   HttpRequestInfo request;
15987   request.method = "GET";
15988   request.url = GURL("http://www.example.org/");
15989   request.traffic_annotation =
15990       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15991 
15992   // First transaction will request a resource and receive a Basic challenge
15993   // with realm="first_realm".
15994   MockWrite data_writes1[] = {
15995       MockWrite("GET / HTTP/1.1\r\n"
15996                 "Host: www.example.org\r\n"
15997                 "Connection: keep-alive\r\n"
15998                 "\r\n"),
15999   };
16000   MockRead data_reads1[] = {
16001       MockRead("HTTP/1.1 401 Unauthorized\r\n"
16002                "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
16003                "\r\n"),
16004   };
16005 
16006   // After calling trans.RestartWithAuth(), provide an Authentication header
16007   // for first_realm. The server will reject and provide a challenge with
16008   // second_realm.
16009   MockWrite data_writes2[] = {
16010       MockWrite("GET / HTTP/1.1\r\n"
16011                 "Host: www.example.org\r\n"
16012                 "Connection: keep-alive\r\n"
16013                 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
16014                 "\r\n"),
16015   };
16016   MockRead data_reads2[] = {
16017       MockRead("HTTP/1.1 401 Unauthorized\r\n"
16018                "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
16019                "\r\n"),
16020   };
16021 
16022   // This again fails, and goes back to first_realm. Make sure that the
16023   // entry is removed from cache.
16024   MockWrite data_writes3[] = {
16025       MockWrite("GET / HTTP/1.1\r\n"
16026                 "Host: www.example.org\r\n"
16027                 "Connection: keep-alive\r\n"
16028                 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
16029                 "\r\n"),
16030   };
16031   MockRead data_reads3[] = {
16032       MockRead("HTTP/1.1 401 Unauthorized\r\n"
16033                "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
16034                "\r\n"),
16035   };
16036 
16037   // Try one last time (with the correct password) and get the resource.
16038   MockWrite data_writes4[] = {
16039       MockWrite("GET / HTTP/1.1\r\n"
16040                 "Host: www.example.org\r\n"
16041                 "Connection: keep-alive\r\n"
16042                 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
16043                 "\r\n"),
16044   };
16045   MockRead data_reads4[] = {
16046       MockRead("HTTP/1.1 200 OK\r\n"
16047                "Content-Type: text/html; charset=iso-8859-1\r\n"
16048                "Content-Length: 5\r\n"
16049                "\r\n"
16050                "hello"),
16051   };
16052 
16053   StaticSocketDataProvider data1(data_reads1, data_writes1);
16054   StaticSocketDataProvider data2(data_reads2, data_writes2);
16055   StaticSocketDataProvider data3(data_reads3, data_writes3);
16056   StaticSocketDataProvider data4(data_reads4, data_writes4);
16057   session_deps_.socket_factory->AddSocketDataProvider(&data1);
16058   session_deps_.socket_factory->AddSocketDataProvider(&data2);
16059   session_deps_.socket_factory->AddSocketDataProvider(&data3);
16060   session_deps_.socket_factory->AddSocketDataProvider(&data4);
16061 
16062   TestCompletionCallback callback1;
16063 
16064   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16065   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16066 
16067   // Issue the first request with Authorize headers. There should be a
16068   // password prompt for first_realm waiting to be filled in after the
16069   // transaction completes.
16070   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
16071   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16072   rv = callback1.WaitForResult();
16073   EXPECT_THAT(rv, IsOk());
16074   const HttpResponseInfo* response = trans.GetResponseInfo();
16075   ASSERT_TRUE(response);
16076   std::optional<AuthChallengeInfo> challenge = response->auth_challenge;
16077   ASSERT_TRUE(challenge);
16078   EXPECT_FALSE(challenge->is_proxy);
16079   EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
16080   EXPECT_EQ("first_realm", challenge->realm);
16081   EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
16082 
16083   // Issue the second request with an incorrect password. There should be a
16084   // password prompt for second_realm waiting to be filled in after the
16085   // transaction completes.
16086   TestCompletionCallback callback2;
16087   rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
16088                              callback2.callback());
16089   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16090   rv = callback2.WaitForResult();
16091   EXPECT_THAT(rv, IsOk());
16092   response = trans.GetResponseInfo();
16093   ASSERT_TRUE(response);
16094   challenge = response->auth_challenge;
16095   ASSERT_TRUE(challenge);
16096   EXPECT_FALSE(challenge->is_proxy);
16097   EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
16098   EXPECT_EQ("second_realm", challenge->realm);
16099   EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
16100 
16101   // Issue the third request with another incorrect password. There should be
16102   // a password prompt for first_realm waiting to be filled in. If the password
16103   // prompt is not present, it indicates that the HttpAuthCacheEntry for
16104   // first_realm was not correctly removed.
16105   TestCompletionCallback callback3;
16106   rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
16107                              callback3.callback());
16108   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16109   rv = callback3.WaitForResult();
16110   EXPECT_THAT(rv, IsOk());
16111   response = trans.GetResponseInfo();
16112   ASSERT_TRUE(response);
16113   challenge = response->auth_challenge;
16114   ASSERT_TRUE(challenge);
16115   EXPECT_FALSE(challenge->is_proxy);
16116   EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
16117   EXPECT_EQ("first_realm", challenge->realm);
16118   EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
16119 
16120   // Issue the fourth request with the correct password and username.
16121   TestCompletionCallback callback4;
16122   rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
16123                              callback4.callback());
16124   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16125   rv = callback4.WaitForResult();
16126   EXPECT_THAT(rv, IsOk());
16127   response = trans.GetResponseInfo();
16128   ASSERT_TRUE(response);
16129   EXPECT_FALSE(response->auth_challenge.has_value());
16130 }
16131 
16132 // Regression test for https://crbug.com/754395.
TEST_P(HttpNetworkTransactionTest,IgnoreAltSvcWithInvalidCert)16133 TEST_P(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
16134   MockRead data_reads[] = {
16135       MockRead("HTTP/1.1 200 OK\r\n"),
16136       MockRead(kAlternativeServiceHttpHeader),
16137       MockRead("\r\n"),
16138       MockRead("hello world"),
16139       MockRead(SYNCHRONOUS, OK),
16140   };
16141 
16142   HttpRequestInfo request;
16143   request.method = "GET";
16144   request.url = GURL("https://www.example.org/");
16145   request.traffic_annotation =
16146       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16147 
16148   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
16149   session_deps_.socket_factory->AddSocketDataProvider(&data);
16150 
16151   SSLSocketDataProvider ssl(ASYNC, OK);
16152   ssl.ssl_info.cert =
16153       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
16154   ASSERT_TRUE(ssl.ssl_info.cert);
16155   ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
16156   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16157 
16158   TestCompletionCallback callback;
16159 
16160   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16161   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16162 
16163   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16164   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16165 
16166   url::SchemeHostPort test_server(request.url);
16167   HttpServerProperties* http_server_properties =
16168       session->http_server_properties();
16169   EXPECT_TRUE(
16170       http_server_properties
16171           ->GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
16172           .empty());
16173 
16174   EXPECT_THAT(callback.WaitForResult(), IsOk());
16175 
16176   const HttpResponseInfo* response = trans.GetResponseInfo();
16177   ASSERT_TRUE(response);
16178   ASSERT_TRUE(response->headers);
16179   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16180   EXPECT_FALSE(response->was_fetched_via_spdy);
16181   EXPECT_FALSE(response->was_alpn_negotiated);
16182 
16183   std::string response_data;
16184   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
16185   EXPECT_EQ("hello world", response_data);
16186 
16187   EXPECT_TRUE(
16188       http_server_properties
16189           ->GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
16190           .empty());
16191 }
16192 
TEST_P(HttpNetworkTransactionTest,HonorAlternativeServiceHeader)16193 TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
16194   MockRead data_reads[] = {
16195       MockRead("HTTP/1.1 200 OK\r\n"),
16196       MockRead(kAlternativeServiceHttpHeader),
16197       MockRead("\r\n"),
16198       MockRead("hello world"),
16199       MockRead(SYNCHRONOUS, OK),
16200   };
16201 
16202   HttpRequestInfo request;
16203   request.method = "GET";
16204   request.url = GURL("https://www.example.org/");
16205   request.traffic_annotation =
16206       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16207 
16208   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
16209   session_deps_.socket_factory->AddSocketDataProvider(&data);
16210 
16211   SSLSocketDataProvider ssl(ASYNC, OK);
16212   ssl.ssl_info.cert =
16213       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
16214   ASSERT_TRUE(ssl.ssl_info.cert);
16215   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16216 
16217   TestCompletionCallback callback;
16218 
16219   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16220   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16221 
16222   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16223   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16224 
16225   url::SchemeHostPort test_server(request.url);
16226   HttpServerProperties* http_server_properties =
16227       session->http_server_properties();
16228   EXPECT_TRUE(
16229       http_server_properties
16230           ->GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
16231           .empty());
16232 
16233   EXPECT_THAT(callback.WaitForResult(), IsOk());
16234 
16235   const HttpResponseInfo* response = trans.GetResponseInfo();
16236   ASSERT_TRUE(response);
16237   ASSERT_TRUE(response->headers);
16238   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16239   EXPECT_FALSE(response->was_fetched_via_spdy);
16240   EXPECT_FALSE(response->was_alpn_negotiated);
16241 
16242   std::string response_data;
16243   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
16244   EXPECT_EQ("hello world", response_data);
16245 
16246   AlternativeServiceInfoVector alternative_service_info_vector =
16247       http_server_properties->GetAlternativeServiceInfos(
16248           test_server, NetworkAnonymizationKey());
16249   ASSERT_EQ(1u, alternative_service_info_vector.size());
16250   AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
16251   EXPECT_EQ(alternative_service,
16252             alternative_service_info_vector[0].alternative_service());
16253 }
16254 
TEST_P(HttpNetworkTransactionTest,HonorAlternativeServiceHeaderWithNetworkAnonymizationKey)16255 TEST_P(HttpNetworkTransactionTest,
16256        HonorAlternativeServiceHeaderWithNetworkAnonymizationKey) {
16257   base::test::ScopedFeatureList feature_list;
16258   feature_list.InitWithFeatures(
16259       // enabled_features
16260       {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
16261        // Need to partition connections by NetworkAnonymizationKey for
16262        // SpdySessionKeys to include NetworkAnonymizationKeys.
16263        features::kPartitionConnectionsByNetworkIsolationKey},
16264       // disabled_features
16265       {});
16266   // Since HttpServerProperties caches the feature value, have to create a new
16267   // one.
16268   session_deps_.http_server_properties =
16269       std::make_unique<HttpServerProperties>();
16270 
16271   const SchemefulSite kSite1(GURL("https://foo.test/"));
16272   const auto kNetworkAnonymizationKey1 =
16273       net::NetworkAnonymizationKey::CreateSameSite(kSite1);
16274   const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
16275   const SchemefulSite kSite2(GURL("https://bar.test/"));
16276   const auto kNetworkAnonymizationKey2 =
16277       net::NetworkAnonymizationKey::CreateSameSite(kSite2);
16278   const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
16279 
16280   MockRead data_reads[] = {
16281       MockRead("HTTP/1.1 200 OK\r\n"),
16282       MockRead(kAlternativeServiceHttpHeader),
16283       MockRead("\r\n"),
16284       MockRead("hello world"),
16285       MockRead(SYNCHRONOUS, OK),
16286   };
16287 
16288   HttpRequestInfo request;
16289   request.method = "GET";
16290   request.url = GURL("https://www.example.org/");
16291   request.traffic_annotation =
16292       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16293   request.network_isolation_key = kNetworkIsolationKey1;
16294   request.network_anonymization_key = kNetworkAnonymizationKey1;
16295 
16296   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
16297   session_deps_.socket_factory->AddSocketDataProvider(&data);
16298 
16299   SSLSocketDataProvider ssl(ASYNC, OK);
16300   ssl.ssl_info.cert =
16301       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
16302   ASSERT_TRUE(ssl.ssl_info.cert);
16303   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16304 
16305   TestCompletionCallback callback;
16306 
16307   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16308   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16309 
16310   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16311   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16312 
16313   url::SchemeHostPort test_server(request.url);
16314   HttpServerProperties* http_server_properties =
16315       session->http_server_properties();
16316   EXPECT_TRUE(
16317       http_server_properties
16318           ->GetAlternativeServiceInfos(test_server, kNetworkAnonymizationKey1)
16319           .empty());
16320 
16321   EXPECT_THAT(callback.WaitForResult(), IsOk());
16322 
16323   const HttpResponseInfo* response = trans.GetResponseInfo();
16324   ASSERT_TRUE(response);
16325   ASSERT_TRUE(response->headers);
16326   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16327   EXPECT_FALSE(response->was_fetched_via_spdy);
16328   EXPECT_FALSE(response->was_alpn_negotiated);
16329 
16330   std::string response_data;
16331   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
16332   EXPECT_EQ("hello world", response_data);
16333 
16334   AlternativeServiceInfoVector alternative_service_info_vector =
16335       http_server_properties->GetAlternativeServiceInfos(
16336           test_server, kNetworkAnonymizationKey1);
16337   ASSERT_EQ(1u, alternative_service_info_vector.size());
16338   AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
16339   EXPECT_EQ(alternative_service,
16340             alternative_service_info_vector[0].alternative_service());
16341 
16342   // Make sure the alternative service information is only associated with
16343   // kNetworkAnonymizationKey1.
16344   EXPECT_TRUE(
16345       http_server_properties
16346           ->GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
16347           .empty());
16348   EXPECT_TRUE(
16349       http_server_properties
16350           ->GetAlternativeServiceInfos(test_server, kNetworkAnonymizationKey2)
16351           .empty());
16352 }
16353 
16354 // Regression test for https://crbug.com/615497.
TEST_P(HttpNetworkTransactionTest,DoNotParseAlternativeServiceHeaderOnInsecureRequest)16355 TEST_P(HttpNetworkTransactionTest,
16356        DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
16357   MockRead data_reads[] = {
16358       MockRead("HTTP/1.1 200 OK\r\n"),
16359       MockRead(kAlternativeServiceHttpHeader),
16360       MockRead("\r\n"),
16361       MockRead("hello world"),
16362       MockRead(SYNCHRONOUS, OK),
16363   };
16364 
16365   HttpRequestInfo request;
16366   request.method = "GET";
16367   request.url = GURL("http://www.example.org/");
16368   request.load_flags = 0;
16369   request.traffic_annotation =
16370       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16371 
16372   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
16373   session_deps_.socket_factory->AddSocketDataProvider(&data);
16374 
16375   TestCompletionCallback callback;
16376 
16377   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16378   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16379 
16380   url::SchemeHostPort test_server(request.url);
16381   HttpServerProperties* http_server_properties =
16382       session->http_server_properties();
16383   EXPECT_TRUE(
16384       http_server_properties
16385           ->GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
16386           .empty());
16387 
16388   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16389   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16390   EXPECT_THAT(callback.WaitForResult(), IsOk());
16391 
16392   const HttpResponseInfo* response = trans.GetResponseInfo();
16393   ASSERT_TRUE(response);
16394   ASSERT_TRUE(response->headers);
16395   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16396   EXPECT_FALSE(response->was_fetched_via_spdy);
16397   EXPECT_FALSE(response->was_alpn_negotiated);
16398 
16399   std::string response_data;
16400   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
16401   EXPECT_EQ("hello world", response_data);
16402 
16403   EXPECT_TRUE(
16404       http_server_properties
16405           ->GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
16406           .empty());
16407 }
16408 
16409 // HTTP/2 Alternative Services should be disabled by default.
16410 // TODO(bnc): Remove when https://crbug.com/615413 is fixed.
TEST_P(HttpNetworkTransactionTest,DisableHTTP2AlternativeServicesWithDifferentHost)16411 TEST_P(HttpNetworkTransactionTest,
16412        DisableHTTP2AlternativeServicesWithDifferentHost) {
16413   session_deps_.enable_http2_alternative_service = false;
16414 
16415   HttpRequestInfo request;
16416   request.method = "GET";
16417   request.url = GURL("https://www.example.org/");
16418   request.load_flags = 0;
16419   request.traffic_annotation =
16420       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16421 
16422   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
16423   StaticSocketDataProvider first_data;
16424   first_data.set_connect_data(mock_connect);
16425   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
16426   SSLSocketDataProvider ssl_http11(ASYNC, OK);
16427   ssl_http11.next_proto = kProtoHTTP11;
16428   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
16429 
16430   MockRead data_reads[] = {
16431       MockRead("HTTP/1.1 200 OK\r\n\r\n"),
16432       MockRead("hello world"),
16433       MockRead(ASYNC, OK),
16434   };
16435   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
16436   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
16437 
16438   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16439 
16440   HttpServerProperties* http_server_properties =
16441       session->http_server_properties();
16442   AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
16443                                          444);
16444   base::Time expiration = base::Time::Now() + base::Days(1);
16445   http_server_properties->SetHttp2AlternativeService(
16446       url::SchemeHostPort(request.url), NetworkAnonymizationKey(),
16447       alternative_service, expiration);
16448 
16449   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16450   TestCompletionCallback callback;
16451 
16452   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16453   // Alternative service is not used, request fails.
16454   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
16455 }
16456 
16457 // Regression test for https://crbug.com/615497:
16458 // Alternative Services should be disabled for http origin.
TEST_P(HttpNetworkTransactionTest,DisableAlternativeServicesForInsecureOrigin)16459 TEST_P(HttpNetworkTransactionTest,
16460        DisableAlternativeServicesForInsecureOrigin) {
16461   HttpRequestInfo request;
16462   request.method = "GET";
16463   request.url = GURL("http://www.example.org/");
16464   request.load_flags = 0;
16465   request.traffic_annotation =
16466       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16467 
16468   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
16469   StaticSocketDataProvider first_data;
16470   first_data.set_connect_data(mock_connect);
16471   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
16472 
16473   MockRead data_reads[] = {
16474       MockRead("HTTP/1.1 200 OK\r\n\r\n"),
16475       MockRead("hello world"),
16476       MockRead(ASYNC, OK),
16477   };
16478   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
16479   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
16480 
16481   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16482 
16483   HttpServerProperties* http_server_properties =
16484       session->http_server_properties();
16485   AlternativeService alternative_service(kProtoHTTP2, "", 444);
16486   base::Time expiration = base::Time::Now() + base::Days(1);
16487   http_server_properties->SetHttp2AlternativeService(
16488       url::SchemeHostPort(request.url), NetworkAnonymizationKey(),
16489       alternative_service, expiration);
16490 
16491   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16492   TestCompletionCallback callback;
16493 
16494   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16495   // Alternative service is not used, request fails.
16496   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
16497 }
16498 
TEST_P(HttpNetworkTransactionTest,ClearAlternativeServices)16499 TEST_P(HttpNetworkTransactionTest, ClearAlternativeServices) {
16500   // Set an alternative service for origin.
16501   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16502   HttpServerProperties* http_server_properties =
16503       session->http_server_properties();
16504   url::SchemeHostPort test_server("https", "www.example.org", 443);
16505   AlternativeService alternative_service(kProtoQUIC, "", 80);
16506   base::Time expiration = base::Time::Now() + base::Days(1);
16507   http_server_properties->SetQuicAlternativeService(
16508       test_server, NetworkAnonymizationKey(), alternative_service, expiration,
16509       session->context().quic_context->params()->supported_versions);
16510   EXPECT_EQ(1u, http_server_properties
16511                     ->GetAlternativeServiceInfos(test_server,
16512                                                  NetworkAnonymizationKey())
16513                     .size());
16514 
16515   // Send a clear header.
16516   MockRead data_reads[] = {
16517       MockRead("HTTP/1.1 200 OK\r\n"),
16518       MockRead("Alt-Svc: clear\r\n"),
16519       MockRead("\r\n"),
16520       MockRead("hello world"),
16521       MockRead(SYNCHRONOUS, OK),
16522   };
16523   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
16524   session_deps_.socket_factory->AddSocketDataProvider(&data);
16525 
16526   SSLSocketDataProvider ssl(ASYNC, OK);
16527   ssl.ssl_info.cert =
16528       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
16529   ASSERT_TRUE(ssl.ssl_info.cert);
16530   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16531 
16532   HttpRequestInfo request;
16533   request.method = "GET";
16534   request.url = GURL("https://www.example.org/");
16535   request.traffic_annotation =
16536       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16537 
16538   TestCompletionCallback callback;
16539 
16540   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16541 
16542   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16543   EXPECT_THAT(callback.GetResult(rv), IsOk());
16544 
16545   const HttpResponseInfo* response = trans.GetResponseInfo();
16546   ASSERT_TRUE(response);
16547   ASSERT_TRUE(response->headers);
16548   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16549   EXPECT_FALSE(response->was_fetched_via_spdy);
16550   EXPECT_FALSE(response->was_alpn_negotiated);
16551 
16552   std::string response_data;
16553   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
16554   EXPECT_EQ("hello world", response_data);
16555 
16556   EXPECT_TRUE(
16557       http_server_properties
16558           ->GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
16559           .empty());
16560 }
16561 
TEST_P(HttpNetworkTransactionTest,HonorMultipleAlternativeServiceHeaders)16562 TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
16563   MockRead data_reads[] = {
16564       MockRead("HTTP/1.1 200 OK\r\n"),
16565       MockRead("Alt-Svc: h2=\"www.example.com:443\","),
16566       MockRead("h2=\":1234\"\r\n\r\n"),
16567       MockRead("hello world"),
16568       MockRead(SYNCHRONOUS, OK),
16569   };
16570 
16571   HttpRequestInfo request;
16572   request.method = "GET";
16573   request.url = GURL("https://www.example.org/");
16574   request.traffic_annotation =
16575       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16576 
16577   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
16578   session_deps_.socket_factory->AddSocketDataProvider(&data);
16579 
16580   SSLSocketDataProvider ssl(ASYNC, OK);
16581   ssl.ssl_info.cert =
16582       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
16583   ASSERT_TRUE(ssl.ssl_info.cert);
16584   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16585 
16586   TestCompletionCallback callback;
16587 
16588   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16589   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16590 
16591   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16592   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16593 
16594   url::SchemeHostPort test_server("https", "www.example.org", 443);
16595   HttpServerProperties* http_server_properties =
16596       session->http_server_properties();
16597   EXPECT_TRUE(
16598       http_server_properties
16599           ->GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
16600           .empty());
16601 
16602   EXPECT_THAT(callback.WaitForResult(), IsOk());
16603 
16604   const HttpResponseInfo* response = trans.GetResponseInfo();
16605   ASSERT_TRUE(response);
16606   ASSERT_TRUE(response->headers);
16607   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16608   EXPECT_FALSE(response->was_fetched_via_spdy);
16609   EXPECT_FALSE(response->was_alpn_negotiated);
16610 
16611   std::string response_data;
16612   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
16613   EXPECT_EQ("hello world", response_data);
16614 
16615   AlternativeServiceInfoVector alternative_service_info_vector =
16616       http_server_properties->GetAlternativeServiceInfos(
16617           test_server, NetworkAnonymizationKey());
16618   ASSERT_EQ(2u, alternative_service_info_vector.size());
16619 
16620   AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
16621   EXPECT_EQ(alternative_service,
16622             alternative_service_info_vector[0].alternative_service());
16623   AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
16624                                            1234);
16625   EXPECT_EQ(alternative_service_2,
16626             alternative_service_info_vector[1].alternative_service());
16627 }
16628 
TEST_P(HttpNetworkTransactionTest,IdentifyQuicBroken)16629 TEST_P(HttpNetworkTransactionTest, IdentifyQuicBroken) {
16630   url::SchemeHostPort server("https", "origin.example.org", 443);
16631   HostPortPair alternative("alternative.example.org", 443);
16632   std::string origin_url = "https://origin.example.org:443";
16633   std::string alternative_url = "https://alternative.example.org:443";
16634 
16635   // Negotiate HTTP/1.1 with alternative.example.org.
16636   SSLSocketDataProvider ssl(ASYNC, OK);
16637   ssl.next_proto = kProtoHTTP11;
16638   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16639 
16640   // HTTP/1.1 data for request.
16641   MockWrite http_writes[] = {
16642       MockWrite("GET / HTTP/1.1\r\n"
16643                 "Host: alternative.example.org\r\n"
16644                 "Connection: keep-alive\r\n\r\n"),
16645   };
16646 
16647   MockRead http_reads[] = {
16648       MockRead("HTTP/1.1 200 OK\r\n"
16649                "Content-Type: text/html; charset=iso-8859-1\r\n"
16650                "Content-Length: 40\r\n\r\n"
16651                "first HTTP/1.1 response from alternative"),
16652   };
16653   StaticSocketDataProvider http_data(http_reads, http_writes);
16654   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16655 
16656   StaticSocketDataProvider data_refused;
16657   data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16658   session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16659 
16660   // Set up a QUIC alternative service for server.
16661   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16662   HttpServerProperties* http_server_properties =
16663       session->http_server_properties();
16664   AlternativeService alternative_service(kProtoQUIC, alternative);
16665   base::Time expiration = base::Time::Now() + base::Days(1);
16666   http_server_properties->SetQuicAlternativeService(
16667       server, NetworkAnonymizationKey(), alternative_service, expiration,
16668       DefaultSupportedQuicVersions());
16669   // Mark the QUIC alternative service as broken.
16670   http_server_properties->MarkAlternativeServiceBroken(
16671       alternative_service, NetworkAnonymizationKey());
16672 
16673   HttpRequestInfo request;
16674   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16675   request.method = "GET";
16676   request.url = GURL(origin_url);
16677   request.traffic_annotation =
16678       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16679 
16680   TestCompletionCallback callback;
16681   NetErrorDetails details;
16682   EXPECT_FALSE(details.quic_broken);
16683 
16684   trans.Start(&request, callback.callback(), NetLogWithSource());
16685   trans.PopulateNetErrorDetails(&details);
16686   EXPECT_TRUE(details.quic_broken);
16687 }
16688 
TEST_P(HttpNetworkTransactionTest,IdentifyQuicNotBroken)16689 TEST_P(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
16690   url::SchemeHostPort server("https", "origin.example.org", 443);
16691   HostPortPair alternative1("alternative1.example.org", 443);
16692   HostPortPair alternative2("alternative2.example.org", 443);
16693   std::string origin_url = "https://origin.example.org:443";
16694   std::string alternative_url1 = "https://alternative1.example.org:443";
16695   std::string alternative_url2 = "https://alternative2.example.org:443";
16696 
16697   // Negotiate HTTP/1.1 with alternative1.example.org.
16698   SSLSocketDataProvider ssl(ASYNC, OK);
16699   ssl.next_proto = kProtoHTTP11;
16700   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16701 
16702   // HTTP/1.1 data for request.
16703   MockWrite http_writes[] = {
16704       MockWrite("GET / HTTP/1.1\r\n"
16705                 "Host: alternative1.example.org\r\n"
16706                 "Connection: keep-alive\r\n\r\n"),
16707   };
16708 
16709   MockRead http_reads[] = {
16710       MockRead("HTTP/1.1 200 OK\r\n"
16711                "Content-Type: text/html; charset=iso-8859-1\r\n"
16712                "Content-Length: 40\r\n\r\n"
16713                "first HTTP/1.1 response from alternative1"),
16714   };
16715   StaticSocketDataProvider http_data(http_reads, http_writes);
16716   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16717 
16718   StaticSocketDataProvider data_refused;
16719   data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16720   session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16721 
16722   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16723   HttpServerProperties* http_server_properties =
16724       session->http_server_properties();
16725 
16726   // Set up two QUIC alternative services for server.
16727   AlternativeServiceInfoVector alternative_service_info_vector;
16728   base::Time expiration = base::Time::Now() + base::Days(1);
16729 
16730   AlternativeService alternative_service1(kProtoQUIC, alternative1);
16731   alternative_service_info_vector.push_back(
16732       AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
16733           alternative_service1, expiration,
16734           session->context().quic_context->params()->supported_versions));
16735   AlternativeService alternative_service2(kProtoQUIC, alternative2);
16736   alternative_service_info_vector.push_back(
16737       AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
16738           alternative_service2, expiration,
16739           session->context().quic_context->params()->supported_versions));
16740 
16741   http_server_properties->SetAlternativeServices(
16742       server, NetworkAnonymizationKey(), alternative_service_info_vector);
16743 
16744   // Mark one of the QUIC alternative service as broken.
16745   http_server_properties->MarkAlternativeServiceBroken(
16746       alternative_service1, NetworkAnonymizationKey());
16747   EXPECT_EQ(2u,
16748             http_server_properties
16749                 ->GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
16750                 .size());
16751 
16752   HttpRequestInfo request;
16753   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16754   request.method = "GET";
16755   request.url = GURL(origin_url);
16756   request.traffic_annotation =
16757       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16758 
16759   TestCompletionCallback callback;
16760   NetErrorDetails details;
16761   EXPECT_FALSE(details.quic_broken);
16762 
16763   trans.Start(&request, callback.callback(), NetLogWithSource());
16764   trans.PopulateNetErrorDetails(&details);
16765   EXPECT_FALSE(details.quic_broken);
16766 }
16767 
TEST_P(HttpNetworkTransactionTest,MarkBrokenAlternateProtocolAndFallback)16768 TEST_P(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
16769   HttpRequestInfo request;
16770   request.method = "GET";
16771   request.url = GURL("https://www.example.org/");
16772   request.traffic_annotation =
16773       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16774 
16775   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
16776   StaticSocketDataProvider first_data;
16777   first_data.set_connect_data(mock_connect);
16778   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
16779   SSLSocketDataProvider ssl_http11(ASYNC, OK);
16780   ssl_http11.next_proto = kProtoHTTP11;
16781   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
16782 
16783   MockRead data_reads[] = {
16784       MockRead("HTTP/1.1 200 OK\r\n\r\n"),
16785       MockRead("hello world"),
16786       MockRead(ASYNC, OK),
16787   };
16788   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
16789   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
16790 
16791   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16792 
16793   HttpServerProperties* http_server_properties =
16794       session->http_server_properties();
16795   const url::SchemeHostPort server(request.url);
16796   // Port must be < 1024, or the header will be ignored (since initial port was
16797   // port 80 (another restricted port).
16798   // Port is ignored by MockConnect anyway.
16799   const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
16800                                                666);
16801   base::Time expiration = base::Time::Now() + base::Days(1);
16802   http_server_properties->SetHttp2AlternativeService(
16803       server, NetworkAnonymizationKey(), alternative_service, expiration);
16804 
16805   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16806   TestCompletionCallback callback;
16807 
16808   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16809   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16810   EXPECT_THAT(callback.WaitForResult(), IsOk());
16811 
16812   const HttpResponseInfo* response = trans.GetResponseInfo();
16813   ASSERT_TRUE(response);
16814   ASSERT_TRUE(response->headers);
16815   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16816 
16817   std::string response_data;
16818   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
16819   EXPECT_EQ("hello world", response_data);
16820 
16821   const AlternativeServiceInfoVector alternative_service_info_vector =
16822       http_server_properties->GetAlternativeServiceInfos(
16823           server, NetworkAnonymizationKey());
16824   ASSERT_EQ(1u, alternative_service_info_vector.size());
16825   EXPECT_EQ(alternative_service,
16826             alternative_service_info_vector[0].alternative_service());
16827   EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
16828       alternative_service, NetworkAnonymizationKey()));
16829 }
16830 
16831 // Ensure that we are not allowed to redirect traffic via an alternate protocol
16832 // to an unrestricted (port >= 1024) when the original traffic was on a
16833 // restricted port (port < 1024).  Ensure that we can redirect in all other
16834 // cases.
TEST_P(HttpNetworkTransactionTest,AlternateProtocolPortRestrictedBlocked)16835 TEST_P(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
16836   HttpRequestInfo restricted_port_request;
16837   restricted_port_request.method = "GET";
16838   restricted_port_request.url = GURL("https://www.example.org:1023/");
16839   restricted_port_request.load_flags = 0;
16840   restricted_port_request.traffic_annotation =
16841       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16842 
16843   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
16844   StaticSocketDataProvider first_data;
16845   first_data.set_connect_data(mock_connect);
16846   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
16847 
16848   MockRead data_reads[] = {
16849       MockRead("HTTP/1.1 200 OK\r\n\r\n"),
16850       MockRead("hello world"),
16851       MockRead(ASYNC, OK),
16852   };
16853   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
16854   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
16855   SSLSocketDataProvider ssl_http11(ASYNC, OK);
16856   ssl_http11.next_proto = kProtoHTTP11;
16857   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
16858 
16859   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16860 
16861   HttpServerProperties* http_server_properties =
16862       session->http_server_properties();
16863   const int kUnrestrictedAlternatePort = 1024;
16864   AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
16865                                          kUnrestrictedAlternatePort);
16866   base::Time expiration = base::Time::Now() + base::Days(1);
16867   http_server_properties->SetHttp2AlternativeService(
16868       url::SchemeHostPort(restricted_port_request.url),
16869       NetworkAnonymizationKey(), alternative_service, expiration);
16870 
16871   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16872   TestCompletionCallback callback;
16873 
16874   int rv = trans.Start(&restricted_port_request, callback.callback(),
16875                        NetLogWithSource());
16876   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16877   // Invalid change to unrestricted port should fail.
16878   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
16879 }
16880 
16881 // Ensure that we are allowed to redirect traffic via an alternate protocol to
16882 // an unrestricted (port >= 1024) when the original traffic was on a restricted
16883 // port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
TEST_P(HttpNetworkTransactionTest,AlternateProtocolPortRestrictedPermitted)16884 TEST_P(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
16885   session_deps_.enable_user_alternate_protocol_ports = true;
16886 
16887   HttpRequestInfo restricted_port_request;
16888   restricted_port_request.method = "GET";
16889   restricted_port_request.url = GURL("https://www.example.org:1023/");
16890   restricted_port_request.load_flags = 0;
16891   restricted_port_request.traffic_annotation =
16892       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16893 
16894   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
16895   StaticSocketDataProvider first_data;
16896   first_data.set_connect_data(mock_connect);
16897   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
16898 
16899   MockRead data_reads[] = {
16900       MockRead("HTTP/1.1 200 OK\r\n\r\n"),
16901       MockRead("hello world"),
16902       MockRead(ASYNC, OK),
16903   };
16904   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
16905   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
16906   SSLSocketDataProvider ssl_http11(ASYNC, OK);
16907   ssl_http11.next_proto = kProtoHTTP11;
16908   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
16909 
16910   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16911 
16912   HttpServerProperties* http_server_properties =
16913       session->http_server_properties();
16914   const int kUnrestrictedAlternatePort = 1024;
16915   AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
16916                                          kUnrestrictedAlternatePort);
16917   base::Time expiration = base::Time::Now() + base::Days(1);
16918   http_server_properties->SetHttp2AlternativeService(
16919       url::SchemeHostPort(restricted_port_request.url),
16920       NetworkAnonymizationKey(), alternative_service, expiration);
16921 
16922   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16923   TestCompletionCallback callback;
16924 
16925   EXPECT_EQ(ERR_IO_PENDING,
16926             trans.Start(&restricted_port_request, callback.callback(),
16927                         NetLogWithSource()));
16928   // Change to unrestricted port should succeed.
16929   EXPECT_THAT(callback.WaitForResult(), IsOk());
16930 }
16931 
16932 // Ensure that we are not allowed to redirect traffic via an alternate protocol
16933 // to an unrestricted (port >= 1024) when the original traffic was on a
16934 // restricted port (port < 1024).  Ensure that we can redirect in all other
16935 // cases.
TEST_P(HttpNetworkTransactionTest,AlternateProtocolPortRestrictedAllowed)16936 TEST_P(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
16937   HttpRequestInfo restricted_port_request;
16938   restricted_port_request.method = "GET";
16939   restricted_port_request.url = GURL("https://www.example.org:1023/");
16940   restricted_port_request.load_flags = 0;
16941   restricted_port_request.traffic_annotation =
16942       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16943 
16944   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
16945   StaticSocketDataProvider first_data;
16946   first_data.set_connect_data(mock_connect);
16947   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
16948 
16949   MockRead data_reads[] = {
16950       MockRead("HTTP/1.1 200 OK\r\n\r\n"),
16951       MockRead("hello world"),
16952       MockRead(ASYNC, OK),
16953   };
16954   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
16955   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
16956 
16957   SSLSocketDataProvider ssl(ASYNC, OK);
16958   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16959 
16960   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16961 
16962   HttpServerProperties* http_server_properties =
16963       session->http_server_properties();
16964   const int kRestrictedAlternatePort = 80;
16965   AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
16966                                          kRestrictedAlternatePort);
16967   base::Time expiration = base::Time::Now() + base::Days(1);
16968   http_server_properties->SetHttp2AlternativeService(
16969       url::SchemeHostPort(restricted_port_request.url),
16970       NetworkAnonymizationKey(), alternative_service, expiration);
16971 
16972   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16973   TestCompletionCallback callback;
16974 
16975   int rv = trans.Start(&restricted_port_request, callback.callback(),
16976                        NetLogWithSource());
16977   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16978   // Valid change to restricted port should pass.
16979   EXPECT_THAT(callback.WaitForResult(), IsOk());
16980 }
16981 
16982 // Ensure that we are not allowed to redirect traffic via an alternate protocol
16983 // to an unrestricted (port >= 1024) when the original traffic was on a
16984 // restricted port (port < 1024).  Ensure that we can redirect in all other
16985 // cases.
TEST_P(HttpNetworkTransactionTest,AlternateProtocolPortUnrestrictedAllowed1)16986 TEST_P(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
16987   HttpRequestInfo unrestricted_port_request;
16988   unrestricted_port_request.method = "GET";
16989   unrestricted_port_request.url = GURL("https://www.example.org:1024/");
16990   unrestricted_port_request.load_flags = 0;
16991   unrestricted_port_request.traffic_annotation =
16992       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16993 
16994   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
16995   StaticSocketDataProvider first_data;
16996   first_data.set_connect_data(mock_connect);
16997   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
16998 
16999   MockRead data_reads[] = {
17000       MockRead("HTTP/1.1 200 OK\r\n\r\n"),
17001       MockRead("hello world"),
17002       MockRead(ASYNC, OK),
17003   };
17004   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
17005   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
17006   SSLSocketDataProvider ssl_http11(ASYNC, OK);
17007   ssl_http11.next_proto = kProtoHTTP11;
17008   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
17009 
17010   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17011 
17012   HttpServerProperties* http_server_properties =
17013       session->http_server_properties();
17014   const int kRestrictedAlternatePort = 80;
17015   AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
17016                                          kRestrictedAlternatePort);
17017   base::Time expiration = base::Time::Now() + base::Days(1);
17018   http_server_properties->SetHttp2AlternativeService(
17019       url::SchemeHostPort(unrestricted_port_request.url),
17020       NetworkAnonymizationKey(), alternative_service, expiration);
17021 
17022   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17023   TestCompletionCallback callback;
17024 
17025   int rv = trans.Start(&unrestricted_port_request, callback.callback(),
17026                        NetLogWithSource());
17027   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17028   // Valid change to restricted port should pass.
17029   EXPECT_THAT(callback.WaitForResult(), IsOk());
17030 }
17031 
17032 // Ensure that we are not allowed to redirect traffic via an alternate protocol
17033 // to an unrestricted (port >= 1024) when the original traffic was on a
17034 // restricted port (port < 1024).  Ensure that we can redirect in all other
17035 // cases.
TEST_P(HttpNetworkTransactionTest,AlternateProtocolPortUnrestrictedAllowed2)17036 TEST_P(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
17037   HttpRequestInfo unrestricted_port_request;
17038   unrestricted_port_request.method = "GET";
17039   unrestricted_port_request.url = GURL("https://www.example.org:1024/");
17040   unrestricted_port_request.load_flags = 0;
17041   unrestricted_port_request.traffic_annotation =
17042       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17043 
17044   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
17045   StaticSocketDataProvider first_data;
17046   first_data.set_connect_data(mock_connect);
17047   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
17048 
17049   MockRead data_reads[] = {
17050       MockRead("HTTP/1.1 200 OK\r\n\r\n"),
17051       MockRead("hello world"),
17052       MockRead(ASYNC, OK),
17053   };
17054   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
17055   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
17056 
17057   SSLSocketDataProvider ssl(ASYNC, OK);
17058   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17059 
17060   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17061 
17062   HttpServerProperties* http_server_properties =
17063       session->http_server_properties();
17064   const int kUnrestrictedAlternatePort = 1025;
17065   AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
17066                                          kUnrestrictedAlternatePort);
17067   base::Time expiration = base::Time::Now() + base::Days(1);
17068   http_server_properties->SetHttp2AlternativeService(
17069       url::SchemeHostPort(unrestricted_port_request.url),
17070       NetworkAnonymizationKey(), alternative_service, expiration);
17071 
17072   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17073   TestCompletionCallback callback;
17074 
17075   int rv = trans.Start(&unrestricted_port_request, callback.callback(),
17076                        NetLogWithSource());
17077   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17078   // Valid change to an unrestricted port should pass.
17079   EXPECT_THAT(callback.WaitForResult(), IsOk());
17080 }
17081 
17082 // Ensure that we are not allowed to redirect traffic via an alternate protocol
17083 // to an unsafe port, and that we resume the second HttpStreamFactory::Job once
17084 // the alternate protocol request fails.
TEST_P(HttpNetworkTransactionTest,AlternateProtocolUnsafeBlocked)17085 TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
17086   HttpRequestInfo request;
17087   request.method = "GET";
17088   request.url = GURL("http://www.example.org/");
17089   request.traffic_annotation =
17090       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17091 
17092   // The alternate protocol request will error out before we attempt to connect,
17093   // so only the standard HTTP request will try to connect.
17094   MockRead data_reads[] = {
17095       MockRead("HTTP/1.1 200 OK\r\n\r\n"),
17096       MockRead("hello world"),
17097       MockRead(ASYNC, OK),
17098   };
17099   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
17100   session_deps_.socket_factory->AddSocketDataProvider(&data);
17101 
17102   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17103 
17104   HttpServerProperties* http_server_properties =
17105       session->http_server_properties();
17106   const int kUnsafePort = 7;
17107   AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
17108                                          kUnsafePort);
17109   base::Time expiration = base::Time::Now() + base::Days(1);
17110   http_server_properties->SetHttp2AlternativeService(
17111       url::SchemeHostPort(request.url), NetworkAnonymizationKey(),
17112       alternative_service, expiration);
17113 
17114   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17115   TestCompletionCallback callback;
17116 
17117   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17118   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17119   // The HTTP request should succeed.
17120   EXPECT_THAT(callback.WaitForResult(), IsOk());
17121 
17122   const HttpResponseInfo* response = trans.GetResponseInfo();
17123   ASSERT_TRUE(response);
17124   ASSERT_TRUE(response->headers);
17125   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
17126 
17127   std::string response_data;
17128   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
17129   EXPECT_EQ("hello world", response_data);
17130 }
17131 
TEST_P(HttpNetworkTransactionTest,UseAlternateProtocolForNpnSpdy)17132 TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
17133   HttpRequestInfo request;
17134   request.method = "GET";
17135   request.url = GURL("https://www.example.org/");
17136   request.traffic_annotation =
17137       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17138 
17139   MockRead data_reads[] = {
17140       MockRead("HTTP/1.1 200 OK\r\n"),
17141       MockRead(kAlternativeServiceHttpHeader),
17142       MockRead("\r\n"),
17143       MockRead("hello world"),
17144       MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
17145       MockRead(ASYNC, OK)};
17146 
17147   StaticSocketDataProvider first_transaction(data_reads,
17148                                              base::span<MockWrite>());
17149   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
17150   SSLSocketDataProvider ssl_http11(ASYNC, OK);
17151   ssl_http11.next_proto = kProtoHTTP11;
17152   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
17153 
17154   AddSSLSocketData();
17155 
17156   spdy::SpdySerializedFrame req(
17157       spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
17158   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
17159 
17160   spdy::SpdySerializedFrame resp(
17161       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17162   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
17163   MockRead spdy_reads[] = {
17164       CreateMockRead(resp, 1),
17165       CreateMockRead(data, 2),
17166       MockRead(ASYNC, 0, 3),
17167   };
17168 
17169   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
17170   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
17171 
17172   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
17173   StaticSocketDataProvider hanging_non_alternate_protocol_socket;
17174   hanging_non_alternate_protocol_socket.set_connect_data(
17175       never_finishing_connect);
17176   session_deps_.socket_factory->AddSocketDataProvider(
17177       &hanging_non_alternate_protocol_socket);
17178 
17179   TestCompletionCallback callback;
17180 
17181   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17182   auto trans =
17183       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
17184 
17185   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17186   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17187   EXPECT_THAT(callback.WaitForResult(), IsOk());
17188 
17189   const HttpResponseInfo* response = trans->GetResponseInfo();
17190   ASSERT_TRUE(response);
17191   ASSERT_TRUE(response->headers);
17192   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
17193 
17194   std::string response_data;
17195   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
17196   EXPECT_EQ("hello world", response_data);
17197 
17198   trans =
17199       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
17200 
17201   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17202   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17203   EXPECT_THAT(callback.WaitForResult(), IsOk());
17204 
17205   response = trans->GetResponseInfo();
17206   ASSERT_TRUE(response);
17207   ASSERT_TRUE(response->headers);
17208   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
17209   EXPECT_TRUE(response->was_fetched_via_spdy);
17210   EXPECT_TRUE(response->was_alpn_negotiated);
17211 
17212   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
17213   EXPECT_EQ("hello!", response_data);
17214 }
17215 
TEST_P(HttpNetworkTransactionTest,AlternateProtocolWithSpdyLateBinding)17216 TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
17217   HttpRequestInfo request;
17218   request.method = "GET";
17219   request.url = GURL("https://www.example.org/");
17220   request.traffic_annotation =
17221       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17222 
17223   // First transaction receives Alt-Svc header over HTTP/1.1.
17224   MockRead data_reads[] = {
17225       MockRead("HTTP/1.1 200 OK\r\n"),
17226       MockRead(kAlternativeServiceHttpHeader),
17227       MockRead("\r\n"),
17228       MockRead("hello world"),
17229       MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
17230       MockRead(ASYNC, OK),
17231   };
17232 
17233   StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
17234   session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
17235 
17236   SSLSocketDataProvider ssl_http11(ASYNC, OK);
17237   ssl_http11.ssl_info.cert =
17238       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
17239   ASSERT_TRUE(ssl_http11.ssl_info.cert);
17240   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
17241 
17242   // Second transaction starts an alternative and a non-alternative Job.
17243   // Both sockets hang.
17244   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
17245   StaticSocketDataProvider hanging_socket1;
17246   hanging_socket1.set_connect_data(never_finishing_connect);
17247   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
17248 
17249   StaticSocketDataProvider hanging_socket2;
17250   hanging_socket2.set_connect_data(never_finishing_connect);
17251   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
17252 
17253   // Third transaction starts an alternative and a non-alternative job.
17254   // The non-alternative job hangs, but the alternative one succeeds.
17255   // The second transaction, still pending, binds to this socket.
17256   spdy::SpdySerializedFrame req1(
17257       spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
17258   spdy::SpdySerializedFrame req2(
17259       spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
17260   MockWrite spdy_writes[] = {
17261       CreateMockWrite(req1, 0),
17262       CreateMockWrite(req2, 1),
17263   };
17264   spdy::SpdySerializedFrame resp1(
17265       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17266   spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
17267   spdy::SpdySerializedFrame resp2(
17268       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
17269   spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
17270   MockRead spdy_reads[] = {
17271       CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
17272       CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
17273       MockRead(ASYNC, 0, 6),
17274   };
17275 
17276   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
17277   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
17278 
17279   AddSSLSocketData();
17280 
17281   StaticSocketDataProvider hanging_socket3;
17282   hanging_socket3.set_connect_data(never_finishing_connect);
17283   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
17284 
17285   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17286   TestCompletionCallback callback1;
17287   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
17288 
17289   int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
17290   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17291   EXPECT_THAT(callback1.WaitForResult(), IsOk());
17292 
17293   const HttpResponseInfo* response = trans1.GetResponseInfo();
17294   ASSERT_TRUE(response);
17295   ASSERT_TRUE(response->headers);
17296   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
17297 
17298   std::string response_data;
17299   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
17300   EXPECT_EQ("hello world", response_data);
17301 
17302   TestCompletionCallback callback2;
17303   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
17304   rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
17305   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17306 
17307   TestCompletionCallback callback3;
17308   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
17309   rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
17310   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17311 
17312   EXPECT_THAT(callback2.WaitForResult(), IsOk());
17313   EXPECT_THAT(callback3.WaitForResult(), IsOk());
17314 
17315   response = trans2.GetResponseInfo();
17316   ASSERT_TRUE(response);
17317   ASSERT_TRUE(response->headers);
17318   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
17319   EXPECT_TRUE(response->was_fetched_via_spdy);
17320   EXPECT_TRUE(response->was_alpn_negotiated);
17321   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
17322   EXPECT_EQ("hello!", response_data);
17323 
17324   response = trans3.GetResponseInfo();
17325   ASSERT_TRUE(response);
17326   ASSERT_TRUE(response->headers);
17327   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
17328   EXPECT_TRUE(response->was_fetched_via_spdy);
17329   EXPECT_TRUE(response->was_alpn_negotiated);
17330   ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
17331   EXPECT_EQ("hello!", response_data);
17332 }
17333 
TEST_P(HttpNetworkTransactionTest,StallAlternativeServiceForNpnSpdy)17334 TEST_P(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
17335   session_deps_.host_resolver->set_synchronous_mode(true);
17336 
17337   HttpRequestInfo request;
17338   request.method = "GET";
17339   request.url = GURL("https://www.example.org/");
17340   request.traffic_annotation =
17341       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17342 
17343   MockRead data_reads[] = {
17344       MockRead("HTTP/1.1 200 OK\r\n"),
17345       MockRead(kAlternativeServiceHttpHeader),
17346       MockRead("\r\n"),
17347       MockRead("hello world"),
17348       MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
17349       MockRead(ASYNC, OK),
17350   };
17351 
17352   StaticSocketDataProvider first_transaction(data_reads,
17353                                              base::span<MockWrite>());
17354   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
17355 
17356   SSLSocketDataProvider ssl(ASYNC, OK);
17357   ssl.ssl_info.cert =
17358       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
17359   ASSERT_TRUE(ssl.ssl_info.cert);
17360   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17361 
17362   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
17363   StaticSocketDataProvider hanging_alternate_protocol_socket;
17364   hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
17365   session_deps_.socket_factory->AddSocketDataProvider(
17366       &hanging_alternate_protocol_socket);
17367 
17368   // 2nd request is just a copy of the first one, over HTTP/1.1 again.
17369   StaticSocketDataProvider second_transaction(data_reads,
17370                                               base::span<MockWrite>());
17371   session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
17372   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17373 
17374   TestCompletionCallback callback;
17375 
17376   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17377   auto trans =
17378       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
17379 
17380   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17381   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17382   EXPECT_THAT(callback.WaitForResult(), IsOk());
17383 
17384   const HttpResponseInfo* response = trans->GetResponseInfo();
17385   ASSERT_TRUE(response);
17386   ASSERT_TRUE(response->headers);
17387   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
17388 
17389   std::string response_data;
17390   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
17391   EXPECT_EQ("hello world", response_data);
17392 
17393   trans =
17394       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
17395 
17396   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17397   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17398   EXPECT_THAT(callback.WaitForResult(), IsOk());
17399 
17400   response = trans->GetResponseInfo();
17401   ASSERT_TRUE(response);
17402   ASSERT_TRUE(response->headers);
17403   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
17404   EXPECT_FALSE(response->was_fetched_via_spdy);
17405   EXPECT_FALSE(response->was_alpn_negotiated);
17406 
17407   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
17408   EXPECT_EQ("hello world", response_data);
17409 }
17410 
17411 // Test that proxy is resolved using the origin url,
17412 // regardless of the alternative server.
TEST_P(HttpNetworkTransactionTest,UseOriginNotAlternativeForProxy)17413 TEST_P(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
17414   // Configure proxy to bypass www.example.org, which is the origin URL.
17415   ProxyConfig proxy_config;
17416   proxy_config.proxy_rules().ParseFromString("myproxy:70");
17417   proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
17418   auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
17419       ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
17420 
17421   CapturingProxyResolver capturing_proxy_resolver;
17422   auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
17423       &capturing_proxy_resolver);
17424 
17425   session_deps_.proxy_resolution_service =
17426       std::make_unique<ConfiguredProxyResolutionService>(
17427           std::move(proxy_config_service), std::move(proxy_resolver_factory),
17428           net::NetLog::Get(), /*quick_check_enabled=*/true);
17429 
17430   session_deps_.net_log = net::NetLog::Get();
17431 
17432   // Configure alternative service with a hostname that is not bypassed by the
17433   // proxy.
17434   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17435   HttpServerProperties* http_server_properties =
17436       session->http_server_properties();
17437   url::SchemeHostPort server("https", "www.example.org", 443);
17438   HostPortPair alternative("www.example.com", 443);
17439   AlternativeService alternative_service(kProtoHTTP2, alternative);
17440   base::Time expiration = base::Time::Now() + base::Days(1);
17441   http_server_properties->SetHttp2AlternativeService(
17442       server, NetworkAnonymizationKey(), alternative_service, expiration);
17443 
17444   // Non-alternative job should hang.
17445   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
17446   StaticSocketDataProvider hanging_alternate_protocol_socket;
17447   hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
17448   session_deps_.socket_factory->AddSocketDataProvider(
17449       &hanging_alternate_protocol_socket);
17450 
17451   AddSSLSocketData();
17452 
17453   HttpRequestInfo request;
17454   request.method = "GET";
17455   request.url = GURL("https://www.example.org/");
17456   request.load_flags = 0;
17457   request.traffic_annotation =
17458       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17459 
17460   spdy::SpdySerializedFrame req(
17461       spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
17462 
17463   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
17464 
17465   spdy::SpdySerializedFrame resp(
17466       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17467   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
17468   MockRead spdy_reads[] = {
17469       CreateMockRead(resp, 1),
17470       CreateMockRead(data, 2),
17471       MockRead(ASYNC, 0, 3),
17472   };
17473 
17474   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
17475   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
17476 
17477   TestCompletionCallback callback;
17478 
17479   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17480 
17481   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17482   EXPECT_THAT(callback.GetResult(rv), IsOk());
17483 
17484   const HttpResponseInfo* response = trans.GetResponseInfo();
17485   ASSERT_TRUE(response);
17486   ASSERT_TRUE(response->headers);
17487   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
17488   EXPECT_TRUE(response->was_fetched_via_spdy);
17489   EXPECT_TRUE(response->was_alpn_negotiated);
17490 
17491   std::string response_data;
17492   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
17493   EXPECT_EQ("hello!", response_data);
17494 
17495   // Origin host bypasses proxy, no resolution should have happened.
17496   ASSERT_TRUE(capturing_proxy_resolver.lookup_info().empty());
17497 }
17498 
TEST_P(HttpNetworkTransactionTest,UseAlternativeServiceForTunneledNpnSpdy)17499 TEST_P(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
17500   ProxyConfig proxy_config;
17501   proxy_config.set_auto_detect(true);
17502   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17503 
17504   CapturingProxyResolver capturing_proxy_resolver;
17505   session_deps_.proxy_resolution_service =
17506       std::make_unique<ConfiguredProxyResolutionService>(
17507           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17508               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
17509           std::make_unique<CapturingProxyResolverFactory>(
17510               &capturing_proxy_resolver),
17511           nullptr, /*quick_check_enabled=*/true);
17512   session_deps_.net_log = net::NetLog::Get();
17513 
17514   HttpRequestInfo request;
17515   request.method = "GET";
17516   request.url = GURL("https://www.example.org/");
17517   request.traffic_annotation =
17518       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17519 
17520   MockRead data_reads[] = {
17521       MockRead("HTTP/1.1 200 OK\r\n"),
17522       MockRead(kAlternativeServiceHttpHeader),
17523       MockRead("\r\n"),
17524       MockRead("hello world"),
17525       MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
17526       MockRead(ASYNC, OK),
17527   };
17528 
17529   StaticSocketDataProvider first_transaction(data_reads,
17530                                              base::span<MockWrite>());
17531   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
17532   SSLSocketDataProvider ssl_http11(ASYNC, OK);
17533   ssl_http11.next_proto = kProtoHTTP11;
17534   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
17535 
17536   AddSSLSocketData();
17537 
17538   spdy::SpdySerializedFrame req(
17539       spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
17540   MockWrite spdy_writes[] = {
17541       MockWrite(ASYNC, 0,
17542                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
17543                 "Host: www.example.org:443\r\n"
17544                 "Proxy-Connection: keep-alive\r\n\r\n"),
17545       CreateMockWrite(req, 2),
17546   };
17547 
17548   const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
17549 
17550   spdy::SpdySerializedFrame resp(
17551       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17552   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
17553   MockRead spdy_reads[] = {
17554       MockRead(ASYNC, 1, kCONNECTResponse),
17555       CreateMockRead(resp, 3),
17556       CreateMockRead(data, 4),
17557       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
17558   };
17559 
17560   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
17561   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
17562 
17563   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
17564   StaticSocketDataProvider hanging_non_alternate_protocol_socket;
17565   hanging_non_alternate_protocol_socket.set_connect_data(
17566       never_finishing_connect);
17567   session_deps_.socket_factory->AddSocketDataProvider(
17568       &hanging_non_alternate_protocol_socket);
17569 
17570   TestCompletionCallback callback;
17571 
17572   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17573   auto trans =
17574       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
17575 
17576   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17577   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17578   EXPECT_THAT(callback.WaitForResult(), IsOk());
17579 
17580   const HttpResponseInfo* response = trans->GetResponseInfo();
17581   ASSERT_TRUE(response);
17582   ASSERT_TRUE(response->headers);
17583   EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
17584   EXPECT_FALSE(response->was_fetched_via_spdy);
17585   EXPECT_TRUE(response->was_alpn_negotiated);
17586 
17587   std::string response_data;
17588   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
17589   EXPECT_EQ("hello world", response_data);
17590 
17591   trans =
17592       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
17593 
17594   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17595   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17596   EXPECT_THAT(callback.WaitForResult(), IsOk());
17597 
17598   response = trans->GetResponseInfo();
17599   ASSERT_TRUE(response);
17600   ASSERT_TRUE(response->headers);
17601   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
17602   EXPECT_TRUE(response->was_fetched_via_spdy);
17603   EXPECT_TRUE(response->was_alpn_negotiated);
17604 
17605   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
17606   EXPECT_EQ("hello!", response_data);
17607   ASSERT_EQ(2u, capturing_proxy_resolver.lookup_info().size());
17608   EXPECT_EQ("https://www.example.org/",
17609             capturing_proxy_resolver.lookup_info()[0].url.spec());
17610   EXPECT_EQ("https://www.example.org/",
17611             capturing_proxy_resolver.lookup_info()[1].url.spec());
17612 
17613   LoadTimingInfo load_timing_info;
17614   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
17615   TestLoadTimingNotReusedWithPac(load_timing_info,
17616                                  CONNECT_TIMING_HAS_SSL_TIMES);
17617 }
17618 
TEST_P(HttpNetworkTransactionTest,UseAlternativeServiceForNpnSpdyWithExistingSpdySession)17619 TEST_P(HttpNetworkTransactionTest,
17620        UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
17621   HttpRequestInfo request;
17622   request.method = "GET";
17623   request.url = GURL("https://www.example.org/");
17624   request.traffic_annotation =
17625       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17626 
17627   MockRead data_reads[] = {
17628       MockRead("HTTP/1.1 200 OK\r\n"),
17629       MockRead(kAlternativeServiceHttpHeader),
17630       MockRead("\r\n"),
17631       MockRead("hello world"),
17632       MockRead(ASYNC, OK),
17633   };
17634 
17635   StaticSocketDataProvider first_transaction(data_reads,
17636                                              base::span<MockWrite>());
17637   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
17638   SSLSocketDataProvider ssl_http11(ASYNC, OK);
17639   ssl_http11.next_proto = kProtoHTTP11;
17640   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
17641 
17642   AddSSLSocketData();
17643 
17644   spdy::SpdySerializedFrame req(
17645       spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
17646   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
17647 
17648   spdy::SpdySerializedFrame resp(
17649       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17650   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
17651   MockRead spdy_reads[] = {
17652       CreateMockRead(resp, 1),
17653       CreateMockRead(data, 2),
17654       MockRead(ASYNC, 0, 3),
17655   };
17656 
17657   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
17658   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
17659 
17660   TestCompletionCallback callback;
17661 
17662   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17663 
17664   auto trans =
17665       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
17666 
17667   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17668   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17669   EXPECT_THAT(callback.WaitForResult(), IsOk());
17670 
17671   const HttpResponseInfo* response = trans->GetResponseInfo();
17672   ASSERT_TRUE(response);
17673   ASSERT_TRUE(response->headers);
17674   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
17675 
17676   std::string response_data;
17677   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
17678   EXPECT_EQ("hello world", response_data);
17679 
17680   // Set up an initial SpdySession in the pool to reuse.
17681   HostPortPair host_port_pair("www.example.org", 443);
17682   SpdySessionKey key(host_port_pair, PRIVACY_MODE_DISABLED,
17683                      ProxyChain::Direct(), SessionUsage::kDestination,
17684                      SocketTag(), NetworkAnonymizationKey(),
17685                      SecureDnsPolicy::kAllow,
17686                      /*disable_cert_verification_network_fetches=*/false);
17687   base::WeakPtr<SpdySession> spdy_session =
17688       CreateSpdySession(session.get(), key, NetLogWithSource());
17689 
17690   trans =
17691       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
17692 
17693   ConnectedHandler connected_handler;
17694   trans->SetConnectedCallback(connected_handler.Callback());
17695 
17696   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17697   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17698   EXPECT_THAT(callback.WaitForResult(), IsOk());
17699 
17700   TransportInfo expected_transport;
17701   expected_transport.type = TransportType::kDirect;
17702   expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 443);
17703   expected_transport.negotiated_protocol = kProtoHTTP2;
17704   EXPECT_THAT(connected_handler.transports(), ElementsAre(expected_transport));
17705 
17706   response = trans->GetResponseInfo();
17707   ASSERT_TRUE(response);
17708   ASSERT_TRUE(response->headers);
17709   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
17710   EXPECT_TRUE(response->was_fetched_via_spdy);
17711   EXPECT_TRUE(response->was_alpn_negotiated);
17712 
17713   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
17714   EXPECT_EQ("hello!", response_data);
17715 }
17716 
17717 // GenerateAuthToken is a mighty big test.
17718 // It tests all permutation of GenerateAuthToken behavior:
17719 //   - Synchronous and Asynchronous completion.
17720 //   - OK or error on completion.
17721 //   - Direct connection, non-authenticating proxy, and authenticating proxy.
17722 //   - HTTP or HTTPS backend (to include proxy tunneling).
17723 //   - Non-authenticating and authenticating backend.
17724 //
17725 // In all, there are 44 reasonable permuations (for example, if there are
17726 // problems generating an auth token for an authenticating proxy, we don't
17727 // need to test all permutations of the backend server).
17728 //
17729 // The test proceeds by going over each of the configuration cases, and
17730 // potentially running up to three rounds in each of the tests. The TestConfig
17731 // specifies both the configuration for the test as well as the expectations
17732 // for the results.
TEST_P(HttpNetworkTransactionTest,GenerateAuthToken)17733 TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
17734   static const char kServer[] = "http://www.example.com";
17735   static const char kSecureServer[] = "https://www.example.com";
17736   static const char kProxy[] = "myproxy:70";
17737 
17738   enum AuthTiming {
17739     AUTH_NONE,
17740     AUTH_SYNC,
17741     AUTH_ASYNC,
17742   };
17743 
17744   const MockWrite kGet(
17745       "GET / HTTP/1.1\r\n"
17746       "Host: www.example.com\r\n"
17747       "Connection: keep-alive\r\n\r\n");
17748   const MockWrite kGetProxy(
17749       "GET http://www.example.com/ HTTP/1.1\r\n"
17750       "Host: www.example.com\r\n"
17751       "Proxy-Connection: keep-alive\r\n\r\n");
17752   const MockWrite kGetAuth(
17753       "GET / HTTP/1.1\r\n"
17754       "Host: www.example.com\r\n"
17755       "Connection: keep-alive\r\n"
17756       "Authorization: auth_token\r\n\r\n");
17757   const MockWrite kGetProxyAuth(
17758       "GET http://www.example.com/ HTTP/1.1\r\n"
17759       "Host: www.example.com\r\n"
17760       "Proxy-Connection: keep-alive\r\n"
17761       "Proxy-Authorization: auth_token\r\n\r\n");
17762   const MockWrite kGetAuthThroughProxy(
17763       "GET http://www.example.com/ HTTP/1.1\r\n"
17764       "Host: www.example.com\r\n"
17765       "Proxy-Connection: keep-alive\r\n"
17766       "Authorization: auth_token\r\n\r\n");
17767   const MockWrite kGetAuthWithProxyAuth(
17768       "GET http://www.example.com/ HTTP/1.1\r\n"
17769       "Host: www.example.com\r\n"
17770       "Proxy-Connection: keep-alive\r\n"
17771       "Proxy-Authorization: auth_token\r\n"
17772       "Authorization: auth_token\r\n\r\n");
17773   const MockWrite kConnect(
17774       "CONNECT www.example.com:443 HTTP/1.1\r\n"
17775       "Host: www.example.com:443\r\n"
17776       "Proxy-Connection: keep-alive\r\n\r\n");
17777   const MockWrite kConnectProxyAuth(
17778       "CONNECT www.example.com:443 HTTP/1.1\r\n"
17779       "Host: www.example.com:443\r\n"
17780       "Proxy-Connection: keep-alive\r\n"
17781       "Proxy-Authorization: auth_token\r\n\r\n");
17782 
17783   const MockRead kSuccess(
17784       "HTTP/1.1 200 OK\r\n"
17785       "Content-Type: text/html; charset=iso-8859-1\r\n"
17786       "Content-Length: 3\r\n\r\n"
17787       "Yes");
17788   const MockRead kFailure("Should not be called.");
17789   const MockRead kServerChallenge(
17790       "HTTP/1.1 401 Unauthorized\r\n"
17791       "WWW-Authenticate: Mock realm=server\r\n"
17792       "Content-Type: text/html; charset=iso-8859-1\r\n"
17793       "Content-Length: 14\r\n\r\n"
17794       "Unauthorized\r\n");
17795   const MockRead kProxyChallenge(
17796       "HTTP/1.1 407 Unauthorized\r\n"
17797       "Proxy-Authenticate: Mock realm=proxy\r\n"
17798       "Proxy-Connection: close\r\n"
17799       "Content-Type: text/html; charset=iso-8859-1\r\n"
17800       "Content-Length: 14\r\n\r\n"
17801       "Unauthorized\r\n");
17802   const MockRead kProxyConnected("HTTP/1.1 200 Connection Established\r\n\r\n");
17803 
17804   // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
17805   // no constructors, but the C++ compiler on Windows warns about
17806   // unspecified data in compound literals. So, moved to using constructors,
17807   // and TestRound's created with the default constructor should not be used.
17808   struct TestRound {
17809     TestRound()
17810         : expected_rv(ERR_UNEXPECTED),
17811           extra_write(nullptr),
17812           extra_read(nullptr) {}
17813     TestRound(const MockWrite& write_arg,
17814               const MockRead& read_arg,
17815               int expected_rv_arg)
17816         : write(write_arg),
17817           read(read_arg),
17818           expected_rv(expected_rv_arg),
17819           extra_write(nullptr),
17820           extra_read(nullptr) {}
17821     TestRound(const MockWrite& write_arg,
17822               const MockRead& read_arg,
17823               int expected_rv_arg,
17824               const MockWrite* extra_write_arg,
17825               const MockRead* extra_read_arg)
17826         : write(write_arg),
17827           read(read_arg),
17828           expected_rv(expected_rv_arg),
17829           extra_write(extra_write_arg),
17830           extra_read(extra_read_arg) {}
17831     MockWrite write;
17832     MockRead read;
17833     int expected_rv;
17834     raw_ptr<const MockWrite> extra_write = nullptr;
17835     raw_ptr<const MockRead> extra_read = nullptr;
17836   };
17837 
17838   static const int kNoSSL = 500;
17839 
17840   struct TestConfig {
17841     int line_number;
17842     const char* const proxy_url;
17843     AuthTiming proxy_auth_timing;
17844     int first_generate_proxy_token_rv;
17845     const char* const server_url;
17846     AuthTiming server_auth_timing;
17847     int first_generate_server_token_rv;
17848     int num_auth_rounds;
17849     int first_ssl_round;
17850     TestRound rounds[4];
17851   } test_configs[] = {
17852       // Non-authenticating HTTP server with a direct connection.
17853       {__LINE__,
17854        nullptr,
17855        AUTH_NONE,
17856        OK,
17857        kServer,
17858        AUTH_NONE,
17859        OK,
17860        1,
17861        kNoSSL,
17862        {TestRound(kGet, kSuccess, OK)}},
17863       // Authenticating HTTP server with a direct connection.
17864       {__LINE__,
17865        nullptr,
17866        AUTH_NONE,
17867        OK,
17868        kServer,
17869        AUTH_SYNC,
17870        OK,
17871        2,
17872        kNoSSL,
17873        {TestRound(kGet, kServerChallenge, OK),
17874         TestRound(kGetAuth, kSuccess, OK)}},
17875       {__LINE__,
17876        nullptr,
17877        AUTH_NONE,
17878        OK,
17879        kServer,
17880        AUTH_SYNC,
17881        ERR_INVALID_AUTH_CREDENTIALS,
17882        3,
17883        kNoSSL,
17884        {TestRound(kGet, kServerChallenge, OK),
17885         TestRound(kGet, kServerChallenge, OK),
17886         TestRound(kGetAuth, kSuccess, OK)}},
17887       {__LINE__,
17888        nullptr,
17889        AUTH_NONE,
17890        OK,
17891        kServer,
17892        AUTH_SYNC,
17893        ERR_UNSUPPORTED_AUTH_SCHEME,
17894        2,
17895        kNoSSL,
17896        {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
17897       {__LINE__,
17898        nullptr,
17899        AUTH_NONE,
17900        OK,
17901        kServer,
17902        AUTH_SYNC,
17903        ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
17904        2,
17905        kNoSSL,
17906        {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
17907       {__LINE__,
17908        kProxy,
17909        AUTH_SYNC,
17910        ERR_FAILED,
17911        kServer,
17912        AUTH_NONE,
17913        OK,
17914        2,
17915        kNoSSL,
17916        {TestRound(kGetProxy, kProxyChallenge, OK),
17917         TestRound(kGetProxy, kFailure, ERR_FAILED)}},
17918       {__LINE__,
17919        kProxy,
17920        AUTH_ASYNC,
17921        ERR_FAILED,
17922        kServer,
17923        AUTH_NONE,
17924        OK,
17925        2,
17926        kNoSSL,
17927        {TestRound(kGetProxy, kProxyChallenge, OK),
17928         TestRound(kGetProxy, kFailure, ERR_FAILED)}},
17929       {__LINE__,
17930        nullptr,
17931        AUTH_NONE,
17932        OK,
17933        kServer,
17934        AUTH_SYNC,
17935        ERR_FAILED,
17936        2,
17937        kNoSSL,
17938        {TestRound(kGet, kServerChallenge, OK),
17939         TestRound(kGet, kFailure, ERR_FAILED)}},
17940       {__LINE__,
17941        nullptr,
17942        AUTH_NONE,
17943        OK,
17944        kServer,
17945        AUTH_ASYNC,
17946        ERR_FAILED,
17947        2,
17948        kNoSSL,
17949        {TestRound(kGet, kServerChallenge, OK),
17950         TestRound(kGet, kFailure, ERR_FAILED)}},
17951       {__LINE__,
17952        nullptr,
17953        AUTH_NONE,
17954        OK,
17955        kServer,
17956        AUTH_ASYNC,
17957        OK,
17958        2,
17959        kNoSSL,
17960        {TestRound(kGet, kServerChallenge, OK),
17961         TestRound(kGetAuth, kSuccess, OK)}},
17962       {__LINE__,
17963        nullptr,
17964        AUTH_NONE,
17965        OK,
17966        kServer,
17967        AUTH_ASYNC,
17968        ERR_INVALID_AUTH_CREDENTIALS,
17969        3,
17970        kNoSSL,
17971        {TestRound(kGet, kServerChallenge, OK),
17972         // The second round uses a HttpAuthHandlerMock that always succeeds.
17973         TestRound(kGet, kServerChallenge, OK),
17974         TestRound(kGetAuth, kSuccess, OK)}},
17975       // Non-authenticating HTTP server through a non-authenticating proxy.
17976       {__LINE__,
17977        kProxy,
17978        AUTH_NONE,
17979        OK,
17980        kServer,
17981        AUTH_NONE,
17982        OK,
17983        1,
17984        kNoSSL,
17985        {TestRound(kGetProxy, kSuccess, OK)}},
17986       // Authenticating HTTP server through a non-authenticating proxy.
17987       {__LINE__,
17988        kProxy,
17989        AUTH_NONE,
17990        OK,
17991        kServer,
17992        AUTH_SYNC,
17993        OK,
17994        2,
17995        kNoSSL,
17996        {TestRound(kGetProxy, kServerChallenge, OK),
17997         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
17998       {__LINE__,
17999        kProxy,
18000        AUTH_NONE,
18001        OK,
18002        kServer,
18003        AUTH_SYNC,
18004        ERR_INVALID_AUTH_CREDENTIALS,
18005        3,
18006        kNoSSL,
18007        {TestRound(kGetProxy, kServerChallenge, OK),
18008         TestRound(kGetProxy, kServerChallenge, OK),
18009         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
18010       {__LINE__,
18011        kProxy,
18012        AUTH_NONE,
18013        OK,
18014        kServer,
18015        AUTH_ASYNC,
18016        OK,
18017        2,
18018        kNoSSL,
18019        {TestRound(kGetProxy, kServerChallenge, OK),
18020         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
18021       {__LINE__,
18022        kProxy,
18023        AUTH_NONE,
18024        OK,
18025        kServer,
18026        AUTH_ASYNC,
18027        ERR_INVALID_AUTH_CREDENTIALS,
18028        2,
18029        kNoSSL,
18030        {TestRound(kGetProxy, kServerChallenge, OK),
18031         TestRound(kGetProxy, kSuccess, OK)}},
18032       // Non-authenticating HTTP server through an authenticating proxy.
18033       {__LINE__,
18034        kProxy,
18035        AUTH_SYNC,
18036        OK,
18037        kServer,
18038        AUTH_NONE,
18039        OK,
18040        2,
18041        kNoSSL,
18042        {TestRound(kGetProxy, kProxyChallenge, OK),
18043         TestRound(kGetProxyAuth, kSuccess, OK)}},
18044       {__LINE__,
18045        kProxy,
18046        AUTH_SYNC,
18047        ERR_INVALID_AUTH_CREDENTIALS,
18048        kServer,
18049        AUTH_NONE,
18050        OK,
18051        2,
18052        kNoSSL,
18053        {TestRound(kGetProxy, kProxyChallenge, OK),
18054         TestRound(kGetProxy, kSuccess, OK)}},
18055       {__LINE__,
18056        kProxy,
18057        AUTH_ASYNC,
18058        OK,
18059        kServer,
18060        AUTH_NONE,
18061        OK,
18062        2,
18063        kNoSSL,
18064        {TestRound(kGetProxy, kProxyChallenge, OK),
18065         TestRound(kGetProxyAuth, kSuccess, OK)}},
18066       {__LINE__,
18067        kProxy,
18068        AUTH_ASYNC,
18069        ERR_INVALID_AUTH_CREDENTIALS,
18070        kServer,
18071        AUTH_NONE,
18072        OK,
18073        2,
18074        kNoSSL,
18075        {TestRound(kGetProxy, kProxyChallenge, OK),
18076         TestRound(kGetProxy, kSuccess, OK)}},
18077       {__LINE__,
18078        kProxy,
18079        AUTH_ASYNC,
18080        ERR_INVALID_AUTH_CREDENTIALS,
18081        kServer,
18082        AUTH_NONE,
18083        OK,
18084        3,
18085        kNoSSL,
18086        {TestRound(kGetProxy, kProxyChallenge, OK),
18087         TestRound(kGetProxy, kProxyChallenge, OK),
18088         TestRound(kGetProxyAuth, kSuccess, OK)}},
18089       // Authenticating HTTP server through an authenticating proxy.
18090       {__LINE__,
18091        kProxy,
18092        AUTH_SYNC,
18093        OK,
18094        kServer,
18095        AUTH_SYNC,
18096        OK,
18097        3,
18098        kNoSSL,
18099        {TestRound(kGetProxy, kProxyChallenge, OK),
18100         TestRound(kGetProxyAuth, kServerChallenge, OK),
18101         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
18102       {__LINE__,
18103        kProxy,
18104        AUTH_SYNC,
18105        OK,
18106        kServer,
18107        AUTH_SYNC,
18108        ERR_INVALID_AUTH_CREDENTIALS,
18109        3,
18110        kNoSSL,
18111        {TestRound(kGetProxy, kProxyChallenge, OK),
18112         TestRound(kGetProxyAuth, kServerChallenge, OK),
18113         TestRound(kGetProxyAuth, kSuccess, OK)}},
18114       {__LINE__,
18115        kProxy,
18116        AUTH_ASYNC,
18117        OK,
18118        kServer,
18119        AUTH_SYNC,
18120        OK,
18121        3,
18122        kNoSSL,
18123        {TestRound(kGetProxy, kProxyChallenge, OK),
18124         TestRound(kGetProxyAuth, kServerChallenge, OK),
18125         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
18126       {__LINE__,
18127        kProxy,
18128        AUTH_ASYNC,
18129        OK,
18130        kServer,
18131        AUTH_SYNC,
18132        ERR_INVALID_AUTH_CREDENTIALS,
18133        3,
18134        kNoSSL,
18135        {TestRound(kGetProxy, kProxyChallenge, OK),
18136         TestRound(kGetProxyAuth, kServerChallenge, OK),
18137         TestRound(kGetProxyAuth, kSuccess, OK)}},
18138       {__LINE__,
18139        kProxy,
18140        AUTH_SYNC,
18141        OK,
18142        kServer,
18143        AUTH_ASYNC,
18144        OK,
18145        3,
18146        kNoSSL,
18147        {TestRound(kGetProxy, kProxyChallenge, OK),
18148         TestRound(kGetProxyAuth, kServerChallenge, OK),
18149         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
18150       {__LINE__,
18151        kProxy,
18152        AUTH_SYNC,
18153        ERR_INVALID_AUTH_CREDENTIALS,
18154        kServer,
18155        AUTH_ASYNC,
18156        OK,
18157        4,
18158        kNoSSL,
18159        {TestRound(kGetProxy, kProxyChallenge, OK),
18160         TestRound(kGetProxy, kProxyChallenge, OK),
18161         TestRound(kGetProxyAuth, kServerChallenge, OK),
18162         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
18163       {__LINE__,
18164        kProxy,
18165        AUTH_SYNC,
18166        OK,
18167        kServer,
18168        AUTH_ASYNC,
18169        ERR_INVALID_AUTH_CREDENTIALS,
18170        3,
18171        kNoSSL,
18172        {TestRound(kGetProxy, kProxyChallenge, OK),
18173         TestRound(kGetProxyAuth, kServerChallenge, OK),
18174         TestRound(kGetProxyAuth, kSuccess, OK)}},
18175       {__LINE__,
18176        kProxy,
18177        AUTH_ASYNC,
18178        OK,
18179        kServer,
18180        AUTH_ASYNC,
18181        OK,
18182        3,
18183        kNoSSL,
18184        {TestRound(kGetProxy, kProxyChallenge, OK),
18185         TestRound(kGetProxyAuth, kServerChallenge, OK),
18186         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
18187       {__LINE__,
18188        kProxy,
18189        AUTH_ASYNC,
18190        OK,
18191        kServer,
18192        AUTH_ASYNC,
18193        ERR_INVALID_AUTH_CREDENTIALS,
18194        3,
18195        kNoSSL,
18196        {TestRound(kGetProxy, kProxyChallenge, OK),
18197         TestRound(kGetProxyAuth, kServerChallenge, OK),
18198         TestRound(kGetProxyAuth, kSuccess, OK)}},
18199       {__LINE__,
18200        kProxy,
18201        AUTH_ASYNC,
18202        ERR_INVALID_AUTH_CREDENTIALS,
18203        kServer,
18204        AUTH_ASYNC,
18205        ERR_INVALID_AUTH_CREDENTIALS,
18206        4,
18207        kNoSSL,
18208        {TestRound(kGetProxy, kProxyChallenge, OK),
18209         TestRound(kGetProxy, kProxyChallenge, OK),
18210         TestRound(kGetProxyAuth, kServerChallenge, OK),
18211         TestRound(kGetProxyAuth, kSuccess, OK)}},
18212       // Non-authenticating HTTPS server with a direct connection.
18213       {__LINE__,
18214        nullptr,
18215        AUTH_NONE,
18216        OK,
18217        kSecureServer,
18218        AUTH_NONE,
18219        OK,
18220        1,
18221        0,
18222        {TestRound(kGet, kSuccess, OK)}},
18223       // Authenticating HTTPS server with a direct connection.
18224       {__LINE__,
18225        nullptr,
18226        AUTH_NONE,
18227        OK,
18228        kSecureServer,
18229        AUTH_SYNC,
18230        OK,
18231        2,
18232        0,
18233        {TestRound(kGet, kServerChallenge, OK),
18234         TestRound(kGetAuth, kSuccess, OK)}},
18235       {__LINE__,
18236        nullptr,
18237        AUTH_NONE,
18238        OK,
18239        kSecureServer,
18240        AUTH_SYNC,
18241        ERR_INVALID_AUTH_CREDENTIALS,
18242        2,
18243        0,
18244        {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
18245       {__LINE__,
18246        nullptr,
18247        AUTH_NONE,
18248        OK,
18249        kSecureServer,
18250        AUTH_ASYNC,
18251        OK,
18252        2,
18253        0,
18254        {TestRound(kGet, kServerChallenge, OK),
18255         TestRound(kGetAuth, kSuccess, OK)}},
18256       {__LINE__,
18257        nullptr,
18258        AUTH_NONE,
18259        OK,
18260        kSecureServer,
18261        AUTH_ASYNC,
18262        ERR_INVALID_AUTH_CREDENTIALS,
18263        2,
18264        0,
18265        {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
18266       // Non-authenticating HTTPS server with a non-authenticating proxy.
18267       {__LINE__,
18268        kProxy,
18269        AUTH_NONE,
18270        OK,
18271        kSecureServer,
18272        AUTH_NONE,
18273        OK,
18274        1,
18275        0,
18276        {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
18277       // Authenticating HTTPS server through a non-authenticating proxy.
18278       {__LINE__,
18279        kProxy,
18280        AUTH_NONE,
18281        OK,
18282        kSecureServer,
18283        AUTH_SYNC,
18284        OK,
18285        2,
18286        0,
18287        {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
18288         TestRound(kGetAuth, kSuccess, OK)}},
18289       {__LINE__,
18290        kProxy,
18291        AUTH_NONE,
18292        OK,
18293        kSecureServer,
18294        AUTH_SYNC,
18295        ERR_INVALID_AUTH_CREDENTIALS,
18296        2,
18297        0,
18298        {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
18299         TestRound(kGet, kSuccess, OK)}},
18300       {__LINE__,
18301        kProxy,
18302        AUTH_NONE,
18303        OK,
18304        kSecureServer,
18305        AUTH_ASYNC,
18306        OK,
18307        2,
18308        0,
18309        {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
18310         TestRound(kGetAuth, kSuccess, OK)}},
18311       {__LINE__,
18312        kProxy,
18313        AUTH_NONE,
18314        OK,
18315        kSecureServer,
18316        AUTH_ASYNC,
18317        ERR_INVALID_AUTH_CREDENTIALS,
18318        2,
18319        0,
18320        {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
18321         TestRound(kGet, kSuccess, OK)}},
18322       // Non-Authenticating HTTPS server through an authenticating proxy.
18323       {__LINE__,
18324        kProxy,
18325        AUTH_SYNC,
18326        OK,
18327        kSecureServer,
18328        AUTH_NONE,
18329        OK,
18330        2,
18331        1,
18332        {TestRound(kConnect, kProxyChallenge, OK),
18333         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
18334       {__LINE__,
18335        kProxy,
18336        AUTH_SYNC,
18337        ERR_INVALID_AUTH_CREDENTIALS,
18338        kSecureServer,
18339        AUTH_NONE,
18340        OK,
18341        2,
18342        kNoSSL,
18343        {TestRound(kConnect, kProxyChallenge, OK),
18344         TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
18345       {__LINE__,
18346        kProxy,
18347        AUTH_SYNC,
18348        ERR_UNSUPPORTED_AUTH_SCHEME,
18349        kSecureServer,
18350        AUTH_NONE,
18351        OK,
18352        2,
18353        kNoSSL,
18354        {TestRound(kConnect, kProxyChallenge, OK),
18355         TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
18356       {__LINE__,
18357        kProxy,
18358        AUTH_SYNC,
18359        ERR_UNEXPECTED,
18360        kSecureServer,
18361        AUTH_NONE,
18362        OK,
18363        2,
18364        kNoSSL,
18365        {TestRound(kConnect, kProxyChallenge, OK),
18366         TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
18367       {__LINE__,
18368        kProxy,
18369        AUTH_ASYNC,
18370        OK,
18371        kSecureServer,
18372        AUTH_NONE,
18373        OK,
18374        2,
18375        1,
18376        {TestRound(kConnect, kProxyChallenge, OK),
18377         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
18378       {__LINE__,
18379        kProxy,
18380        AUTH_ASYNC,
18381        ERR_INVALID_AUTH_CREDENTIALS,
18382        kSecureServer,
18383        AUTH_NONE,
18384        OK,
18385        2,
18386        kNoSSL,
18387        {TestRound(kConnect, kProxyChallenge, OK),
18388         TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
18389       // Authenticating HTTPS server through an authenticating proxy.
18390       {__LINE__,
18391        kProxy,
18392        AUTH_SYNC,
18393        OK,
18394        kSecureServer,
18395        AUTH_SYNC,
18396        OK,
18397        3,
18398        1,
18399        {TestRound(kConnect, kProxyChallenge, OK),
18400         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
18401                   &kServerChallenge),
18402         TestRound(kGetAuth, kSuccess, OK)}},
18403       {__LINE__,
18404        kProxy,
18405        AUTH_SYNC,
18406        OK,
18407        kSecureServer,
18408        AUTH_SYNC,
18409        ERR_INVALID_AUTH_CREDENTIALS,
18410        3,
18411        1,
18412        {TestRound(kConnect, kProxyChallenge, OK),
18413         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
18414                   &kServerChallenge),
18415         TestRound(kGet, kSuccess, OK)}},
18416       {__LINE__,
18417        kProxy,
18418        AUTH_ASYNC,
18419        OK,
18420        kSecureServer,
18421        AUTH_SYNC,
18422        OK,
18423        3,
18424        1,
18425        {TestRound(kConnect, kProxyChallenge, OK),
18426         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
18427                   &kServerChallenge),
18428         TestRound(kGetAuth, kSuccess, OK)}},
18429       {__LINE__,
18430        kProxy,
18431        AUTH_ASYNC,
18432        OK,
18433        kSecureServer,
18434        AUTH_SYNC,
18435        ERR_INVALID_AUTH_CREDENTIALS,
18436        3,
18437        1,
18438        {TestRound(kConnect, kProxyChallenge, OK),
18439         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
18440                   &kServerChallenge),
18441         TestRound(kGet, kSuccess, OK)}},
18442       {__LINE__,
18443        kProxy,
18444        AUTH_SYNC,
18445        OK,
18446        kSecureServer,
18447        AUTH_ASYNC,
18448        OK,
18449        3,
18450        1,
18451        {TestRound(kConnect, kProxyChallenge, OK),
18452         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
18453                   &kServerChallenge),
18454         TestRound(kGetAuth, kSuccess, OK)}},
18455       {__LINE__,
18456        kProxy,
18457        AUTH_SYNC,
18458        OK,
18459        kSecureServer,
18460        AUTH_ASYNC,
18461        ERR_INVALID_AUTH_CREDENTIALS,
18462        3,
18463        1,
18464        {TestRound(kConnect, kProxyChallenge, OK),
18465         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
18466                   &kServerChallenge),
18467         TestRound(kGet, kSuccess, OK)}},
18468       {__LINE__,
18469        kProxy,
18470        AUTH_ASYNC,
18471        OK,
18472        kSecureServer,
18473        AUTH_ASYNC,
18474        OK,
18475        3,
18476        1,
18477        {TestRound(kConnect, kProxyChallenge, OK),
18478         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
18479                   &kServerChallenge),
18480         TestRound(kGetAuth, kSuccess, OK)}},
18481       {__LINE__,
18482        kProxy,
18483        AUTH_ASYNC,
18484        OK,
18485        kSecureServer,
18486        AUTH_ASYNC,
18487        ERR_INVALID_AUTH_CREDENTIALS,
18488        3,
18489        1,
18490        {TestRound(kConnect, kProxyChallenge, OK),
18491         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
18492                   &kServerChallenge),
18493         TestRound(kGet, kSuccess, OK)}},
18494       {__LINE__,
18495        kProxy,
18496        AUTH_ASYNC,
18497        ERR_INVALID_AUTH_CREDENTIALS,
18498        kSecureServer,
18499        AUTH_ASYNC,
18500        ERR_INVALID_AUTH_CREDENTIALS,
18501        4,
18502        2,
18503        {TestRound(kConnect, kProxyChallenge, OK),
18504         TestRound(kConnect, kProxyChallenge, OK),
18505         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
18506                   &kServerChallenge),
18507         TestRound(kGet, kSuccess, OK)}},
18508   };
18509 
18510   for (const auto& test_config : test_configs) {
18511     SCOPED_TRACE(::testing::Message()
18512                  << "Test config at " << test_config.line_number);
18513     auto auth_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
18514     auto* auth_factory_ptr = auth_factory.get();
18515     session_deps_.http_auth_handler_factory = std::move(auth_factory);
18516     SSLInfo empty_ssl_info;
18517 
18518     // Set up authentication handlers as necessary.
18519     if (test_config.proxy_auth_timing != AUTH_NONE) {
18520       for (int n = 0; n < 3; n++) {
18521         auto auth_handler = std::make_unique<HttpAuthHandlerMock>();
18522         std::string auth_challenge = "Mock realm=proxy";
18523         url::SchemeHostPort scheme_host_port(GURL(test_config.proxy_url));
18524         HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
18525                                              auth_challenge.end());
18526         auth_handler->InitFromChallenge(
18527             &tokenizer, HttpAuth::AUTH_PROXY, empty_ssl_info,
18528             NetworkAnonymizationKey(), scheme_host_port, NetLogWithSource());
18529         auth_handler->SetGenerateExpectation(
18530             test_config.proxy_auth_timing == AUTH_ASYNC,
18531             n == 0 ? test_config.first_generate_proxy_token_rv : OK);
18532         auth_factory_ptr->AddMockHandler(std::move(auth_handler),
18533                                          HttpAuth::AUTH_PROXY);
18534       }
18535     }
18536     if (test_config.server_auth_timing != AUTH_NONE) {
18537       auto auth_handler = std::make_unique<HttpAuthHandlerMock>();
18538       std::string auth_challenge = "Mock realm=server";
18539       url::SchemeHostPort scheme_host_port(GURL(test_config.server_url));
18540       HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
18541                                            auth_challenge.end());
18542       auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
18543                                       empty_ssl_info, NetworkAnonymizationKey(),
18544                                       scheme_host_port, NetLogWithSource());
18545       auth_handler->SetGenerateExpectation(
18546           test_config.server_auth_timing == AUTH_ASYNC,
18547           test_config.first_generate_server_token_rv);
18548       auth_factory_ptr->AddMockHandler(std::move(auth_handler),
18549                                        HttpAuth::AUTH_SERVER);
18550 
18551       // The second handler always succeeds. It should only be used where there
18552       // are multiple auth sessions for server auth in the same network
18553       // transaction using the same auth scheme.
18554       std::unique_ptr<HttpAuthHandlerMock> second_handler =
18555           std::make_unique<HttpAuthHandlerMock>();
18556       second_handler->InitFromChallenge(
18557           &tokenizer, HttpAuth::AUTH_SERVER, empty_ssl_info,
18558           NetworkAnonymizationKey(), scheme_host_port, NetLogWithSource());
18559       second_handler->SetGenerateExpectation(true, OK);
18560       auth_factory_ptr->AddMockHandler(std::move(second_handler),
18561                                        HttpAuth::AUTH_SERVER);
18562     }
18563     if (test_config.proxy_url) {
18564       session_deps_.proxy_resolution_service =
18565           ConfiguredProxyResolutionService::CreateFixedForTest(
18566               test_config.proxy_url, TRAFFIC_ANNOTATION_FOR_TESTS);
18567     } else {
18568       session_deps_.proxy_resolution_service =
18569           ConfiguredProxyResolutionService::CreateDirect();
18570     }
18571 
18572     HttpRequestInfo request;
18573     request.method = "GET";
18574     request.url = GURL(test_config.server_url);
18575     request.traffic_annotation =
18576         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18577 
18578     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18579 
18580     SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
18581 
18582     std::vector<std::vector<MockRead>> mock_reads(1);
18583     std::vector<std::vector<MockWrite>> mock_writes(1);
18584     for (int round = 0; round < test_config.num_auth_rounds; ++round) {
18585       SCOPED_TRACE(round);
18586       const TestRound& read_write_round = test_config.rounds[round];
18587 
18588       // Set up expected reads and writes.
18589       mock_reads.back().push_back(read_write_round.read);
18590       mock_writes.back().push_back(read_write_round.write);
18591 
18592       // kProxyChallenge uses Proxy-Connection: close which means that the
18593       // socket is closed and a new one will be created for the next request.
18594       if (read_write_round.read.data == kProxyChallenge.data) {
18595         mock_reads.emplace_back();
18596         mock_writes.emplace_back();
18597       }
18598 
18599       if (read_write_round.extra_read) {
18600         mock_reads.back().push_back(*read_write_round.extra_read);
18601       }
18602       if (read_write_round.extra_write) {
18603         mock_writes.back().push_back(*read_write_round.extra_write);
18604       }
18605 
18606       // Add an SSL sequence if necessary.
18607       if (round >= test_config.first_ssl_round) {
18608         session_deps_.socket_factory->AddSSLSocketDataProvider(
18609             &ssl_socket_data_provider);
18610       }
18611     }
18612 
18613     std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
18614     for (size_t i = 0; i < mock_reads.size(); ++i) {
18615       data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
18616           mock_reads[i], mock_writes[i]));
18617       session_deps_.socket_factory->AddSocketDataProvider(
18618           data_providers.back().get());
18619     }
18620 
18621     // Transaction must be created after DataProviders, so it's destroyed before
18622     // they are as well.
18623     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18624 
18625     for (int round = 0; round < test_config.num_auth_rounds; ++round) {
18626       SCOPED_TRACE(round);
18627       const TestRound& read_write_round = test_config.rounds[round];
18628       // Start or restart the transaction.
18629       TestCompletionCallback callback;
18630       int rv;
18631       if (round == 0) {
18632         rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18633       } else {
18634         rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
18635                                    callback.callback());
18636       }
18637       if (rv == ERR_IO_PENDING) {
18638         rv = callback.WaitForResult();
18639       }
18640 
18641       // Compare results with expected data.
18642       EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
18643       const HttpResponseInfo* response = trans.GetResponseInfo();
18644       if (read_write_round.expected_rv != OK) {
18645         EXPECT_EQ(round + 1, test_config.num_auth_rounds);
18646         continue;
18647       }
18648       if (round + 1 < test_config.num_auth_rounds) {
18649         EXPECT_TRUE(response->auth_challenge.has_value());
18650       } else {
18651         EXPECT_FALSE(response->auth_challenge.has_value());
18652         EXPECT_FALSE(trans.IsReadyToRestartForAuth());
18653       }
18654     }
18655   }
18656 }
18657 
TEST_P(HttpNetworkTransactionTest,MultiRoundAuth)18658 TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
18659   // Do multi-round authentication and make sure it works correctly.
18660   auto auth_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
18661   auto* auth_factory_ptr = auth_factory.get();
18662   session_deps_.http_auth_handler_factory = std::move(auth_factory);
18663   session_deps_.proxy_resolution_service =
18664       ConfiguredProxyResolutionService::CreateDirect();
18665   session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
18666 
18667   auto auth_handler = std::make_unique<HttpAuthHandlerMock>();
18668   auto* auth_handler_ptr = auth_handler.get();
18669   auth_handler->set_connection_based(true);
18670   std::string auth_challenge = "Mock realm=server";
18671   GURL url("http://www.example.com");
18672   HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
18673                                        auth_challenge.end());
18674   SSLInfo empty_ssl_info;
18675   auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
18676                                   empty_ssl_info, NetworkAnonymizationKey(),
18677                                   url::SchemeHostPort(url), NetLogWithSource());
18678   auth_factory_ptr->AddMockHandler(std::move(auth_handler),
18679                                    HttpAuth::AUTH_SERVER);
18680 
18681   int rv = OK;
18682   const HttpResponseInfo* response = nullptr;
18683   HttpRequestInfo request;
18684   request.method = "GET";
18685   request.url = url;
18686   request.traffic_annotation =
18687       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18688 
18689   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18690 
18691   // Use a TCP Socket Pool with only one connection per group. This is used
18692   // to validate that the TCP socket is not released to the pool between
18693   // each round of multi-round authentication.
18694   HttpNetworkSessionPeer session_peer(session.get());
18695   CommonConnectJobParams common_connect_job_params(
18696       session->CreateCommonConnectJobParams());
18697   auto transport_pool = std::make_unique<TransportClientSocketPool>(
18698       50,  // Max sockets for pool
18699       1,   // Max sockets per group
18700       /*unused_idle_socket_timeout=*/base::Seconds(10), ProxyChain::Direct(),
18701       /*is_for_websockets=*/false, &common_connect_job_params);
18702   auto* transport_pool_ptr = transport_pool.get();
18703   auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
18704   mock_pool_manager->SetSocketPool(ProxyChain::Direct(),
18705                                    std::move(transport_pool));
18706   session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
18707 
18708   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18709   TestCompletionCallback callback;
18710 
18711   const MockWrite kGet(
18712       "GET / HTTP/1.1\r\n"
18713       "Host: www.example.com\r\n"
18714       "Connection: keep-alive\r\n\r\n");
18715   const MockWrite kGetAuth(
18716       "GET / HTTP/1.1\r\n"
18717       "Host: www.example.com\r\n"
18718       "Connection: keep-alive\r\n"
18719       "Authorization: auth_token\r\n\r\n");
18720 
18721   const MockRead kServerChallenge(
18722       "HTTP/1.1 401 Unauthorized\r\n"
18723       "WWW-Authenticate: Mock realm=server\r\n"
18724       "Content-Type: text/html; charset=iso-8859-1\r\n"
18725       "Content-Length: 14\r\n\r\n"
18726       "Unauthorized\r\n");
18727   const MockRead kSuccess(
18728       "HTTP/1.1 200 OK\r\n"
18729       "Content-Type: text/html; charset=iso-8859-1\r\n"
18730       "Content-Length: 3\r\n\r\n"
18731       "Yes");
18732 
18733   MockWrite writes[] = {
18734       // First round
18735       kGet,
18736       // Second round
18737       kGetAuth,
18738       // Third round
18739       kGetAuth,
18740       // Fourth round
18741       kGetAuth,
18742       // Competing request
18743       kGet,
18744   };
18745   MockRead reads[] = {
18746       // First round
18747       kServerChallenge,
18748       // Second round
18749       kServerChallenge,
18750       // Third round
18751       kServerChallenge,
18752       // Fourth round
18753       kSuccess,
18754       // Competing response
18755       kSuccess,
18756   };
18757   StaticSocketDataProvider data_provider(reads, writes);
18758   session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
18759 
18760   const ClientSocketPool::GroupId kSocketGroup(
18761       url::SchemeHostPort(url::kHttpScheme, "www.example.com", 80),
18762       PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
18763       SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false);
18764 
18765   // First round of authentication.
18766   auth_handler_ptr->SetGenerateExpectation(false, OK);
18767   rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18768   if (rv == ERR_IO_PENDING) {
18769     rv = callback.WaitForResult();
18770   }
18771   EXPECT_THAT(rv, IsOk());
18772   response = trans.GetResponseInfo();
18773   ASSERT_TRUE(response);
18774   EXPECT_TRUE(response->auth_challenge.has_value());
18775   EXPECT_EQ(0u, transport_pool_ptr->IdleSocketCountInGroup(kSocketGroup));
18776   EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
18777             auth_handler_ptr->state());
18778 
18779   // In between rounds, another request comes in for the same domain.
18780   // It should not be able to grab the TCP socket that trans has already
18781   // claimed.
18782   HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
18783   TestCompletionCallback callback_compete;
18784   rv = trans_compete.Start(&request, callback_compete.callback(),
18785                            NetLogWithSource());
18786   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18787   // callback_compete.WaitForResult at this point would stall forever,
18788   // since the HttpNetworkTransaction does not release the request back to
18789   // the pool until after authentication completes.
18790 
18791   // Second round of authentication.
18792   auth_handler_ptr->SetGenerateExpectation(false, OK);
18793   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
18794   if (rv == ERR_IO_PENDING) {
18795     rv = callback.WaitForResult();
18796   }
18797   EXPECT_THAT(rv, IsOk());
18798   response = trans.GetResponseInfo();
18799   ASSERT_TRUE(response);
18800   EXPECT_FALSE(response->auth_challenge.has_value());
18801   EXPECT_EQ(0u, transport_pool_ptr->IdleSocketCountInGroup(kSocketGroup));
18802   EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
18803             auth_handler_ptr->state());
18804 
18805   // Third round of authentication.
18806   auth_handler_ptr->SetGenerateExpectation(false, OK);
18807   rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
18808   if (rv == ERR_IO_PENDING) {
18809     rv = callback.WaitForResult();
18810   }
18811   EXPECT_THAT(rv, IsOk());
18812   response = trans.GetResponseInfo();
18813   ASSERT_TRUE(response);
18814   EXPECT_FALSE(response->auth_challenge.has_value());
18815   EXPECT_EQ(0u, transport_pool_ptr->IdleSocketCountInGroup(kSocketGroup));
18816   EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
18817             auth_handler_ptr->state());
18818 
18819   // Fourth round of authentication, which completes successfully.
18820   auth_handler_ptr->SetGenerateExpectation(false, OK);
18821   rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
18822   if (rv == ERR_IO_PENDING) {
18823     rv = callback.WaitForResult();
18824   }
18825   EXPECT_THAT(rv, IsOk());
18826   response = trans.GetResponseInfo();
18827   ASSERT_TRUE(response);
18828   EXPECT_FALSE(response->auth_challenge.has_value());
18829   EXPECT_EQ(0u, transport_pool_ptr->IdleSocketCountInGroup(kSocketGroup));
18830 
18831   // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
18832   // auth handler should transition to a DONE state in concert with the remote
18833   // server. But that's not something we can test here with a mock handler.
18834   EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
18835             auth_handler_ptr->state());
18836 
18837   // Read the body since the fourth round was successful. This will also
18838   // release the socket back to the pool.
18839   scoped_refptr<IOBufferWithSize> io_buf =
18840       base::MakeRefCounted<IOBufferWithSize>(50);
18841   rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
18842   if (rv == ERR_IO_PENDING) {
18843     rv = callback.WaitForResult();
18844   }
18845   EXPECT_EQ(3, rv);
18846   rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
18847   EXPECT_EQ(0, rv);
18848   // There are still 0 idle sockets, since the trans_compete transaction
18849   // will be handed it immediately after trans releases it to the group.
18850   EXPECT_EQ(0u, transport_pool_ptr->IdleSocketCountInGroup(kSocketGroup));
18851 
18852   // The competing request can now finish. Wait for the headers and then
18853   // read the body.
18854   rv = callback_compete.WaitForResult();
18855   EXPECT_THAT(rv, IsOk());
18856   rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
18857   if (rv == ERR_IO_PENDING) {
18858     rv = callback.WaitForResult();
18859   }
18860   EXPECT_EQ(3, rv);
18861   rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
18862   EXPECT_EQ(0, rv);
18863 
18864   // Finally, the socket is released to the group.
18865   EXPECT_EQ(1u, transport_pool_ptr->IdleSocketCountInGroup(kSocketGroup));
18866 }
18867 
18868 // This tests the case that a request is issued via http instead of spdy after
18869 // npn is negotiated.
TEST_P(HttpNetworkTransactionTest,NpnWithHttpOverSSL)18870 TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
18871   HttpRequestInfo request;
18872   request.method = "GET";
18873   request.url = GURL("https://www.example.org/");
18874   request.traffic_annotation =
18875       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18876 
18877   MockWrite data_writes[] = {
18878       MockWrite("GET / HTTP/1.1\r\n"
18879                 "Host: www.example.org\r\n"
18880                 "Connection: keep-alive\r\n\r\n"),
18881   };
18882 
18883   MockRead data_reads[] = {
18884       MockRead("HTTP/1.1 200 OK\r\n"),
18885       MockRead(kAlternativeServiceHttpHeader),
18886       MockRead("\r\n"),
18887       MockRead("hello world"),
18888       MockRead(SYNCHRONOUS, OK),
18889   };
18890 
18891   SSLSocketDataProvider ssl(ASYNC, OK);
18892   ssl.next_proto = kProtoHTTP11;
18893 
18894   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18895 
18896   StaticSocketDataProvider data(data_reads, data_writes);
18897   session_deps_.socket_factory->AddSocketDataProvider(&data);
18898 
18899   TestCompletionCallback callback;
18900 
18901   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18902   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18903 
18904   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18905 
18906   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18907   EXPECT_THAT(callback.WaitForResult(), IsOk());
18908 
18909   const HttpResponseInfo* response = trans.GetResponseInfo();
18910   ASSERT_TRUE(response);
18911   ASSERT_TRUE(response->headers);
18912   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
18913 
18914   std::string response_data;
18915   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
18916   EXPECT_EQ("hello world", response_data);
18917 
18918   EXPECT_FALSE(response->was_fetched_via_spdy);
18919   EXPECT_TRUE(response->was_alpn_negotiated);
18920 }
18921 
18922 // Simulate the SSL handshake completing with a ALPN negotiation followed by an
18923 // immediate server closing of the socket.
18924 // Regression test for https://crbug.com/46369.
TEST_P(HttpNetworkTransactionTest,SpdyPostALPNServerHangup)18925 TEST_P(HttpNetworkTransactionTest, SpdyPostALPNServerHangup) {
18926   HttpRequestInfo request;
18927   request.method = "GET";
18928   request.url = GURL("https://www.example.org/");
18929   request.traffic_annotation =
18930       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18931 
18932   SSLSocketDataProvider ssl(ASYNC, OK);
18933   ssl.next_proto = kProtoHTTP2;
18934   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18935 
18936   spdy::SpdySerializedFrame req(
18937       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
18938   MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
18939 
18940   MockRead spdy_reads[] = {
18941       MockRead(SYNCHRONOUS, 0, 0)  // Not async - return 0 immediately.
18942   };
18943 
18944   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
18945   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
18946 
18947   TestCompletionCallback callback;
18948 
18949   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18950   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18951 
18952   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18953   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18954   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
18955 }
18956 
18957 // A subclass of HttpAuthHandlerMock that records the request URL when
18958 // it gets it. This is needed since the auth handler may get destroyed
18959 // before we get a chance to query it.
18960 class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
18961  public:
UrlRecordingHttpAuthHandlerMock(GURL * url)18962   explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
18963 
18964   ~UrlRecordingHttpAuthHandlerMock() override = default;
18965 
18966  protected:
GenerateAuthTokenImpl(const AuthCredentials * credentials,const HttpRequestInfo * request,CompletionOnceCallback callback,std::string * auth_token)18967   int GenerateAuthTokenImpl(const AuthCredentials* credentials,
18968                             const HttpRequestInfo* request,
18969                             CompletionOnceCallback callback,
18970                             std::string* auth_token) override {
18971     *url_ = request->url;
18972     return HttpAuthHandlerMock::GenerateAuthTokenImpl(
18973         credentials, request, std::move(callback), auth_token);
18974   }
18975 
18976  private:
18977   raw_ptr<GURL> url_ = nullptr;
18978 };
18979 
18980 // Test that if we cancel the transaction as the connection is completing, that
18981 // everything tears down correctly.
TEST_P(HttpNetworkTransactionTest,SimpleCancel)18982 TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
18983   // Setup everything about the connection to complete synchronously, so that
18984   // after calling HttpNetworkTransaction::Start, the only thing we're waiting
18985   // for is the callback from the HttpStreamRequest.
18986   // Then cancel the transaction.
18987   // Verify that we don't crash.
18988   MockConnect mock_connect(SYNCHRONOUS, OK);
18989   MockRead data_reads[] = {
18990       MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
18991       MockRead(SYNCHRONOUS, "hello world"),
18992       MockRead(SYNCHRONOUS, OK),
18993   };
18994 
18995   HttpRequestInfo request;
18996   request.method = "GET";
18997   request.url = GURL("http://www.example.org/");
18998   request.traffic_annotation =
18999       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19000 
19001   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19002   auto trans =
19003       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19004 
19005   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19006   data.set_connect_data(mock_connect);
19007   session_deps_.socket_factory->AddSocketDataProvider(&data);
19008 
19009   TestCompletionCallback callback;
19010 
19011   int rv = trans->Start(&request, callback.callback(),
19012                         NetLogWithSource::Make(NetLogSourceType::NONE));
19013   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19014   trans.reset();  // Cancel the transaction here.
19015 
19016   base::RunLoop().RunUntilIdle();
19017 }
19018 
19019 // Test that if a transaction is cancelled after receiving the headers, the
19020 // stream is drained properly and added back to the socket pool.  The main
19021 // purpose of this test is to make sure that an HttpStreamParser can be read
19022 // from after the HttpNetworkTransaction and the objects it owns have been
19023 // deleted.
19024 // See http://crbug.com/368418
TEST_P(HttpNetworkTransactionTest,CancelAfterHeaders)19025 TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
19026   MockRead data_reads[] = {
19027       MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
19028       MockRead(ASYNC, "Content-Length: 2\r\n"),
19029       MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"), MockRead(ASYNC, "1"),
19030       // 2 async reads are necessary to trigger a ReadResponseBody call after
19031       // the HttpNetworkTransaction has been deleted.
19032       MockRead(ASYNC, "2"),
19033       MockRead(SYNCHRONOUS, ERR_IO_PENDING),  // Should never read this.
19034   };
19035   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19036   session_deps_.socket_factory->AddSocketDataProvider(&data);
19037 
19038   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19039 
19040   {
19041     HttpRequestInfo request;
19042     request.method = "GET";
19043     request.url = GURL("http://www.example.org/");
19044     request.traffic_annotation =
19045         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19046 
19047     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19048     TestCompletionCallback callback;
19049 
19050     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
19051     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19052     callback.WaitForResult();
19053 
19054     const HttpResponseInfo* response = trans.GetResponseInfo();
19055     ASSERT_TRUE(response);
19056     EXPECT_TRUE(response->headers);
19057     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
19058 
19059     // The transaction and HttpRequestInfo are deleted.
19060   }
19061 
19062   // Let the HttpResponseBodyDrainer drain the socket.
19063   base::RunLoop().RunUntilIdle();
19064 
19065   // Socket should now be idle, waiting to be reused.
19066   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
19067 }
19068 
19069 // Test a basic GET request through a proxy.
TEST_P(HttpNetworkTransactionTest,ProxyGet)19070 TEST_P(HttpNetworkTransactionTest, ProxyGet) {
19071   session_deps_.proxy_resolution_service =
19072       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
19073           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19074   session_deps_.net_log = NetLog::Get();
19075   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19076 
19077   HttpRequestInfo request;
19078   request.method = "GET";
19079   request.url = GURL("http://www.example.org/");
19080   request.traffic_annotation =
19081       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19082 
19083   MockWrite data_writes1[] = {
19084       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
19085                 "Host: www.example.org\r\n"
19086                 "Proxy-Connection: keep-alive\r\n\r\n"),
19087   };
19088 
19089   MockRead data_reads1[] = {
19090       MockRead("HTTP/1.1 200 OK\r\n"),
19091       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19092       MockRead("Content-Length: 100\r\n\r\n"),
19093       MockRead(SYNCHRONOUS, OK),
19094   };
19095 
19096   StaticSocketDataProvider data1(data_reads1, data_writes1);
19097   session_deps_.socket_factory->AddSocketDataProvider(&data1);
19098 
19099   TestCompletionCallback callback1;
19100 
19101   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19102   ConnectedHandler connected_handler;
19103   trans.SetConnectedCallback(connected_handler.Callback());
19104 
19105   int rv = trans.Start(&request, callback1.callback(),
19106                        NetLogWithSource::Make(NetLogSourceType::NONE));
19107   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19108 
19109   rv = callback1.WaitForResult();
19110   EXPECT_THAT(rv, IsOk());
19111 
19112   const HttpResponseInfo* response = trans.GetResponseInfo();
19113   ASSERT_TRUE(response);
19114 
19115   EXPECT_TRUE(response->headers->IsKeepAlive());
19116   EXPECT_EQ(200, response->headers->response_code());
19117   EXPECT_EQ(100, response->headers->GetContentLength());
19118   EXPECT_TRUE(response->was_fetched_via_proxy);
19119   EXPECT_FALSE(response->proxy_chain.is_for_ip_protection());
19120   EXPECT_EQ(ProxyChain(ProxyServer::SCHEME_HTTP,
19121                        HostPortPair::FromString("myproxy:70")),
19122             response->proxy_chain);
19123   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
19124 
19125   TransportInfo expected_transport;
19126   expected_transport.type = TransportType::kProxied;
19127   expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 70);
19128   expected_transport.negotiated_protocol = kProtoUnknown;
19129   EXPECT_THAT(connected_handler.transports(), ElementsAre(expected_transport));
19130 
19131   LoadTimingInfo load_timing_info;
19132   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
19133   TestLoadTimingNotReusedWithPac(load_timing_info,
19134                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
19135 }
19136 
19137 // Test a basic HTTPS GET request through a proxy.
TEST_P(HttpNetworkTransactionTest,ProxyTunnelGet)19138 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
19139   session_deps_.proxy_resolution_service =
19140       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
19141           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19142   RecordingNetLogObserver net_log_observer;
19143   session_deps_.net_log = NetLog::Get();
19144   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19145 
19146   HttpRequestInfo request;
19147   request.method = "GET";
19148   request.url = GURL("https://www.example.org/");
19149   request.traffic_annotation =
19150       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19151 
19152   // Since we have proxy, should try to establish tunnel.
19153   MockWrite data_writes1[] = {
19154       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19155                 "Host: www.example.org:443\r\n"
19156                 "Proxy-Connection: keep-alive\r\n\r\n"),
19157 
19158       MockWrite("GET / HTTP/1.1\r\n"
19159                 "Host: www.example.org\r\n"
19160                 "Connection: keep-alive\r\n\r\n"),
19161   };
19162 
19163   MockRead data_reads1[] = {
19164       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19165 
19166       MockRead("HTTP/1.1 200 OK\r\n"),
19167       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19168       MockRead("Content-Length: 100\r\n\r\n"),
19169       MockRead(SYNCHRONOUS, OK),
19170   };
19171 
19172   StaticSocketDataProvider data1(data_reads1, data_writes1);
19173   session_deps_.socket_factory->AddSocketDataProvider(&data1);
19174   SSLSocketDataProvider ssl(ASYNC, OK);
19175   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19176 
19177   TestCompletionCallback callback1;
19178 
19179   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19180   ConnectedHandler connected_handler;
19181   trans.SetConnectedCallback(connected_handler.Callback());
19182 
19183   int rv = trans.Start(&request, callback1.callback(),
19184                        NetLogWithSource::Make(NetLogSourceType::NONE));
19185   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19186 
19187   rv = callback1.WaitForResult();
19188   EXPECT_THAT(rv, IsOk());
19189   auto entries = net_log_observer.GetEntries();
19190   size_t pos = ExpectLogContainsSomewhere(
19191       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
19192       NetLogEventPhase::NONE);
19193   ExpectLogContainsSomewhere(
19194       entries, pos,
19195       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
19196       NetLogEventPhase::NONE);
19197 
19198   const HttpResponseInfo* response = trans.GetResponseInfo();
19199   ASSERT_TRUE(response);
19200 
19201   EXPECT_TRUE(response->headers->IsKeepAlive());
19202   EXPECT_EQ(200, response->headers->response_code());
19203   EXPECT_EQ(100, response->headers->GetContentLength());
19204   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
19205   EXPECT_TRUE(response->was_fetched_via_proxy);
19206   EXPECT_EQ(ProxyChain(ProxyServer::SCHEME_HTTP,
19207                        HostPortPair::FromString("myproxy:70")),
19208             response->proxy_chain);
19209 
19210   TransportInfo expected_transport;
19211   expected_transport.type = TransportType::kProxied;
19212   expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 70);
19213   expected_transport.negotiated_protocol = kProtoUnknown;
19214   EXPECT_THAT(connected_handler.transports(), ElementsAre(expected_transport));
19215 
19216   LoadTimingInfo load_timing_info;
19217   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
19218   TestLoadTimingNotReusedWithPac(load_timing_info,
19219                                  CONNECT_TIMING_HAS_SSL_TIMES);
19220 }
19221 
19222 // Test a basic HTTPS GET request through a proxy, connecting to an IPv6
19223 // literal host.
TEST_P(HttpNetworkTransactionTest,ProxyTunnelGetIPv6)19224 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
19225   session_deps_.proxy_resolution_service =
19226       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
19227           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19228   RecordingNetLogObserver net_log_observer;
19229   session_deps_.net_log = NetLog::Get();
19230   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19231 
19232   HttpRequestInfo request;
19233   request.method = "GET";
19234   request.url = GURL("https://[::2]:443/");
19235   request.traffic_annotation =
19236       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19237 
19238   // Since we have proxy, should try to establish tunnel.
19239   MockWrite data_writes1[] = {
19240       MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
19241                 "Host: [::2]:443\r\n"
19242                 "Proxy-Connection: keep-alive\r\n\r\n"),
19243 
19244       MockWrite("GET / HTTP/1.1\r\n"
19245                 "Host: [::2]\r\n"
19246                 "Connection: keep-alive\r\n\r\n"),
19247   };
19248 
19249   MockRead data_reads1[] = {
19250       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19251 
19252       MockRead("HTTP/1.1 200 OK\r\n"),
19253       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19254       MockRead("Content-Length: 100\r\n\r\n"),
19255       MockRead(SYNCHRONOUS, OK),
19256   };
19257 
19258   StaticSocketDataProvider data1(data_reads1, data_writes1);
19259   session_deps_.socket_factory->AddSocketDataProvider(&data1);
19260   SSLSocketDataProvider ssl(ASYNC, OK);
19261   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19262 
19263   TestCompletionCallback callback1;
19264 
19265   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19266 
19267   int rv = trans.Start(&request, callback1.callback(),
19268                        NetLogWithSource::Make(NetLogSourceType::NONE));
19269   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19270 
19271   rv = callback1.WaitForResult();
19272   EXPECT_THAT(rv, IsOk());
19273   auto entries = net_log_observer.GetEntries();
19274   size_t pos = ExpectLogContainsSomewhere(
19275       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
19276       NetLogEventPhase::NONE);
19277   ExpectLogContainsSomewhere(
19278       entries, pos,
19279       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
19280       NetLogEventPhase::NONE);
19281 
19282   const HttpResponseInfo* response = trans.GetResponseInfo();
19283   ASSERT_TRUE(response);
19284 
19285   EXPECT_TRUE(response->headers->IsKeepAlive());
19286   EXPECT_EQ(200, response->headers->response_code());
19287   EXPECT_EQ(100, response->headers->GetContentLength());
19288   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
19289   EXPECT_TRUE(response->was_fetched_via_proxy);
19290   EXPECT_EQ(ProxyChain(ProxyServer::SCHEME_HTTP,
19291                        HostPortPair::FromString("myproxy:70")),
19292             response->proxy_chain);
19293 
19294   LoadTimingInfo load_timing_info;
19295   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
19296   TestLoadTimingNotReusedWithPac(load_timing_info,
19297                                  CONNECT_TIMING_HAS_SSL_TIMES);
19298 }
19299 
19300 // Test a basic HTTPS GET request through a proxy, but the server hangs up
19301 // while establishing the tunnel.
TEST_P(HttpNetworkTransactionTest,ProxyTunnelGetHangup)19302 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
19303   session_deps_.proxy_resolution_service =
19304       ConfiguredProxyResolutionService::CreateFixedForTest(
19305           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19306   RecordingNetLogObserver net_log_observer;
19307   session_deps_.net_log = NetLog::Get();
19308   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19309 
19310   HttpRequestInfo request;
19311   request.method = "GET";
19312   request.url = GURL("https://www.example.org/");
19313   request.traffic_annotation =
19314       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19315 
19316   // Since we have proxy, should try to establish tunnel.
19317   MockWrite data_writes1[] = {
19318       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19319                 "Host: www.example.org:443\r\n"
19320                 "Proxy-Connection: keep-alive\r\n\r\n"),
19321 
19322       MockWrite("GET / HTTP/1.1\r\n"
19323                 "Host: www.example.org\r\n"
19324                 "Connection: keep-alive\r\n\r\n"),
19325   };
19326 
19327   MockRead data_reads1[] = {
19328       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19329       MockRead(ASYNC, 0, 0),  // EOF
19330   };
19331 
19332   StaticSocketDataProvider data1(data_reads1, data_writes1);
19333   session_deps_.socket_factory->AddSocketDataProvider(&data1);
19334   SSLSocketDataProvider ssl(ASYNC, OK);
19335   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19336 
19337   TestCompletionCallback callback1;
19338 
19339   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19340 
19341   int rv = trans.Start(&request, callback1.callback(),
19342                        NetLogWithSource::Make(NetLogSourceType::NONE));
19343   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19344 
19345   rv = callback1.WaitForResult();
19346   EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
19347   auto entries = net_log_observer.GetEntries();
19348   size_t pos = ExpectLogContainsSomewhere(
19349       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
19350       NetLogEventPhase::NONE);
19351   ExpectLogContainsSomewhere(
19352       entries, pos,
19353       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
19354       NetLogEventPhase::NONE);
19355 }
19356 
19357 // Test for crbug.com/55424.
TEST_P(HttpNetworkTransactionTest,PreconnectWithExistingSpdySession)19358 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
19359   spdy::SpdySerializedFrame req(
19360       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
19361   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
19362 
19363   spdy::SpdySerializedFrame resp(
19364       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
19365   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
19366   MockRead spdy_reads[] = {
19367       CreateMockRead(resp, 1),
19368       CreateMockRead(data, 2),
19369       MockRead(ASYNC, 0, 3),
19370   };
19371 
19372   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
19373   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
19374 
19375   SSLSocketDataProvider ssl(ASYNC, OK);
19376   ssl.next_proto = kProtoHTTP2;
19377   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19378 
19379   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19380 
19381   // Set up an initial SpdySession in the pool to reuse.
19382   HostPortPair host_port_pair("www.example.org", 443);
19383   SpdySessionKey key(host_port_pair, PRIVACY_MODE_DISABLED,
19384                      ProxyChain::Direct(), SessionUsage::kDestination,
19385                      SocketTag(), NetworkAnonymizationKey(),
19386                      SecureDnsPolicy::kAllow,
19387                      /*disable_cert_verification_network_fetches=*/false);
19388   base::WeakPtr<SpdySession> spdy_session =
19389       CreateSpdySession(session.get(), key, NetLogWithSource());
19390 
19391   HttpRequestInfo request;
19392   request.method = "GET";
19393   request.url = GURL("https://www.example.org/");
19394   request.traffic_annotation =
19395       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19396 
19397   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19398 
19399   TestCompletionCallback callback;
19400   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
19401   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19402   EXPECT_THAT(callback.WaitForResult(), IsOk());
19403 }
19404 
19405 // Given a net error, cause that error to be returned from the first Write()
19406 // call and verify that the HttpNetworkTransaction fails with that error.
CheckErrorIsPassedBack(int error,IoMode mode)19407 void HttpNetworkTransactionTestBase::CheckErrorIsPassedBack(int error,
19408                                                             IoMode mode) {
19409   HttpRequestInfo request_info;
19410   request_info.url = GURL("https://www.example.com/");
19411   request_info.method = "GET";
19412   request_info.load_flags = LOAD_NORMAL;
19413   request_info.traffic_annotation =
19414       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19415 
19416   SSLSocketDataProvider ssl_data(mode, OK);
19417   MockWrite data_writes[] = {
19418       MockWrite(mode, error),
19419   };
19420   StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
19421   session_deps_.socket_factory->AddSocketDataProvider(&data);
19422   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
19423 
19424   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19425   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19426 
19427   TestCompletionCallback callback;
19428   int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
19429   if (rv == ERR_IO_PENDING) {
19430     rv = callback.WaitForResult();
19431   }
19432   ASSERT_EQ(error, rv);
19433 }
19434 
TEST_P(HttpNetworkTransactionTest,SSLWriteCertError)19435 TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
19436   // Just check a grab bag of cert errors.
19437   static const int kErrors[] = {
19438       ERR_CERT_COMMON_NAME_INVALID,
19439       ERR_CERT_AUTHORITY_INVALID,
19440       ERR_CERT_DATE_INVALID,
19441   };
19442   for (int error : kErrors) {
19443     CheckErrorIsPassedBack(error, ASYNC);
19444     CheckErrorIsPassedBack(error, SYNCHRONOUS);
19445   }
19446 }
19447 
19448 // Ensure that a client certificate is removed from the SSL client auth
19449 // cache when:
19450 //  1) No proxy is involved.
19451 //  2) TLS False Start is disabled.
19452 //  3) The initial TLS handshake requests a client certificate.
19453 //  4) The client supplies an invalid/unacceptable certificate.
TEST_P(HttpNetworkTransactionTest,ClientAuthCertCache_Direct_NoFalseStart)19454 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
19455   HttpRequestInfo request_info;
19456   request_info.url = GURL("https://www.example.com/");
19457   request_info.method = "GET";
19458   request_info.load_flags = LOAD_NORMAL;
19459   request_info.traffic_annotation =
19460       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19461 
19462   auto cert_request = base::MakeRefCounted<SSLCertRequestInfo>();
19463   cert_request->host_and_port = HostPortPair("www.example.com", 443);
19464 
19465   // [ssl_]data1 contains the data for the first SSL handshake. When a
19466   // CertificateRequest is received for the first time, the handshake will
19467   // be aborted to allow the caller to provide a certificate.
19468   SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
19469   ssl_data1.cert_request_info = cert_request;
19470   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
19471   StaticSocketDataProvider data1;
19472   session_deps_.socket_factory->AddSocketDataProvider(&data1);
19473 
19474   // [ssl_]data2 contains the data for the second SSL handshake. When TLS
19475   // False Start is not being used, the result of the SSL handshake will be
19476   // returned as part of the SSLClientSocket::Connect() call. This test
19477   // matches the result of a server sending a handshake_failure alert,
19478   // rather than a Finished message, because it requires a client
19479   // certificate and none was supplied.
19480   SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
19481   ssl_data2.cert_request_info = cert_request;
19482   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
19483   StaticSocketDataProvider data2;
19484   session_deps_.socket_factory->AddSocketDataProvider(&data2);
19485 
19486   // [ssl_]data3 contains the data for the third SSL handshake. When a
19487   // connection to a server fails during an SSL handshake,
19488   // HttpNetworkTransaction will attempt to fallback with legacy cryptography
19489   // enabled on some errors. This is transparent to the caller
19490   // of the HttpNetworkTransaction. Because this test failure is due to
19491   // requiring a client certificate, this fallback handshake should also
19492   // fail.
19493   SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
19494   ssl_data3.cert_request_info = cert_request;
19495   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
19496   StaticSocketDataProvider data3;
19497   session_deps_.socket_factory->AddSocketDataProvider(&data3);
19498 
19499   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19500   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19501 
19502   // Begin the SSL handshake with the peer. This consumes ssl_data1.
19503   TestCompletionCallback callback;
19504   int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
19505   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
19506 
19507   // Complete the SSL handshake, which should abort due to requiring a
19508   // client certificate.
19509   rv = callback.WaitForResult();
19510   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
19511 
19512   // Indicate that no certificate should be supplied. From the perspective
19513   // of SSLClientCertCache, NULL is just as meaningful as a real
19514   // certificate, so this is the same as supply a
19515   // legitimate-but-unacceptable certificate.
19516   rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
19517   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
19518 
19519   // Ensure the certificate was added to the client auth cache before
19520   // allowing the connection to continue restarting.
19521   scoped_refptr<X509Certificate> client_cert;
19522   scoped_refptr<SSLPrivateKey> client_private_key;
19523   ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate(
19524       HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
19525   ASSERT_FALSE(client_cert);
19526 
19527   // Restart the handshake. This will consume ssl_data2, which fails, and
19528   // then consume ssl_data3 and ssl_data4, both of which should also fail.
19529   // The result code is checked against what ssl_data4 should return.
19530   rv = callback.WaitForResult();
19531   ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
19532 
19533   // Ensure that the client certificate is removed from the cache on a
19534   // handshake failure.
19535   ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate(
19536       HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
19537 }
19538 
19539 // Ensure that a client certificate is removed from the SSL client auth
19540 // cache when:
19541 //  1) No proxy is involved.
19542 //  2) TLS False Start is enabled.
19543 //  3) The initial TLS handshake requests a client certificate.
19544 //  4) The client supplies an invalid/unacceptable certificate.
TEST_P(HttpNetworkTransactionTest,ClientAuthCertCache_Direct_FalseStart)19545 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
19546   HttpRequestInfo request_info;
19547   request_info.url = GURL("https://www.example.com/");
19548   request_info.method = "GET";
19549   request_info.load_flags = LOAD_NORMAL;
19550   request_info.traffic_annotation =
19551       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19552 
19553   auto cert_request = base::MakeRefCounted<SSLCertRequestInfo>();
19554   cert_request->host_and_port = HostPortPair("www.example.com", 443);
19555 
19556   // When TLS False Start is used, SSLClientSocket::Connect() calls will
19557   // return successfully after reading up to the peer's Certificate message.
19558   // This is to allow the caller to call SSLClientSocket::Write(), which can
19559   // enqueue application data to be sent in the same packet as the
19560   // ChangeCipherSpec and Finished messages.
19561   // The actual handshake will be finished when SSLClientSocket::Read() is
19562   // called, which expects to process the peer's ChangeCipherSpec and
19563   // Finished messages. If there was an error negotiating with the peer,
19564   // such as due to the peer requiring a client certificate when none was
19565   // supplied, the alert sent by the peer won't be processed until Read() is
19566   // called.
19567 
19568   // Like the non-False Start case, when a client certificate is requested by
19569   // the peer, the handshake is aborted during the Connect() call.
19570   // [ssl_]data1 represents the initial SSL handshake with the peer.
19571   SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
19572   ssl_data1.cert_request_info = cert_request;
19573   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
19574   StaticSocketDataProvider data1;
19575   session_deps_.socket_factory->AddSocketDataProvider(&data1);
19576 
19577   // When a client certificate is supplied, Connect() will not be aborted
19578   // when the peer requests the certificate. Instead, the handshake will
19579   // artificially succeed, allowing the caller to write the HTTP request to
19580   // the socket. The handshake messages are not processed until Read() is
19581   // called, which then detects that the handshake was aborted, due to the
19582   // peer sending a handshake_failure because it requires a client
19583   // certificate.
19584   SSLSocketDataProvider ssl_data2(ASYNC, OK);
19585   ssl_data2.cert_request_info = cert_request;
19586   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
19587   MockRead data2_reads[] = {
19588       MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
19589   };
19590   StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
19591   session_deps_.socket_factory->AddSocketDataProvider(&data2);
19592 
19593   // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
19594   // the data for the SSL handshake once the TLSv1.1 connection falls back to
19595   // TLSv1. It has the same behaviour as [ssl_]data2.
19596   SSLSocketDataProvider ssl_data3(ASYNC, OK);
19597   ssl_data3.cert_request_info = cert_request;
19598   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
19599   StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
19600   session_deps_.socket_factory->AddSocketDataProvider(&data3);
19601 
19602   // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
19603   // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
19604   SSLSocketDataProvider ssl_data4(ASYNC, OK);
19605   ssl_data4.cert_request_info = cert_request;
19606   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
19607   StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
19608   session_deps_.socket_factory->AddSocketDataProvider(&data4);
19609 
19610   // Need one more if TLSv1.2 is enabled.
19611   SSLSocketDataProvider ssl_data5(ASYNC, OK);
19612   ssl_data5.cert_request_info = cert_request;
19613   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
19614   StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
19615   session_deps_.socket_factory->AddSocketDataProvider(&data5);
19616 
19617   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19618   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19619 
19620   // Begin the initial SSL handshake.
19621   TestCompletionCallback callback;
19622   int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
19623   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
19624 
19625   // Complete the SSL handshake, which should abort due to requiring a
19626   // client certificate.
19627   rv = callback.WaitForResult();
19628   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
19629 
19630   // Indicate that no certificate should be supplied. From the perspective
19631   // of SSLClientCertCache, NULL is just as meaningful as a real
19632   // certificate, so this is the same as supply a
19633   // legitimate-but-unacceptable certificate.
19634   rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
19635   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
19636 
19637   // Ensure the certificate was added to the client auth cache before
19638   // allowing the connection to continue restarting.
19639   scoped_refptr<X509Certificate> client_cert;
19640   scoped_refptr<SSLPrivateKey> client_private_key;
19641   ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate(
19642       HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
19643   ASSERT_FALSE(client_cert);
19644 
19645   // Restart the handshake. This will consume ssl_data2, which fails, and
19646   // then consume ssl_data3 and ssl_data4, both of which should also fail.
19647   // The result code is checked against what ssl_data4 should return.
19648   rv = callback.WaitForResult();
19649   ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
19650 
19651   // Ensure that the client certificate is removed from the cache on a
19652   // handshake failure.
19653   ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate(
19654       HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
19655 }
19656 
19657 // Ensure that a client certificate is removed from the SSL client auth
19658 // cache when:
19659 //  1) An HTTPS proxy is involved.
19660 //  3) The HTTPS proxy requests a client certificate.
19661 //  4) The client supplies an invalid/unacceptable certificate for the
19662 //     proxy.
TEST_P(HttpNetworkTransactionTest,ClientAuthCertCache_Proxy_Fail)19663 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
19664   session_deps_.proxy_resolution_service =
19665       ConfiguredProxyResolutionService::CreateFixedForTest(
19666           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19667   session_deps_.net_log = NetLog::Get();
19668 
19669   auto cert_request = base::MakeRefCounted<SSLCertRequestInfo>();
19670   cert_request->host_and_port = HostPortPair("proxy", 70);
19671 
19672   // Repeat the test for connecting to an HTTPS endpoint, then for connecting to
19673   // an HTTP endpoint.
19674   HttpRequestInfo requests[2];
19675   requests[0].url = GURL("https://www.example.com/");
19676   requests[0].method = "GET";
19677   requests[0].load_flags = LOAD_NORMAL;
19678   requests[0].traffic_annotation =
19679       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19680 
19681   // HTTPS requests are tunneled.
19682   MockWrite https_writes[] = {
19683       MockWrite("CONNECT www.example.com:443 HTTP/1.1\r\n"
19684                 "Host: www.example.com:443\r\n"
19685                 "Proxy-Connection: keep-alive\r\n\r\n"),
19686   };
19687 
19688   requests[1].url = GURL("http://www.example.com/");
19689   requests[1].method = "GET";
19690   requests[1].load_flags = LOAD_NORMAL;
19691   requests[1].traffic_annotation =
19692       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19693 
19694   // HTTP requests are not.
19695   MockWrite http_writes[] = {
19696       MockWrite("GET http://www.example.com/ HTTP/1.1\r\n"
19697                 "Host: www.example.com\r\n"
19698                 "Proxy-Connection: keep-alive\r\n\r\n"),
19699   };
19700 
19701   // When the server rejects the client certificate, it will close the
19702   // connection. In TLS 1.2, this is signaled out of Connect(). In TLS 1.3 (or
19703   // TLS 1.2 with False Start), the error is returned out of the first Read().
19704   for (bool reject_in_connect : {true, false}) {
19705     SCOPED_TRACE(reject_in_connect);
19706     // Client certificate errors are typically signaled with
19707     // ERR_BAD_SSL_CLIENT_AUTH_CERT, but sometimes the server gives an arbitrary
19708     // protocol error.
19709     for (Error reject_error :
19710          {ERR_SSL_PROTOCOL_ERROR, ERR_BAD_SSL_CLIENT_AUTH_CERT}) {
19711       SCOPED_TRACE(reject_error);
19712       // Tunneled and non-tunneled requests are handled differently. Test both.
19713       for (const HttpRequestInfo& request : requests) {
19714         SCOPED_TRACE(request.url);
19715 
19716         session_deps_.socket_factory =
19717             std::make_unique<MockClientSocketFactory>();
19718 
19719         // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
19720         // [ssl_]data[1-3].
19721         SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
19722         ssl_data1.cert_request_info = cert_request;
19723         session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
19724         StaticSocketDataProvider data1;
19725         session_deps_.socket_factory->AddSocketDataProvider(&data1);
19726 
19727         std::optional<SSLSocketDataProvider> ssl_data2;
19728         std::optional<StaticSocketDataProvider> data2;
19729         MockRead error_in_read[] = {MockRead(ASYNC, reject_error)};
19730         if (reject_in_connect) {
19731           ssl_data2.emplace(ASYNC, reject_error);
19732           // There are no reads or writes.
19733           data2.emplace();
19734         } else {
19735           ssl_data2.emplace(ASYNC, OK);
19736           // We will get one Write() in before observing the error in Read().
19737           if (request.url.SchemeIsCryptographic()) {
19738             data2.emplace(error_in_read, https_writes);
19739           } else {
19740             data2.emplace(error_in_read, http_writes);
19741           }
19742         }
19743         ssl_data2->cert_request_info = cert_request.get();
19744         session_deps_.socket_factory->AddSSLSocketDataProvider(
19745             &ssl_data2.value());
19746         session_deps_.socket_factory->AddSocketDataProvider(&data2.value());
19747 
19748         // If the handshake returns ERR_SSL_PROTOCOL_ERROR, we attempt to
19749         // connect twice.
19750         std::optional<SSLSocketDataProvider> ssl_data3;
19751         std::optional<StaticSocketDataProvider> data3;
19752         if (reject_in_connect && reject_error == ERR_SSL_PROTOCOL_ERROR) {
19753           ssl_data3.emplace(ASYNC, reject_error);
19754           data3.emplace();  // There are no reads or writes.
19755           ssl_data3->cert_request_info = cert_request.get();
19756           session_deps_.socket_factory->AddSSLSocketDataProvider(
19757               &ssl_data3.value());
19758           session_deps_.socket_factory->AddSocketDataProvider(&data3.value());
19759         }
19760 
19761         std::unique_ptr<HttpNetworkSession> session =
19762             CreateSession(&session_deps_);
19763         HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19764 
19765         // Begin the SSL handshake with the proxy.
19766         TestCompletionCallback callback;
19767         int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
19768         ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
19769 
19770         // Complete the SSL handshake, which should abort due to requiring a
19771         // client certificate.
19772         rv = callback.WaitForResult();
19773         ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
19774 
19775         // Indicate that no certificate should be supplied. From the
19776         // perspective of SSLClientCertCache, NULL is just as meaningful as a
19777         // real certificate, so this is the same as supply a
19778         // legitimate-but-unacceptable certificate.
19779         rv =
19780             trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
19781         ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
19782 
19783         // Ensure the certificate was added to the client auth cache before
19784         // allowing the connection to continue restarting.
19785         scoped_refptr<X509Certificate> client_cert;
19786         scoped_refptr<SSLPrivateKey> client_private_key;
19787         ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate(
19788             HostPortPair("proxy", 70), &client_cert, &client_private_key));
19789         ASSERT_FALSE(client_cert);
19790         // Ensure the certificate was NOT cached for the endpoint. This only
19791         // applies to HTTPS requests, but is fine to check for HTTP requests.
19792         ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate(
19793             HostPortPair("www.example.com", 443), &client_cert,
19794             &client_private_key));
19795 
19796         // Restart the handshake. This will consume ssl_data2. The result code
19797         // is checked against what ssl_data2 should return.
19798         rv = callback.WaitForResult();
19799         ASSERT_THAT(rv, AnyOf(IsError(ERR_PROXY_CONNECTION_FAILED),
19800                               IsError(reject_error)));
19801 
19802         // Now that the new handshake has failed, ensure that the client
19803         // certificate was removed from the client auth cache.
19804         ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate(
19805             HostPortPair("proxy", 70), &client_cert, &client_private_key));
19806         ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate(
19807             HostPortPair("www.example.com", 443), &client_cert,
19808             &client_private_key));
19809       }
19810     }
19811   }
19812 }
19813 
19814 // Test that HttpNetworkTransaction correctly handles (mocked) certificate
19815 // requests during a TLS renegotiation.
TEST_P(HttpNetworkTransactionTest,CertificateRequestInRenego)19816 TEST_P(HttpNetworkTransactionTest, CertificateRequestInRenego) {
19817   HttpRequestInfo request_info;
19818   request_info.url = GURL("https://www.example.com/");
19819   request_info.method = "GET";
19820   request_info.load_flags = LOAD_NORMAL;
19821   request_info.traffic_annotation =
19822       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19823 
19824   auto cert_request = base::MakeRefCounted<SSLCertRequestInfo>();
19825   cert_request->host_and_port = HostPortPair("www.example.com", 443);
19826 
19827   std::unique_ptr<FakeClientCertIdentity> identity =
19828       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
19829           GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
19830   ASSERT_TRUE(identity);
19831 
19832   // The first connection's handshake succeeds, but we get
19833   // ERR_SSL_CLIENT_AUTH_CERT_NEEDED instead of an HTTP response.
19834   SSLSocketDataProvider ssl_data1(ASYNC, OK);
19835   ssl_data1.cert_request_info = cert_request;
19836   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
19837   MockWrite data1_writes[] = {
19838       MockWrite("GET / HTTP/1.1\r\n"
19839                 "Host: www.example.com\r\n"
19840                 "Connection: keep-alive\r\n\r\n"),
19841   };
19842   MockRead data1_reads[] = {
19843       MockRead(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED),
19844   };
19845   StaticSocketDataProvider data1(data1_reads, data1_writes);
19846   session_deps_.socket_factory->AddSocketDataProvider(&data1);
19847 
19848   // After supplying with certificate, we restart the request from the top,
19849   // which succeeds this time.
19850   SSLSocketDataProvider ssl_data2(ASYNC, OK);
19851   ssl_data2.expected_send_client_cert = true;
19852   ssl_data2.expected_client_cert = identity->certificate();
19853   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
19854   MockWrite data2_writes[] = {
19855       MockWrite("GET / HTTP/1.1\r\n"
19856                 "Host: www.example.com\r\n"
19857                 "Connection: keep-alive\r\n\r\n"),
19858   };
19859   MockRead data2_reads[] = {
19860       MockRead("HTTP/1.1 200 OK\r\n"
19861                "Content-Length: 0\r\n\r\n"),
19862   };
19863   StaticSocketDataProvider data2(data2_reads, data2_writes);
19864   session_deps_.socket_factory->AddSocketDataProvider(&data2);
19865 
19866   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
19867   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19868 
19869   TestCompletionCallback callback;
19870   int rv = callback.GetResult(
19871       trans.Start(&request_info, callback.callback(), NetLogWithSource()));
19872   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
19873 
19874   rv = trans.RestartWithCertificate(identity->certificate(),
19875                                     identity->ssl_private_key(),
19876                                     callback.callback());
19877   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
19878 
19879   // Ensure the certificate was added to the client auth cache
19880   // allowing the connection to continue restarting.
19881   scoped_refptr<X509Certificate> client_cert;
19882   scoped_refptr<SSLPrivateKey> client_private_key;
19883   ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate(
19884       HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
19885   EXPECT_TRUE(client_cert->EqualsIncludingChain(identity->certificate()));
19886 
19887   // Complete the handshake. The request now succeeds.
19888   rv = callback.WaitForResult();
19889   ASSERT_THAT(rv, IsError(OK));
19890   EXPECT_EQ(200, trans.GetResponseInfo()->headers->response_code());
19891 
19892   // The client certificate remains in the cache.
19893   ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate(
19894       HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
19895   EXPECT_TRUE(client_cert->EqualsIncludingChain(identity->certificate()));
19896 }
19897 
TEST_P(HttpNetworkTransactionTest,UseIPConnectionPooling)19898 TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
19899   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
19900   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
19901   session_deps_.host_resolver->rules()->AddRule("www.example.org", "1.2.3.4");
19902   session_deps_.host_resolver->rules()->AddRule("mail.example.com", "1.2.3.4");
19903   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19904 
19905   AddSSLSocketData();
19906 
19907   spdy::SpdySerializedFrame host1_req(
19908       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
19909   spdy_util_.UpdateWithStreamDestruction(1);
19910   spdy::SpdySerializedFrame host2_req(
19911       spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
19912   MockWrite spdy_writes[] = {
19913       CreateMockWrite(host1_req, 0),
19914       CreateMockWrite(host2_req, 3),
19915   };
19916   spdy::SpdySerializedFrame host1_resp(
19917       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
19918   spdy::SpdySerializedFrame host1_resp_body(
19919       spdy_util_.ConstructSpdyDataFrame(1, true));
19920   spdy::SpdySerializedFrame host2_resp(
19921       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
19922   spdy::SpdySerializedFrame host2_resp_body(
19923       spdy_util_.ConstructSpdyDataFrame(3, true));
19924   MockRead spdy_reads[] = {
19925       CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
19926       CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
19927       MockRead(ASYNC, 0, 6),
19928   };
19929 
19930   IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
19931   MockConnect connect(ASYNC, OK, peer_addr);
19932   SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
19933   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
19934 
19935   TestCompletionCallback callback;
19936   HttpRequestInfo request1;
19937   request1.method = "GET";
19938   request1.url = GURL("https://www.example.org/");
19939   request1.load_flags = 0;
19940   request1.traffic_annotation =
19941       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19942   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
19943 
19944   int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
19945   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19946   EXPECT_THAT(callback.WaitForResult(), IsOk());
19947 
19948   const HttpResponseInfo* response = trans1.GetResponseInfo();
19949   ASSERT_TRUE(response);
19950   ASSERT_TRUE(response->headers);
19951   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19952 
19953   std::string response_data;
19954   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
19955   EXPECT_EQ("hello!", response_data);
19956 
19957   // Preload mail.example.com into HostCache.
19958   rv = session_deps_.host_resolver->LoadIntoCache(
19959       HostPortPair("mail.example.com", 443), NetworkAnonymizationKey(),
19960       std::nullopt);
19961   EXPECT_THAT(rv, IsOk());
19962 
19963   HttpRequestInfo request2;
19964   request2.method = "GET";
19965   request2.url = GURL("https://mail.example.com/");
19966   request2.load_flags = 0;
19967   request2.traffic_annotation =
19968       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19969   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
19970 
19971   ConnectedHandler connected_handler2;
19972   trans2.SetConnectedCallback(connected_handler2.Callback());
19973 
19974   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
19975   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19976   EXPECT_THAT(callback.WaitForResult(), IsOk());
19977 
19978   TransportInfo expected_transport;
19979   expected_transport.type = TransportType::kDirect;
19980   expected_transport.endpoint =
19981       net::IPEndPoint(net::IPAddress(1, 2, 3, 4), 443);
19982   expected_transport.negotiated_protocol = kProtoHTTP2;
19983   EXPECT_THAT(connected_handler2.transports(), ElementsAre(expected_transport));
19984 
19985   response = trans2.GetResponseInfo();
19986   ASSERT_TRUE(response);
19987   ASSERT_TRUE(response->headers);
19988   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19989   EXPECT_TRUE(response->was_fetched_via_spdy);
19990   EXPECT_TRUE(response->was_alpn_negotiated);
19991   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
19992   EXPECT_EQ("hello!", response_data);
19993 }
19994 
TEST_P(HttpNetworkTransactionTest,UseIPConnectionPoolingAfterResolution)19995 TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
19996   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
19997   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
19998   session_deps_.host_resolver->rules()->AddRule("www.example.org", "1.2.3.4");
19999   session_deps_.host_resolver->rules()->AddRule("mail.example.com", "1.2.3.4");
20000   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20001 
20002   AddSSLSocketData();
20003 
20004   spdy::SpdySerializedFrame host1_req(
20005       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
20006   spdy_util_.UpdateWithStreamDestruction(1);
20007   spdy::SpdySerializedFrame host2_req(
20008       spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
20009   MockWrite spdy_writes[] = {
20010       CreateMockWrite(host1_req, 0),
20011       CreateMockWrite(host2_req, 3),
20012   };
20013   spdy::SpdySerializedFrame host1_resp(
20014       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
20015   spdy::SpdySerializedFrame host1_resp_body(
20016       spdy_util_.ConstructSpdyDataFrame(1, true));
20017   spdy::SpdySerializedFrame host2_resp(
20018       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
20019   spdy::SpdySerializedFrame host2_resp_body(
20020       spdy_util_.ConstructSpdyDataFrame(3, true));
20021   MockRead spdy_reads[] = {
20022       CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
20023       CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
20024       MockRead(ASYNC, 0, 6),
20025   };
20026 
20027   IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
20028   MockConnect connect(ASYNC, OK, peer_addr);
20029   SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
20030   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
20031 
20032   TestCompletionCallback callback;
20033   HttpRequestInfo request1;
20034   request1.method = "GET";
20035   request1.url = GURL("https://www.example.org/");
20036   request1.load_flags = 0;
20037   request1.traffic_annotation =
20038       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20039   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
20040 
20041   int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
20042   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20043   EXPECT_THAT(callback.WaitForResult(), IsOk());
20044 
20045   const HttpResponseInfo* response = trans1.GetResponseInfo();
20046   ASSERT_TRUE(response);
20047   ASSERT_TRUE(response->headers);
20048   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20049 
20050   std::string response_data;
20051   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
20052   EXPECT_EQ("hello!", response_data);
20053 
20054   HttpRequestInfo request2;
20055   request2.method = "GET";
20056   request2.url = GURL("https://mail.example.com/");
20057   request2.load_flags = 0;
20058   request2.traffic_annotation =
20059       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20060   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
20061 
20062   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
20063   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20064   EXPECT_THAT(callback.WaitForResult(), IsOk());
20065 
20066   response = trans2.GetResponseInfo();
20067   ASSERT_TRUE(response);
20068   ASSERT_TRUE(response->headers);
20069   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20070   EXPECT_TRUE(response->was_fetched_via_spdy);
20071   EXPECT_TRUE(response->was_alpn_negotiated);
20072   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
20073   EXPECT_EQ("hello!", response_data);
20074 }
20075 
20076 // Tests that a SPDY session to an HTTPS proxy for the purposes of proxying
20077 // won't alias with a session directly to a host even if direct connections to
20078 // the proxy server host and to the other host would alias. The request through
20079 // the proxy is made using SPDY.
TEST_P(HttpNetworkTransactionTest,NoIPConnectionPoolingForProxyAndHostSpdy)20080 TEST_P(HttpNetworkTransactionTest, NoIPConnectionPoolingForProxyAndHostSpdy) {
20081   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
20082   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
20083   session_deps_.host_resolver->rules()->AddRule("www.example.org", "1.2.3.4");
20084   session_deps_.host_resolver->rules()->AddRule("mail.example.com", "1.2.3.4");
20085 
20086   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
20087                                   HostPortPair("www.example.org", 443)};
20088   const ProxyChain kProxyServer1Chain{{
20089       kProxyServer1,
20090   }};
20091 
20092   session_deps_.proxy_delegate = std::make_unique<TestProxyDelegate>();
20093   auto* proxy_delegate =
20094       static_cast<TestProxyDelegate*>(session_deps_.proxy_delegate.get());
20095   proxy_delegate->set_proxy_chain(kProxyServer1Chain);
20096 
20097   session_deps_.proxy_resolution_service =
20098       ConfiguredProxyResolutionService::CreateFixedForTest(
20099           "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
20100   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
20101   session_deps_.net_log = NetLog::Get();
20102   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20103 
20104   // CONNECT to request1.test:443 via SPDY.
20105   spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
20106       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
20107       HostPortPair("request1.test", 443)));
20108   spdy::SpdySerializedFrame conn_resp1(
20109       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
20110 
20111   // Fetch https://www.example.org/ via SPDY.
20112   SpdyTestUtil req1_spdy_util(/*use_priority_header=*/true);
20113   spdy::SpdySerializedFrame get1(
20114       req1_spdy_util.ConstructSpdyGet("https://request1.test/", 1, LOWEST));
20115   spdy::SpdySerializedFrame wrapped_get1(
20116       spdy_util_.ConstructWrappedSpdyFrame(get1, 1));
20117   spdy::SpdySerializedFrame get_resp1(
20118       req1_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
20119   spdy::SpdySerializedFrame wrapped_get_resp1(
20120       spdy_util_.ConstructWrappedSpdyFrame(get_resp1, 1));
20121 
20122   spdy::SpdySerializedFrame body1(
20123       req1_spdy_util.ConstructSpdyDataFrame(1, true));
20124   spdy::SpdySerializedFrame wrapped_body1(
20125       spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
20126 
20127   MockWrite spdy_writes[] = {
20128       CreateMockWrite(connect1, 0),
20129       CreateMockWrite(wrapped_get1, 2),
20130   };
20131 
20132   MockRead spdy_reads[] = {
20133       CreateMockRead(conn_resp1, 1),
20134       // TODO(https://crbug.com/497228): We have to manually delay this read so
20135       // that the higher-level SPDY stream doesn't get notified of an available
20136       // read before the write it initiated (the second CONNECT) finishes,
20137       // triggering a DCHECK.
20138       MockRead(ASYNC, ERR_IO_PENDING, 3), CreateMockRead(wrapped_get_resp1, 4),
20139       CreateMockRead(wrapped_body1, 5),
20140       // Pause reads so that the socket will remain open (so we can see whether
20141       // it gets re-used below).
20142       MockRead(ASYNC, ERR_IO_PENDING, 6), MockRead(ASYNC, 0, 7)};
20143 
20144   IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
20145   MockConnect connect(ASYNC, OK, peer_addr);
20146   SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
20147   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
20148 
20149   AddSSLSocketData();
20150   AddSSLSocketData();
20151 
20152   HttpRequestInfo request1;
20153   request1.method = "GET";
20154   request1.url = GURL("https://request1.test/");
20155   request1.traffic_annotation =
20156       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20157 
20158   TestCompletionCallback callback1;
20159 
20160   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
20161 
20162   int rv = trans1.Start(&request1, callback1.callback(),
20163                         NetLogWithSource::Make(NetLogSourceType::NONE));
20164   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20165 
20166   spdy_data.RunUntilPaused();
20167   base::RunLoop().RunUntilIdle();
20168   spdy_data.Resume();
20169 
20170   rv = callback1.WaitForResult();
20171   ASSERT_THAT(rv, IsOk());
20172 
20173   const HttpResponseInfo* response = trans1.GetResponseInfo();
20174   ASSERT_TRUE(response);
20175   ASSERT_TRUE(response->headers);
20176   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20177 
20178   std::string response_data;
20179   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
20180   EXPECT_EQ(kUploadData, response_data);
20181 
20182   proxy_delegate->set_proxy_chain(ProxyChain::Direct());
20183 
20184   SpdyTestUtil req2_spdy_util(/*use_priority_header=*/true);
20185   spdy::SpdySerializedFrame req2(
20186       req2_spdy_util.ConstructSpdyGet("https://mail.example.com/", 1, LOWEST));
20187 
20188   spdy::SpdySerializedFrame resp2(
20189       req2_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
20190   spdy::SpdySerializedFrame data2(
20191       req2_spdy_util.ConstructSpdyDataFrame(1, true));
20192 
20193   MockWrite spdy_writes2[] = {
20194       CreateMockWrite(req2, 0),
20195   };
20196   MockRead spdy_reads2[] = {
20197       CreateMockRead(resp2, 1),
20198       CreateMockRead(data2, 2),
20199       MockRead(ASYNC, 0, 3),
20200   };
20201   SequencedSocketData spdy_data2(connect, spdy_reads2, spdy_writes2);
20202   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
20203 
20204   AddSSLSocketData();
20205 
20206   HttpRequestInfo request2;
20207   request2.method = "GET";
20208   request2.url = GURL("https://mail.example.com/");
20209   request2.traffic_annotation =
20210       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20211 
20212   TestCompletionCallback callback2;
20213 
20214   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
20215 
20216   rv = trans2.Start(&request2, callback2.callback(),
20217                     NetLogWithSource::Make(NetLogSourceType::NONE));
20218   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20219 
20220   rv = callback2.WaitForResult();
20221   ASSERT_THAT(rv, IsOk());
20222 
20223   response = trans2.GetResponseInfo();
20224   ASSERT_TRUE(response);
20225   ASSERT_TRUE(response->headers);
20226   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20227 }
20228 
20229 // Tests that a SPDY session to an HTTPS proxy for the purposes of proxying
20230 // won't alias with a session directly to a host even if direct connections to
20231 // the proxy server host and to the other host would alias. The request through
20232 // the proxy is made using HTTP.
TEST_P(HttpNetworkTransactionTest,NoIPConnectionPoolingForProxyAndHostHttp)20233 TEST_P(HttpNetworkTransactionTest, NoIPConnectionPoolingForProxyAndHostHttp) {
20234   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
20235   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
20236   session_deps_.host_resolver->rules()->AddRule("www.example.org", "1.2.3.4");
20237   session_deps_.host_resolver->rules()->AddRule("mail.example.com", "1.2.3.4");
20238 
20239   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
20240                                   HostPortPair("www.example.org", 443)};
20241   const ProxyChain kProxyServer1Chain{{
20242       kProxyServer1,
20243   }};
20244 
20245   session_deps_.proxy_delegate = std::make_unique<TestProxyDelegate>();
20246   auto* proxy_delegate =
20247       static_cast<TestProxyDelegate*>(session_deps_.proxy_delegate.get());
20248   proxy_delegate->set_proxy_chain(kProxyServer1Chain);
20249 
20250   session_deps_.proxy_resolution_service =
20251       ConfiguredProxyResolutionService::CreateFixedForTest(
20252           "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
20253   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
20254 
20255   session_deps_.net_log = NetLog::Get();
20256   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20257 
20258   spdy::SpdySerializedFrame req(
20259       spdy_util_.ConstructSpdyGet("http://request1.test/", 1, LOWEST));
20260   spdy::SpdySerializedFrame resp(
20261       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
20262   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
20263 
20264   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
20265 
20266   MockRead spdy_reads[] = {CreateMockRead(resp, 1), CreateMockRead(data, 2),
20267                            // Pause reads so that the socket will remain open
20268                            // (so we can see whether it gets re-used below).
20269                            MockRead(ASYNC, ERR_IO_PENDING, 3),
20270                            MockRead(ASYNC, 0, 4)};
20271 
20272   IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
20273   MockConnect connect(ASYNC, OK, peer_addr);
20274   SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
20275   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
20276 
20277   AddSSLSocketData();
20278 
20279   HttpRequestInfo request1;
20280   request1.method = "GET";
20281   request1.url = GURL("http://request1.test/");
20282   request1.traffic_annotation =
20283       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20284 
20285   TestCompletionCallback callback1;
20286 
20287   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
20288 
20289   int rv = trans1.Start(&request1, callback1.callback(),
20290                         NetLogWithSource::Make(NetLogSourceType::NONE));
20291   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20292 
20293   rv = callback1.WaitForResult();
20294   ASSERT_THAT(rv, IsOk());
20295 
20296   const HttpResponseInfo* response = trans1.GetResponseInfo();
20297   ASSERT_TRUE(response);
20298   ASSERT_TRUE(response->headers);
20299   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20300 
20301   std::string response_data;
20302   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
20303   EXPECT_EQ(kUploadData, response_data);
20304 
20305   proxy_delegate->set_proxy_chain(ProxyChain::Direct());
20306 
20307   SpdyTestUtil req2_spdy_util(/*use_priority_header=*/true);
20308   spdy::SpdySerializedFrame req2(
20309       req2_spdy_util.ConstructSpdyGet("https://mail.example.com/", 1, LOWEST));
20310 
20311   spdy::SpdySerializedFrame resp2(
20312       req2_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
20313   spdy::SpdySerializedFrame data2(
20314       req2_spdy_util.ConstructSpdyDataFrame(1, true));
20315 
20316   MockWrite spdy_writes2[] = {
20317       CreateMockWrite(req2, 0),
20318   };
20319   MockRead spdy_reads2[] = {
20320       CreateMockRead(resp2, 1),
20321       CreateMockRead(data2, 2),
20322       MockRead(ASYNC, 0, 3),
20323   };
20324   SequencedSocketData spdy_data2(connect, spdy_reads2, spdy_writes2);
20325   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
20326 
20327   AddSSLSocketData();
20328 
20329   HttpRequestInfo request2;
20330   request2.method = "GET";
20331   request2.url = GURL("https://mail.example.com/");
20332   request2.traffic_annotation =
20333       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20334 
20335   TestCompletionCallback callback2;
20336 
20337   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
20338 
20339   rv = trans2.Start(&request2, callback2.callback(),
20340                     NetLogWithSource::Make(NetLogSourceType::NONE));
20341   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20342 
20343   rv = callback2.WaitForResult();
20344   ASSERT_THAT(rv, IsOk());
20345 
20346   response = trans2.GetResponseInfo();
20347   ASSERT_TRUE(response);
20348   ASSERT_TRUE(response->headers);
20349   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20350 }
20351 
20352 // Tests that a SPDY session to an HTTPS proxy for the purposes of proxying
20353 // won't alias with another proxy session even if direct connections to the
20354 // proxy servers hosts themselves would alias. The requests through the proxy
20355 // are made using SPDY.
TEST_P(HttpNetworkTransactionTest,NoIPConnectionPoolingForTwoProxiesSpdy)20356 TEST_P(HttpNetworkTransactionTest, NoIPConnectionPoolingForTwoProxiesSpdy) {
20357   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
20358   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
20359   session_deps_.host_resolver->rules()->AddRule("www.example.org", "1.2.3.4");
20360   session_deps_.host_resolver->rules()->AddRule("mail.example.com", "1.2.3.4");
20361 
20362   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
20363                                   HostPortPair("www.example.org", 443)};
20364   const ProxyChain kProxyServer1Chain{{
20365       kProxyServer1,
20366   }};
20367 
20368   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
20369                                   HostPortPair("mail.example.com", 443)};
20370   const ProxyChain kProxyServer2Chain{{
20371       kProxyServer2,
20372   }};
20373 
20374   session_deps_.proxy_delegate = std::make_unique<TestProxyDelegate>();
20375   auto* proxy_delegate =
20376       static_cast<TestProxyDelegate*>(session_deps_.proxy_delegate.get());
20377   proxy_delegate->set_proxy_chain(kProxyServer1Chain);
20378 
20379   session_deps_.proxy_resolution_service =
20380       ConfiguredProxyResolutionService::CreateFixedForTest(
20381           "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
20382   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
20383 
20384   session_deps_.net_log = NetLog::Get();
20385   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20386 
20387   // CONNECT to request1.test:443 via SPDY.
20388   spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
20389       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
20390       HostPortPair("request1.test", 443)));
20391   spdy::SpdySerializedFrame conn_resp1(
20392       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
20393 
20394   // Fetch https://www.example.org/ via SPDY.
20395   SpdyTestUtil req1_spdy_util(/*use_priority_header=*/true);
20396   spdy::SpdySerializedFrame get1(
20397       req1_spdy_util.ConstructSpdyGet("https://request1.test/", 1, LOWEST));
20398   spdy::SpdySerializedFrame wrapped_get1(
20399       spdy_util_.ConstructWrappedSpdyFrame(get1, 1));
20400   spdy::SpdySerializedFrame get_resp1(
20401       req1_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
20402   spdy::SpdySerializedFrame wrapped_get_resp1(
20403       spdy_util_.ConstructWrappedSpdyFrame(get_resp1, 1));
20404 
20405   spdy::SpdySerializedFrame body1(
20406       req1_spdy_util.ConstructSpdyDataFrame(1, true));
20407   spdy::SpdySerializedFrame wrapped_body1(
20408       spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
20409 
20410   MockWrite spdy_writes[] = {
20411       CreateMockWrite(connect1, 0),
20412       CreateMockWrite(wrapped_get1, 2),
20413   };
20414 
20415   MockRead spdy_reads[] = {
20416       CreateMockRead(conn_resp1, 1),
20417       // TODO(https://crbug.com/497228): We have to manually delay this read so
20418       // that the higher-level SPDY stream doesn't get notified of an available
20419       // read before the write it initiated (the second CONNECT) finishes,
20420       // triggering a DCHECK.
20421       MockRead(ASYNC, ERR_IO_PENDING, 3), CreateMockRead(wrapped_get_resp1, 4),
20422       CreateMockRead(wrapped_body1, 5),
20423       // Pause reads so that the socket will remain open (so we can see whether
20424       // it gets re-used below).
20425       MockRead(ASYNC, ERR_IO_PENDING, 6), MockRead(ASYNC, 0, 7)};
20426 
20427   IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
20428   MockConnect connect(ASYNC, OK, peer_addr);
20429   SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
20430   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
20431 
20432   AddSSLSocketData();
20433   AddSSLSocketData();
20434 
20435   HttpRequestInfo request1;
20436   request1.method = "GET";
20437   request1.url = GURL("https://request1.test/");
20438   request1.traffic_annotation =
20439       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20440 
20441   TestCompletionCallback callback1;
20442 
20443   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
20444 
20445   int rv = trans1.Start(&request1, callback1.callback(),
20446                         NetLogWithSource::Make(NetLogSourceType::NONE));
20447   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20448 
20449   spdy_data.RunUntilPaused();
20450   base::RunLoop().RunUntilIdle();
20451   spdy_data.Resume();
20452 
20453   rv = callback1.WaitForResult();
20454   ASSERT_THAT(rv, IsOk());
20455 
20456   const HttpResponseInfo* response = trans1.GetResponseInfo();
20457   ASSERT_TRUE(response);
20458   ASSERT_TRUE(response->headers);
20459   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20460 
20461   std::string response_data;
20462   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
20463   EXPECT_EQ(kUploadData, response_data);
20464 
20465   proxy_delegate->set_proxy_chain(kProxyServer2Chain);
20466 
20467   // CONNECT to request2.test:443 via SPDY.
20468   SpdyTestUtil req2_spdy_util(/*use_priority_header=*/true);
20469   spdy::SpdySerializedFrame connect2(req2_spdy_util.ConstructSpdyConnect(
20470       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
20471       HostPortPair("request2.test", 443)));
20472   spdy::SpdySerializedFrame conn_resp2(
20473       req2_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
20474 
20475   // Fetch https://www.example.org/ via SPDY.
20476   SpdyTestUtil wrapped_req2_spdy_util(/*use_priority_header=*/true);
20477   spdy::SpdySerializedFrame get2(wrapped_req2_spdy_util.ConstructSpdyGet(
20478       "https://request2.test/", 1, LOWEST));
20479   spdy::SpdySerializedFrame wrapped_get2(
20480       req2_spdy_util.ConstructWrappedSpdyFrame(get2, 1));
20481   spdy::SpdySerializedFrame get_resp2(
20482       wrapped_req2_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
20483   spdy::SpdySerializedFrame wrapped_get_resp2(
20484       req2_spdy_util.ConstructWrappedSpdyFrame(get_resp2, 1));
20485 
20486   spdy::SpdySerializedFrame body2(
20487       wrapped_req2_spdy_util.ConstructSpdyDataFrame(1, true));
20488   spdy::SpdySerializedFrame wrapped_body2(
20489       req2_spdy_util.ConstructWrappedSpdyFrame(body2, 1));
20490 
20491   MockWrite spdy_writes2[] = {
20492       CreateMockWrite(connect2, 0),
20493       CreateMockWrite(wrapped_get2, 2),
20494   };
20495 
20496   MockRead spdy_reads2[] = {
20497       CreateMockRead(conn_resp2, 1),
20498       // TODO(https://crbug.com/497228): We have to manually delay this read so
20499       // that the higher-level SPDY stream doesn't get notified of an available
20500       // read before the write it initiated (the second CONNECT) finishes,
20501       // triggering a DCHECK.
20502       MockRead(ASYNC, ERR_IO_PENDING, 3),
20503       CreateMockRead(wrapped_get_resp2, 4),
20504       CreateMockRead(wrapped_body2, 5),
20505       MockRead(ASYNC, 0, 6),
20506   };
20507 
20508   SequencedSocketData spdy_data2(connect, spdy_reads2, spdy_writes2);
20509   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
20510 
20511   AddSSLSocketData();
20512   AddSSLSocketData();
20513 
20514   HttpRequestInfo request2;
20515   request2.method = "GET";
20516   request2.url = GURL("https://request2.test/");
20517   request2.traffic_annotation =
20518       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20519 
20520   TestCompletionCallback callback2;
20521 
20522   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
20523 
20524   rv = trans2.Start(&request2, callback2.callback(),
20525                     NetLogWithSource::Make(NetLogSourceType::NONE));
20526   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20527 
20528   spdy_data2.RunUntilPaused();
20529   base::RunLoop().RunUntilIdle();
20530   spdy_data2.Resume();
20531 
20532   rv = callback2.WaitForResult();
20533   ASSERT_THAT(rv, IsOk());
20534 
20535   response = trans2.GetResponseInfo();
20536   ASSERT_TRUE(response);
20537   ASSERT_TRUE(response->headers);
20538   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20539 }
20540 
20541 // Tests that a SPDY session to an HTTPS proxy for the purposes of proxying
20542 // won't alias with another proxy session even if direct connections to the
20543 // proxy servers hosts themselves would alias. The requests through the proxy
20544 // are made using HTTP.
TEST_P(HttpNetworkTransactionTest,NoIPConnectionPoolingForTwoProxiesHttp)20545 TEST_P(HttpNetworkTransactionTest, NoIPConnectionPoolingForTwoProxiesHttp) {
20546   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
20547   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
20548   session_deps_.host_resolver->rules()->AddRule("www.example.org", "1.2.3.4");
20549   session_deps_.host_resolver->rules()->AddRule("mail.example.com", "1.2.3.4");
20550 
20551   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
20552                                   HostPortPair("www.example.org", 443)};
20553   const ProxyChain kProxyServer1Chain{{
20554       kProxyServer1,
20555   }};
20556 
20557   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
20558                                   HostPortPair("mail.example.com", 443)};
20559   const ProxyChain kProxyServer2Chain{{
20560       kProxyServer2,
20561   }};
20562 
20563   session_deps_.proxy_delegate = std::make_unique<TestProxyDelegate>();
20564   auto* proxy_delegate =
20565       static_cast<TestProxyDelegate*>(session_deps_.proxy_delegate.get());
20566   proxy_delegate->set_proxy_chain(kProxyServer1Chain);
20567 
20568   session_deps_.proxy_resolution_service =
20569       ConfiguredProxyResolutionService::CreateFixedForTest(
20570           "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
20571   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
20572   session_deps_.net_log = NetLog::Get();
20573   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20574 
20575   spdy::SpdySerializedFrame req(
20576       spdy_util_.ConstructSpdyGet("http://request1.test/", 1, LOWEST));
20577   spdy::SpdySerializedFrame resp(
20578       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
20579   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
20580 
20581   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
20582 
20583   MockRead spdy_reads[] = {CreateMockRead(resp, 1), CreateMockRead(data, 2),
20584                            // Pause reads so that the socket will remain open
20585                            // (so we can see whether it gets re-used below).
20586                            MockRead(ASYNC, ERR_IO_PENDING, 3),
20587                            MockRead(ASYNC, 0, 4)};
20588 
20589   IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
20590   MockConnect connect(ASYNC, OK, peer_addr);
20591   SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
20592   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
20593 
20594   AddSSLSocketData();
20595 
20596   HttpRequestInfo request1;
20597   request1.method = "GET";
20598   request1.url = GURL("http://request1.test/");
20599   request1.traffic_annotation =
20600       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20601 
20602   TestCompletionCallback callback1;
20603 
20604   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
20605 
20606   int rv = trans1.Start(&request1, callback1.callback(),
20607                         NetLogWithSource::Make(NetLogSourceType::NONE));
20608   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20609 
20610   rv = callback1.WaitForResult();
20611   ASSERT_THAT(rv, IsOk());
20612 
20613   const HttpResponseInfo* response = trans1.GetResponseInfo();
20614   ASSERT_TRUE(response);
20615   ASSERT_TRUE(response->headers);
20616   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20617 
20618   std::string response_data;
20619   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
20620   EXPECT_EQ(kUploadData, response_data);
20621 
20622   proxy_delegate->set_proxy_chain(kProxyServer2Chain);
20623 
20624   SpdyTestUtil req2_spdy_util(/*use_priority_header=*/true);
20625   spdy::SpdySerializedFrame req2(
20626       req2_spdy_util.ConstructSpdyGet("http://request2.test/", 1, LOWEST));
20627 
20628   spdy::SpdySerializedFrame resp2(
20629       req2_spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
20630   spdy::SpdySerializedFrame data2(
20631       req2_spdy_util.ConstructSpdyDataFrame(1, true));
20632 
20633   MockWrite spdy_writes2[] = {CreateMockWrite(req2, 0)};
20634 
20635   MockRead spdy_reads2[] = {
20636       CreateMockRead(resp2, 1),
20637       CreateMockRead(data2, 2),
20638       MockRead(ASYNC, 0, 3),
20639   };
20640 
20641   SequencedSocketData spdy_data2(connect, spdy_reads2, spdy_writes2);
20642   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
20643 
20644   AddSSLSocketData();
20645 
20646   HttpRequestInfo request2;
20647   request2.method = "GET";
20648   request2.url = GURL("http://request2.test/");
20649   request2.traffic_annotation =
20650       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20651 
20652   TestCompletionCallback callback2;
20653 
20654   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
20655 
20656   rv = trans2.Start(&request2, callback2.callback(),
20657                     NetLogWithSource::Make(NetLogSourceType::NONE));
20658   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20659 
20660   rv = callback2.WaitForResult();
20661   ASSERT_THAT(rv, IsOk());
20662 
20663   response = trans2.GetResponseInfo();
20664   ASSERT_TRUE(response);
20665   ASSERT_TRUE(response->headers);
20666   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20667 }
20668 
20669 // Regression test for https://crbug.com/546991.
20670 // The server might not be able to serve an IP pooled request, and might send a
20671 // 421 Misdirected Request response status to indicate this.
20672 // HttpNetworkTransaction should reset the request and retry without IP pooling.
TEST_P(HttpNetworkTransactionTest,RetryWithoutConnectionPooling)20673 TEST_P(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
20674   // Two hosts resolve to the same IP address.
20675   const std::string ip_addr = "1.2.3.4";
20676   IPAddress ip;
20677   ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
20678   IPEndPoint peer_addr = IPEndPoint(ip, 443);
20679 
20680   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
20681   session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
20682   session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
20683 
20684   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20685 
20686   // Two requests on the first connection.
20687   spdy::SpdySerializedFrame req1(
20688       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
20689   spdy_util_.UpdateWithStreamDestruction(1);
20690   spdy::SpdySerializedFrame req2(
20691       spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
20692   spdy::SpdySerializedFrame rst(
20693       spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
20694   MockWrite writes1[] = {
20695       CreateMockWrite(req1, 0),
20696       CreateMockWrite(req2, 3),
20697       CreateMockWrite(rst, 6),
20698   };
20699 
20700   // The first one succeeds, the second gets error 421 Misdirected Request.
20701   spdy::SpdySerializedFrame resp1(
20702       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
20703   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
20704   spdy::Http2HeaderBlock response_headers;
20705   response_headers[spdy::kHttp2StatusHeader] = "421";
20706   spdy::SpdySerializedFrame resp2(
20707       spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
20708   MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
20709                        CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
20710 
20711   MockConnect connect1(ASYNC, OK, peer_addr);
20712   SequencedSocketData data1(connect1, reads1, writes1);
20713   session_deps_.socket_factory->AddSocketDataProvider(&data1);
20714 
20715   AddSSLSocketData();
20716 
20717   // Retry the second request on a second connection.
20718   SpdyTestUtil spdy_util2(/*use_priority_header=*/true);
20719   spdy::SpdySerializedFrame req3(
20720       spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
20721   MockWrite writes2[] = {
20722       CreateMockWrite(req3, 0),
20723   };
20724 
20725   spdy::SpdySerializedFrame resp3(
20726       spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
20727   spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
20728   MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
20729                        MockRead(ASYNC, 0, 3)};
20730 
20731   MockConnect connect2(ASYNC, OK, peer_addr);
20732   SequencedSocketData data2(connect2, reads2, writes2);
20733   session_deps_.socket_factory->AddSocketDataProvider(&data2);
20734 
20735   AddSSLSocketData();
20736 
20737   // Preload mail.example.org into HostCache.
20738   int rv = session_deps_.host_resolver->LoadIntoCache(
20739       HostPortPair("mail.example.org", 443), NetworkAnonymizationKey(),
20740       std::nullopt);
20741   EXPECT_THAT(rv, IsOk());
20742 
20743   HttpRequestInfo request1;
20744   request1.method = "GET";
20745   request1.url = GURL("https://www.example.org/");
20746   request1.load_flags = 0;
20747   request1.traffic_annotation =
20748       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20749   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
20750 
20751   TestCompletionCallback callback;
20752   rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
20753   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20754   rv = callback.WaitForResult();
20755   EXPECT_THAT(rv, IsOk());
20756 
20757   const HttpResponseInfo* response = trans1.GetResponseInfo();
20758   ASSERT_TRUE(response);
20759   ASSERT_TRUE(response->headers);
20760   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20761   EXPECT_TRUE(response->was_fetched_via_spdy);
20762   EXPECT_TRUE(response->was_alpn_negotiated);
20763   std::string response_data;
20764   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
20765   EXPECT_EQ("hello!", response_data);
20766 
20767   HttpRequestInfo request2;
20768   request2.method = "GET";
20769   request2.url = GURL("https://mail.example.org/");
20770   request2.load_flags = 0;
20771   request2.traffic_annotation =
20772       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20773   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
20774 
20775   RecordingNetLogObserver net_log_observer;
20776   rv = trans2.Start(&request2, callback.callback(),
20777                     NetLogWithSource::Make(NetLogSourceType::NONE));
20778   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20779   rv = callback.WaitForResult();
20780   EXPECT_THAT(rv, IsOk());
20781 
20782   response = trans2.GetResponseInfo();
20783   ASSERT_TRUE(response);
20784   ASSERT_TRUE(response->headers);
20785   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20786   EXPECT_TRUE(response->was_fetched_via_spdy);
20787   EXPECT_TRUE(response->was_alpn_negotiated);
20788   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
20789   EXPECT_EQ("hello!", response_data);
20790 
20791   auto entries = net_log_observer.GetEntries();
20792   ExpectLogContainsSomewhere(
20793       entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
20794       NetLogEventPhase::NONE);
20795 }
20796 
20797 // Test that HTTP 421 responses are properly returned to the caller if received
20798 // on the retry as well. HttpNetworkTransaction should not infinite loop or lose
20799 // portions of the response.
TEST_P(HttpNetworkTransactionTest,ReturnHTTP421OnRetry)20800 TEST_P(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
20801   // Two hosts resolve to the same IP address.
20802   const std::string ip_addr = "1.2.3.4";
20803   IPAddress ip;
20804   ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
20805   IPEndPoint peer_addr = IPEndPoint(ip, 443);
20806 
20807   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
20808   session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
20809   session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
20810 
20811   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20812 
20813   // Two requests on the first connection.
20814   spdy::SpdySerializedFrame req1(
20815       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
20816   spdy_util_.UpdateWithStreamDestruction(1);
20817   spdy::SpdySerializedFrame req2(
20818       spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
20819   spdy::SpdySerializedFrame rst(
20820       spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
20821   MockWrite writes1[] = {
20822       CreateMockWrite(req1, 0),
20823       CreateMockWrite(req2, 3),
20824       CreateMockWrite(rst, 6),
20825   };
20826 
20827   // The first one succeeds, the second gets error 421 Misdirected Request.
20828   spdy::SpdySerializedFrame resp1(
20829       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
20830   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
20831   spdy::Http2HeaderBlock response_headers;
20832   response_headers[spdy::kHttp2StatusHeader] = "421";
20833   spdy::SpdySerializedFrame resp2(
20834       spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
20835   MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
20836                        CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
20837 
20838   MockConnect connect1(ASYNC, OK, peer_addr);
20839   SequencedSocketData data1(connect1, reads1, writes1);
20840   session_deps_.socket_factory->AddSocketDataProvider(&data1);
20841 
20842   AddSSLSocketData();
20843 
20844   // Retry the second request on a second connection. It returns 421 Misdirected
20845   // Retry again.
20846   SpdyTestUtil spdy_util2(/*use_priority_header=*/true);
20847   spdy::SpdySerializedFrame req3(
20848       spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
20849   MockWrite writes2[] = {
20850       CreateMockWrite(req3, 0),
20851   };
20852 
20853   spdy::SpdySerializedFrame resp3(
20854       spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
20855   spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
20856   MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
20857                        MockRead(ASYNC, 0, 3)};
20858 
20859   MockConnect connect2(ASYNC, OK, peer_addr);
20860   SequencedSocketData data2(connect2, reads2, writes2);
20861   session_deps_.socket_factory->AddSocketDataProvider(&data2);
20862 
20863   AddSSLSocketData();
20864 
20865   // Preload mail.example.org into HostCache.
20866   int rv = session_deps_.host_resolver->LoadIntoCache(
20867       HostPortPair("mail.example.org", 443), NetworkAnonymizationKey(),
20868       std::nullopt);
20869   EXPECT_THAT(rv, IsOk());
20870 
20871   HttpRequestInfo request1;
20872   request1.method = "GET";
20873   request1.url = GURL("https://www.example.org/");
20874   request1.load_flags = 0;
20875   request1.traffic_annotation =
20876       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20877   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
20878 
20879   TestCompletionCallback callback;
20880   rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
20881   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20882   rv = callback.WaitForResult();
20883   EXPECT_THAT(rv, IsOk());
20884 
20885   const HttpResponseInfo* response = trans1.GetResponseInfo();
20886   ASSERT_TRUE(response);
20887   ASSERT_TRUE(response->headers);
20888   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20889   EXPECT_TRUE(response->was_fetched_via_spdy);
20890   EXPECT_TRUE(response->was_alpn_negotiated);
20891   std::string response_data;
20892   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
20893   EXPECT_EQ("hello!", response_data);
20894 
20895   HttpRequestInfo request2;
20896   request2.method = "GET";
20897   request2.url = GURL("https://mail.example.org/");
20898   request2.load_flags = 0;
20899   request2.traffic_annotation =
20900       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20901   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
20902 
20903   rv = trans2.Start(&request2, callback.callback(),
20904                     NetLogWithSource::Make(NetLogSourceType::NONE));
20905   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20906   rv = callback.WaitForResult();
20907   EXPECT_THAT(rv, IsOk());
20908 
20909   // After a retry, the 421 Misdirected Request is reported back up to the
20910   // caller.
20911   response = trans2.GetResponseInfo();
20912   ASSERT_TRUE(response);
20913   ASSERT_TRUE(response->headers);
20914   EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
20915   EXPECT_TRUE(response->was_fetched_via_spdy);
20916   EXPECT_TRUE(response->was_alpn_negotiated);
20917   EXPECT_TRUE(response->ssl_info.cert);
20918   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
20919   EXPECT_EQ("hello!", response_data);
20920 }
20921 
TEST_P(HttpNetworkTransactionTest,Response421WithStreamingBodyWithNonNullSource)20922 TEST_P(HttpNetworkTransactionTest,
20923        Response421WithStreamingBodyWithNonNullSource) {
20924   const std::string ip_addr = "1.2.3.4";
20925   IPAddress ip;
20926   ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
20927   IPEndPoint peer_addr = IPEndPoint(ip, 443);
20928 
20929   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
20930   session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
20931   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20932 
20933   const std::string request_body = "hello";
20934   spdy::SpdySerializedFrame req1 = spdy_util_.ConstructChunkedSpdyPost({}, 0);
20935   spdy::SpdySerializedFrame req1_body =
20936       spdy_util_.ConstructSpdyDataFrame(1, request_body, /*fin=*/true);
20937   spdy::SpdySerializedFrame rst =
20938       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL);
20939   MockWrite writes1[] = {
20940       CreateMockWrite(req1, 0),
20941       CreateMockWrite(req1_body, 1),
20942       CreateMockWrite(rst, 4),
20943   };
20944 
20945   spdy::Http2HeaderBlock response_headers;
20946   response_headers[spdy::kHttp2StatusHeader] = "421";
20947   spdy::SpdySerializedFrame resp1 =
20948       spdy_util_.ConstructSpdyReply(1, std::move(response_headers));
20949   MockRead reads1[] = {CreateMockRead(resp1, 2), MockRead(ASYNC, 0, 3)};
20950 
20951   MockConnect connect1(ASYNC, OK, peer_addr);
20952   SequencedSocketData data1(connect1, reads1, writes1);
20953   session_deps_.socket_factory->AddSocketDataProvider(&data1);
20954 
20955   AddSSLSocketData();
20956 
20957   SpdyTestUtil spdy_util2(/*use_priority_header=*/true);
20958   spdy::SpdySerializedFrame req2 = spdy_util2.ConstructChunkedSpdyPost({}, 0);
20959   spdy::SpdySerializedFrame req2_body =
20960       spdy_util2.ConstructSpdyDataFrame(1, request_body, /*fin=*/true);
20961   MockWrite writes2[] = {
20962       CreateMockWrite(req2, 0),
20963       CreateMockWrite(req2_body, 1),
20964   };
20965 
20966   spdy::Http2HeaderBlock resp2_headers;
20967   resp2_headers[spdy::kHttp2StatusHeader] = "200";
20968   spdy::SpdySerializedFrame resp2 =
20969       spdy_util2.ConstructSpdyReply(1, std::move(resp2_headers));
20970   spdy::SpdySerializedFrame resp2_body(
20971       spdy_util2.ConstructSpdyDataFrame(1, true));
20972   MockRead reads2[] = {CreateMockRead(resp2, 2), CreateMockRead(resp2_body, 3),
20973                        MockRead(ASYNC, 0, 4)};
20974 
20975   MockConnect connect2(ASYNC, OK, peer_addr);
20976   SequencedSocketData data2(connect2, reads2, writes2);
20977   session_deps_.socket_factory->AddSocketDataProvider(&data2);
20978 
20979   AddSSLSocketData();
20980 
20981   TestCompletionCallback callback;
20982   HttpRequestInfo request;
20983   ChunkedUploadDataStream upload_data_stream(0, /*has_null_source=*/false);
20984   upload_data_stream.AppendData(request_body.data(), request_body.size(),
20985                                 /*is_done=*/true);
20986   request.method = "POST";
20987   request.url = GURL("https://www.example.org");
20988   request.load_flags = 0;
20989   request.traffic_annotation =
20990       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20991   request.upload_data_stream = &upload_data_stream;
20992   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
20993 
20994   int rv = trans.Start(&request, callback.callback(),
20995                        NetLogWithSource::Make(NetLogSourceType::NONE));
20996   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20997   rv = callback.WaitForResult();
20998   EXPECT_THAT(rv, IsOk());
20999 
21000   const HttpResponseInfo* response = trans.GetResponseInfo();
21001   std::string response_data;
21002   ASSERT_TRUE(response);
21003   ASSERT_TRUE(response->headers);
21004   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
21005   EXPECT_TRUE(response->was_fetched_via_spdy);
21006   EXPECT_TRUE(response->was_alpn_negotiated);
21007   EXPECT_TRUE(response->ssl_info.cert);
21008   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
21009   EXPECT_EQ("hello!", response_data);
21010 }
21011 
TEST_P(HttpNetworkTransactionTest,Response421WithStreamingBodyWithNullSource)21012 TEST_P(HttpNetworkTransactionTest, Response421WithStreamingBodyWithNullSource) {
21013   const std::string ip_addr = "1.2.3.4";
21014   IPAddress ip;
21015   ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
21016   IPEndPoint peer_addr = IPEndPoint(ip, 443);
21017 
21018   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
21019   session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
21020   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21021 
21022   const std::string request_body = "hello";
21023   spdy::SpdySerializedFrame req1 = spdy_util_.ConstructChunkedSpdyPost({}, 0);
21024   spdy::SpdySerializedFrame req1_body =
21025       spdy_util_.ConstructSpdyDataFrame(1, request_body, /*fin=*/true);
21026   spdy::SpdySerializedFrame rst =
21027       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL);
21028   MockWrite writes1[] = {
21029       CreateMockWrite(req1, 0),
21030       CreateMockWrite(req1_body, 1),
21031       CreateMockWrite(rst, 5),
21032   };
21033 
21034   spdy::Http2HeaderBlock response_headers;
21035   response_headers[spdy::kHttp2StatusHeader] = "421";
21036   spdy::SpdySerializedFrame resp1 =
21037       spdy_util_.ConstructSpdyReply(1, std::move(response_headers));
21038   spdy::SpdySerializedFrame resp1_body(
21039       spdy_util_.ConstructSpdyDataFrame(1, true));
21040   MockRead reads1[] = {CreateMockRead(resp1, 2), CreateMockRead(resp1_body, 3),
21041                        MockRead(ASYNC, 0, 4)};
21042 
21043   MockConnect connect1(ASYNC, OK, peer_addr);
21044   SequencedSocketData data1(connect1, reads1, writes1);
21045   session_deps_.socket_factory->AddSocketDataProvider(&data1);
21046 
21047   AddSSLSocketData();
21048 
21049   TestCompletionCallback callback;
21050   HttpRequestInfo request;
21051   ChunkedUploadDataStream upload_data_stream(0, /*has_null_source=*/true);
21052   upload_data_stream.AppendData(request_body.data(), request_body.size(),
21053                                 /*is_done=*/true);
21054   request.method = "POST";
21055   request.url = GURL("https://www.example.org");
21056   request.load_flags = 0;
21057   request.traffic_annotation =
21058       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21059   request.upload_data_stream = &upload_data_stream;
21060   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
21061 
21062   int rv = trans.Start(&request, callback.callback(),
21063                        NetLogWithSource::Make(NetLogSourceType::NONE));
21064   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
21065   rv = callback.WaitForResult();
21066   EXPECT_THAT(rv, IsOk());
21067 
21068   const HttpResponseInfo* response = trans.GetResponseInfo();
21069   std::string response_data;
21070   ASSERT_TRUE(response);
21071   ASSERT_TRUE(response->headers);
21072   EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
21073   EXPECT_TRUE(response->was_fetched_via_spdy);
21074   EXPECT_TRUE(response->was_alpn_negotiated);
21075   EXPECT_TRUE(response->ssl_info.cert);
21076   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
21077   EXPECT_EQ("hello!", response_data);
21078 }
21079 
TEST_P(HttpNetworkTransactionTest,UseIPConnectionPoolingWithHostCacheExpiration)21080 TEST_P(HttpNetworkTransactionTest,
21081        UseIPConnectionPoolingWithHostCacheExpiration) {
21082   // Set up HostResolver to invalidate cached entries after 1 cached resolve.
21083   session_deps_.host_resolver =
21084       std::make_unique<MockCachingHostResolver>(1 /* cache_invalidation_num */);
21085   session_deps_.host_resolver->rules()->AddRule("www.example.org", "1.2.3.4");
21086   session_deps_.host_resolver->rules()->AddRule("mail.example.com", "1.2.3.4");
21087   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21088 
21089   AddSSLSocketData();
21090 
21091   spdy::SpdySerializedFrame host1_req(
21092       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
21093   spdy_util_.UpdateWithStreamDestruction(1);
21094   spdy::SpdySerializedFrame host2_req(
21095       spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
21096   MockWrite spdy_writes[] = {
21097       CreateMockWrite(host1_req, 0),
21098       CreateMockWrite(host2_req, 3),
21099   };
21100   spdy::SpdySerializedFrame host1_resp(
21101       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
21102   spdy::SpdySerializedFrame host1_resp_body(
21103       spdy_util_.ConstructSpdyDataFrame(1, true));
21104   spdy::SpdySerializedFrame host2_resp(
21105       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
21106   spdy::SpdySerializedFrame host2_resp_body(
21107       spdy_util_.ConstructSpdyDataFrame(3, true));
21108   MockRead spdy_reads[] = {
21109       CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
21110       CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
21111       MockRead(ASYNC, 0, 6),
21112   };
21113 
21114   IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
21115   MockConnect connect(ASYNC, OK, peer_addr);
21116   SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
21117   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
21118 
21119   TestCompletionCallback callback;
21120   HttpRequestInfo request1;
21121   request1.method = "GET";
21122   request1.url = GURL("https://www.example.org/");
21123   request1.load_flags = 0;
21124   request1.traffic_annotation =
21125       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21126   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
21127 
21128   int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
21129   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
21130   EXPECT_THAT(callback.WaitForResult(), IsOk());
21131 
21132   const HttpResponseInfo* response = trans1.GetResponseInfo();
21133   ASSERT_TRUE(response);
21134   ASSERT_TRUE(response->headers);
21135   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
21136 
21137   std::string response_data;
21138   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
21139   EXPECT_EQ("hello!", response_data);
21140 
21141   // Preload cache entries into HostCache.
21142   rv = session_deps_.host_resolver->LoadIntoCache(
21143       HostPortPair("mail.example.com", 443), NetworkAnonymizationKey(),
21144       std::nullopt);
21145   EXPECT_THAT(rv, IsOk());
21146 
21147   HttpRequestInfo request2;
21148   request2.method = "GET";
21149   request2.url = GURL("https://mail.example.com/");
21150   request2.load_flags = 0;
21151   request2.traffic_annotation =
21152       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21153   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
21154 
21155   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
21156   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
21157   EXPECT_THAT(callback.WaitForResult(), IsOk());
21158 
21159   response = trans2.GetResponseInfo();
21160   ASSERT_TRUE(response);
21161   ASSERT_TRUE(response->headers);
21162   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
21163   EXPECT_TRUE(response->was_fetched_via_spdy);
21164   EXPECT_TRUE(response->was_alpn_negotiated);
21165   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
21166   EXPECT_EQ("hello!", response_data);
21167 }
21168 
TEST_P(HttpNetworkTransactionTest,DoNotUseSpdySessionForHttp)21169 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
21170   const std::string https_url = "https://www.example.org:8080/";
21171   const std::string http_url = "http://www.example.org:8080/";
21172 
21173   // SPDY GET for HTTPS URL
21174   spdy::SpdySerializedFrame req1(
21175       spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
21176 
21177   MockWrite writes1[] = {
21178       CreateMockWrite(req1, 0),
21179   };
21180 
21181   spdy::SpdySerializedFrame resp1(
21182       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
21183   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
21184   MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
21185                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
21186 
21187   SequencedSocketData data1(reads1, writes1);
21188   MockConnect connect_data1(ASYNC, OK);
21189   data1.set_connect_data(connect_data1);
21190 
21191   // HTTP GET for the HTTP URL
21192   MockWrite writes2[] = {
21193       MockWrite(ASYNC, 0,
21194                 "GET / HTTP/1.1\r\n"
21195                 "Host: www.example.org:8080\r\n"
21196                 "Connection: keep-alive\r\n\r\n"),
21197   };
21198 
21199   MockRead reads2[] = {
21200       MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
21201       MockRead(ASYNC, 2, "hello"),
21202       MockRead(ASYNC, OK, 3),
21203   };
21204 
21205   SequencedSocketData data2(reads2, writes2);
21206 
21207   SSLSocketDataProvider ssl(ASYNC, OK);
21208   ssl.next_proto = kProtoHTTP2;
21209   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
21210   session_deps_.socket_factory->AddSocketDataProvider(&data1);
21211   session_deps_.socket_factory->AddSocketDataProvider(&data2);
21212 
21213   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21214 
21215   // Start the first transaction to set up the SpdySession
21216   HttpRequestInfo request1;
21217   request1.method = "GET";
21218   request1.url = GURL(https_url);
21219   request1.load_flags = 0;
21220   request1.traffic_annotation =
21221       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21222   HttpNetworkTransaction trans1(LOWEST, session.get());
21223   TestCompletionCallback callback1;
21224   EXPECT_EQ(ERR_IO_PENDING,
21225             trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
21226   base::RunLoop().RunUntilIdle();
21227 
21228   EXPECT_THAT(callback1.WaitForResult(), IsOk());
21229   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
21230 
21231   // Now, start the HTTP request
21232   HttpRequestInfo request2;
21233   request2.method = "GET";
21234   request2.url = GURL(http_url);
21235   request2.load_flags = 0;
21236   request2.traffic_annotation =
21237       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21238   HttpNetworkTransaction trans2(MEDIUM, session.get());
21239   TestCompletionCallback callback2;
21240   EXPECT_EQ(ERR_IO_PENDING,
21241             trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
21242   base::RunLoop().RunUntilIdle();
21243 
21244   EXPECT_THAT(callback2.WaitForResult(), IsOk());
21245   EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
21246 }
21247 
21248 // Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
21249 // with the alternative server.  That connection should not be used.
TEST_P(HttpNetworkTransactionTest,AlternativeServiceNotOnHttp11)21250 TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
21251   url::SchemeHostPort server("https", "www.example.org", 443);
21252   HostPortPair alternative("www.example.org", 444);
21253 
21254   // Negotiate HTTP/1.1 with alternative.
21255   SSLSocketDataProvider ssl(ASYNC, OK);
21256   ssl.next_proto = kProtoHTTP11;
21257   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
21258 
21259   // No data should be read from the alternative, because HTTP/1.1 is
21260   // negotiated.
21261   StaticSocketDataProvider data;
21262   session_deps_.socket_factory->AddSocketDataProvider(&data);
21263 
21264   // This test documents that an alternate Job should not be used if HTTP/1.1 is
21265   // negotiated.  In order to test this, a failed connection to the server is
21266   // mocked.  This way the request relies on the alternate Job.
21267   StaticSocketDataProvider data_refused;
21268   data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
21269   session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
21270 
21271   // Set up alternative service for server.
21272   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21273   HttpServerProperties* http_server_properties =
21274       session->http_server_properties();
21275   AlternativeService alternative_service(kProtoHTTP2, alternative);
21276   base::Time expiration = base::Time::Now() + base::Days(1);
21277   http_server_properties->SetHttp2AlternativeService(
21278       server, NetworkAnonymizationKey(), alternative_service, expiration);
21279 
21280   HttpRequestInfo request;
21281   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
21282   request.method = "GET";
21283   request.url = GURL("https://www.example.org:443");
21284   request.traffic_annotation =
21285       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21286   TestCompletionCallback callback;
21287 
21288   // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
21289   // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
21290   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
21291   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
21292 }
21293 
21294 // A request to a server with an alternative service fires two Jobs: one to the
21295 // server, and an alternate one to the alternative server.  If the former
21296 // succeeds, the request should succeed,  even if the latter fails because
21297 // HTTP/1.1 is negotiated which is insufficient for alternative service.
TEST_P(HttpNetworkTransactionTest,FailedAlternativeServiceIsNotUserVisible)21298 TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
21299   url::SchemeHostPort server("https", "www.example.org", 443);
21300   HostPortPair alternative("www.example.org", 444);
21301 
21302   // Negotiate HTTP/1.1 with alternative.
21303   SSLSocketDataProvider alternative_ssl(ASYNC, OK);
21304   alternative_ssl.next_proto = kProtoHTTP11;
21305   session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
21306 
21307   // No data should be read from the alternative, because HTTP/1.1 is
21308   // negotiated.
21309   StaticSocketDataProvider data;
21310   session_deps_.socket_factory->AddSocketDataProvider(&data);
21311 
21312   // Negotiate HTTP/1.1 with server.
21313   SSLSocketDataProvider origin_ssl(ASYNC, OK);
21314   origin_ssl.next_proto = kProtoHTTP11;
21315   session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
21316 
21317   MockWrite http_writes[] = {
21318       MockWrite("GET / HTTP/1.1\r\n"
21319                 "Host: www.example.org\r\n"
21320                 "Connection: keep-alive\r\n\r\n"),
21321       MockWrite("GET /second HTTP/1.1\r\n"
21322                 "Host: www.example.org\r\n"
21323                 "Connection: keep-alive\r\n\r\n"),
21324   };
21325 
21326   MockRead http_reads[] = {
21327       MockRead("HTTP/1.1 200 OK\r\n"),
21328       MockRead("Content-Type: text/html\r\n"),
21329       MockRead("Content-Length: 6\r\n\r\n"),
21330       MockRead("foobar"),
21331       MockRead("HTTP/1.1 200 OK\r\n"),
21332       MockRead("Content-Type: text/html\r\n"),
21333       MockRead("Content-Length: 7\r\n\r\n"),
21334       MockRead("another"),
21335   };
21336   StaticSocketDataProvider http_data(http_reads, http_writes);
21337   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
21338 
21339   // Set up alternative service for server.
21340   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21341   HttpServerProperties* http_server_properties =
21342       session->http_server_properties();
21343   AlternativeService alternative_service(kProtoHTTP2, alternative);
21344   base::Time expiration = base::Time::Now() + base::Days(1);
21345   http_server_properties->SetHttp2AlternativeService(
21346       server, NetworkAnonymizationKey(), alternative_service, expiration);
21347 
21348   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
21349   HttpRequestInfo request1;
21350   request1.method = "GET";
21351   request1.url = GURL("https://www.example.org:443");
21352   request1.load_flags = 0;
21353   request1.traffic_annotation =
21354       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21355   TestCompletionCallback callback1;
21356 
21357   int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
21358   rv = callback1.GetResult(rv);
21359   EXPECT_THAT(rv, IsOk());
21360 
21361   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
21362   ASSERT_TRUE(response1);
21363   ASSERT_TRUE(response1->headers);
21364   EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
21365 
21366   std::string response_data1;
21367   ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
21368   EXPECT_EQ("foobar", response_data1);
21369 
21370   // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
21371   // for alternative service.
21372   EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
21373       alternative_service, NetworkAnonymizationKey()));
21374 
21375   // Since |alternative_service| is broken, a second transaction to server
21376   // should not start an alternate Job.  It should pool to existing connection
21377   // to server.
21378   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
21379   HttpRequestInfo request2;
21380   request2.method = "GET";
21381   request2.url = GURL("https://www.example.org:443/second");
21382   request2.load_flags = 0;
21383   request2.traffic_annotation =
21384       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21385   TestCompletionCallback callback2;
21386 
21387   rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
21388   rv = callback2.GetResult(rv);
21389   EXPECT_THAT(rv, IsOk());
21390 
21391   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
21392   ASSERT_TRUE(response2);
21393   ASSERT_TRUE(response2->headers);
21394   EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
21395 
21396   std::string response_data2;
21397   ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
21398   EXPECT_EQ("another", response_data2);
21399 }
21400 
21401 // Alternative service requires HTTP/2 (or SPDY), but there is already a
21402 // HTTP/1.1 socket open to the alternative server.  That socket should not be
21403 // used.
TEST_P(HttpNetworkTransactionTest,AlternativeServiceShouldNotPoolToHttp11)21404 TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
21405   url::SchemeHostPort server("https", "origin.example.org", 443);
21406   HostPortPair alternative("alternative.example.org", 443);
21407   std::string origin_url = "https://origin.example.org:443";
21408   std::string alternative_url = "https://alternative.example.org:443";
21409 
21410   // Negotiate HTTP/1.1 with alternative.example.org.
21411   SSLSocketDataProvider ssl(ASYNC, OK);
21412   ssl.next_proto = kProtoHTTP11;
21413   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
21414 
21415   // HTTP/1.1 data for |request1| and |request2|.
21416   MockWrite http_writes[] = {
21417       MockWrite("GET / HTTP/1.1\r\n"
21418                 "Host: alternative.example.org\r\n"
21419                 "Connection: keep-alive\r\n\r\n"),
21420       MockWrite("GET / HTTP/1.1\r\n"
21421                 "Host: alternative.example.org\r\n"
21422                 "Connection: keep-alive\r\n\r\n"),
21423   };
21424 
21425   MockRead http_reads[] = {
21426       MockRead("HTTP/1.1 200 OK\r\n"
21427                "Content-Type: text/html; charset=iso-8859-1\r\n"
21428                "Content-Length: 40\r\n\r\n"
21429                "first HTTP/1.1 response from alternative"),
21430       MockRead("HTTP/1.1 200 OK\r\n"
21431                "Content-Type: text/html; charset=iso-8859-1\r\n"
21432                "Content-Length: 41\r\n\r\n"
21433                "second HTTP/1.1 response from alternative"),
21434   };
21435   StaticSocketDataProvider http_data(http_reads, http_writes);
21436   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
21437 
21438   // This test documents that an alternate Job should not pool to an already
21439   // existing HTTP/1.1 connection.  In order to test this, a failed connection
21440   // to the server is mocked.  This way |request2| relies on the alternate Job.
21441   StaticSocketDataProvider data_refused;
21442   data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
21443   session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
21444 
21445   // Set up alternative service for server.
21446   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21447   HttpServerProperties* http_server_properties =
21448       session->http_server_properties();
21449   AlternativeService alternative_service(kProtoHTTP2, alternative);
21450   base::Time expiration = base::Time::Now() + base::Days(1);
21451   http_server_properties->SetHttp2AlternativeService(
21452       server, NetworkAnonymizationKey(), alternative_service, expiration);
21453 
21454   // First transaction to alternative to open an HTTP/1.1 socket.
21455   HttpRequestInfo request1;
21456   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
21457   request1.method = "GET";
21458   request1.url = GURL(alternative_url);
21459   request1.load_flags = 0;
21460   request1.traffic_annotation =
21461       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21462   TestCompletionCallback callback1;
21463 
21464   int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
21465   EXPECT_THAT(callback1.GetResult(rv), IsOk());
21466   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
21467   ASSERT_TRUE(response1);
21468   ASSERT_TRUE(response1->headers);
21469   EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
21470   EXPECT_TRUE(response1->was_alpn_negotiated);
21471   EXPECT_FALSE(response1->was_fetched_via_spdy);
21472   std::string response_data1;
21473   ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
21474   EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
21475 
21476   // Request for origin.example.org, which has an alternative service.  This
21477   // will start two Jobs: the alternative looks for connections to pool to,
21478   // finds one which is HTTP/1.1, and should ignore it, and should not try to
21479   // open other connections to alternative server.  The Job to server fails, so
21480   // this request fails.
21481   HttpRequestInfo request2;
21482   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
21483   request2.method = "GET";
21484   request2.url = GURL(origin_url);
21485   request2.load_flags = 0;
21486   request2.traffic_annotation =
21487       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21488   TestCompletionCallback callback2;
21489 
21490   rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
21491   EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
21492 
21493   // Another transaction to alternative.  This is to test that the HTTP/1.1
21494   // socket is still open and in the pool.
21495   HttpRequestInfo request3;
21496   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
21497   request3.method = "GET";
21498   request3.url = GURL(alternative_url);
21499   request3.load_flags = 0;
21500   request3.traffic_annotation =
21501       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21502   TestCompletionCallback callback3;
21503 
21504   rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
21505   EXPECT_THAT(callback3.GetResult(rv), IsOk());
21506   const HttpResponseInfo* response3 = trans3.GetResponseInfo();
21507   ASSERT_TRUE(response3);
21508   ASSERT_TRUE(response3->headers);
21509   EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
21510   EXPECT_TRUE(response3->was_alpn_negotiated);
21511   EXPECT_FALSE(response3->was_fetched_via_spdy);
21512   std::string response_data3;
21513   ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
21514   EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
21515 }
21516 
TEST_P(HttpNetworkTransactionTest,DoNotUseSpdySessionForHttpOverTunnel)21517 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
21518   const std::string https_url = "https://www.example.org:8080/";
21519   const std::string http_url = "http://www.example.org:8080/";
21520 
21521   // Separate SPDY util instance for naked and wrapped requests.
21522   SpdyTestUtil spdy_util_wrapped(/*use_priority_header=*/true);
21523 
21524   // SPDY GET for HTTPS URL (through CONNECT tunnel)
21525   const HostPortPair host_port_pair("www.example.org", 8080);
21526   spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
21527       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
21528       host_port_pair));
21529   spdy::SpdySerializedFrame req1(
21530       spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
21531   spdy::SpdySerializedFrame wrapped_req1(
21532       spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
21533 
21534   // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
21535   spdy::Http2HeaderBlock req2_block;
21536   req2_block[spdy::kHttp2MethodHeader] = "GET";
21537   req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
21538   req2_block[spdy::kHttp2SchemeHeader] = "http";
21539   req2_block[spdy::kHttp2PathHeader] = "/";
21540   spdy::SpdySerializedFrame req2(
21541       spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
21542 
21543   MockWrite writes1[] = {
21544       CreateMockWrite(connect, 0),
21545       CreateMockWrite(wrapped_req1, 2),
21546       CreateMockWrite(req2, 6),
21547   };
21548 
21549   spdy::SpdySerializedFrame conn_resp(
21550       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
21551   spdy::SpdySerializedFrame resp1(
21552       spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
21553   spdy::SpdySerializedFrame body1(
21554       spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
21555   spdy::SpdySerializedFrame wrapped_resp1(
21556       spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
21557   spdy::SpdySerializedFrame wrapped_body1(
21558       spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
21559   spdy::SpdySerializedFrame resp2(
21560       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
21561   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
21562   MockRead reads1[] = {
21563       CreateMockRead(conn_resp, 1),
21564       MockRead(ASYNC, ERR_IO_PENDING, 3),
21565       CreateMockRead(wrapped_resp1, 4),
21566       CreateMockRead(wrapped_body1, 5),
21567       MockRead(ASYNC, ERR_IO_PENDING, 7),
21568       CreateMockRead(resp2, 8),
21569       CreateMockRead(body2, 9),
21570       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
21571   };
21572 
21573   SequencedSocketData data1(reads1, writes1);
21574   MockConnect connect_data1(ASYNC, OK);
21575   data1.set_connect_data(connect_data1);
21576 
21577   session_deps_.proxy_resolution_service =
21578       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
21579           "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
21580   session_deps_.net_log = net::NetLog::Get();
21581   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
21582   ssl1.next_proto = kProtoHTTP2;
21583   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
21584   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
21585   ssl2.next_proto = kProtoHTTP2;
21586   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
21587   session_deps_.socket_factory->AddSocketDataProvider(&data1);
21588 
21589   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
21590 
21591   // Start the first transaction to set up the SpdySession
21592   HttpRequestInfo request1;
21593   request1.method = "GET";
21594   request1.url = GURL(https_url);
21595   request1.load_flags = 0;
21596   request1.traffic_annotation =
21597       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21598   HttpNetworkTransaction trans1(LOWEST, session.get());
21599   TestCompletionCallback callback1;
21600   int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
21601 
21602   // This pause is a hack to avoid running into https://crbug.com/497228.
21603   data1.RunUntilPaused();
21604   base::RunLoop().RunUntilIdle();
21605   data1.Resume();
21606   EXPECT_THAT(callback1.GetResult(rv), IsOk());
21607   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
21608 
21609   LoadTimingInfo load_timing_info1;
21610   EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
21611   TestLoadTimingNotReusedWithPac(load_timing_info1,
21612                                  CONNECT_TIMING_HAS_SSL_TIMES);
21613 
21614   // Now, start the HTTP request.
21615   HttpRequestInfo request2;
21616   request2.method = "GET";
21617   request2.url = GURL(http_url);
21618   request2.load_flags = 0;
21619   request2.traffic_annotation =
21620       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21621   HttpNetworkTransaction trans2(MEDIUM, session.get());
21622   TestCompletionCallback callback2;
21623   rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
21624 
21625   // This pause is a hack to avoid running into https://crbug.com/497228.
21626   data1.RunUntilPaused();
21627   base::RunLoop().RunUntilIdle();
21628   data1.Resume();
21629   EXPECT_THAT(callback2.GetResult(rv), IsOk());
21630 
21631   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
21632 
21633   LoadTimingInfo load_timing_info2;
21634   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
21635   // The established SPDY sessions is considered reused by the HTTP request.
21636   TestLoadTimingReusedWithPac(load_timing_info2);
21637   // HTTP requests over a SPDY session should have a different connection
21638   // socket_log_id than requests over a tunnel.
21639   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
21640 }
21641 
21642 // Test that in the case where we have a SPDY session to a SPDY proxy
21643 // that we do not pool other origins that resolve to the same IP when
21644 // the certificate does not match the new origin.
21645 // http://crbug.com/134690
TEST_P(HttpNetworkTransactionTest,DoNotUseSpdySessionIfCertDoesNotMatch)21646 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
21647   const std::string url1 = "http://www.example.org/";
21648   const std::string url2 = "https://news.example.org/";
21649   const std::string ip_addr = "1.2.3.4";
21650 
21651   // Second SpdyTestUtil instance for the second socket.
21652   SpdyTestUtil spdy_util_secure(/*use_priority_header=*/true);
21653 
21654   // SPDY GET for HTTP URL (through SPDY proxy)
21655   spdy::Http2HeaderBlock headers(
21656       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
21657   spdy::SpdySerializedFrame req1(
21658       spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
21659 
21660   MockWrite writes1[] = {
21661       CreateMockWrite(req1, 0),
21662   };
21663 
21664   spdy::SpdySerializedFrame resp1(
21665       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
21666   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
21667   MockRead reads1[] = {
21668       MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
21669       CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4),  // EOF
21670   };
21671 
21672   SequencedSocketData data1(reads1, writes1);
21673   IPAddress ip;
21674   ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
21675   IPEndPoint peer_addr = IPEndPoint(ip, 443);
21676   MockConnect connect_data1(ASYNC, OK, peer_addr);
21677   data1.set_connect_data(connect_data1);
21678 
21679   // SPDY GET for HTTPS URL (direct)
21680   spdy::SpdySerializedFrame req2(
21681       spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
21682 
21683   MockWrite writes2[] = {
21684       CreateMockWrite(req2, 0),
21685   };
21686 
21687   spdy::SpdySerializedFrame resp2(
21688       spdy_util_secure.ConstructSpdyGetReply(nullptr, 0, 1));
21689   spdy::SpdySerializedFrame body2(
21690       spdy_util_secure.ConstructSpdyDataFrame(1, true));
21691   MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
21692                        MockRead(ASYNC, OK, 3)};
21693 
21694   SequencedSocketData data2(reads2, writes2);
21695   MockConnect connect_data2(ASYNC, OK);
21696   data2.set_connect_data(connect_data2);
21697 
21698   // Set up a proxy config that sends HTTP requests to a proxy, and
21699   // all others direct.
21700   ProxyConfig proxy_config;
21701   proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
21702   session_deps_.proxy_resolution_service =
21703       ConfiguredProxyResolutionService::CreateFixedForTest(
21704           ProxyConfigWithAnnotation(proxy_config,
21705                                     TRAFFIC_ANNOTATION_FOR_TESTS));
21706 
21707   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
21708   ssl1.next_proto = kProtoHTTP2;
21709   // Load a valid cert.  Note, that this does not need to
21710   // be valid for proxy because the MockSSLClientSocket does
21711   // not actually verify it.  But SpdySession will use this
21712   // to see if it is valid for the new origin
21713   ssl1.ssl_info.cert =
21714       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
21715   ASSERT_TRUE(ssl1.ssl_info.cert);
21716   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
21717   session_deps_.socket_factory->AddSocketDataProvider(&data1);
21718 
21719   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
21720   ssl2.next_proto = kProtoHTTP2;
21721   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
21722   session_deps_.socket_factory->AddSocketDataProvider(&data2);
21723 
21724   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
21725   session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
21726   session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
21727 
21728   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
21729 
21730   // Start the first transaction to set up the SpdySession
21731   HttpRequestInfo request1;
21732   request1.method = "GET";
21733   request1.url = GURL(url1);
21734   request1.load_flags = 0;
21735   request1.traffic_annotation =
21736       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21737   HttpNetworkTransaction trans1(LOWEST, session.get());
21738   TestCompletionCallback callback1;
21739   ASSERT_EQ(ERR_IO_PENDING,
21740             trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
21741   // This pause is a hack to avoid running into https://crbug.com/497228.
21742   data1.RunUntilPaused();
21743   base::RunLoop().RunUntilIdle();
21744   data1.Resume();
21745 
21746   EXPECT_THAT(callback1.WaitForResult(), IsOk());
21747   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
21748 
21749   // Now, start the HTTP request
21750   HttpRequestInfo request2;
21751   request2.method = "GET";
21752   request2.url = GURL(url2);
21753   request2.load_flags = 0;
21754   request2.traffic_annotation =
21755       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21756   HttpNetworkTransaction trans2(MEDIUM, session.get());
21757   TestCompletionCallback callback2;
21758   EXPECT_EQ(ERR_IO_PENDING,
21759             trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
21760   base::RunLoop().RunUntilIdle();
21761 
21762   ASSERT_TRUE(callback2.have_result());
21763   EXPECT_THAT(callback2.WaitForResult(), IsOk());
21764   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
21765 }
21766 
21767 // Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
21768 // error) in SPDY session, removes the socket from pool and closes the SPDY
21769 // session. Verify that new url's from the same HttpNetworkSession (and a new
21770 // SpdySession) do work. http://crbug.com/224701
TEST_P(HttpNetworkTransactionTest,ErrorSocketNotConnected)21771 TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
21772   const std::string https_url = "https://www.example.org/";
21773 
21774   MockRead reads1[] = {MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)};
21775 
21776   SequencedSocketData data1(reads1, base::span<MockWrite>());
21777 
21778   spdy::SpdySerializedFrame req2(
21779       spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
21780   MockWrite writes2[] = {
21781       CreateMockWrite(req2, 0),
21782   };
21783 
21784   spdy::SpdySerializedFrame resp2(
21785       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
21786   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
21787   MockRead reads2[] = {
21788       CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
21789       MockRead(ASYNC, OK, 3)  // EOF
21790   };
21791 
21792   SequencedSocketData data2(reads2, writes2);
21793 
21794   SSLSocketDataProvider ssl1(ASYNC, OK);
21795   ssl1.next_proto = kProtoHTTP2;
21796   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
21797   session_deps_.socket_factory->AddSocketDataProvider(&data1);
21798 
21799   SSLSocketDataProvider ssl2(ASYNC, OK);
21800   ssl2.next_proto = kProtoHTTP2;
21801   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
21802   session_deps_.socket_factory->AddSocketDataProvider(&data2);
21803 
21804   std::unique_ptr<HttpNetworkSession> session(
21805       SpdySessionDependencies::SpdyCreateSession(&session_deps_));
21806 
21807   // Start the first transaction to set up the SpdySession and verify that
21808   // connection was closed.
21809   HttpRequestInfo request1;
21810   request1.method = "GET";
21811   request1.url = GURL(https_url);
21812   request1.load_flags = 0;
21813   request1.traffic_annotation =
21814       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21815   HttpNetworkTransaction trans1(MEDIUM, session.get());
21816   TestCompletionCallback callback1;
21817   EXPECT_EQ(ERR_IO_PENDING,
21818             trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
21819   EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
21820 
21821   // Now, start the second request and make sure it succeeds.
21822   HttpRequestInfo request2;
21823   request2.method = "GET";
21824   request2.url = GURL(https_url);
21825   request2.load_flags = 0;
21826   request2.traffic_annotation =
21827       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21828   HttpNetworkTransaction trans2(MEDIUM, session.get());
21829   TestCompletionCallback callback2;
21830   EXPECT_EQ(ERR_IO_PENDING,
21831             trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
21832 
21833   ASSERT_THAT(callback2.WaitForResult(), IsOk());
21834   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
21835 }
21836 
TEST_P(HttpNetworkTransactionTest,CloseIdleSpdySessionToOpenNewOne)21837 TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
21838   ClientSocketPoolManager::set_max_sockets_per_group(
21839       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
21840   ClientSocketPoolManager::set_max_sockets_per_pool(
21841       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
21842 
21843   // Use two different hosts with different IPs so they don't get pooled.
21844   session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
21845   session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
21846   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21847 
21848   SSLSocketDataProvider ssl1(ASYNC, OK);
21849   ssl1.next_proto = kProtoHTTP2;
21850   SSLSocketDataProvider ssl2(ASYNC, OK);
21851   ssl2.next_proto = kProtoHTTP2;
21852   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
21853   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
21854 
21855   spdy::SpdySerializedFrame host1_req(
21856       spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
21857   MockWrite spdy1_writes[] = {
21858       CreateMockWrite(host1_req, 0),
21859   };
21860   spdy::SpdySerializedFrame host1_resp(
21861       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
21862   spdy::SpdySerializedFrame host1_resp_body(
21863       spdy_util_.ConstructSpdyDataFrame(1, true));
21864   MockRead spdy1_reads[] = {
21865       CreateMockRead(host1_resp, 1),
21866       CreateMockRead(host1_resp_body, 2),
21867       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
21868   };
21869 
21870   // Use a separate test instance for the separate SpdySession that will be
21871   // created.
21872   SpdyTestUtil spdy_util_2(/*use_priority_header=*/true);
21873   SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
21874   session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
21875 
21876   spdy::SpdySerializedFrame host2_req(
21877       spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
21878   MockWrite spdy2_writes[] = {
21879       CreateMockWrite(host2_req, 0),
21880   };
21881   spdy::SpdySerializedFrame host2_resp(
21882       spdy_util_2.ConstructSpdyGetReply(nullptr, 0, 1));
21883   spdy::SpdySerializedFrame host2_resp_body(
21884       spdy_util_2.ConstructSpdyDataFrame(1, true));
21885   MockRead spdy2_reads[] = {
21886       CreateMockRead(host2_resp, 1),
21887       CreateMockRead(host2_resp_body, 2),
21888       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
21889   };
21890 
21891   SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
21892   session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
21893 
21894   MockWrite http_write[] = {
21895       MockWrite("GET / HTTP/1.1\r\n"
21896                 "Host: www.a.com\r\n"
21897                 "Connection: keep-alive\r\n\r\n"),
21898   };
21899 
21900   MockRead http_read[] = {
21901       MockRead("HTTP/1.1 200 OK\r\n"),
21902       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
21903       MockRead("Content-Length: 6\r\n\r\n"),
21904       MockRead("hello!"),
21905   };
21906   StaticSocketDataProvider http_data(http_read, http_write);
21907   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
21908 
21909   HostPortPair host_port_pair_a("www.a.com", 443);
21910   SpdySessionKey spdy_session_key_a(
21911       host_port_pair_a, PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
21912       SessionUsage::kDestination, SocketTag(), NetworkAnonymizationKey(),
21913       SecureDnsPolicy::kAllow,
21914       /*disable_cert_verification_network_fetches=*/false);
21915   EXPECT_FALSE(
21916       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
21917 
21918   TestCompletionCallback callback;
21919   HttpRequestInfo request1;
21920   request1.method = "GET";
21921   request1.url = GURL("https://www.a.com/");
21922   request1.load_flags = 0;
21923   request1.traffic_annotation =
21924       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21925   auto trans =
21926       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
21927 
21928   int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
21929   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
21930   EXPECT_THAT(callback.WaitForResult(), IsOk());
21931 
21932   const HttpResponseInfo* response = trans->GetResponseInfo();
21933   ASSERT_TRUE(response);
21934   ASSERT_TRUE(response->headers);
21935   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
21936   EXPECT_TRUE(response->was_fetched_via_spdy);
21937   EXPECT_TRUE(response->was_alpn_negotiated);
21938 
21939   std::string response_data;
21940   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
21941   EXPECT_EQ("hello!", response_data);
21942   trans.reset();
21943   EXPECT_TRUE(HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
21944 
21945   HostPortPair host_port_pair_b("www.b.com", 443);
21946   SpdySessionKey spdy_session_key_b(
21947       host_port_pair_b, PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
21948       SessionUsage::kDestination, SocketTag(), NetworkAnonymizationKey(),
21949       SecureDnsPolicy::kAllow,
21950       /*disable_cert_verification_network_fetches=*/false);
21951   EXPECT_FALSE(
21952       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
21953   HttpRequestInfo request2;
21954   request2.method = "GET";
21955   request2.url = GURL("https://www.b.com/");
21956   request2.load_flags = 0;
21957   request2.traffic_annotation =
21958       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21959   trans =
21960       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
21961 
21962   rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
21963   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
21964   EXPECT_THAT(callback.WaitForResult(), IsOk());
21965 
21966   response = trans->GetResponseInfo();
21967   ASSERT_TRUE(response);
21968   ASSERT_TRUE(response->headers);
21969   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
21970   EXPECT_TRUE(response->was_fetched_via_spdy);
21971   EXPECT_TRUE(response->was_alpn_negotiated);
21972   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
21973   EXPECT_EQ("hello!", response_data);
21974   EXPECT_FALSE(
21975       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
21976   EXPECT_TRUE(HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
21977 
21978   HostPortPair host_port_pair_a1("www.a.com", 80);
21979   SpdySessionKey spdy_session_key_a1(
21980       host_port_pair_a1, PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
21981       SessionUsage::kDestination, SocketTag(), NetworkAnonymizationKey(),
21982       SecureDnsPolicy::kAllow,
21983       /*disable_cert_verification_network_fetches=*/false);
21984   EXPECT_FALSE(
21985       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
21986   HttpRequestInfo request3;
21987   request3.method = "GET";
21988   request3.url = GURL("http://www.a.com/");
21989   request3.load_flags = 0;
21990   request3.traffic_annotation =
21991       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21992   trans =
21993       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
21994 
21995   rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
21996   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
21997   EXPECT_THAT(callback.WaitForResult(), IsOk());
21998 
21999   response = trans->GetResponseInfo();
22000   ASSERT_TRUE(response);
22001   ASSERT_TRUE(response->headers);
22002   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
22003   EXPECT_FALSE(response->was_fetched_via_spdy);
22004   EXPECT_FALSE(response->was_alpn_negotiated);
22005   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
22006   EXPECT_EQ("hello!", response_data);
22007   EXPECT_FALSE(
22008       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
22009   EXPECT_FALSE(
22010       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
22011 }
22012 
TEST_P(HttpNetworkTransactionTest,HttpSyncConnectError)22013 TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
22014   HttpRequestInfo request;
22015   request.method = "GET";
22016   request.url = GURL("http://www.example.org/");
22017   request.traffic_annotation =
22018       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22019 
22020   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22021   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22022 
22023   MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
22024   StaticSocketDataProvider data;
22025   data.set_connect_data(mock_connect);
22026   session_deps_.socket_factory->AddSocketDataProvider(&data);
22027 
22028   TestCompletionCallback callback;
22029 
22030   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22031   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22032 
22033   rv = callback.WaitForResult();
22034   EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
22035 
22036   ConnectionAttempts attempts = trans.GetConnectionAttempts();
22037   ASSERT_EQ(1u, attempts.size());
22038   EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
22039 
22040   IPEndPoint endpoint;
22041   EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
22042   EXPECT_TRUE(endpoint.address().empty());
22043 }
22044 
TEST_P(HttpNetworkTransactionTest,HttpAsyncConnectError)22045 TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
22046   HttpRequestInfo request;
22047   request.method = "GET";
22048   request.url = GURL("http://www.example.org/");
22049   request.traffic_annotation =
22050       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22051 
22052   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22053   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22054 
22055   MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
22056   StaticSocketDataProvider data;
22057   data.set_connect_data(mock_connect);
22058   session_deps_.socket_factory->AddSocketDataProvider(&data);
22059 
22060   TestCompletionCallback callback;
22061 
22062   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22063   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22064 
22065   rv = callback.WaitForResult();
22066   EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
22067 
22068   ConnectionAttempts attempts = trans.GetConnectionAttempts();
22069   ASSERT_EQ(1u, attempts.size());
22070   EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
22071 
22072   IPEndPoint endpoint;
22073   EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
22074   EXPECT_TRUE(endpoint.address().empty());
22075 }
22076 
TEST_P(HttpNetworkTransactionTest,HttpSyncWriteError)22077 TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
22078   HttpRequestInfo request;
22079   request.method = "GET";
22080   request.url = GURL("http://www.example.org/");
22081   request.traffic_annotation =
22082       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22083 
22084   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22085   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22086 
22087   MockWrite data_writes[] = {
22088       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
22089   };
22090   MockRead data_reads[] = {
22091       MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
22092   };
22093 
22094   StaticSocketDataProvider data(data_reads, data_writes);
22095   session_deps_.socket_factory->AddSocketDataProvider(&data);
22096 
22097   TestCompletionCallback callback;
22098 
22099   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22100   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22101 
22102   rv = callback.WaitForResult();
22103   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
22104 }
22105 
TEST_P(HttpNetworkTransactionTest,HttpAsyncWriteError)22106 TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
22107   HttpRequestInfo request;
22108   request.method = "GET";
22109   request.url = GURL("http://www.example.org/");
22110   request.traffic_annotation =
22111       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22112 
22113   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22114   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22115 
22116   MockWrite data_writes[] = {
22117       MockWrite(ASYNC, ERR_CONNECTION_RESET),
22118   };
22119   MockRead data_reads[] = {
22120       MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
22121   };
22122 
22123   StaticSocketDataProvider data(data_reads, data_writes);
22124   session_deps_.socket_factory->AddSocketDataProvider(&data);
22125 
22126   TestCompletionCallback callback;
22127 
22128   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22129   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22130 
22131   rv = callback.WaitForResult();
22132   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
22133 }
22134 
TEST_P(HttpNetworkTransactionTest,HttpSyncReadError)22135 TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
22136   HttpRequestInfo request;
22137   request.method = "GET";
22138   request.url = GURL("http://www.example.org/");
22139   request.traffic_annotation =
22140       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22141 
22142   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22143   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22144 
22145   MockWrite data_writes[] = {
22146       MockWrite("GET / HTTP/1.1\r\n"
22147                 "Host: www.example.org\r\n"
22148                 "Connection: keep-alive\r\n\r\n"),
22149   };
22150   MockRead data_reads[] = {
22151       MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
22152   };
22153 
22154   StaticSocketDataProvider data(data_reads, data_writes);
22155   session_deps_.socket_factory->AddSocketDataProvider(&data);
22156 
22157   TestCompletionCallback callback;
22158 
22159   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22160   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22161 
22162   rv = callback.WaitForResult();
22163   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
22164 }
22165 
TEST_P(HttpNetworkTransactionTest,HttpAsyncReadError)22166 TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
22167   HttpRequestInfo request;
22168   request.method = "GET";
22169   request.url = GURL("http://www.example.org/");
22170   request.traffic_annotation =
22171       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22172 
22173   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22174   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22175 
22176   MockWrite data_writes[] = {
22177       MockWrite("GET / HTTP/1.1\r\n"
22178                 "Host: www.example.org\r\n"
22179                 "Connection: keep-alive\r\n\r\n"),
22180   };
22181   MockRead data_reads[] = {
22182       MockRead(ASYNC, ERR_CONNECTION_RESET),
22183   };
22184 
22185   StaticSocketDataProvider data(data_reads, data_writes);
22186   session_deps_.socket_factory->AddSocketDataProvider(&data);
22187 
22188   TestCompletionCallback callback;
22189 
22190   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22191   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22192 
22193   rv = callback.WaitForResult();
22194   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
22195 }
22196 
22197 // Tests that when a used socket is returned to the SSL socket pool, it's closed
22198 // if the transport socket pool is stalled on the global socket limit.
TEST_P(HttpNetworkTransactionTest,CloseSSLSocketOnIdleForHttpRequest)22199 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
22200   ClientSocketPoolManager::set_max_sockets_per_group(
22201       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
22202   ClientSocketPoolManager::set_max_sockets_per_pool(
22203       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
22204 
22205   // Set up SSL request.
22206 
22207   HttpRequestInfo ssl_request;
22208   ssl_request.method = "GET";
22209   ssl_request.url = GURL("https://www.example.org/");
22210   ssl_request.traffic_annotation =
22211       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22212 
22213   MockWrite ssl_writes[] = {
22214       MockWrite("GET / HTTP/1.1\r\n"
22215                 "Host: www.example.org\r\n"
22216                 "Connection: keep-alive\r\n\r\n"),
22217   };
22218   MockRead ssl_reads[] = {
22219       MockRead("HTTP/1.1 200 OK\r\n"),
22220       MockRead("Content-Length: 11\r\n\r\n"),
22221       MockRead("hello world"),
22222       MockRead(SYNCHRONOUS, OK),
22223   };
22224   StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
22225   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
22226 
22227   SSLSocketDataProvider ssl(ASYNC, OK);
22228   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
22229 
22230   // Set up HTTP request.
22231 
22232   HttpRequestInfo http_request;
22233   http_request.method = "GET";
22234   http_request.url = GURL("http://www.example.org/");
22235   http_request.traffic_annotation =
22236       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22237 
22238   MockWrite http_writes[] = {
22239       MockWrite("GET / HTTP/1.1\r\n"
22240                 "Host: www.example.org\r\n"
22241                 "Connection: keep-alive\r\n\r\n"),
22242   };
22243   MockRead http_reads[] = {
22244       MockRead("HTTP/1.1 200 OK\r\n"),
22245       MockRead("Content-Length: 7\r\n\r\n"),
22246       MockRead("falafel"),
22247       MockRead(SYNCHRONOUS, OK),
22248   };
22249   StaticSocketDataProvider http_data(http_reads, http_writes);
22250   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
22251 
22252   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22253 
22254   // Start the SSL request.
22255   TestCompletionCallback ssl_callback;
22256   HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
22257   ASSERT_EQ(ERR_IO_PENDING,
22258             ssl_trans.Start(&ssl_request, ssl_callback.callback(),
22259                             NetLogWithSource()));
22260 
22261   // Start the HTTP request.  Pool should stall.
22262   TestCompletionCallback http_callback;
22263   HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
22264   ASSERT_EQ(ERR_IO_PENDING,
22265             http_trans.Start(&http_request, http_callback.callback(),
22266                              NetLogWithSource()));
22267   EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
22268 
22269   // Wait for response from SSL request.
22270   ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
22271   std::string response_data;
22272   ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
22273   EXPECT_EQ("hello world", response_data);
22274 
22275   // The SSL socket should automatically be closed, so the HTTP request can
22276   // start.
22277   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
22278   ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
22279 
22280   // The HTTP request can now complete.
22281   ASSERT_THAT(http_callback.WaitForResult(), IsOk());
22282   ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
22283   EXPECT_EQ("falafel", response_data);
22284 
22285   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
22286 }
22287 
22288 // Tests that when a SSL connection is established but there's no corresponding
22289 // request that needs it, the new socket is closed if the transport socket pool
22290 // is stalled on the global socket limit.
TEST_P(HttpNetworkTransactionTest,CloseSSLSocketOnIdleForHttpRequest2)22291 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
22292   ClientSocketPoolManager::set_max_sockets_per_group(
22293       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
22294   ClientSocketPoolManager::set_max_sockets_per_pool(
22295       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
22296 
22297   // Set up an ssl request.
22298 
22299   HttpRequestInfo ssl_request;
22300   ssl_request.method = "GET";
22301   ssl_request.url = GURL("https://www.foopy.com/");
22302   ssl_request.traffic_annotation =
22303       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22304 
22305   // No data will be sent on the SSL socket.
22306   StaticSocketDataProvider ssl_data;
22307   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
22308 
22309   SSLSocketDataProvider ssl(ASYNC, OK);
22310   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
22311 
22312   // Set up HTTP request.
22313 
22314   HttpRequestInfo http_request;
22315   http_request.method = "GET";
22316   http_request.url = GURL("http://www.example.org/");
22317   http_request.traffic_annotation =
22318       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22319 
22320   MockWrite http_writes[] = {
22321       MockWrite("GET / HTTP/1.1\r\n"
22322                 "Host: www.example.org\r\n"
22323                 "Connection: keep-alive\r\n\r\n"),
22324   };
22325   MockRead http_reads[] = {
22326       MockRead("HTTP/1.1 200 OK\r\n"),
22327       MockRead("Content-Length: 7\r\n\r\n"),
22328       MockRead("falafel"),
22329       MockRead(SYNCHRONOUS, OK),
22330   };
22331   StaticSocketDataProvider http_data(http_reads, http_writes);
22332   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
22333 
22334   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22335 
22336   // Preconnect an SSL socket.  A preconnect is needed because connect jobs are
22337   // cancelled when a normal transaction is cancelled.
22338   HttpStreamFactory* http_stream_factory = session->http_stream_factory();
22339   http_stream_factory->PreconnectStreams(1, ssl_request);
22340   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
22341 
22342   // Start the HTTP request.  Pool should stall.
22343   TestCompletionCallback http_callback;
22344   HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
22345   ASSERT_EQ(ERR_IO_PENDING,
22346             http_trans.Start(&http_request, http_callback.callback(),
22347                              NetLogWithSource()));
22348   EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
22349 
22350   // The SSL connection will automatically be closed once the connection is
22351   // established, to let the HTTP request start.
22352   ASSERT_THAT(http_callback.WaitForResult(), IsOk());
22353   std::string response_data;
22354   ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
22355   EXPECT_EQ("falafel", response_data);
22356 
22357   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
22358 }
22359 
TEST_P(HttpNetworkTransactionTest,PostReadsErrorResponseAfterReset)22360 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
22361   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
22362   element_readers.push_back(
22363       std::make_unique<UploadBytesElementReader>("foo", 3));
22364   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
22365 
22366   HttpRequestInfo request;
22367   request.method = "POST";
22368   request.url = GURL("http://www.foo.com/");
22369   request.upload_data_stream = &upload_data_stream;
22370   request.traffic_annotation =
22371       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22372 
22373   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22374   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22375   // Send headers successfully, but get an error while sending the body.
22376   MockWrite data_writes[] = {
22377       MockWrite("POST / HTTP/1.1\r\n"
22378                 "Host: www.foo.com\r\n"
22379                 "Connection: keep-alive\r\n"
22380                 "Content-Length: 3\r\n\r\n"),
22381       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
22382   };
22383 
22384   MockRead data_reads[] = {
22385       MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
22386       MockRead("hello world"),
22387       MockRead(SYNCHRONOUS, OK),
22388   };
22389   StaticSocketDataProvider data(data_reads, data_writes);
22390   session_deps_.socket_factory->AddSocketDataProvider(&data);
22391 
22392   TestCompletionCallback callback;
22393 
22394   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22395   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22396 
22397   rv = callback.WaitForResult();
22398   EXPECT_THAT(rv, IsOk());
22399 
22400   const HttpResponseInfo* response = trans.GetResponseInfo();
22401   ASSERT_TRUE(response);
22402 
22403   EXPECT_TRUE(response->headers);
22404   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
22405 
22406   std::string response_data;
22407   rv = ReadTransaction(&trans, &response_data);
22408   EXPECT_THAT(rv, IsOk());
22409   EXPECT_EQ("hello world", response_data);
22410 }
22411 
22412 // This test makes sure the retry logic doesn't trigger when reading an error
22413 // response from a server that rejected a POST with a CONNECTION_RESET.
TEST_P(HttpNetworkTransactionTest,PostReadsErrorResponseAfterResetOnReusedSocket)22414 TEST_P(HttpNetworkTransactionTest,
22415        PostReadsErrorResponseAfterResetOnReusedSocket) {
22416   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22417   MockWrite data_writes[] = {
22418       MockWrite("GET / HTTP/1.1\r\n"
22419                 "Host: www.foo.com\r\n"
22420                 "Connection: keep-alive\r\n\r\n"),
22421       MockWrite("POST / HTTP/1.1\r\n"
22422                 "Host: www.foo.com\r\n"
22423                 "Connection: keep-alive\r\n"
22424                 "Content-Length: 3\r\n\r\n"),
22425       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
22426   };
22427 
22428   MockRead data_reads[] = {
22429       MockRead("HTTP/1.1 200 Peachy\r\n"
22430                "Content-Length: 14\r\n\r\n"),
22431       MockRead("first response"),
22432       MockRead("HTTP/1.1 400 Not OK\r\n"
22433                "Content-Length: 15\r\n\r\n"),
22434       MockRead("second response"),
22435       MockRead(SYNCHRONOUS, OK),
22436   };
22437   StaticSocketDataProvider data(data_reads, data_writes);
22438   session_deps_.socket_factory->AddSocketDataProvider(&data);
22439 
22440   TestCompletionCallback callback;
22441   HttpRequestInfo request1;
22442   request1.method = "GET";
22443   request1.url = GURL("http://www.foo.com/");
22444   request1.load_flags = 0;
22445   request1.traffic_annotation =
22446       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22447 
22448   auto trans1 =
22449       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22450   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
22451   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22452 
22453   rv = callback.WaitForResult();
22454   EXPECT_THAT(rv, IsOk());
22455 
22456   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
22457   ASSERT_TRUE(response1);
22458 
22459   EXPECT_TRUE(response1->headers);
22460   EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
22461 
22462   std::string response_data1;
22463   rv = ReadTransaction(trans1.get(), &response_data1);
22464   EXPECT_THAT(rv, IsOk());
22465   EXPECT_EQ("first response", response_data1);
22466   // Delete the transaction to release the socket back into the socket pool.
22467   trans1.reset();
22468 
22469   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
22470   element_readers.push_back(
22471       std::make_unique<UploadBytesElementReader>("foo", 3));
22472   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
22473 
22474   HttpRequestInfo request2;
22475   request2.method = "POST";
22476   request2.url = GURL("http://www.foo.com/");
22477   request2.upload_data_stream = &upload_data_stream;
22478   request2.load_flags = 0;
22479   request2.traffic_annotation =
22480       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22481 
22482   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
22483   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
22484   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22485 
22486   rv = callback.WaitForResult();
22487   EXPECT_THAT(rv, IsOk());
22488 
22489   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
22490   ASSERT_TRUE(response2);
22491 
22492   EXPECT_TRUE(response2->headers);
22493   EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
22494 
22495   std::string response_data2;
22496   rv = ReadTransaction(&trans2, &response_data2);
22497   EXPECT_THAT(rv, IsOk());
22498   EXPECT_EQ("second response", response_data2);
22499 }
22500 
TEST_P(HttpNetworkTransactionTest,PostReadsErrorResponseAfterResetPartialBodySent)22501 TEST_P(HttpNetworkTransactionTest,
22502        PostReadsErrorResponseAfterResetPartialBodySent) {
22503   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
22504   element_readers.push_back(
22505       std::make_unique<UploadBytesElementReader>("foo", 3));
22506   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
22507 
22508   HttpRequestInfo request;
22509   request.method = "POST";
22510   request.url = GURL("http://www.foo.com/");
22511   request.upload_data_stream = &upload_data_stream;
22512   request.traffic_annotation =
22513       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22514 
22515   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22516   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22517   // Send headers successfully, but get an error while sending the body.
22518   MockWrite data_writes[] = {
22519       MockWrite("POST / HTTP/1.1\r\n"
22520                 "Host: www.foo.com\r\n"
22521                 "Connection: keep-alive\r\n"
22522                 "Content-Length: 3\r\n\r\n"
22523                 "fo"),
22524       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
22525   };
22526 
22527   MockRead data_reads[] = {
22528       MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
22529       MockRead("hello world"),
22530       MockRead(SYNCHRONOUS, OK),
22531   };
22532   StaticSocketDataProvider data(data_reads, data_writes);
22533   session_deps_.socket_factory->AddSocketDataProvider(&data);
22534 
22535   TestCompletionCallback callback;
22536 
22537   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22538   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22539 
22540   rv = callback.WaitForResult();
22541   EXPECT_THAT(rv, IsOk());
22542 
22543   const HttpResponseInfo* response = trans.GetResponseInfo();
22544   ASSERT_TRUE(response);
22545 
22546   EXPECT_TRUE(response->headers);
22547   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
22548 
22549   std::string response_data;
22550   rv = ReadTransaction(&trans, &response_data);
22551   EXPECT_THAT(rv, IsOk());
22552   EXPECT_EQ("hello world", response_data);
22553 }
22554 
22555 // This tests the more common case than the previous test, where headers and
22556 // body are not merged into a single request.
TEST_P(HttpNetworkTransactionTest,ChunkedPostReadsErrorResponseAfterReset)22557 TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
22558   ChunkedUploadDataStream upload_data_stream(0);
22559 
22560   HttpRequestInfo request;
22561   request.method = "POST";
22562   request.url = GURL("http://www.foo.com/");
22563   request.upload_data_stream = &upload_data_stream;
22564   request.traffic_annotation =
22565       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22566 
22567   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22568   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22569   // Send headers successfully, but get an error while sending the body.
22570   MockWrite data_writes[] = {
22571       MockWrite("POST / HTTP/1.1\r\n"
22572                 "Host: www.foo.com\r\n"
22573                 "Connection: keep-alive\r\n"
22574                 "Transfer-Encoding: chunked\r\n\r\n"),
22575       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
22576   };
22577 
22578   MockRead data_reads[] = {
22579       MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
22580       MockRead("hello world"),
22581       MockRead(SYNCHRONOUS, OK),
22582   };
22583   StaticSocketDataProvider data(data_reads, data_writes);
22584   session_deps_.socket_factory->AddSocketDataProvider(&data);
22585 
22586   TestCompletionCallback callback;
22587 
22588   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22589   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22590   // Make sure the headers are sent before adding a chunk.  This ensures that
22591   // they can't be merged with the body in a single send.  Not currently
22592   // necessary since a chunked body is never merged with headers, but this makes
22593   // the test more future proof.
22594   base::RunLoop().RunUntilIdle();
22595 
22596   upload_data_stream.AppendData("last chunk", 10, true);
22597 
22598   rv = callback.WaitForResult();
22599   EXPECT_THAT(rv, IsOk());
22600 
22601   const HttpResponseInfo* response = trans.GetResponseInfo();
22602   ASSERT_TRUE(response);
22603 
22604   EXPECT_TRUE(response->headers);
22605   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
22606 
22607   std::string response_data;
22608   rv = ReadTransaction(&trans, &response_data);
22609   EXPECT_THAT(rv, IsOk());
22610   EXPECT_EQ("hello world", response_data);
22611 }
22612 
TEST_P(HttpNetworkTransactionTest,PostReadsErrorResponseAfterResetAnd100)22613 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
22614   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
22615   element_readers.push_back(
22616       std::make_unique<UploadBytesElementReader>("foo", 3));
22617   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
22618 
22619   HttpRequestInfo request;
22620   request.method = "POST";
22621   request.url = GURL("http://www.foo.com/");
22622   request.upload_data_stream = &upload_data_stream;
22623   request.traffic_annotation =
22624       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22625 
22626   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22627   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22628 
22629   MockWrite data_writes[] = {
22630       MockWrite("POST / HTTP/1.1\r\n"
22631                 "Host: www.foo.com\r\n"
22632                 "Connection: keep-alive\r\n"
22633                 "Content-Length: 3\r\n\r\n"),
22634       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
22635   };
22636 
22637   MockRead data_reads[] = {
22638       MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
22639       MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
22640       MockRead("hello world"),
22641       MockRead(SYNCHRONOUS, OK),
22642   };
22643   StaticSocketDataProvider data(data_reads, data_writes);
22644   session_deps_.socket_factory->AddSocketDataProvider(&data);
22645 
22646   TestCompletionCallback callback;
22647 
22648   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22649   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22650 
22651   rv = callback.WaitForResult();
22652   EXPECT_THAT(rv, IsOk());
22653 
22654   const HttpResponseInfo* response = trans.GetResponseInfo();
22655   ASSERT_TRUE(response);
22656 
22657   EXPECT_TRUE(response->headers);
22658   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
22659 
22660   std::string response_data;
22661   rv = ReadTransaction(&trans, &response_data);
22662   EXPECT_THAT(rv, IsOk());
22663   EXPECT_EQ("hello world", response_data);
22664 }
22665 
TEST_P(HttpNetworkTransactionTest,PostIgnoresNonErrorResponseAfterReset)22666 TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
22667   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
22668   element_readers.push_back(
22669       std::make_unique<UploadBytesElementReader>("foo", 3));
22670   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
22671 
22672   HttpRequestInfo request;
22673   request.method = "POST";
22674   request.url = GURL("http://www.foo.com/");
22675   request.upload_data_stream = &upload_data_stream;
22676   request.traffic_annotation =
22677       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22678 
22679   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22680   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22681   // Send headers successfully, but get an error while sending the body.
22682   MockWrite data_writes[] = {
22683       MockWrite("POST / HTTP/1.1\r\n"
22684                 "Host: www.foo.com\r\n"
22685                 "Connection: keep-alive\r\n"
22686                 "Content-Length: 3\r\n\r\n"),
22687       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
22688   };
22689 
22690   MockRead data_reads[] = {
22691       MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
22692       MockRead("hello world"),
22693       MockRead(SYNCHRONOUS, OK),
22694   };
22695   StaticSocketDataProvider data(data_reads, data_writes);
22696   session_deps_.socket_factory->AddSocketDataProvider(&data);
22697 
22698   TestCompletionCallback callback;
22699 
22700   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22701   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22702 
22703   rv = callback.WaitForResult();
22704   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
22705 }
22706 
TEST_P(HttpNetworkTransactionTest,PostIgnoresNonErrorResponseAfterResetAnd100)22707 TEST_P(HttpNetworkTransactionTest,
22708        PostIgnoresNonErrorResponseAfterResetAnd100) {
22709   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
22710   element_readers.push_back(
22711       std::make_unique<UploadBytesElementReader>("foo", 3));
22712   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
22713 
22714   HttpRequestInfo request;
22715   request.method = "POST";
22716   request.url = GURL("http://www.foo.com/");
22717   request.upload_data_stream = &upload_data_stream;
22718   request.traffic_annotation =
22719       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22720 
22721   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22722   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22723   // Send headers successfully, but get an error while sending the body.
22724   MockWrite data_writes[] = {
22725       MockWrite("POST / HTTP/1.1\r\n"
22726                 "Host: www.foo.com\r\n"
22727                 "Connection: keep-alive\r\n"
22728                 "Content-Length: 3\r\n\r\n"),
22729       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
22730   };
22731 
22732   MockRead data_reads[] = {
22733       MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
22734       MockRead("HTTP/1.0 302 Redirect\r\n"),
22735       MockRead("Location: http://somewhere-else.com/\r\n"),
22736       MockRead("Content-Length: 0\r\n\r\n"),
22737       MockRead(SYNCHRONOUS, OK),
22738   };
22739   StaticSocketDataProvider data(data_reads, data_writes);
22740   session_deps_.socket_factory->AddSocketDataProvider(&data);
22741 
22742   TestCompletionCallback callback;
22743 
22744   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22745   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22746 
22747   rv = callback.WaitForResult();
22748   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
22749 }
22750 
TEST_P(HttpNetworkTransactionTest,PostIgnoresHttp09ResponseAfterReset)22751 TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
22752   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
22753   element_readers.push_back(
22754       std::make_unique<UploadBytesElementReader>("foo", 3));
22755   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
22756 
22757   HttpRequestInfo request;
22758   request.method = "POST";
22759   request.url = GURL("http://www.foo.com/");
22760   request.upload_data_stream = &upload_data_stream;
22761   request.traffic_annotation =
22762       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22763 
22764   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22765   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22766   // Send headers successfully, but get an error while sending the body.
22767   MockWrite data_writes[] = {
22768       MockWrite("POST / HTTP/1.1\r\n"
22769                 "Host: www.foo.com\r\n"
22770                 "Connection: keep-alive\r\n"
22771                 "Content-Length: 3\r\n\r\n"),
22772       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
22773   };
22774 
22775   MockRead data_reads[] = {
22776       MockRead("HTTP 0.9 rocks!"),
22777       MockRead(SYNCHRONOUS, OK),
22778   };
22779   StaticSocketDataProvider data(data_reads, data_writes);
22780   session_deps_.socket_factory->AddSocketDataProvider(&data);
22781 
22782   TestCompletionCallback callback;
22783 
22784   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22785   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22786 
22787   rv = callback.WaitForResult();
22788   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
22789 }
22790 
TEST_P(HttpNetworkTransactionTest,PostIgnoresPartial400HeadersAfterReset)22791 TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
22792   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
22793   element_readers.push_back(
22794       std::make_unique<UploadBytesElementReader>("foo", 3));
22795   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
22796 
22797   HttpRequestInfo request;
22798   request.method = "POST";
22799   request.url = GURL("http://www.foo.com/");
22800   request.upload_data_stream = &upload_data_stream;
22801   request.traffic_annotation =
22802       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22803 
22804   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22805   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22806   // Send headers successfully, but get an error while sending the body.
22807   MockWrite data_writes[] = {
22808       MockWrite("POST / HTTP/1.1\r\n"
22809                 "Host: www.foo.com\r\n"
22810                 "Connection: keep-alive\r\n"
22811                 "Content-Length: 3\r\n\r\n"),
22812       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
22813   };
22814 
22815   MockRead data_reads[] = {
22816       MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
22817       MockRead(SYNCHRONOUS, OK),
22818   };
22819   StaticSocketDataProvider data(data_reads, data_writes);
22820   session_deps_.socket_factory->AddSocketDataProvider(&data);
22821 
22822   TestCompletionCallback callback;
22823 
22824   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22825   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22826 
22827   rv = callback.WaitForResult();
22828   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
22829 }
22830 
22831 #if BUILDFLAG(ENABLE_WEBSOCKETS)
22832 
22833 namespace {
22834 
AddWebSocketHeaders(HttpRequestHeaders * headers)22835 void AddWebSocketHeaders(HttpRequestHeaders* headers) {
22836   headers->SetHeader("Connection", "Upgrade");
22837   headers->SetHeader("Upgrade", "websocket");
22838   headers->SetHeader("Origin", "http://www.example.org");
22839   headers->SetHeader("Sec-WebSocket-Version", "13");
22840 }
22841 
22842 }  // namespace
22843 
TEST_P(HttpNetworkTransactionTest,CreateWebSocketHandshakeStream)22844 TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
22845   for (bool secure : {true, false}) {
22846     MockWrite data_writes[] = {
22847         MockWrite("GET / HTTP/1.1\r\n"
22848                   "Host: www.example.org\r\n"
22849                   "Connection: Upgrade\r\n"
22850                   "Upgrade: websocket\r\n"
22851                   "Origin: http://www.example.org\r\n"
22852                   "Sec-WebSocket-Version: 13\r\n"
22853                   "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
22854                   "Sec-WebSocket-Extensions: permessage-deflate; "
22855                   "client_max_window_bits\r\n\r\n")};
22856 
22857     MockRead data_reads[] = {
22858         MockRead("HTTP/1.1 101 Switching Protocols\r\n"
22859                  "Upgrade: websocket\r\n"
22860                  "Connection: Upgrade\r\n"
22861                  "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
22862 
22863     StaticSocketDataProvider data(data_reads, data_writes);
22864     session_deps_.socket_factory->AddSocketDataProvider(&data);
22865     SSLSocketDataProvider ssl(ASYNC, OK);
22866     if (secure) {
22867       session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
22868     }
22869 
22870     HttpRequestInfo request;
22871     request.method = "GET";
22872     request.url =
22873         GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
22874     AddWebSocketHeaders(&request.extra_headers);
22875     request.traffic_annotation =
22876         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22877 
22878     TestWebSocketHandshakeStreamCreateHelper
22879         websocket_handshake_stream_create_helper;
22880 
22881     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22882     HttpNetworkTransaction trans(LOW, session.get());
22883     trans.SetWebSocketHandshakeStreamCreateHelper(
22884         &websocket_handshake_stream_create_helper);
22885 
22886     TestCompletionCallback callback;
22887     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22888     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22889 
22890     const HttpStreamRequest* stream_request = trans.stream_request_.get();
22891     ASSERT_TRUE(stream_request);
22892     EXPECT_EQ(&websocket_handshake_stream_create_helper,
22893               stream_request->websocket_handshake_stream_create_helper());
22894 
22895     rv = callback.WaitForResult();
22896     EXPECT_THAT(rv, IsOk());
22897 
22898     EXPECT_TRUE(data.AllReadDataConsumed());
22899     EXPECT_TRUE(data.AllWriteDataConsumed());
22900   }
22901 }
22902 
22903 // Verify that proxy headers are not sent to the destination server when
22904 // establishing a tunnel for a secure WebSocket connection.
TEST_P(HttpNetworkTransactionTest,ProxyHeadersNotSentOverWssTunnel)22905 TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
22906   HttpRequestInfo request;
22907   request.method = "GET";
22908   request.url = GURL("wss://www.example.org/");
22909   request.traffic_annotation =
22910       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22911   AddWebSocketHeaders(&request.extra_headers);
22912 
22913   // Configure against proxy server "myproxy:70".
22914   session_deps_.proxy_resolution_service =
22915       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
22916           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
22917 
22918   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22919 
22920   // Since a proxy is configured, try to establish a tunnel.
22921   MockWrite data_writes[] = {
22922       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
22923                 "Host: www.example.org:443\r\n"
22924                 "Proxy-Connection: keep-alive\r\n\r\n"),
22925 
22926       // After calling trans->RestartWithAuth(), this is the request we should
22927       // be issuing -- the final header line contains the credentials.
22928       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
22929                 "Host: www.example.org:443\r\n"
22930                 "Proxy-Connection: keep-alive\r\n"
22931                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
22932 
22933       MockWrite("GET / HTTP/1.1\r\n"
22934                 "Host: www.example.org\r\n"
22935                 "Connection: Upgrade\r\n"
22936                 "Upgrade: websocket\r\n"
22937                 "Origin: http://www.example.org\r\n"
22938                 "Sec-WebSocket-Version: 13\r\n"
22939                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
22940                 "Sec-WebSocket-Extensions: permessage-deflate; "
22941                 "client_max_window_bits\r\n\r\n")};
22942 
22943   // The proxy responds to the connect with a 407, using a persistent
22944   // connection.
22945   MockRead data_reads[] = {
22946       // No credentials.
22947       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
22948                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
22949                "Content-Length: 0\r\n"
22950                "Proxy-Connection: keep-alive\r\n\r\n"),
22951 
22952       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
22953 
22954       MockRead("HTTP/1.1 101 Switching Protocols\r\n"
22955                "Upgrade: websocket\r\n"
22956                "Connection: Upgrade\r\n"
22957                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
22958 
22959   StaticSocketDataProvider data(data_reads, data_writes);
22960   session_deps_.socket_factory->AddSocketDataProvider(&data);
22961   SSLSocketDataProvider ssl(ASYNC, OK);
22962   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
22963 
22964   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
22965 
22966   auto trans =
22967       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22968   trans->SetWebSocketHandshakeStreamCreateHelper(
22969       &websocket_stream_create_helper);
22970 
22971   {
22972     TestCompletionCallback callback;
22973 
22974     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
22975     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22976 
22977     rv = callback.WaitForResult();
22978     EXPECT_THAT(rv, IsOk());
22979   }
22980 
22981   const HttpResponseInfo* response = trans->GetResponseInfo();
22982   ASSERT_TRUE(response);
22983   ASSERT_TRUE(response->headers);
22984   EXPECT_EQ(407, response->headers->response_code());
22985 
22986   {
22987     TestCompletionCallback callback;
22988 
22989     int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
22990                                     callback.callback());
22991     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22992 
22993     rv = callback.WaitForResult();
22994     EXPECT_THAT(rv, IsOk());
22995   }
22996 
22997   response = trans->GetResponseInfo();
22998   ASSERT_TRUE(response);
22999   ASSERT_TRUE(response->headers);
23000 
23001   EXPECT_EQ(101, response->headers->response_code());
23002 
23003   trans.reset();
23004   session->CloseAllConnections(ERR_FAILED, "Very good reason");
23005 }
23006 
23007 // Verify that proxy headers are not sent to the destination server when
23008 // establishing a tunnel for an insecure WebSocket connection.
23009 // This requires the authentication info to be injected into the auth cache
23010 // due to crbug.com/395064
23011 // TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
TEST_P(HttpNetworkTransactionTest,ProxyHeadersNotSentOverWsTunnel)23012 TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
23013   HttpRequestInfo request;
23014   request.method = "GET";
23015   request.url = GURL("ws://www.example.org/");
23016   request.traffic_annotation =
23017       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
23018   AddWebSocketHeaders(&request.extra_headers);
23019 
23020   // Configure against proxy server "myproxy:70".
23021   session_deps_.proxy_resolution_service =
23022       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
23023           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
23024 
23025   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23026 
23027   MockWrite data_writes[] = {
23028       // Try to establish a tunnel for the WebSocket connection, with
23029       // credentials. Because WebSockets have a separate set of socket pools,
23030       // they cannot and will not use the same TCP/IP connection as the
23031       // preflight HTTP request.
23032       MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
23033                 "Host: www.example.org:80\r\n"
23034                 "Proxy-Connection: keep-alive\r\n"
23035                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
23036 
23037       MockWrite("GET / HTTP/1.1\r\n"
23038                 "Host: www.example.org\r\n"
23039                 "Connection: Upgrade\r\n"
23040                 "Upgrade: websocket\r\n"
23041                 "Origin: http://www.example.org\r\n"
23042                 "Sec-WebSocket-Version: 13\r\n"
23043                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
23044                 "Sec-WebSocket-Extensions: permessage-deflate; "
23045                 "client_max_window_bits\r\n\r\n")};
23046 
23047   MockRead data_reads[] = {
23048       // HTTP CONNECT with credentials.
23049       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
23050 
23051       // WebSocket connection established inside tunnel.
23052       MockRead("HTTP/1.1 101 Switching Protocols\r\n"
23053                "Upgrade: websocket\r\n"
23054                "Connection: Upgrade\r\n"
23055                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
23056 
23057   StaticSocketDataProvider data(data_reads, data_writes);
23058   session_deps_.socket_factory->AddSocketDataProvider(&data);
23059 
23060   session->http_auth_cache()->Add(
23061       url::SchemeHostPort(GURL("http://myproxy:70/")), HttpAuth::AUTH_PROXY,
23062       "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
23063       "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
23064 
23065   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
23066 
23067   auto trans =
23068       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
23069   trans->SetWebSocketHandshakeStreamCreateHelper(
23070       &websocket_stream_create_helper);
23071 
23072   TestCompletionCallback callback;
23073 
23074   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
23075   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
23076 
23077   rv = callback.WaitForResult();
23078   EXPECT_THAT(rv, IsOk());
23079 
23080   const HttpResponseInfo* response = trans->GetResponseInfo();
23081   ASSERT_TRUE(response);
23082   ASSERT_TRUE(response->headers);
23083 
23084   EXPECT_EQ(101, response->headers->response_code());
23085 
23086   trans.reset();
23087   session->CloseAllConnections(ERR_FAILED, "Very good reason");
23088 }
23089 
23090 // WebSockets over QUIC is not supported, including over QUIC proxies.
TEST_P(HttpNetworkTransactionTest,WebSocketNotSentOverQuicProxy)23091 TEST_P(HttpNetworkTransactionTest, WebSocketNotSentOverQuicProxy) {
23092   for (bool secure : {true, false}) {
23093     SCOPED_TRACE(secure);
23094     session_deps_.proxy_resolution_service =
23095         ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
23096             {ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC,
23097                                                "myproxy.org", 443)},
23098             TRAFFIC_ANNOTATION_FOR_TESTS);
23099     session_deps_.enable_quic = true;
23100 
23101     HttpRequestInfo request;
23102     request.url =
23103         GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
23104     AddWebSocketHeaders(&request.extra_headers);
23105     request.traffic_annotation =
23106         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
23107 
23108     TestWebSocketHandshakeStreamCreateHelper
23109         websocket_handshake_stream_create_helper;
23110 
23111     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23112     HttpNetworkTransaction trans(LOW, session.get());
23113     trans.SetWebSocketHandshakeStreamCreateHelper(
23114         &websocket_handshake_stream_create_helper);
23115 
23116     TestCompletionCallback callback;
23117     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
23118     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
23119 
23120     rv = callback.WaitForResult();
23121     EXPECT_THAT(rv, IsError(ERR_NO_SUPPORTED_PROXIES));
23122   }
23123 }
23124 
23125 #endif  // BUILDFLAG(ENABLE_WEBSOCKETS)
23126 
TEST_P(HttpNetworkTransactionTest,TotalNetworkBytesPost)23127 TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
23128   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
23129   element_readers.push_back(
23130       std::make_unique<UploadBytesElementReader>("foo", 3));
23131   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
23132 
23133   HttpRequestInfo request;
23134   request.method = "POST";
23135   request.url = GURL("http://www.foo.com/");
23136   request.upload_data_stream = &upload_data_stream;
23137   request.traffic_annotation =
23138       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
23139 
23140   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23141   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
23142   MockWrite data_writes[] = {
23143       MockWrite("POST / HTTP/1.1\r\n"
23144                 "Host: www.foo.com\r\n"
23145                 "Connection: keep-alive\r\n"
23146                 "Content-Length: 3\r\n\r\n"),
23147       MockWrite("foo"),
23148   };
23149 
23150   MockRead data_reads[] = {
23151       MockRead("HTTP/1.1 200 OK\r\n\r\n"),
23152       MockRead("hello world"),
23153       MockRead(SYNCHRONOUS, OK),
23154   };
23155   StaticSocketDataProvider data(data_reads, data_writes);
23156   session_deps_.socket_factory->AddSocketDataProvider(&data);
23157 
23158   TestCompletionCallback callback;
23159 
23160   EXPECT_EQ(ERR_IO_PENDING,
23161             trans.Start(&request, callback.callback(), NetLogWithSource()));
23162   EXPECT_THAT(callback.WaitForResult(), IsOk());
23163 
23164   std::string response_data;
23165   EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
23166 
23167   EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
23168   EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
23169 }
23170 
TEST_P(HttpNetworkTransactionTest,TotalNetworkBytesPost100Continue)23171 TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
23172   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
23173   element_readers.push_back(
23174       std::make_unique<UploadBytesElementReader>("foo", 3));
23175   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
23176 
23177   HttpRequestInfo request;
23178   request.method = "POST";
23179   request.url = GURL("http://www.foo.com/");
23180   request.upload_data_stream = &upload_data_stream;
23181   request.traffic_annotation =
23182       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
23183 
23184   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23185   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
23186   MockWrite data_writes[] = {
23187       MockWrite("POST / HTTP/1.1\r\n"
23188                 "Host: www.foo.com\r\n"
23189                 "Connection: keep-alive\r\n"
23190                 "Content-Length: 3\r\n\r\n"),
23191       MockWrite("foo"),
23192   };
23193 
23194   MockRead data_reads[] = {
23195       MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
23196       MockRead("HTTP/1.1 200 OK\r\n\r\n"),
23197       MockRead("hello world"),
23198       MockRead(SYNCHRONOUS, OK),
23199   };
23200   StaticSocketDataProvider data(data_reads, data_writes);
23201   session_deps_.socket_factory->AddSocketDataProvider(&data);
23202 
23203   TestCompletionCallback callback;
23204 
23205   EXPECT_EQ(ERR_IO_PENDING,
23206             trans.Start(&request, callback.callback(), NetLogWithSource()));
23207   EXPECT_THAT(callback.WaitForResult(), IsOk());
23208 
23209   std::string response_data;
23210   EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
23211 
23212   EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
23213   EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
23214 }
23215 
TEST_P(HttpNetworkTransactionTest,TotalNetworkBytesChunkedPost)23216 TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
23217   ChunkedUploadDataStream upload_data_stream(0);
23218 
23219   HttpRequestInfo request;
23220   request.method = "POST";
23221   request.url = GURL("http://www.foo.com/");
23222   request.upload_data_stream = &upload_data_stream;
23223   request.traffic_annotation =
23224       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
23225 
23226   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23227   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
23228   // Send headers successfully, but get an error while sending the body.
23229   MockWrite data_writes[] = {
23230       MockWrite("POST / HTTP/1.1\r\n"
23231                 "Host: www.foo.com\r\n"
23232                 "Connection: keep-alive\r\n"
23233                 "Transfer-Encoding: chunked\r\n\r\n"),
23234       MockWrite("1\r\nf\r\n"),
23235       MockWrite("2\r\noo\r\n"),
23236       MockWrite("0\r\n\r\n"),
23237   };
23238 
23239   MockRead data_reads[] = {
23240       MockRead("HTTP/1.1 200 OK\r\n\r\n"),
23241       MockRead("hello world"),
23242       MockRead(SYNCHRONOUS, OK),
23243   };
23244   StaticSocketDataProvider data(data_reads, data_writes);
23245   session_deps_.socket_factory->AddSocketDataProvider(&data);
23246 
23247   TestCompletionCallback callback;
23248 
23249   EXPECT_EQ(ERR_IO_PENDING,
23250             trans.Start(&request, callback.callback(), NetLogWithSource()));
23251 
23252   base::RunLoop().RunUntilIdle();
23253   upload_data_stream.AppendData("f", 1, false);
23254 
23255   base::RunLoop().RunUntilIdle();
23256   upload_data_stream.AppendData("oo", 2, true);
23257 
23258   EXPECT_THAT(callback.WaitForResult(), IsOk());
23259 
23260   std::string response_data;
23261   EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
23262 
23263   EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
23264   EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
23265 }
23266 
CheckContentEncodingMatching(SpdySessionDependencies * session_deps,const std::string & accept_encoding,const std::string & content_encoding,const std::string & location,bool should_match)23267 void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
23268                                   const std::string& accept_encoding,
23269                                   const std::string& content_encoding,
23270                                   const std::string& location,
23271                                   bool should_match) {
23272   HttpRequestInfo request;
23273   request.method = "GET";
23274   request.url = GURL("http://www.foo.com/");
23275   request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
23276                                   accept_encoding);
23277   request.traffic_annotation =
23278       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
23279 
23280   std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
23281   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
23282   // Send headers successfully, but get an error while sending the body.
23283   MockWrite data_writes[] = {
23284       MockWrite("GET / HTTP/1.1\r\n"
23285                 "Host: www.foo.com\r\n"
23286                 "Connection: keep-alive\r\n"
23287                 "Accept-Encoding: "),
23288       MockWrite(accept_encoding.data()),
23289       MockWrite("\r\n\r\n"),
23290   };
23291 
23292   std::string response_code = "200 OK";
23293   std::string extra;
23294   if (!location.empty()) {
23295     response_code = "301 Redirect\r\nLocation: ";
23296     response_code.append(location);
23297   }
23298 
23299   MockRead data_reads[] = {
23300       MockRead("HTTP/1.0 "),
23301       MockRead(response_code.data()),
23302       MockRead("\r\nContent-Encoding: "),
23303       MockRead(content_encoding.data()),
23304       MockRead("\r\n\r\n"),
23305       MockRead(SYNCHRONOUS, OK),
23306   };
23307   StaticSocketDataProvider data(data_reads, data_writes);
23308   session_deps->socket_factory->AddSocketDataProvider(&data);
23309 
23310   TestCompletionCallback callback;
23311 
23312   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
23313   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
23314 
23315   rv = callback.WaitForResult();
23316   if (should_match) {
23317     EXPECT_THAT(rv, IsOk());
23318   } else {
23319     EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
23320   }
23321 }
23322 
TEST_P(HttpNetworkTransactionTest,MatchContentEncoding1)23323 TEST_P(HttpNetworkTransactionTest, MatchContentEncoding1) {
23324   CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
23325 }
23326 
TEST_P(HttpNetworkTransactionTest,MatchContentEncoding2)23327 TEST_P(HttpNetworkTransactionTest, MatchContentEncoding2) {
23328   CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
23329                                true);
23330 }
23331 
TEST_P(HttpNetworkTransactionTest,MatchContentEncoding3)23332 TEST_P(HttpNetworkTransactionTest, MatchContentEncoding3) {
23333   CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
23334                                "", false);
23335 }
23336 
TEST_P(HttpNetworkTransactionTest,MatchContentEncoding4)23337 TEST_P(HttpNetworkTransactionTest, MatchContentEncoding4) {
23338   CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
23339                                "www.foo.com/other", true);
23340 }
23341 
TEST_P(HttpNetworkTransactionTest,ProxyResolutionFailsSync)23342 TEST_P(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
23343   ProxyConfig proxy_config;
23344   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
23345   proxy_config.set_pac_mandatory(true);
23346   MockAsyncProxyResolver resolver;
23347   session_deps_.proxy_resolution_service =
23348       std::make_unique<ConfiguredProxyResolutionService>(
23349 
23350           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
23351               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
23352           std::make_unique<FailingProxyResolverFactory>(), nullptr,
23353           /*quick_check_enabled=*/true);
23354 
23355   HttpRequestInfo request;
23356   request.method = "GET";
23357   request.url = GURL("http://www.example.org/");
23358   request.traffic_annotation =
23359       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
23360 
23361   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23362   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
23363 
23364   TestCompletionCallback callback;
23365 
23366   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
23367   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
23368   EXPECT_THAT(callback.WaitForResult(),
23369               IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
23370 }
23371 
TEST_P(HttpNetworkTransactionTest,ProxyResolutionFailsAsync)23372 TEST_P(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
23373   ProxyConfig proxy_config;
23374   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
23375   proxy_config.set_pac_mandatory(true);
23376   auto proxy_resolver_factory =
23377       std::make_unique<MockAsyncProxyResolverFactory>(false);
23378   auto* proxy_resolver_factory_ptr = proxy_resolver_factory.get();
23379   MockAsyncProxyResolver resolver;
23380   session_deps_.proxy_resolution_service =
23381       std::make_unique<ConfiguredProxyResolutionService>(
23382 
23383           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
23384               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
23385           std::move(proxy_resolver_factory), nullptr,
23386           /*quick_check_enabled=*/true);
23387   HttpRequestInfo request;
23388   request.method = "GET";
23389   request.url = GURL("http://www.example.org/");
23390   request.traffic_annotation =
23391       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
23392 
23393   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23394   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
23395 
23396   TestCompletionCallback callback;
23397   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
23398   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
23399 
23400   proxy_resolver_factory_ptr->pending_requests()[0]->CompleteNowWithForwarder(
23401       ERR_FAILED, &resolver);
23402   EXPECT_THAT(callback.WaitForResult(),
23403               IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
23404 }
23405 
TEST_P(HttpNetworkTransactionTest,NoSupportedProxies)23406 TEST_P(HttpNetworkTransactionTest, NoSupportedProxies) {
23407   session_deps_.proxy_resolution_service =
23408       ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
23409           {ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC,
23410                                              "myproxy.org", 443)},
23411           TRAFFIC_ANNOTATION_FOR_TESTS);
23412   session_deps_.enable_quic = false;
23413   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23414 
23415   HttpRequestInfo request;
23416   request.method = "GET";
23417   request.url = GURL("http://www.example.org/");
23418   request.traffic_annotation =
23419       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
23420 
23421   TestCompletionCallback callback;
23422   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
23423   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
23424   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
23425 
23426   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
23427 }
23428 
23429 //-----------------------------------------------------------------------------
23430 // Reporting tests
23431 
23432 #if BUILDFLAG(ENABLE_REPORTING)
23433 class HttpNetworkTransactionReportingTest
23434     : public HttpNetworkTransactionTestBase,
23435       public ::testing::WithParamInterface<bool> {
23436  protected:
HttpNetworkTransactionReportingTest()23437   HttpNetworkTransactionReportingTest() {
23438     std::vector<base::test::FeatureRef> required_features = {
23439         features::kPartitionNelAndReportingByNetworkIsolationKey};
23440     if (UseDocumentReporting()) {
23441       required_features.push_back(features::kDocumentReporting);
23442     }
23443     feature_list_.InitWithFeatures(required_features, {});
23444   }
23445 
SetUp()23446   void SetUp() override {
23447     HttpNetworkTransactionTestBase::SetUp();
23448     auto test_reporting_context = std::make_unique<TestReportingContext>(
23449         &clock_, &tick_clock_, ReportingPolicy());
23450     test_reporting_context_ = test_reporting_context.get();
23451     session_deps_.reporting_service =
23452         ReportingService::CreateForTesting(std::move(test_reporting_context));
23453   }
23454 
reporting_context() const23455   TestReportingContext* reporting_context() const {
23456     return test_reporting_context_;
23457   }
23458 
TearDown()23459   void TearDown() override {
23460     clear_reporting_service();
23461     HttpNetworkTransactionTestBase::TearDown();
23462   }
clear_reporting_service()23463   void clear_reporting_service() {
23464     test_reporting_context_ = nullptr;
23465     session_deps_.reporting_service.reset();
23466   }
23467 
23468   // Makes an HTTPS request that should install a valid Reporting policy
23469   // using Report-To header.
RequestPolicy(CertStatus cert_status=0)23470   void RequestPolicy(CertStatus cert_status = 0) {
23471     HttpRequestInfo request;
23472     request.method = "GET";
23473     request.url = GURL(url_);
23474     request.traffic_annotation =
23475         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
23476     request.network_isolation_key = kNetworkIsolationKey;
23477     request.network_anonymization_key = kNetworkAnonymizationKey;
23478     MockWrite data_writes[] = {
23479         MockWrite("GET / HTTP/1.1\r\n"
23480                   "Host: www.example.org\r\n"
23481                   "Connection: keep-alive\r\n\r\n"),
23482     };
23483 
23484     MockRead reporting_header;
23485     reporting_header = MockRead(
23486         "Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
23487         "\"endpoints\": [{\"url\": "
23488         "\"https://www.example.org/upload/\"}]}\r\n");
23489     MockRead data_reads[] = {
23490         MockRead("HTTP/1.0 200 OK\r\n"),
23491         std::move(reporting_header),
23492         MockRead("\r\n"),
23493         MockRead("hello world"),
23494         MockRead(SYNCHRONOUS, OK),
23495     };
23496 
23497     StaticSocketDataProvider reads(data_reads, data_writes);
23498     session_deps_.socket_factory->AddSocketDataProvider(&reads);
23499 
23500     SSLSocketDataProvider ssl(ASYNC, OK);
23501     if (request.url.SchemeIsCryptographic()) {
23502       ssl.ssl_info.cert =
23503           ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
23504       ASSERT_TRUE(ssl.ssl_info.cert);
23505       ssl.ssl_info.cert_status = cert_status;
23506       session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
23507     }
23508 
23509     TestCompletionCallback callback;
23510     auto session = CreateSession(&session_deps_);
23511     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
23512     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
23513     EXPECT_THAT(callback.GetResult(rv), IsOk());
23514   }
23515 
23516  protected:
UseDocumentReporting() const23517   bool UseDocumentReporting() const { return GetParam(); }
23518   std::string url_ = "https://www.example.org/";
23519 
23520  private:
23521   base::test::ScopedFeatureList feature_list_;
23522   raw_ptr<TestReportingContext> test_reporting_context_ = nullptr;
23523 };
23524 
TEST_P(HttpNetworkTransactionReportingTest,DontProcessReportToHeaderNoService)23525 TEST_P(HttpNetworkTransactionReportingTest,
23526        DontProcessReportToHeaderNoService) {
23527   clear_reporting_service();
23528   RequestPolicy();
23529   // No crash.
23530 }
23531 
TEST_P(HttpNetworkTransactionReportingTest,DontProcessReportToHeaderHttp)23532 TEST_P(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
23533   url_ = "http://www.example.org/";
23534   RequestPolicy();
23535   EXPECT_EQ(0u, reporting_context()->cache()->GetEndpointCount());
23536 }
23537 
TEST_P(HttpNetworkTransactionReportingTest,ProcessReportToHeaderHttps)23538 TEST_P(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
23539   RequestPolicy();
23540   ASSERT_EQ(1u, reporting_context()->cache()->GetEndpointCount());
23541   const ReportingEndpoint endpoint =
23542       reporting_context()->cache()->GetEndpointForTesting(
23543           ReportingEndpointGroupKey(
23544               kNetworkAnonymizationKey,
23545               url::Origin::Create(GURL("https://www.example.org/")), "nel"),
23546           GURL("https://www.example.org/upload/"));
23547   EXPECT_TRUE(endpoint);
23548 }
23549 
TEST_P(HttpNetworkTransactionReportingTest,DontProcessReportToHeaderInvalidHttps)23550 TEST_P(HttpNetworkTransactionReportingTest,
23551        DontProcessReportToHeaderInvalidHttps) {
23552   CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
23553   RequestPolicy(cert_status);
23554   EXPECT_EQ(0u, reporting_context()->cache()->GetEndpointCount());
23555 }
23556 
23557 INSTANTIATE_TEST_SUITE_P(All,
23558                          HttpNetworkTransactionReportingTest,
23559                          ::testing::Bool());
23560 
23561 #endif  // BUILDFLAG(ENABLE_REPORTING)
23562 
23563 //-----------------------------------------------------------------------------
23564 // Network Error Logging tests
23565 
23566 #if BUILDFLAG(ENABLE_REPORTING)
23567 namespace {
23568 
23569 const char kUserAgent[] = "Mozilla/1.0";
23570 const char kReferrer[] = "https://www.referrer.org/";
23571 
23572 }  // namespace
23573 
23574 class HttpNetworkTransactionNetworkErrorLoggingTest
23575     : public HttpNetworkTransactionTest {
23576  protected:
SetUp()23577   void SetUp() override {
23578     HttpNetworkTransactionTestBase::SetUp();
23579     auto network_error_logging_service =
23580         std::make_unique<TestNetworkErrorLoggingService>();
23581     test_network_error_logging_service_ = network_error_logging_service.get();
23582     session_deps_.network_error_logging_service =
23583         std::move(network_error_logging_service);
23584 
23585     extra_headers_.SetHeader("User-Agent", kUserAgent);
23586     extra_headers_.SetHeader("Referer", kReferrer);
23587 
23588     request_.method = "GET";
23589     request_.url = GURL(url_);
23590     request_.network_isolation_key = kNetworkIsolationKey;
23591     request_.network_anonymization_key = kNetworkAnonymizationKey;
23592     request_.extra_headers = extra_headers_;
23593     request_.reporting_upload_depth = reporting_upload_depth_;
23594     request_.traffic_annotation =
23595         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
23596   }
23597 
TearDown()23598   void TearDown() override {
23599     clear_network_error_logging_service();
23600     HttpNetworkTransactionTestBase::TearDown();
23601   }
23602 
network_error_logging_service() const23603   TestNetworkErrorLoggingService* network_error_logging_service() const {
23604     return test_network_error_logging_service_;
23605   }
23606 
clear_network_error_logging_service()23607   void clear_network_error_logging_service() {
23608     test_network_error_logging_service_ = nullptr;
23609     session_deps_.network_error_logging_service.reset();
23610   }
23611 
23612   // Makes an HTTPS request that should install a valid NEL policy.
RequestPolicy(CertStatus cert_status=0)23613   void RequestPolicy(CertStatus cert_status = 0) {
23614     std::string extra_header_string = extra_headers_.ToString();
23615     MockWrite data_writes[] = {
23616         MockWrite("GET / HTTP/1.1\r\n"
23617                   "Host: www.example.org\r\n"
23618                   "Connection: keep-alive\r\n"),
23619         MockWrite(ASYNC, extra_header_string.data(),
23620                   extra_header_string.size()),
23621     };
23622     MockRead data_reads[] = {
23623         MockRead("HTTP/1.0 200 OK\r\n"),
23624         MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
23625         MockRead("\r\n"),
23626         MockRead("hello world"),
23627         MockRead(SYNCHRONOUS, OK),
23628     };
23629 
23630     StaticSocketDataProvider reads(data_reads, data_writes);
23631     session_deps_.socket_factory->AddSocketDataProvider(&reads);
23632 
23633     SSLSocketDataProvider ssl(ASYNC, OK);
23634     if (request_.url.SchemeIsCryptographic()) {
23635       ssl.ssl_info.cert =
23636           ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
23637       ASSERT_TRUE(ssl.ssl_info.cert);
23638       ssl.ssl_info.cert_status = cert_status;
23639       session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
23640     }
23641 
23642     TestCompletionCallback callback;
23643     auto session = CreateSession(&session_deps_);
23644     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
23645     int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
23646     EXPECT_THAT(callback.GetResult(rv), IsOk());
23647 
23648     std::string response_data;
23649     ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
23650     EXPECT_EQ("hello world", response_data);
23651   }
23652 
CheckReport(size_t index,int status_code,int error_type,IPAddress server_ip=IPAddress::IPv4Localhost ())23653   void CheckReport(size_t index,
23654                    int status_code,
23655                    int error_type,
23656                    IPAddress server_ip = IPAddress::IPv4Localhost()) {
23657     ASSERT_LT(index, network_error_logging_service()->errors().size());
23658 
23659     const NetworkErrorLoggingService::RequestDetails& error =
23660         network_error_logging_service()->errors()[index];
23661     EXPECT_EQ(url_, error.uri);
23662     EXPECT_EQ(kNetworkAnonymizationKey, error.network_anonymization_key);
23663     EXPECT_EQ(kReferrer, error.referrer);
23664     EXPECT_EQ(kUserAgent, error.user_agent);
23665     EXPECT_EQ(server_ip, error.server_ip);
23666     EXPECT_EQ("http/1.1", error.protocol);
23667     EXPECT_EQ("GET", error.method);
23668     EXPECT_EQ(status_code, error.status_code);
23669     EXPECT_EQ(error_type, error.type);
23670     EXPECT_EQ(0, error.reporting_upload_depth);
23671   }
23672 
23673  protected:
23674   std::string url_ = "https://www.example.org/";
23675   CertStatus cert_status_ = 0;
23676   HttpRequestInfo request_;
23677   HttpRequestHeaders extra_headers_;
23678   int reporting_upload_depth_ = 0;
23679 
23680  private:
23681   raw_ptr<TestNetworkErrorLoggingService> test_network_error_logging_service_ =
23682       nullptr;
23683 };
23684 
23685 INSTANTIATE_TEST_SUITE_P(All,
23686                          HttpNetworkTransactionNetworkErrorLoggingTest,
23687                          testing::Values(true, false));
23688 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,DontProcessNelHeaderNoService)23689 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
23690        DontProcessNelHeaderNoService) {
23691   clear_network_error_logging_service();
23692   RequestPolicy();
23693   // No crash.
23694 }
23695 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,DontProcessNelHeaderHttp)23696 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
23697        DontProcessNelHeaderHttp) {
23698   url_ = "http://www.example.org/";
23699   request_.url = GURL(url_);
23700   RequestPolicy();
23701   EXPECT_EQ(0u, network_error_logging_service()->headers().size());
23702 }
23703 
23704 // Don't set NEL policies received on a proxied connection.
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,DontProcessNelHeaderProxy)23705 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
23706        DontProcessNelHeaderProxy) {
23707   session_deps_.proxy_resolution_service =
23708       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
23709           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
23710   session_deps_.net_log = NetLog::Get();
23711   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23712 
23713   HttpRequestInfo request;
23714   request.method = "GET";
23715   request.url = GURL("https://www.example.org/");
23716   request.traffic_annotation =
23717       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
23718 
23719   // Since we have proxy, should try to establish tunnel.
23720   MockWrite data_writes1[] = {
23721       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
23722                 "Host: www.example.org:443\r\n"
23723                 "Proxy-Connection: keep-alive\r\n\r\n"),
23724 
23725       MockWrite("GET / HTTP/1.1\r\n"
23726                 "Host: www.example.org\r\n"
23727                 "Connection: keep-alive\r\n\r\n"),
23728   };
23729 
23730   MockRead data_reads1[] = {
23731       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
23732 
23733       MockRead("HTTP/1.1 200 OK\r\n"),
23734       MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
23735       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
23736       MockRead("Content-Length: 100\r\n\r\n"),
23737       MockRead(SYNCHRONOUS, OK),
23738   };
23739 
23740   StaticSocketDataProvider data1(data_reads1, data_writes1);
23741   session_deps_.socket_factory->AddSocketDataProvider(&data1);
23742   SSLSocketDataProvider ssl(ASYNC, OK);
23743   ssl.ssl_info.cert =
23744       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
23745   ASSERT_TRUE(ssl.ssl_info.cert);
23746   ssl.ssl_info.cert_status = 0;
23747   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
23748 
23749   TestCompletionCallback callback1;
23750   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
23751 
23752   int rv = trans.Start(&request, callback1.callback(),
23753                        NetLogWithSource::Make(NetLogSourceType::NONE));
23754   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
23755 
23756   rv = callback1.WaitForResult();
23757   EXPECT_THAT(rv, IsOk());
23758 
23759   const HttpResponseInfo* response = trans.GetResponseInfo();
23760   ASSERT_TRUE(response);
23761   EXPECT_EQ(200, response->headers->response_code());
23762   EXPECT_TRUE(response->was_fetched_via_proxy);
23763 
23764   // No NEL header was set.
23765   EXPECT_EQ(0u, network_error_logging_service()->headers().size());
23766 }
23767 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,ProcessNelHeaderHttps)23768 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
23769   RequestPolicy();
23770   ASSERT_EQ(1u, network_error_logging_service()->headers().size());
23771   const auto& header = network_error_logging_service()->headers()[0];
23772   EXPECT_EQ(kNetworkAnonymizationKey, header.network_anonymization_key);
23773   EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
23774             header.origin);
23775   EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
23776   EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
23777 }
23778 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,DontProcessNelHeaderInvalidHttps)23779 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
23780        DontProcessNelHeaderInvalidHttps) {
23781   CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
23782   RequestPolicy(cert_status);
23783   EXPECT_EQ(0u, network_error_logging_service()->headers().size());
23784 }
23785 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportSuccess)23786 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
23787   RequestPolicy();
23788   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
23789   CheckReport(0 /* index */, 200 /* status_code */, OK);
23790 }
23791 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportDNSErrorAfterStartSync)23792 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
23793        CreateReportDNSErrorAfterStartSync) {
23794   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23795   auto trans =
23796       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
23797 
23798   session_deps_.host_resolver->set_synchronous_mode(true);
23799   session_deps_.host_resolver->rules()->AddRule(GURL(url_).host(),
23800                                                 ERR_NAME_NOT_RESOLVED);
23801   TestCompletionCallback callback;
23802 
23803   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
23804   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
23805 
23806   trans.reset();
23807 
23808   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
23809   CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
23810               IPAddress() /* server_ip */);
23811 }
23812 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportDNSErrorAfterStartAsync)23813 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
23814        CreateReportDNSErrorAfterStartAsync) {
23815   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23816   auto trans =
23817       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
23818 
23819   session_deps_.host_resolver->set_synchronous_mode(false);
23820   session_deps_.host_resolver->rules()->AddRule(GURL(url_).host(),
23821                                                 ERR_NAME_NOT_RESOLVED);
23822   TestCompletionCallback callback;
23823 
23824   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
23825   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
23826 
23827   trans.reset();
23828 
23829   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
23830   CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
23831               IPAddress() /* server_ip */);
23832 }
23833 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportErrorAfterStart)23834 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
23835        CreateReportErrorAfterStart) {
23836   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23837   auto trans =
23838       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
23839 
23840   MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
23841   StaticSocketDataProvider data;
23842   data.set_connect_data(mock_connect);
23843   session_deps_.socket_factory->AddSocketDataProvider(&data);
23844 
23845   TestCompletionCallback callback;
23846 
23847   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
23848   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
23849 
23850   trans.reset();
23851 
23852   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
23853   CheckReport(0 /* index */, 0 /* status_code */, ERR_CONNECTION_REFUSED,
23854               IPAddress::IPv4Localhost() /* server_ip */);
23855 }
23856 
23857 // Same as above except the error is ASYNC
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportErrorAfterStartAsync)23858 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
23859        CreateReportErrorAfterStartAsync) {
23860   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23861   auto trans =
23862       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
23863 
23864   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
23865   StaticSocketDataProvider data;
23866   data.set_connect_data(mock_connect);
23867   session_deps_.socket_factory->AddSocketDataProvider(&data);
23868 
23869   TestCompletionCallback callback;
23870 
23871   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
23872   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
23873 
23874   trans.reset();
23875 
23876   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
23877   CheckReport(0 /* index */, 0 /* status_code */, ERR_CONNECTION_REFUSED,
23878               IPAddress::IPv4Localhost() /* server_ip */);
23879 }
23880 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportReadBodyError)23881 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
23882        CreateReportReadBodyError) {
23883   std::string extra_header_string = extra_headers_.ToString();
23884   MockWrite data_writes[] = {
23885       MockWrite("GET / HTTP/1.1\r\n"
23886                 "Host: www.example.org\r\n"
23887                 "Connection: keep-alive\r\n"),
23888       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
23889   };
23890   MockRead data_reads[] = {
23891       MockRead("HTTP/1.0 200 OK\r\n"),
23892       MockRead("Content-Length: 100\r\n\r\n"),  // wrong content length
23893       MockRead("hello world"),
23894       MockRead(SYNCHRONOUS, OK),
23895   };
23896 
23897   StaticSocketDataProvider reads(data_reads, data_writes);
23898   session_deps_.socket_factory->AddSocketDataProvider(&reads);
23899 
23900   SSLSocketDataProvider ssl(ASYNC, OK);
23901   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
23902 
23903   // Log start time
23904   base::TimeTicks start_time = base::TimeTicks::Now();
23905 
23906   TestCompletionCallback callback;
23907   auto session = CreateSession(&session_deps_);
23908   auto trans =
23909       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
23910   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
23911   EXPECT_THAT(callback.GetResult(rv), IsOk());
23912 
23913   const HttpResponseInfo* response = trans->GetResponseInfo();
23914   ASSERT_TRUE(response);
23915 
23916   EXPECT_TRUE(response->headers);
23917   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
23918 
23919   std::string response_data;
23920   rv = ReadTransaction(trans.get(), &response_data);
23921   EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
23922 
23923   trans.reset();
23924 
23925   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
23926 
23927   CheckReport(0 /* index */, 200 /* status_code */,
23928               ERR_CONTENT_LENGTH_MISMATCH);
23929   const NetworkErrorLoggingService::RequestDetails& error =
23930       network_error_logging_service()->errors()[0];
23931   EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
23932 }
23933 
23934 // Same as above except the final read is ASYNC.
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportReadBodyErrorAsync)23935 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
23936        CreateReportReadBodyErrorAsync) {
23937   std::string extra_header_string = extra_headers_.ToString();
23938   MockWrite data_writes[] = {
23939       MockWrite("GET / HTTP/1.1\r\n"
23940                 "Host: www.example.org\r\n"
23941                 "Connection: keep-alive\r\n"),
23942       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
23943   };
23944   MockRead data_reads[] = {
23945       MockRead("HTTP/1.0 200 OK\r\n"),
23946       MockRead("Content-Length: 100\r\n\r\n"),  // wrong content length
23947       MockRead("hello world"),
23948       MockRead(ASYNC, OK),
23949   };
23950 
23951   StaticSocketDataProvider reads(data_reads, data_writes);
23952   session_deps_.socket_factory->AddSocketDataProvider(&reads);
23953 
23954   SSLSocketDataProvider ssl(ASYNC, OK);
23955   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
23956 
23957   // Log start time
23958   base::TimeTicks start_time = base::TimeTicks::Now();
23959 
23960   TestCompletionCallback callback;
23961   auto session = CreateSession(&session_deps_);
23962   auto trans =
23963       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
23964   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
23965   EXPECT_THAT(callback.GetResult(rv), IsOk());
23966 
23967   const HttpResponseInfo* response = trans->GetResponseInfo();
23968   ASSERT_TRUE(response);
23969 
23970   EXPECT_TRUE(response->headers);
23971   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
23972 
23973   std::string response_data;
23974   rv = ReadTransaction(trans.get(), &response_data);
23975   EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
23976 
23977   trans.reset();
23978 
23979   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
23980 
23981   CheckReport(0 /* index */, 200 /* status_code */,
23982               ERR_CONTENT_LENGTH_MISMATCH);
23983   const NetworkErrorLoggingService::RequestDetails& error =
23984       network_error_logging_service()->errors()[0];
23985   EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
23986 }
23987 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportRestartWithAuth)23988 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
23989        CreateReportRestartWithAuth) {
23990   std::string extra_header_string = extra_headers_.ToString();
23991   static const base::TimeDelta kSleepDuration = base::Milliseconds(10);
23992 
23993   MockWrite data_writes1[] = {
23994       MockWrite("GET / HTTP/1.1\r\n"
23995                 "Host: www.example.org\r\n"
23996                 "Connection: keep-alive\r\n"),
23997       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
23998   };
23999 
24000   MockRead data_reads1[] = {
24001       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
24002       // Give a couple authenticate options (only the middle one is actually
24003       // supported).
24004       MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
24005       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
24006       MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
24007       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
24008       // Large content-length -- won't matter, as connection will be reset.
24009       MockRead("Content-Length: 10000\r\n\r\n"),
24010       MockRead(SYNCHRONOUS, ERR_FAILED),
24011   };
24012 
24013   // After calling trans->RestartWithAuth(), this is the request we should
24014   // be issuing -- the final header line contains the credentials.
24015   MockWrite data_writes2[] = {
24016       MockWrite("GET / HTTP/1.1\r\n"
24017                 "Host: www.example.org\r\n"
24018                 "Connection: keep-alive\r\n"
24019                 "Authorization: Basic Zm9vOmJhcg==\r\n"),
24020       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
24021   };
24022 
24023   // Lastly, the server responds with the actual content.
24024   MockRead data_reads2[] = {
24025       MockRead("HTTP/1.0 200 OK\r\n\r\n"),
24026       MockRead("hello world"),
24027       MockRead(SYNCHRONOUS, OK),
24028   };
24029 
24030   StaticSocketDataProvider data1(data_reads1, data_writes1);
24031   StaticSocketDataProvider data2(data_reads2, data_writes2);
24032   session_deps_.socket_factory->AddSocketDataProvider(&data1);
24033   session_deps_.socket_factory->AddSocketDataProvider(&data2);
24034 
24035   SSLSocketDataProvider ssl1(ASYNC, OK);
24036   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
24037   SSLSocketDataProvider ssl2(ASYNC, OK);
24038   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
24039 
24040   base::TimeTicks start_time = base::TimeTicks::Now();
24041   base::TimeTicks restart_time;
24042 
24043   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24044   auto trans =
24045       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24046 
24047   TestCompletionCallback callback1;
24048 
24049   int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
24050   EXPECT_THAT(callback1.GetResult(rv), IsOk());
24051 
24052   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
24053 
24054   TestCompletionCallback callback2;
24055 
24056   // Wait 10 ms then restart with auth
24057   FastForwardBy(kSleepDuration);
24058   restart_time = base::TimeTicks::Now();
24059   rv =
24060       trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
24061   EXPECT_THAT(callback2.GetResult(rv), IsOk());
24062 
24063   std::string response_data;
24064   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
24065   EXPECT_EQ("hello world", response_data);
24066 
24067   trans.reset();
24068 
24069   // One 401 report for the auth challenge, then a 200 report for the successful
24070   // retry. Note that we don't report the error draining the body, as the first
24071   // request already generated a report for the auth challenge.
24072   ASSERT_EQ(2u, network_error_logging_service()->errors().size());
24073 
24074   // Check error report contents
24075   CheckReport(0 /* index */, 401 /* status_code */, OK);
24076   CheckReport(1 /* index */, 200 /* status_code */, OK);
24077 
24078   const NetworkErrorLoggingService::RequestDetails& error1 =
24079       network_error_logging_service()->errors()[0];
24080   const NetworkErrorLoggingService::RequestDetails& error2 =
24081       network_error_logging_service()->errors()[1];
24082 
24083   // Sanity-check elapsed time values
24084   EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
24085   // Check that the start time is refreshed when restarting with auth.
24086   EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
24087 }
24088 
24089 // Same as above, except draining the body before restarting fails
24090 // asynchronously.
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportRestartWithAuthAsync)24091 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
24092        CreateReportRestartWithAuthAsync) {
24093   std::string extra_header_string = extra_headers_.ToString();
24094   static const base::TimeDelta kSleepDuration = base::Milliseconds(10);
24095 
24096   MockWrite data_writes1[] = {
24097       MockWrite("GET / HTTP/1.1\r\n"
24098                 "Host: www.example.org\r\n"
24099                 "Connection: keep-alive\r\n"),
24100       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
24101   };
24102 
24103   MockRead data_reads1[] = {
24104       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
24105       // Give a couple authenticate options (only the middle one is actually
24106       // supported).
24107       MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
24108       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
24109       MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
24110       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
24111       // Large content-length -- won't matter, as connection will be reset.
24112       MockRead("Content-Length: 10000\r\n\r\n"),
24113       MockRead(ASYNC, ERR_FAILED),
24114   };
24115 
24116   // After calling trans->RestartWithAuth(), this is the request we should
24117   // be issuing -- the final header line contains the credentials.
24118   MockWrite data_writes2[] = {
24119       MockWrite("GET / HTTP/1.1\r\n"
24120                 "Host: www.example.org\r\n"
24121                 "Connection: keep-alive\r\n"
24122                 "Authorization: Basic Zm9vOmJhcg==\r\n"),
24123       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
24124   };
24125 
24126   // Lastly, the server responds with the actual content.
24127   MockRead data_reads2[] = {
24128       MockRead("HTTP/1.0 200 OK\r\n\r\n"),
24129       MockRead("hello world"),
24130       MockRead(SYNCHRONOUS, OK),
24131   };
24132 
24133   StaticSocketDataProvider data1(data_reads1, data_writes1);
24134   StaticSocketDataProvider data2(data_reads2, data_writes2);
24135   session_deps_.socket_factory->AddSocketDataProvider(&data1);
24136   session_deps_.socket_factory->AddSocketDataProvider(&data2);
24137 
24138   SSLSocketDataProvider ssl1(ASYNC, OK);
24139   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
24140   SSLSocketDataProvider ssl2(ASYNC, OK);
24141   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
24142 
24143   base::TimeTicks start_time = base::TimeTicks::Now();
24144   base::TimeTicks restart_time;
24145 
24146   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24147   auto trans =
24148       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24149 
24150   TestCompletionCallback callback1;
24151 
24152   int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
24153   EXPECT_THAT(callback1.GetResult(rv), IsOk());
24154 
24155   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
24156 
24157   TestCompletionCallback callback2;
24158 
24159   // Wait 10 ms then restart with auth
24160   FastForwardBy(kSleepDuration);
24161   restart_time = base::TimeTicks::Now();
24162   rv =
24163       trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
24164   EXPECT_THAT(callback2.GetResult(rv), IsOk());
24165 
24166   std::string response_data;
24167   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
24168   EXPECT_EQ("hello world", response_data);
24169 
24170   trans.reset();
24171 
24172   // One 401 report for the auth challenge, then a 200 report for the successful
24173   // retry. Note that we don't report the error draining the body, as the first
24174   // request already generated a report for the auth challenge.
24175   ASSERT_EQ(2u, network_error_logging_service()->errors().size());
24176 
24177   // Check error report contents
24178   CheckReport(0 /* index */, 401 /* status_code */, OK);
24179   CheckReport(1 /* index */, 200 /* status_code */, OK);
24180 
24181   const NetworkErrorLoggingService::RequestDetails& error1 =
24182       network_error_logging_service()->errors()[0];
24183   const NetworkErrorLoggingService::RequestDetails& error2 =
24184       network_error_logging_service()->errors()[1];
24185 
24186   // Sanity-check elapsed time values
24187   EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
24188   // Check that the start time is refreshed when restarting with auth.
24189   EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
24190 }
24191 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportRetryKeepAliveConnectionReset)24192 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
24193        CreateReportRetryKeepAliveConnectionReset) {
24194   std::string extra_header_string = extra_headers_.ToString();
24195   MockWrite data_writes1[] = {
24196       MockWrite("GET / HTTP/1.1\r\n"
24197                 "Host: www.example.org\r\n"
24198                 "Connection: keep-alive\r\n"),
24199       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
24200       MockWrite("GET / HTTP/1.1\r\n"
24201                 "Host: www.example.org\r\n"
24202                 "Connection: keep-alive\r\n"),
24203       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
24204   };
24205 
24206   MockRead data_reads1[] = {
24207       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
24208       MockRead("hello"),
24209       // Connection is reset
24210       MockRead(ASYNC, ERR_CONNECTION_RESET),
24211   };
24212 
24213   // Successful retry
24214   MockRead data_reads2[] = {
24215       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
24216       MockRead("world"),
24217       MockRead(ASYNC, OK),
24218   };
24219 
24220   StaticSocketDataProvider data1(data_reads1, data_writes1);
24221   StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
24222   session_deps_.socket_factory->AddSocketDataProvider(&data1);
24223   session_deps_.socket_factory->AddSocketDataProvider(&data2);
24224 
24225   SSLSocketDataProvider ssl1(ASYNC, OK);
24226   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
24227   SSLSocketDataProvider ssl2(ASYNC, OK);
24228   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
24229 
24230   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24231   auto trans1 =
24232       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24233 
24234   TestCompletionCallback callback1;
24235 
24236   int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
24237   EXPECT_THAT(callback1.GetResult(rv), IsOk());
24238 
24239   std::string response_data;
24240   ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
24241   EXPECT_EQ("hello", response_data);
24242 
24243   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
24244 
24245   auto trans2 =
24246       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24247 
24248   TestCompletionCallback callback2;
24249 
24250   rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
24251   EXPECT_THAT(callback2.GetResult(rv), IsOk());
24252 
24253   ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
24254   EXPECT_EQ("world", response_data);
24255 
24256   trans1.reset();
24257   trans2.reset();
24258 
24259   // One OK report from first request, then a ERR_CONNECTION_RESET report from
24260   // the second request, then an OK report from the successful retry.
24261   ASSERT_EQ(3u, network_error_logging_service()->errors().size());
24262 
24263   // Check error report contents
24264   CheckReport(0 /* index */, 200 /* status_code */, OK);
24265   CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
24266   CheckReport(2 /* index */, 200 /* status_code */, OK);
24267 }
24268 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportRetryKeepAlive408)24269 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
24270        CreateReportRetryKeepAlive408) {
24271   std::string extra_header_string = extra_headers_.ToString();
24272   MockWrite data_writes1[] = {
24273       MockWrite("GET / HTTP/1.1\r\n"
24274                 "Host: www.example.org\r\n"
24275                 "Connection: keep-alive\r\n"),
24276       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
24277       MockWrite("GET / HTTP/1.1\r\n"
24278                 "Host: www.example.org\r\n"
24279                 "Connection: keep-alive\r\n"),
24280       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
24281   };
24282 
24283   MockRead data_reads1[] = {
24284       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
24285       MockRead("hello"),
24286       // 408 Request Timeout
24287       MockRead(SYNCHRONOUS,
24288                "HTTP/1.1 408 Request Timeout\r\n"
24289                "Connection: Keep-Alive\r\n"
24290                "Content-Length: 6\r\n\r\n"
24291                "Pickle"),
24292   };
24293 
24294   // Successful retry
24295   MockRead data_reads2[] = {
24296       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
24297       MockRead("world"),
24298       MockRead(ASYNC, OK),
24299   };
24300 
24301   StaticSocketDataProvider data1(data_reads1, data_writes1);
24302   StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
24303   session_deps_.socket_factory->AddSocketDataProvider(&data1);
24304   session_deps_.socket_factory->AddSocketDataProvider(&data2);
24305 
24306   SSLSocketDataProvider ssl1(ASYNC, OK);
24307   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
24308   SSLSocketDataProvider ssl2(ASYNC, OK);
24309   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
24310 
24311   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24312   auto trans1 =
24313       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24314 
24315   TestCompletionCallback callback1;
24316 
24317   int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
24318   EXPECT_THAT(callback1.GetResult(rv), IsOk());
24319 
24320   std::string response_data;
24321   ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
24322   EXPECT_EQ("hello", response_data);
24323 
24324   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
24325 
24326   auto trans2 =
24327       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24328 
24329   TestCompletionCallback callback2;
24330 
24331   rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
24332   EXPECT_THAT(callback2.GetResult(rv), IsOk());
24333 
24334   ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
24335   EXPECT_EQ("world", response_data);
24336 
24337   trans1.reset();
24338   trans2.reset();
24339 
24340   // One 200 report from first request, then a 408 report from
24341   // the second request, then a 200 report from the successful retry.
24342   ASSERT_EQ(3u, network_error_logging_service()->errors().size());
24343 
24344   // Check error report contents
24345   CheckReport(0 /* index */, 200 /* status_code */, OK);
24346   CheckReport(1 /* index */, 408 /* status_code */, OK);
24347   CheckReport(2 /* index */, 200 /* status_code */, OK);
24348 }
24349 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportRetry421WithoutConnectionPooling)24350 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
24351        CreateReportRetry421WithoutConnectionPooling) {
24352   // Two hosts resolve to the same IP address.
24353   const std::string ip_addr = "1.2.3.4";
24354   IPAddress ip;
24355   ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
24356   IPEndPoint peer_addr = IPEndPoint(ip, 443);
24357 
24358   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
24359   session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
24360   session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
24361 
24362   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24363 
24364   // Two requests on the first connection.
24365   spdy::SpdySerializedFrame req1(
24366       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
24367   spdy_util_.UpdateWithStreamDestruction(1);
24368   spdy::SpdySerializedFrame req2(
24369       spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
24370   spdy::SpdySerializedFrame rst(
24371       spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
24372   MockWrite writes1[] = {
24373       CreateMockWrite(req1, 0),
24374       CreateMockWrite(req2, 3),
24375       CreateMockWrite(rst, 6),
24376   };
24377 
24378   // The first one succeeds, the second gets error 421 Misdirected Request.
24379   spdy::SpdySerializedFrame resp1(
24380       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
24381   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
24382   spdy::Http2HeaderBlock response_headers;
24383   response_headers[spdy::kHttp2StatusHeader] = "421";
24384   spdy::SpdySerializedFrame resp2(
24385       spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
24386   MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
24387                        CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
24388 
24389   MockConnect connect1(ASYNC, OK, peer_addr);
24390   SequencedSocketData data1(connect1, reads1, writes1);
24391   session_deps_.socket_factory->AddSocketDataProvider(&data1);
24392 
24393   AddSSLSocketData();
24394 
24395   // Retry the second request on a second connection.
24396   SpdyTestUtil spdy_util2(/*use_priority_header=*/true);
24397   spdy::SpdySerializedFrame req3(
24398       spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
24399   MockWrite writes2[] = {
24400       CreateMockWrite(req3, 0),
24401   };
24402 
24403   spdy::SpdySerializedFrame resp3(
24404       spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
24405   spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
24406   MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
24407                        MockRead(ASYNC, 0, 3)};
24408 
24409   MockConnect connect2(ASYNC, OK, peer_addr);
24410   SequencedSocketData data2(connect2, reads2, writes2);
24411   session_deps_.socket_factory->AddSocketDataProvider(&data2);
24412 
24413   AddSSLSocketData();
24414 
24415   // Preload mail.example.org into HostCache.
24416   int rv = session_deps_.host_resolver->LoadIntoCache(
24417       HostPortPair("mail.example.org", 443), NetworkAnonymizationKey(),
24418       std::nullopt);
24419   EXPECT_THAT(rv, IsOk());
24420 
24421   HttpRequestInfo request1;
24422   request1.method = "GET";
24423   request1.url = GURL("https://www.example.org/");
24424   request1.load_flags = 0;
24425   request1.traffic_annotation =
24426       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
24427   auto trans1 =
24428       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24429 
24430   TestCompletionCallback callback;
24431   rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
24432   EXPECT_THAT(callback.GetResult(rv), IsOk());
24433 
24434   const HttpResponseInfo* response = trans1->GetResponseInfo();
24435   ASSERT_TRUE(response);
24436   ASSERT_TRUE(response->headers);
24437   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
24438   EXPECT_TRUE(response->was_fetched_via_spdy);
24439   EXPECT_TRUE(response->was_alpn_negotiated);
24440   std::string response_data;
24441   ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
24442   EXPECT_EQ("hello!", response_data);
24443 
24444   trans1.reset();
24445 
24446   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
24447 
24448   HttpRequestInfo request2;
24449   request2.method = "GET";
24450   request2.url = GURL("https://mail.example.org/");
24451   request2.load_flags = 0;
24452   request2.traffic_annotation =
24453       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
24454   auto trans2 =
24455       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24456 
24457   rv = trans2->Start(&request2, callback.callback(),
24458                      NetLogWithSource::Make(NetLogSourceType::NONE));
24459   EXPECT_THAT(callback.GetResult(rv), IsOk());
24460 
24461   response = trans2->GetResponseInfo();
24462   ASSERT_TRUE(response);
24463   ASSERT_TRUE(response->headers);
24464   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
24465   EXPECT_TRUE(response->was_fetched_via_spdy);
24466   EXPECT_TRUE(response->was_alpn_negotiated);
24467   ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
24468   EXPECT_EQ("hello!", response_data);
24469 
24470   trans2.reset();
24471 
24472   // One 200 report from the first request, then a 421 report from the
24473   // second request, then a 200 report from the successful retry.
24474   ASSERT_EQ(3u, network_error_logging_service()->errors().size());
24475 
24476   // Check error report contents
24477   const NetworkErrorLoggingService::RequestDetails& error1 =
24478       network_error_logging_service()->errors()[0];
24479   EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
24480   EXPECT_TRUE(error1.referrer.is_empty());
24481   EXPECT_EQ("", error1.user_agent);
24482   EXPECT_EQ(ip, error1.server_ip);
24483   EXPECT_EQ("h2", error1.protocol);
24484   EXPECT_EQ("GET", error1.method);
24485   EXPECT_EQ(200, error1.status_code);
24486   EXPECT_EQ(OK, error1.type);
24487   EXPECT_EQ(0, error1.reporting_upload_depth);
24488 
24489   const NetworkErrorLoggingService::RequestDetails& error2 =
24490       network_error_logging_service()->errors()[1];
24491   EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
24492   EXPECT_TRUE(error2.referrer.is_empty());
24493   EXPECT_EQ("", error2.user_agent);
24494   EXPECT_EQ(ip, error2.server_ip);
24495   EXPECT_EQ("h2", error2.protocol);
24496   EXPECT_EQ("GET", error2.method);
24497   EXPECT_EQ(421, error2.status_code);
24498   EXPECT_EQ(OK, error2.type);
24499   EXPECT_EQ(0, error2.reporting_upload_depth);
24500 
24501   const NetworkErrorLoggingService::RequestDetails& error3 =
24502       network_error_logging_service()->errors()[2];
24503   EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
24504   EXPECT_TRUE(error3.referrer.is_empty());
24505   EXPECT_EQ("", error3.user_agent);
24506   EXPECT_EQ(ip, error3.server_ip);
24507   EXPECT_EQ("h2", error3.protocol);
24508   EXPECT_EQ("GET", error3.method);
24509   EXPECT_EQ(200, error3.status_code);
24510   EXPECT_EQ(OK, error3.type);
24511   EXPECT_EQ(0, error3.reporting_upload_depth);
24512 }
24513 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportCancelAfterStart)24514 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
24515        CreateReportCancelAfterStart) {
24516   StaticSocketDataProvider data;
24517   data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
24518   session_deps_.socket_factory->AddSocketDataProvider(&data);
24519 
24520   TestCompletionCallback callback;
24521   auto session = CreateSession(&session_deps_);
24522   auto trans =
24523       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24524   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
24525   EXPECT_EQ(rv, ERR_IO_PENDING);
24526 
24527   // Cancel after start.
24528   trans.reset();
24529 
24530   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
24531   CheckReport(0 /* index */, 0 /* status_code */, ERR_ABORTED,
24532               IPAddress() /* server_ip */);
24533 }
24534 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportCancelBeforeReadingBody)24535 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
24536        CreateReportCancelBeforeReadingBody) {
24537   std::string extra_header_string = extra_headers_.ToString();
24538   MockWrite data_writes[] = {
24539       MockWrite("GET / HTTP/1.1\r\n"
24540                 "Host: www.example.org\r\n"
24541                 "Connection: keep-alive\r\n"),
24542       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
24543   };
24544   MockRead data_reads[] = {
24545       MockRead("HTTP/1.0 200 OK\r\n"),
24546       MockRead("Content-Length: 100\r\n\r\n"),  // Body is never read.
24547   };
24548 
24549   StaticSocketDataProvider data(data_reads, data_writes);
24550   session_deps_.socket_factory->AddSocketDataProvider(&data);
24551 
24552   SSLSocketDataProvider ssl(ASYNC, OK);
24553   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
24554 
24555   TestCompletionCallback callback;
24556   auto session = CreateSession(&session_deps_);
24557   auto trans =
24558       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24559   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
24560   EXPECT_THAT(callback.GetResult(rv), IsOk());
24561 
24562   const HttpResponseInfo* response = trans->GetResponseInfo();
24563   ASSERT_TRUE(response);
24564 
24565   EXPECT_TRUE(response->headers);
24566   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
24567 
24568   // Cancel before reading the body.
24569   trans.reset();
24570 
24571   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
24572   CheckReport(0 /* index */, 200 /* status_code */, ERR_ABORTED);
24573 }
24574 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,DontCreateReportHttp)24575 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
24576   RequestPolicy();
24577   EXPECT_EQ(1u, network_error_logging_service()->headers().size());
24578   EXPECT_EQ(1u, network_error_logging_service()->errors().size());
24579 
24580   // Make HTTP request
24581   std::string extra_header_string = extra_headers_.ToString();
24582   MockRead data_reads[] = {
24583       MockRead("HTTP/1.0 200 OK\r\n\r\n"),
24584       MockRead("hello world"),
24585       MockRead(SYNCHRONOUS, OK),
24586   };
24587   MockWrite data_writes[] = {
24588       MockWrite("GET / HTTP/1.1\r\n"
24589                 "Host: www.example.org\r\n"
24590                 "Connection: keep-alive\r\n"),
24591       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
24592   };
24593 
24594   StaticSocketDataProvider data(data_reads, data_writes);
24595   session_deps_.socket_factory->AddSocketDataProvider(&data);
24596 
24597   // Insecure url
24598   url_ = "http://www.example.org/";
24599   request_.url = GURL(url_);
24600 
24601   TestCompletionCallback callback;
24602   auto session = CreateSession(&session_deps_);
24603   auto trans =
24604       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24605   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
24606   EXPECT_THAT(callback.GetResult(rv), IsOk());
24607 
24608   std::string response_data;
24609   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
24610   EXPECT_EQ("hello world", response_data);
24611 
24612   // Insecure request does not generate a report
24613   EXPECT_EQ(1u, network_error_logging_service()->errors().size());
24614 }
24615 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,DontCreateReportHttpError)24616 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
24617        DontCreateReportHttpError) {
24618   RequestPolicy();
24619   EXPECT_EQ(1u, network_error_logging_service()->headers().size());
24620   EXPECT_EQ(1u, network_error_logging_service()->errors().size());
24621 
24622   // Make HTTP request that fails
24623   MockRead data_reads[] = {
24624       MockRead("hello world"),
24625       MockRead(SYNCHRONOUS, OK),
24626   };
24627 
24628   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
24629   session_deps_.socket_factory->AddSocketDataProvider(&data);
24630 
24631   url_ = "http://www.originwithoutpolicy.com:2000/";
24632   request_.url = GURL(url_);
24633 
24634   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24635 
24636   auto trans =
24637       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24638   TestCompletionCallback callback;
24639   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
24640   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
24641 
24642   // Insecure request does not generate a report, regardless of existence of a
24643   // policy for the origin.
24644   EXPECT_EQ(1u, network_error_logging_service()->errors().size());
24645 }
24646 
24647 // Don't report on proxy auth challenges, don't report if connecting through a
24648 // proxy.
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,DontCreateReportProxy)24649 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) {
24650   HttpRequestInfo request;
24651   request.method = "GET";
24652   request.url = GURL("https://www.example.org/");
24653   request.traffic_annotation =
24654       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
24655 
24656   // Configure against proxy server "myproxy:70".
24657   session_deps_.proxy_resolution_service =
24658       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
24659           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
24660   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24661 
24662   // Since we have proxy, should try to establish tunnel.
24663   MockWrite data_writes1[] = {
24664       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
24665                 "Host: www.example.org:443\r\n"
24666                 "Proxy-Connection: keep-alive\r\n\r\n"),
24667   };
24668 
24669   // The proxy responds to the connect with a 407, using a non-persistent
24670   // connection.
24671   MockRead data_reads1[] = {
24672       // No credentials.
24673       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
24674       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
24675       MockRead("Proxy-Connection: close\r\n\r\n"),
24676   };
24677 
24678   MockWrite data_writes2[] = {
24679       // After calling trans->RestartWithAuth(), this is the request we should
24680       // be issuing -- the final header line contains the credentials.
24681       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
24682                 "Host: www.example.org:443\r\n"
24683                 "Proxy-Connection: keep-alive\r\n"
24684                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
24685 
24686       MockWrite("GET / HTTP/1.1\r\n"
24687                 "Host: www.example.org\r\n"
24688                 "Connection: keep-alive\r\n\r\n"),
24689   };
24690 
24691   MockRead data_reads2[] = {
24692       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
24693 
24694       MockRead("HTTP/1.1 200 OK\r\n"),
24695       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
24696       MockRead("Content-Length: 5\r\n\r\n"),
24697       MockRead(SYNCHRONOUS, "hello"),
24698   };
24699 
24700   StaticSocketDataProvider data1(data_reads1, data_writes1);
24701   session_deps_.socket_factory->AddSocketDataProvider(&data1);
24702   StaticSocketDataProvider data2(data_reads2, data_writes2);
24703   session_deps_.socket_factory->AddSocketDataProvider(&data2);
24704   SSLSocketDataProvider ssl(ASYNC, OK);
24705   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
24706 
24707   TestCompletionCallback callback1;
24708 
24709   auto trans =
24710       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24711 
24712   int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
24713   EXPECT_THAT(callback1.GetResult(rv), IsOk());
24714 
24715   const HttpResponseInfo* response = trans->GetResponseInfo();
24716   EXPECT_EQ(407, response->headers->response_code());
24717 
24718   std::string response_data;
24719   rv = ReadTransaction(trans.get(), &response_data);
24720   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
24721 
24722   // No NEL report is generated for the 407.
24723   EXPECT_EQ(0u, network_error_logging_service()->errors().size());
24724 
24725   TestCompletionCallback callback2;
24726 
24727   rv =
24728       trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
24729   EXPECT_THAT(callback2.GetResult(rv), IsOk());
24730 
24731   response = trans->GetResponseInfo();
24732   EXPECT_EQ(200, response->headers->response_code());
24733 
24734   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
24735   EXPECT_EQ("hello", response_data);
24736 
24737   trans.reset();
24738 
24739   // No NEL report is generated because we are behind a proxy.
24740   EXPECT_EQ(0u, network_error_logging_service()->errors().size());
24741 }
24742 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,ReportContainsUploadDepth)24743 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,
24744        ReportContainsUploadDepth) {
24745   reporting_upload_depth_ = 7;
24746   request_.reporting_upload_depth = reporting_upload_depth_;
24747   RequestPolicy();
24748   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
24749   const NetworkErrorLoggingService::RequestDetails& error =
24750       network_error_logging_service()->errors()[0];
24751   EXPECT_EQ(7, error.reporting_upload_depth);
24752 }
24753 
TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest,ReportElapsedTime)24754 TEST_P(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
24755   std::string extra_header_string = extra_headers_.ToString();
24756   static const base::TimeDelta kSleepDuration = base::Milliseconds(10);
24757 
24758   std::vector<MockWrite> data_writes = {
24759       MockWrite(ASYNC, 0,
24760                 "GET / HTTP/1.1\r\n"
24761                 "Host: www.example.org\r\n"
24762                 "Connection: keep-alive\r\n"),
24763       MockWrite(ASYNC, 1, extra_header_string.data()),
24764   };
24765 
24766   std::vector<MockRead> data_reads = {
24767       // Write one byte of the status line, followed by a pause.
24768       MockRead(ASYNC, 2, "H"),
24769       MockRead(ASYNC, ERR_IO_PENDING, 3),
24770       MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
24771       MockRead(ASYNC, 5, "hello world"),
24772       MockRead(SYNCHRONOUS, OK, 6),
24773   };
24774 
24775   SequencedSocketData data(data_reads, data_writes);
24776   session_deps_.socket_factory->AddSocketDataProvider(&data);
24777 
24778   SSLSocketDataProvider ssl(ASYNC, OK);
24779   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
24780 
24781   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24782 
24783   auto trans =
24784       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24785 
24786   TestCompletionCallback callback;
24787 
24788   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
24789   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
24790 
24791   data.RunUntilPaused();
24792   ASSERT_TRUE(data.IsPaused());
24793   FastForwardBy(kSleepDuration);
24794   data.Resume();
24795 
24796   EXPECT_THAT(callback.GetResult(rv), IsOk());
24797 
24798   std::string response_data;
24799   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
24800   EXPECT_EQ("hello world", response_data);
24801 
24802   trans.reset();
24803 
24804   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
24805 
24806   CheckReport(0 /* index */, 200 /* status_code */, OK);
24807 
24808   const NetworkErrorLoggingService::RequestDetails& error =
24809       network_error_logging_service()->errors()[0];
24810 
24811   // Sanity-check elapsed time in error report
24812   EXPECT_EQ(kSleepDuration, error.elapsed_time);
24813 }
24814 
24815 #endif  // BUILDFLAG(ENABLE_REPORTING)
24816 
TEST_P(HttpNetworkTransactionTest,AlwaysFailRequestToCache)24817 TEST_P(HttpNetworkTransactionTest, AlwaysFailRequestToCache) {
24818   HttpRequestInfo request;
24819   request.method = "GET";
24820   request.url = GURL("http://example.org/");
24821 
24822   request.load_flags = LOAD_ONLY_FROM_CACHE;
24823 
24824   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24825   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
24826   TestCompletionCallback callback1;
24827   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
24828 
24829   EXPECT_THAT(rv, IsError(ERR_CACHE_MISS));
24830 }
24831 
TEST_P(HttpNetworkTransactionTest,ZeroRTTDoesntConfirm)24832 TEST_P(HttpNetworkTransactionTest, ZeroRTTDoesntConfirm) {
24833   static const base::TimeDelta kDelay = base::Milliseconds(10);
24834   HttpRequestInfo request;
24835   request.method = "GET";
24836   request.url = GURL("https://www.example.org/");
24837   request.traffic_annotation =
24838       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
24839 
24840   MockWrite data_writes[] = {
24841       MockWrite("GET / HTTP/1.1\r\n"
24842                 "Host: www.example.org\r\n"
24843                 "Connection: keep-alive\r\n\r\n"),
24844   };
24845 
24846   MockRead data_reads[] = {
24847       MockRead("HTTP/1.1 200 OK\r\n"),
24848       MockRead("Content-Length: 1\r\n\r\n"),
24849       MockRead(SYNCHRONOUS, "1"),
24850   };
24851 
24852   StaticSocketDataProvider data(data_reads, data_writes);
24853   session_deps_.socket_factory->AddSocketDataProvider(&data);
24854   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
24855   ssl.connect_callback = FastForwardByCallback(kDelay);
24856   ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
24857   ssl.confirm_callback = FastForwardByCallback(kDelay);
24858   session_deps_.enable_early_data = true;
24859   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
24860 
24861   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24862 
24863   TestCompletionCallback callback;
24864   auto trans =
24865       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24866 
24867   base::TimeTicks start_time = base::TimeTicks::Now();
24868   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
24869   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
24870 
24871   rv = callback.WaitForResult();
24872   EXPECT_THAT(rv, IsOk());
24873 
24874   const HttpResponseInfo* response = trans->GetResponseInfo();
24875   ASSERT_TRUE(response);
24876   ASSERT_TRUE(response->headers);
24877   EXPECT_EQ(200, response->headers->response_code());
24878   EXPECT_EQ(1, response->headers->GetContentLength());
24879 
24880   // Check that ConfirmHandshake wasn't called.
24881   ASSERT_FALSE(ssl.ConfirmDataConsumed());
24882   ASSERT_TRUE(ssl.WriteBeforeConfirm());
24883 
24884   // The handshake time should include the time it took to run Connect(), but
24885   // not ConfirmHandshake().
24886   LoadTimingInfo load_timing_info;
24887   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
24888   EXPECT_EQ(load_timing_info.connect_timing.connect_start, start_time);
24889   EXPECT_EQ(load_timing_info.connect_timing.ssl_start, start_time);
24890   EXPECT_EQ(load_timing_info.connect_timing.ssl_end, start_time + kDelay);
24891   EXPECT_EQ(load_timing_info.connect_timing.connect_end, start_time + kDelay);
24892 
24893   trans.reset();
24894 
24895   session->CloseAllConnections(ERR_FAILED, "Very good reason");
24896 }
24897 
TEST_P(HttpNetworkTransactionTest,ZeroRTTSyncConfirmSyncWrite)24898 TEST_P(HttpNetworkTransactionTest, ZeroRTTSyncConfirmSyncWrite) {
24899   static const base::TimeDelta kDelay = base::Milliseconds(10);
24900   HttpRequestInfo request;
24901   request.method = "POST";
24902   request.url = GURL("https://www.example.org/");
24903   request.traffic_annotation =
24904       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
24905 
24906   MockWrite data_writes[] = {
24907       MockWrite(SYNCHRONOUS,
24908                 "POST / HTTP/1.1\r\n"
24909                 "Host: www.example.org\r\n"
24910                 "Connection: keep-alive\r\n"
24911                 "Content-Length: 0\r\n\r\n"),
24912   };
24913 
24914   MockRead data_reads[] = {
24915       MockRead("HTTP/1.1 200 OK\r\n"),
24916       MockRead("Content-Length: 1\r\n\r\n"),
24917       MockRead(SYNCHRONOUS, "1"),
24918   };
24919 
24920   StaticSocketDataProvider data(data_reads, data_writes);
24921   session_deps_.socket_factory->AddSocketDataProvider(&data);
24922   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
24923   ssl.connect_callback = FastForwardByCallback(kDelay);
24924   ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
24925   ssl.confirm_callback = FastForwardByCallback(kDelay);
24926   session_deps_.enable_early_data = true;
24927   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
24928 
24929   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24930 
24931   TestCompletionCallback callback;
24932   auto trans =
24933       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
24934 
24935   base::TimeTicks start_time = base::TimeTicks::Now();
24936   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
24937   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
24938 
24939   rv = callback.WaitForResult();
24940   EXPECT_THAT(rv, IsOk());
24941 
24942   const HttpResponseInfo* response = trans->GetResponseInfo();
24943   ASSERT_TRUE(response);
24944   ASSERT_TRUE(response->headers);
24945   EXPECT_EQ(200, response->headers->response_code());
24946   EXPECT_EQ(1, response->headers->GetContentLength());
24947 
24948   // Check that the Write didn't get called before ConfirmHandshake completed.
24949   ASSERT_FALSE(ssl.WriteBeforeConfirm());
24950 
24951   // The handshake time should include the time it took to run Connect(), but
24952   // not ConfirmHandshake(). If ConfirmHandshake() returns synchronously, we
24953   // assume the connection did not negotiate 0-RTT or the handshake was already
24954   // confirmed.
24955   LoadTimingInfo load_timing_info;
24956   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
24957   EXPECT_EQ(load_timing_info.connect_timing.connect_start, start_time);
24958   EXPECT_EQ(load_timing_info.connect_timing.ssl_start, start_time);
24959   EXPECT_EQ(load_timing_info.connect_timing.ssl_end, start_time + kDelay);
24960   EXPECT_EQ(load_timing_info.connect_timing.connect_end, start_time + kDelay);
24961 
24962   trans.reset();
24963 
24964   session->CloseAllConnections(ERR_FAILED, "Very good reason");
24965 }
24966 
TEST_P(HttpNetworkTransactionTest,ZeroRTTSyncConfirmAsyncWrite)24967 TEST_P(HttpNetworkTransactionTest, ZeroRTTSyncConfirmAsyncWrite) {
24968   HttpRequestInfo request;
24969   request.method = "POST";
24970   request.url = GURL("https://www.example.org/");
24971   request.traffic_annotation =
24972       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
24973 
24974   MockWrite data_writes[] = {
24975       MockWrite(ASYNC,
24976                 "POST / HTTP/1.1\r\n"
24977                 "Host: www.example.org\r\n"
24978                 "Connection: keep-alive\r\n"
24979                 "Content-Length: 0\r\n\r\n"),
24980   };
24981 
24982   MockRead data_reads[] = {
24983       MockRead("HTTP/1.1 200 OK\r\n"),
24984       MockRead("Content-Length: 1\r\n\r\n"),
24985       MockRead(SYNCHRONOUS, "1"),
24986   };
24987 
24988   StaticSocketDataProvider data(data_reads, data_writes);
24989   session_deps_.socket_factory->AddSocketDataProvider(&data);
24990   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
24991   ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
24992   session_deps_.enable_early_data = true;
24993   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
24994 
24995   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24996 
24997   TestCompletionCallback callback;
24998   auto trans =
24999       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
25000 
25001   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
25002   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
25003 
25004   rv = callback.WaitForResult();
25005   EXPECT_THAT(rv, IsOk());
25006 
25007   const HttpResponseInfo* response = trans->GetResponseInfo();
25008   ASSERT_TRUE(response);
25009   ASSERT_TRUE(response->headers);
25010   EXPECT_EQ(200, response->headers->response_code());
25011   EXPECT_EQ(1, response->headers->GetContentLength());
25012 
25013   // Check that the Write didn't get called before ConfirmHandshake completed.
25014   ASSERT_FALSE(ssl.WriteBeforeConfirm());
25015 
25016   trans.reset();
25017 
25018   session->CloseAllConnections(ERR_FAILED, "Very good reason");
25019 }
25020 
TEST_P(HttpNetworkTransactionTest,ZeroRTTAsyncConfirmSyncWrite)25021 TEST_P(HttpNetworkTransactionTest, ZeroRTTAsyncConfirmSyncWrite) {
25022   static const base::TimeDelta kDelay = base::Milliseconds(10);
25023   HttpRequestInfo request;
25024   request.method = "POST";
25025   request.url = GURL("https://www.example.org/");
25026   request.traffic_annotation =
25027       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
25028 
25029   MockWrite data_writes[] = {
25030       MockWrite(SYNCHRONOUS,
25031                 "POST / HTTP/1.1\r\n"
25032                 "Host: www.example.org\r\n"
25033                 "Connection: keep-alive\r\n"
25034                 "Content-Length: 0\r\n\r\n"),
25035   };
25036 
25037   MockRead data_reads[] = {
25038       MockRead("HTTP/1.1 200 OK\r\n"),
25039       MockRead("Content-Length: 1\r\n\r\n"),
25040       MockRead(SYNCHRONOUS, "1"),
25041   };
25042 
25043   StaticSocketDataProvider data(data_reads, data_writes);
25044   session_deps_.socket_factory->AddSocketDataProvider(&data);
25045   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
25046   ssl.connect_callback = FastForwardByCallback(kDelay);
25047   ssl.confirm = MockConfirm(ASYNC, OK);
25048   ssl.confirm_callback = FastForwardByCallback(kDelay);
25049   session_deps_.enable_early_data = true;
25050   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
25051 
25052   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25053 
25054   TestCompletionCallback callback;
25055   auto trans =
25056       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
25057 
25058   base::TimeTicks start_time = base::TimeTicks::Now();
25059   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
25060   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
25061 
25062   rv = callback.WaitForResult();
25063   EXPECT_THAT(rv, IsOk());
25064 
25065   const HttpResponseInfo* response = trans->GetResponseInfo();
25066   ASSERT_TRUE(response);
25067   ASSERT_TRUE(response->headers);
25068   EXPECT_EQ(200, response->headers->response_code());
25069   EXPECT_EQ(1, response->headers->GetContentLength());
25070 
25071   // Check that the Write didn't get called before ConfirmHandshake completed.
25072   ASSERT_FALSE(ssl.WriteBeforeConfirm());
25073 
25074   // The handshake time should include the time it took to run Connect() and
25075   // ConfirmHandshake().
25076   LoadTimingInfo load_timing_info;
25077   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
25078   EXPECT_EQ(load_timing_info.connect_timing.connect_start, start_time);
25079   EXPECT_EQ(load_timing_info.connect_timing.ssl_start, start_time);
25080   EXPECT_EQ(load_timing_info.connect_timing.ssl_end, start_time + 2 * kDelay);
25081   EXPECT_EQ(load_timing_info.connect_timing.connect_end,
25082             start_time + 2 * kDelay);
25083 
25084   trans.reset();
25085 
25086   session->CloseAllConnections(ERR_FAILED, "Very good reason");
25087 }
25088 
TEST_P(HttpNetworkTransactionTest,ZeroRTTAsyncConfirmAsyncWrite)25089 TEST_P(HttpNetworkTransactionTest, ZeroRTTAsyncConfirmAsyncWrite) {
25090   HttpRequestInfo request;
25091   request.method = "POST";
25092   request.url = GURL("https://www.example.org/");
25093   request.traffic_annotation =
25094       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
25095 
25096   MockWrite data_writes[] = {
25097       MockWrite(ASYNC,
25098                 "POST / HTTP/1.1\r\n"
25099                 "Host: www.example.org\r\n"
25100                 "Connection: keep-alive\r\n"
25101                 "Content-Length: 0\r\n\r\n"),
25102   };
25103 
25104   MockRead data_reads[] = {
25105       MockRead("HTTP/1.1 200 OK\r\n"),
25106       MockRead("Content-Length: 1\r\n\r\n"),
25107       MockRead(SYNCHRONOUS, "1"),
25108   };
25109 
25110   StaticSocketDataProvider data(data_reads, data_writes);
25111   session_deps_.socket_factory->AddSocketDataProvider(&data);
25112   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
25113   ssl.confirm = MockConfirm(ASYNC, OK);
25114   session_deps_.enable_early_data = true;
25115   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
25116 
25117   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25118 
25119   TestCompletionCallback callback;
25120   auto trans =
25121       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
25122 
25123   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
25124   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
25125 
25126   rv = callback.WaitForResult();
25127   EXPECT_THAT(rv, IsOk());
25128 
25129   const HttpResponseInfo* response = trans->GetResponseInfo();
25130   ASSERT_TRUE(response);
25131   ASSERT_TRUE(response->headers);
25132   EXPECT_EQ(200, response->headers->response_code());
25133   EXPECT_EQ(1, response->headers->GetContentLength());
25134 
25135   // Check that the Write didn't get called before ConfirmHandshake completed.
25136   ASSERT_FALSE(ssl.WriteBeforeConfirm());
25137 
25138   trans.reset();
25139 
25140   session->CloseAllConnections(ERR_FAILED, "Very good reason");
25141 }
25142 
25143 // 0-RTT rejects are handled at HttpNetworkTransaction.
TEST_P(HttpNetworkTransactionTest,ZeroRTTReject)25144 TEST_P(HttpNetworkTransactionTest, ZeroRTTReject) {
25145   enum class RejectType {
25146     kRead,
25147     kWrite,
25148     kConfirm,
25149   };
25150 
25151   for (RejectType type :
25152        {RejectType::kRead, RejectType::kWrite, RejectType::kConfirm}) {
25153     SCOPED_TRACE(static_cast<int>(type));
25154     for (Error reject_error :
25155          {ERR_EARLY_DATA_REJECTED, ERR_WRONG_VERSION_ON_EARLY_DATA}) {
25156       SCOPED_TRACE(reject_error);
25157       session_deps_.socket_factory =
25158           std::make_unique<MockClientSocketFactory>();
25159 
25160       HttpRequestInfo request;
25161       request.method = type == RejectType::kConfirm ? "POST" : "GET";
25162       request.url = GURL("https://www.example.org/");
25163       request.traffic_annotation =
25164           net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
25165 
25166       // The first request fails.
25167       std::vector<MockWrite> data1_writes;
25168       std::vector<MockRead> data1_reads;
25169       SSLSocketDataProvider ssl1(SYNCHRONOUS, OK);
25170       switch (type) {
25171         case RejectType::kRead:
25172           data1_writes.emplace_back(
25173               "GET / HTTP/1.1\r\n"
25174               "Host: www.example.org\r\n"
25175               "Connection: keep-alive\r\n\r\n");
25176           data1_reads.emplace_back(ASYNC, reject_error);
25177           // Cause ConfirmHandshake to hang (it should not be called).
25178           ssl1.confirm = MockConfirm(SYNCHRONOUS, ERR_IO_PENDING);
25179           break;
25180         case RejectType::kWrite:
25181           data1_writes.emplace_back(ASYNC, reject_error);
25182           // Cause ConfirmHandshake to hang (it should not be called).
25183           ssl1.confirm = MockConfirm(SYNCHRONOUS, ERR_IO_PENDING);
25184           break;
25185         case RejectType::kConfirm:
25186           // The request never gets far enough to read or write.
25187           ssl1.confirm = MockConfirm(ASYNC, reject_error);
25188           break;
25189       }
25190 
25191       StaticSocketDataProvider data1(data1_reads, data1_writes);
25192       session_deps_.socket_factory->AddSocketDataProvider(&data1);
25193       session_deps_.enable_early_data = true;
25194       session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
25195 
25196       // The retry succeeds.
25197       //
25198       // TODO(https://crbug.com/950705): If |reject_error| is
25199       // ERR_EARLY_DATA_REJECTED, the retry should happen over the same socket.
25200       MockWrite data2_writes[] = {
25201           request.method == "POST"
25202               ? MockWrite("POST / HTTP/1.1\r\n"
25203                           "Host: www.example.org\r\n"
25204                           "Connection: keep-alive\r\n"
25205                           "Content-Length: 0\r\n\r\n")
25206               : MockWrite("GET / HTTP/1.1\r\n"
25207                           "Host: www.example.org\r\n"
25208                           "Connection: keep-alive\r\n\r\n"),
25209       };
25210 
25211       MockRead data2_reads[] = {
25212           MockRead("HTTP/1.1 200 OK\r\n"),
25213           MockRead("Content-Length: 1\r\n\r\n"),
25214           MockRead(SYNCHRONOUS, "1"),
25215       };
25216 
25217       StaticSocketDataProvider data2(data2_reads, data2_writes);
25218       session_deps_.socket_factory->AddSocketDataProvider(&data2);
25219       SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
25220       ssl2.confirm = MockConfirm(ASYNC, OK);
25221       session_deps_.enable_early_data = true;
25222       session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
25223 
25224       std::unique_ptr<HttpNetworkSession> session(
25225           CreateSession(&session_deps_));
25226 
25227       TestCompletionCallback callback;
25228       auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
25229                                                             session.get());
25230 
25231       EXPECT_THAT(callback.GetResult(trans->Start(&request, callback.callback(),
25232                                                   NetLogWithSource())),
25233                   IsOk());
25234 
25235       const HttpResponseInfo* response = trans->GetResponseInfo();
25236       ASSERT_TRUE(response);
25237       ASSERT_TRUE(response->headers);
25238       EXPECT_EQ(200, response->headers->response_code());
25239       EXPECT_EQ(1, response->headers->GetContentLength());
25240     }
25241   }
25242 }
25243 
TEST_P(HttpNetworkTransactionTest,ZeroRTTConfirmErrorSync)25244 TEST_P(HttpNetworkTransactionTest, ZeroRTTConfirmErrorSync) {
25245   HttpRequestInfo request;
25246   request.method = "POST";
25247   request.url = GURL("https://www.example.org/");
25248   request.traffic_annotation =
25249       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
25250 
25251   MockWrite data_writes[] = {
25252       MockWrite("POST / HTTP/1.1\r\n"
25253                 "Host: www.example.org\r\n"
25254                 "Connection: keep-alive\r\n"
25255                 "Content-Length: 0\r\n\r\n"),
25256   };
25257 
25258   MockRead data_reads[] = {
25259       MockRead("HTTP/1.1 200 OK\r\n"),
25260       MockRead("Content-Length: 1\r\n\r\n"),
25261       MockRead(SYNCHRONOUS, "1"),
25262   };
25263 
25264   StaticSocketDataProvider data(data_reads, data_writes);
25265   session_deps_.socket_factory->AddSocketDataProvider(&data);
25266   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
25267   ssl.confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
25268   session_deps_.enable_early_data = true;
25269   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
25270 
25271   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25272 
25273   TestCompletionCallback callback;
25274   auto trans =
25275       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
25276 
25277   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
25278   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
25279 
25280   rv = callback.WaitForResult();
25281   EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
25282 
25283   // Check that the Write didn't get called before ConfirmHandshake completed.
25284   ASSERT_FALSE(ssl.WriteBeforeConfirm());
25285 
25286   trans.reset();
25287 
25288   session->CloseAllConnections(ERR_FAILED, "Very good reason");
25289 }
25290 
TEST_P(HttpNetworkTransactionTest,ZeroRTTConfirmErrorAsync)25291 TEST_P(HttpNetworkTransactionTest, ZeroRTTConfirmErrorAsync) {
25292   HttpRequestInfo request;
25293   request.method = "POST";
25294   request.url = GURL("https://www.example.org/");
25295   request.traffic_annotation =
25296       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
25297 
25298   MockWrite data_writes[] = {
25299       MockWrite("POST / HTTP/1.1\r\n"
25300                 "Host: www.example.org\r\n"
25301                 "Connection: keep-alive\r\n"
25302                 "Content-Length: 0\r\n\r\n"),
25303   };
25304 
25305   MockRead data_reads[] = {
25306       MockRead("HTTP/1.1 200 OK\r\n"),
25307       MockRead("Content-Length: 1\r\n\r\n"),
25308       MockRead(SYNCHRONOUS, "1"),
25309   };
25310 
25311   StaticSocketDataProvider data(data_reads, data_writes);
25312   session_deps_.socket_factory->AddSocketDataProvider(&data);
25313   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
25314   ssl.confirm = MockConfirm(ASYNC, ERR_SSL_PROTOCOL_ERROR);
25315   session_deps_.enable_early_data = true;
25316   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
25317 
25318   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25319 
25320   TestCompletionCallback callback;
25321   auto trans =
25322       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
25323 
25324   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
25325   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
25326 
25327   rv = callback.WaitForResult();
25328   EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
25329 
25330   // Check that the Write didn't get called before ConfirmHandshake completed.
25331   ASSERT_FALSE(ssl.WriteBeforeConfirm());
25332 
25333   trans.reset();
25334 
25335   session->CloseAllConnections(ERR_FAILED, "Very good reason");
25336 }
25337 
25338 // Test the proxy and origin server each requesting both TLS client certificates
25339 // and HTTP auth. This is a regression test for https://crbug.com/946406.
TEST_P(HttpNetworkTransactionTest,AuthEverything)25340 TEST_P(HttpNetworkTransactionTest, AuthEverything) {
25341   // Note these hosts must match the CheckBasic*Auth() functions.
25342   session_deps_.proxy_resolution_service =
25343       ConfiguredProxyResolutionService::CreateFixedForTest(
25344           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
25345 
25346   auto cert_request_info_proxy = base::MakeRefCounted<SSLCertRequestInfo>();
25347   cert_request_info_proxy->host_and_port = HostPortPair("myproxy", 70);
25348 
25349   std::unique_ptr<FakeClientCertIdentity> identity_proxy =
25350       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
25351           GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
25352   ASSERT_TRUE(identity_proxy);
25353 
25354   auto cert_request_info_origin = base::MakeRefCounted<SSLCertRequestInfo>();
25355   cert_request_info_origin->host_and_port =
25356       HostPortPair("www.example.org", 443);
25357 
25358   std::unique_ptr<FakeClientCertIdentity> identity_origin =
25359       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
25360           GetTestCertsDirectory(), "client_2.pem", "client_2.pk8");
25361   ASSERT_TRUE(identity_origin);
25362 
25363   HttpRequestInfo request;
25364   request.method = "GET";
25365   request.url = GURL("https://www.example.org/");
25366   request.traffic_annotation =
25367       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
25368 
25369   // First, the client connects to the proxy, which requests a client
25370   // certificate.
25371   SSLSocketDataProvider ssl_proxy1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
25372   ssl_proxy1.cert_request_info = cert_request_info_proxy;
25373   ssl_proxy1.expected_send_client_cert = false;
25374   StaticSocketDataProvider data1;
25375   session_deps_.socket_factory->AddSocketDataProvider(&data1);
25376   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy1);
25377 
25378   // The client responds with a certificate on a new connection. The handshake
25379   // succeeds.
25380   SSLSocketDataProvider ssl_proxy2(ASYNC, OK);
25381   ssl_proxy2.expected_send_client_cert = true;
25382   ssl_proxy2.expected_client_cert = identity_proxy->certificate();
25383   // The client attempts an HTTP CONNECT, but the proxy requests basic auth.
25384   std::vector<MockWrite> mock_writes2;
25385   std::vector<MockRead> mock_reads2;
25386   mock_writes2.emplace_back(
25387       "CONNECT www.example.org:443 HTTP/1.1\r\n"
25388       "Host: www.example.org:443\r\n"
25389       "Proxy-Connection: keep-alive\r\n\r\n");
25390   mock_reads2.emplace_back(
25391       "HTTP/1.1 407 Proxy Authentication Required\r\n"
25392       "Content-Length: 0\r\n"
25393       "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n");
25394   // The client retries with credentials.
25395   mock_writes2.emplace_back(
25396       "CONNECT www.example.org:443 HTTP/1.1\r\n"
25397       "Host: www.example.org:443\r\n"
25398       "Proxy-Connection: keep-alive\r\n"
25399       // Authenticate as proxyuser:proxypass.
25400       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
25401   mock_reads2.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
25402   // The origin requests client certificates.
25403   SSLSocketDataProvider ssl_origin2(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
25404   ssl_origin2.cert_request_info = cert_request_info_origin;
25405   StaticSocketDataProvider data2(mock_reads2, mock_writes2);
25406   session_deps_.socket_factory->AddSocketDataProvider(&data2);
25407   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy2);
25408   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin2);
25409 
25410   // The client responds to the origin client certificate request on a new
25411   // connection.
25412   SSLSocketDataProvider ssl_proxy3(ASYNC, OK);
25413   ssl_proxy3.expected_send_client_cert = true;
25414   ssl_proxy3.expected_client_cert = identity_proxy->certificate();
25415   std::vector<MockWrite> mock_writes3;
25416   std::vector<MockRead> mock_reads3;
25417   mock_writes3.emplace_back(
25418       "CONNECT www.example.org:443 HTTP/1.1\r\n"
25419       "Host: www.example.org:443\r\n"
25420       "Proxy-Connection: keep-alive\r\n"
25421       // Authenticate as proxyuser:proxypass.
25422       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
25423   mock_reads3.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
25424   SSLSocketDataProvider ssl_origin3(ASYNC, OK);
25425   ssl_origin3.expected_send_client_cert = true;
25426   ssl_origin3.expected_client_cert = identity_origin->certificate();
25427   // The client sends the origin HTTP request, which results in another HTTP
25428   // auth request.
25429   mock_writes3.emplace_back(
25430       "GET / HTTP/1.1\r\n"
25431       "Host: www.example.org\r\n"
25432       "Connection: keep-alive\r\n\r\n");
25433   mock_reads3.emplace_back(
25434       "HTTP/1.1 401 Unauthorized\r\n"
25435       "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
25436       "Content-Length: 0\r\n\r\n");
25437   // The client retries with credentials, and the request finally succeeds.
25438   mock_writes3.emplace_back(
25439       "GET / HTTP/1.1\r\n"
25440       "Host: www.example.org\r\n"
25441       "Connection: keep-alive\r\n"
25442       // Authenticate as user:pass.
25443       "Authorization: Basic dXNlcjpwYXNz\r\n\r\n");
25444   mock_reads3.emplace_back(
25445       "HTTP/1.1 200 OK\r\n"
25446       "Content-Length: 0\r\n\r\n");
25447   // The client makes another request. This should reuse the socket with all
25448   // credentials cached.
25449   mock_writes3.emplace_back(
25450       "GET / HTTP/1.1\r\n"
25451       "Host: www.example.org\r\n"
25452       "Connection: keep-alive\r\n"
25453       // Authenticate as user:pass.
25454       "Authorization: Basic dXNlcjpwYXNz\r\n\r\n");
25455   mock_reads3.emplace_back(
25456       "HTTP/1.1 200 OK\r\n"
25457       "Content-Length: 0\r\n\r\n");
25458   StaticSocketDataProvider data3(mock_reads3, mock_writes3);
25459   session_deps_.socket_factory->AddSocketDataProvider(&data3);
25460   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy3);
25461   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin3);
25462 
25463   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25464 
25465   // Start the request.
25466   TestCompletionCallback callback;
25467   auto trans =
25468       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
25469   int rv = callback.GetResult(
25470       trans->Start(&request, callback.callback(), NetLogWithSource()));
25471 
25472   // Handle the proxy client certificate challenge.
25473   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
25474   SSLCertRequestInfo* cert_request_info =
25475       trans->GetResponseInfo()->cert_request_info.get();
25476   ASSERT_TRUE(cert_request_info);
25477   EXPECT_TRUE(cert_request_info->is_proxy);
25478   EXPECT_EQ(cert_request_info->host_and_port,
25479             cert_request_info_proxy->host_and_port);
25480   rv = callback.GetResult(trans->RestartWithCertificate(
25481       identity_proxy->certificate(), identity_proxy->ssl_private_key(),
25482       callback.callback()));
25483 
25484   // Handle the proxy HTTP auth challenge.
25485   ASSERT_THAT(rv, IsOk());
25486   EXPECT_EQ(407, trans->GetResponseInfo()->headers->response_code());
25487   EXPECT_TRUE(
25488       CheckBasicSecureProxyAuth(trans->GetResponseInfo()->auth_challenge));
25489   rv = callback.GetResult(trans->RestartWithAuth(
25490       AuthCredentials(u"proxyuser", u"proxypass"), callback.callback()));
25491 
25492   // Handle the origin client certificate challenge.
25493   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
25494   cert_request_info = trans->GetResponseInfo()->cert_request_info.get();
25495   ASSERT_TRUE(cert_request_info);
25496   EXPECT_FALSE(cert_request_info->is_proxy);
25497   EXPECT_EQ(cert_request_info->host_and_port,
25498             cert_request_info_origin->host_and_port);
25499   rv = callback.GetResult(trans->RestartWithCertificate(
25500       identity_origin->certificate(), identity_origin->ssl_private_key(),
25501       callback.callback()));
25502 
25503   // Handle the origin HTTP auth challenge.
25504   ASSERT_THAT(rv, IsOk());
25505   EXPECT_EQ(401, trans->GetResponseInfo()->headers->response_code());
25506   EXPECT_TRUE(
25507       CheckBasicSecureServerAuth(trans->GetResponseInfo()->auth_challenge));
25508   rv = callback.GetResult(trans->RestartWithAuth(
25509       AuthCredentials(u"user", u"pass"), callback.callback()));
25510 
25511   // The request completes.
25512   ASSERT_THAT(rv, IsOk());
25513   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
25514 
25515   // Make a second request. This time all credentials are cached.
25516   trans =
25517       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
25518   ASSERT_THAT(callback.GetResult(trans->Start(&request, callback.callback(),
25519                                               NetLogWithSource())),
25520               IsOk());
25521   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
25522 }
25523 
25524 // Test the proxy and origin server each requesting both TLS client certificates
25525 // and HTTP auth and each HTTP auth closing the connection. This is a regression
25526 // test for https://crbug.com/946406.
TEST_P(HttpNetworkTransactionTest,AuthEverythingWithConnectClose)25527 TEST_P(HttpNetworkTransactionTest, AuthEverythingWithConnectClose) {
25528   // Note these hosts must match the CheckBasic*Auth() functions.
25529   session_deps_.proxy_resolution_service =
25530       ConfiguredProxyResolutionService::CreateFixedForTest(
25531           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
25532 
25533   auto cert_request_info_proxy = base::MakeRefCounted<SSLCertRequestInfo>();
25534   cert_request_info_proxy->host_and_port = HostPortPair("myproxy", 70);
25535 
25536   std::unique_ptr<FakeClientCertIdentity> identity_proxy =
25537       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
25538           GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
25539   ASSERT_TRUE(identity_proxy);
25540 
25541   auto cert_request_info_origin = base::MakeRefCounted<SSLCertRequestInfo>();
25542   cert_request_info_origin->host_and_port =
25543       HostPortPair("www.example.org", 443);
25544 
25545   std::unique_ptr<FakeClientCertIdentity> identity_origin =
25546       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
25547           GetTestCertsDirectory(), "client_2.pem", "client_2.pk8");
25548   ASSERT_TRUE(identity_origin);
25549 
25550   HttpRequestInfo request;
25551   request.method = "GET";
25552   request.url = GURL("https://www.example.org/");
25553   request.traffic_annotation =
25554       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
25555 
25556   // First, the client connects to the proxy, which requests a client
25557   // certificate.
25558   SSLSocketDataProvider ssl_proxy1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
25559   ssl_proxy1.cert_request_info = cert_request_info_proxy;
25560   ssl_proxy1.expected_send_client_cert = false;
25561   StaticSocketDataProvider data1;
25562   session_deps_.socket_factory->AddSocketDataProvider(&data1);
25563   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy1);
25564 
25565   // The client responds with a certificate on a new connection. The handshake
25566   // succeeds.
25567   SSLSocketDataProvider ssl_proxy2(ASYNC, OK);
25568   ssl_proxy2.expected_send_client_cert = true;
25569   ssl_proxy2.expected_client_cert = identity_proxy->certificate();
25570   // The client attempts an HTTP CONNECT, but the proxy requests basic auth.
25571   std::vector<MockWrite> mock_writes2;
25572   std::vector<MockRead> mock_reads2;
25573   mock_writes2.emplace_back(
25574       "CONNECT www.example.org:443 HTTP/1.1\r\n"
25575       "Host: www.example.org:443\r\n"
25576       "Proxy-Connection: keep-alive\r\n\r\n");
25577   mock_reads2.emplace_back(
25578       "HTTP/1.1 407 Proxy Authentication Required\r\n"
25579       "Content-Length: 0\r\n"
25580       "Proxy-Connection: close\r\n"
25581       "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n");
25582   StaticSocketDataProvider data2(mock_reads2, mock_writes2);
25583   session_deps_.socket_factory->AddSocketDataProvider(&data2);
25584   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy2);
25585 
25586   // The client retries with credentials on a new connection.
25587   SSLSocketDataProvider ssl_proxy3(ASYNC, OK);
25588   ssl_proxy3.expected_send_client_cert = true;
25589   ssl_proxy3.expected_client_cert = identity_proxy->certificate();
25590   std::vector<MockWrite> mock_writes3;
25591   std::vector<MockRead> mock_reads3;
25592   mock_writes3.emplace_back(
25593       "CONNECT www.example.org:443 HTTP/1.1\r\n"
25594       "Host: www.example.org:443\r\n"
25595       "Proxy-Connection: keep-alive\r\n"
25596       // Authenticate as proxyuser:proxypass.
25597       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
25598   mock_reads3.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
25599   // The origin requests client certificates.
25600   SSLSocketDataProvider ssl_origin3(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
25601   ssl_origin3.cert_request_info = cert_request_info_origin;
25602   StaticSocketDataProvider data3(mock_reads3, mock_writes3);
25603   session_deps_.socket_factory->AddSocketDataProvider(&data3);
25604   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy3);
25605   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin3);
25606 
25607   // The client responds to the origin client certificate request on a new
25608   // connection.
25609   SSLSocketDataProvider ssl_proxy4(ASYNC, OK);
25610   ssl_proxy4.expected_send_client_cert = true;
25611   ssl_proxy4.expected_client_cert = identity_proxy->certificate();
25612   std::vector<MockWrite> mock_writes4;
25613   std::vector<MockRead> mock_reads4;
25614   mock_writes4.emplace_back(
25615       "CONNECT www.example.org:443 HTTP/1.1\r\n"
25616       "Host: www.example.org:443\r\n"
25617       "Proxy-Connection: keep-alive\r\n"
25618       // Authenticate as proxyuser:proxypass.
25619       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
25620   mock_reads4.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
25621   SSLSocketDataProvider ssl_origin4(ASYNC, OK);
25622   ssl_origin4.expected_send_client_cert = true;
25623   ssl_origin4.expected_client_cert = identity_origin->certificate();
25624   // The client sends the origin HTTP request, which results in another HTTP
25625   // auth request and closed connection.
25626   mock_writes4.emplace_back(
25627       "GET / HTTP/1.1\r\n"
25628       "Host: www.example.org\r\n"
25629       "Connection: keep-alive\r\n\r\n");
25630   mock_reads4.emplace_back(
25631       "HTTP/1.1 401 Unauthorized\r\n"
25632       "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
25633       "Connection: close\r\n"
25634       "Content-Length: 0\r\n\r\n");
25635   StaticSocketDataProvider data4(mock_reads4, mock_writes4);
25636   session_deps_.socket_factory->AddSocketDataProvider(&data4);
25637   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy4);
25638   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin4);
25639 
25640   // The client retries with credentials on a new connection, and the request
25641   // finally succeeds.
25642   SSLSocketDataProvider ssl_proxy5(ASYNC, OK);
25643   ssl_proxy5.expected_send_client_cert = true;
25644   ssl_proxy5.expected_client_cert = identity_proxy->certificate();
25645   std::vector<MockWrite> mock_writes5;
25646   std::vector<MockRead> mock_reads5;
25647   mock_writes5.emplace_back(
25648       "CONNECT www.example.org:443 HTTP/1.1\r\n"
25649       "Host: www.example.org:443\r\n"
25650       "Proxy-Connection: keep-alive\r\n"
25651       // Authenticate as proxyuser:proxypass.
25652       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
25653   mock_reads5.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
25654   SSLSocketDataProvider ssl_origin5(ASYNC, OK);
25655   ssl_origin5.expected_send_client_cert = true;
25656   ssl_origin5.expected_client_cert = identity_origin->certificate();
25657   mock_writes5.emplace_back(
25658       "GET / HTTP/1.1\r\n"
25659       "Host: www.example.org\r\n"
25660       "Connection: keep-alive\r\n"
25661       // Authenticate as user:pass.
25662       "Authorization: Basic dXNlcjpwYXNz\r\n\r\n");
25663   mock_reads5.emplace_back(
25664       "HTTP/1.1 200 OK\r\n"
25665       "Connection: close\r\n"
25666       "Content-Length: 0\r\n\r\n");
25667   StaticSocketDataProvider data5(mock_reads5, mock_writes5);
25668   session_deps_.socket_factory->AddSocketDataProvider(&data5);
25669   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy5);
25670   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin5);
25671 
25672   // The client makes a second request. This needs yet another connection, but
25673   // all credentials are cached.
25674   SSLSocketDataProvider ssl_proxy6(ASYNC, OK);
25675   ssl_proxy6.expected_send_client_cert = true;
25676   ssl_proxy6.expected_client_cert = identity_proxy->certificate();
25677   std::vector<MockWrite> mock_writes6;
25678   std::vector<MockRead> mock_reads6;
25679   mock_writes6.emplace_back(
25680       "CONNECT www.example.org:443 HTTP/1.1\r\n"
25681       "Host: www.example.org:443\r\n"
25682       "Proxy-Connection: keep-alive\r\n"
25683       // Authenticate as proxyuser:proxypass.
25684       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
25685   mock_reads6.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
25686   SSLSocketDataProvider ssl_origin6(ASYNC, OK);
25687   ssl_origin6.expected_send_client_cert = true;
25688   ssl_origin6.expected_client_cert = identity_origin->certificate();
25689   mock_writes6.emplace_back(
25690       "GET / HTTP/1.1\r\n"
25691       "Host: www.example.org\r\n"
25692       "Connection: keep-alive\r\n"
25693       // Authenticate as user:pass.
25694       "Authorization: Basic dXNlcjpwYXNz\r\n\r\n");
25695   mock_reads6.emplace_back(
25696       "HTTP/1.1 200 OK\r\n"
25697       "Connection: close\r\n"
25698       "Content-Length: 0\r\n\r\n");
25699   StaticSocketDataProvider data6(mock_reads6, mock_writes6);
25700   session_deps_.socket_factory->AddSocketDataProvider(&data6);
25701   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy6);
25702   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin6);
25703 
25704   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25705 
25706   // Start the request.
25707   TestCompletionCallback callback;
25708   auto trans =
25709       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
25710   int rv = callback.GetResult(
25711       trans->Start(&request, callback.callback(), NetLogWithSource()));
25712 
25713   // Handle the proxy client certificate challenge.
25714   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
25715   SSLCertRequestInfo* cert_request_info =
25716       trans->GetResponseInfo()->cert_request_info.get();
25717   ASSERT_TRUE(cert_request_info);
25718   EXPECT_TRUE(cert_request_info->is_proxy);
25719   EXPECT_EQ(cert_request_info->host_and_port,
25720             cert_request_info_proxy->host_and_port);
25721   rv = callback.GetResult(trans->RestartWithCertificate(
25722       identity_proxy->certificate(), identity_proxy->ssl_private_key(),
25723       callback.callback()));
25724 
25725   // Handle the proxy HTTP auth challenge.
25726   ASSERT_THAT(rv, IsOk());
25727   EXPECT_EQ(407, trans->GetResponseInfo()->headers->response_code());
25728   EXPECT_TRUE(
25729       CheckBasicSecureProxyAuth(trans->GetResponseInfo()->auth_challenge));
25730   rv = callback.GetResult(trans->RestartWithAuth(
25731       AuthCredentials(u"proxyuser", u"proxypass"), callback.callback()));
25732 
25733   // Handle the origin client certificate challenge.
25734   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
25735   cert_request_info = trans->GetResponseInfo()->cert_request_info.get();
25736   ASSERT_TRUE(cert_request_info);
25737   EXPECT_FALSE(cert_request_info->is_proxy);
25738   EXPECT_EQ(cert_request_info->host_and_port,
25739             cert_request_info_origin->host_and_port);
25740   rv = callback.GetResult(trans->RestartWithCertificate(
25741       identity_origin->certificate(), identity_origin->ssl_private_key(),
25742       callback.callback()));
25743 
25744   // Handle the origin HTTP auth challenge.
25745   ASSERT_THAT(rv, IsOk());
25746   EXPECT_EQ(401, trans->GetResponseInfo()->headers->response_code());
25747   EXPECT_TRUE(
25748       CheckBasicSecureServerAuth(trans->GetResponseInfo()->auth_challenge));
25749   rv = callback.GetResult(trans->RestartWithAuth(
25750       AuthCredentials(u"user", u"pass"), callback.callback()));
25751 
25752   // The request completes.
25753   ASSERT_THAT(rv, IsOk());
25754   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
25755 
25756   // Make a second request. This time all credentials are cached.
25757   trans =
25758       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
25759   ASSERT_THAT(callback.GetResult(trans->Start(&request, callback.callback(),
25760                                               NetLogWithSource())),
25761               IsOk());
25762   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
25763 }
25764 
25765 // Test the proxy requesting HTTP auth and the server requesting TLS client
25766 // certificates. This is a regression test for https://crbug.com/946406.
TEST_P(HttpNetworkTransactionTest,ProxyHTTPAndServerTLSAuth)25767 TEST_P(HttpNetworkTransactionTest, ProxyHTTPAndServerTLSAuth) {
25768   // Note these hosts must match the CheckBasic*Auth() functions.
25769   session_deps_.proxy_resolution_service =
25770       ConfiguredProxyResolutionService::CreateFixedForTest(
25771           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
25772 
25773   auto cert_request_info_origin = base::MakeRefCounted<SSLCertRequestInfo>();
25774   cert_request_info_origin->host_and_port =
25775       HostPortPair("www.example.org", 443);
25776 
25777   std::unique_ptr<FakeClientCertIdentity> identity_origin =
25778       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
25779           GetTestCertsDirectory(), "client_2.pem", "client_2.pk8");
25780   ASSERT_TRUE(identity_origin);
25781 
25782   HttpRequestInfo request;
25783   request.method = "GET";
25784   request.url = GURL("https://www.example.org/");
25785   request.traffic_annotation =
25786       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
25787 
25788   // The client connects to the proxy. The handshake succeeds.
25789   SSLSocketDataProvider ssl_proxy1(ASYNC, OK);
25790   // The client attempts an HTTP CONNECT, but the proxy requests basic auth.
25791   std::vector<MockWrite> mock_writes1;
25792   std::vector<MockRead> mock_reads1;
25793   mock_writes1.emplace_back(
25794       "CONNECT www.example.org:443 HTTP/1.1\r\n"
25795       "Host: www.example.org:443\r\n"
25796       "Proxy-Connection: keep-alive\r\n\r\n");
25797   mock_reads1.emplace_back(
25798       "HTTP/1.1 407 Proxy Authentication Required\r\n"
25799       "Content-Length: 0\r\n"
25800       "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n");
25801   // The client retries with credentials, and the request finally succeeds.
25802   mock_writes1.emplace_back(
25803       "CONNECT www.example.org:443 HTTP/1.1\r\n"
25804       "Host: www.example.org:443\r\n"
25805       "Proxy-Connection: keep-alive\r\n"
25806       // Authenticate as proxyuser:proxypass.
25807       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
25808   mock_reads1.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
25809   // The origin requests client certificates.
25810   SSLSocketDataProvider ssl_origin1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
25811   ssl_origin1.cert_request_info = cert_request_info_origin;
25812   StaticSocketDataProvider data1(mock_reads1, mock_writes1);
25813   session_deps_.socket_factory->AddSocketDataProvider(&data1);
25814   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy1);
25815   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin1);
25816 
25817   // The client responds to the origin client certificate request on a new
25818   // connection.
25819   SSLSocketDataProvider ssl_proxy2(ASYNC, OK);
25820   std::vector<MockWrite> mock_writes2;
25821   std::vector<MockRead> mock_reads2;
25822   mock_writes2.emplace_back(
25823       "CONNECT www.example.org:443 HTTP/1.1\r\n"
25824       "Host: www.example.org:443\r\n"
25825       "Proxy-Connection: keep-alive\r\n"
25826       // Authenticate as proxyuser:proxypass.
25827       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
25828   mock_reads2.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
25829   SSLSocketDataProvider ssl_origin2(ASYNC, OK);
25830   ssl_origin2.expected_send_client_cert = true;
25831   ssl_origin2.expected_client_cert = identity_origin->certificate();
25832   // The client sends the origin HTTP request, which succeeds.
25833   mock_writes2.emplace_back(
25834       "GET / HTTP/1.1\r\n"
25835       "Host: www.example.org\r\n"
25836       "Connection: keep-alive\r\n\r\n");
25837   mock_reads2.emplace_back(
25838       "HTTP/1.1 200 OK\r\n"
25839       "Content-Length: 0\r\n\r\n");
25840   StaticSocketDataProvider data2(mock_reads2, mock_writes2);
25841   session_deps_.socket_factory->AddSocketDataProvider(&data2);
25842   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy2);
25843   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin2);
25844 
25845   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25846 
25847   // Start the request.
25848   TestCompletionCallback callback;
25849   auto trans =
25850       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
25851   int rv = callback.GetResult(
25852       trans->Start(&request, callback.callback(), NetLogWithSource()));
25853 
25854   // Handle the proxy HTTP auth challenge.
25855   ASSERT_THAT(rv, IsOk());
25856   EXPECT_EQ(407, trans->GetResponseInfo()->headers->response_code());
25857   EXPECT_TRUE(
25858       CheckBasicSecureProxyAuth(trans->GetResponseInfo()->auth_challenge));
25859   rv = callback.GetResult(trans->RestartWithAuth(
25860       AuthCredentials(u"proxyuser", u"proxypass"), callback.callback()));
25861 
25862   // Handle the origin client certificate challenge.
25863   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
25864   SSLCertRequestInfo* cert_request_info =
25865       trans->GetResponseInfo()->cert_request_info.get();
25866   ASSERT_TRUE(cert_request_info);
25867   EXPECT_FALSE(cert_request_info->is_proxy);
25868   EXPECT_EQ(cert_request_info->host_and_port,
25869             cert_request_info_origin->host_and_port);
25870   rv = callback.GetResult(trans->RestartWithCertificate(
25871       identity_origin->certificate(), identity_origin->ssl_private_key(),
25872       callback.callback()));
25873 
25874   // The request completes.
25875   ASSERT_THAT(rv, IsOk());
25876   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
25877 }
25878 
25879 // Test that socket reuse works with client certificates.
TEST_P(HttpNetworkTransactionTest,ClientCertSocketReuse)25880 TEST_P(HttpNetworkTransactionTest, ClientCertSocketReuse) {
25881   auto cert_request_info = base::MakeRefCounted<SSLCertRequestInfo>();
25882   cert_request_info->host_and_port = HostPortPair("www.example.org", 443);
25883 
25884   std::unique_ptr<FakeClientCertIdentity> identity =
25885       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
25886           GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
25887   ASSERT_TRUE(identity);
25888 
25889   HttpRequestInfo request1;
25890   request1.method = "GET";
25891   request1.url = GURL("https://www.example.org/a");
25892   request1.traffic_annotation =
25893       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
25894 
25895   HttpRequestInfo request2;
25896   request2.method = "GET";
25897   request2.url = GURL("https://www.example.org/b");
25898   request2.traffic_annotation =
25899       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
25900 
25901   // The first connection results in a client certificate request.
25902   StaticSocketDataProvider data1;
25903   session_deps_.socket_factory->AddSocketDataProvider(&data1);
25904   SSLSocketDataProvider ssl1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
25905   ssl1.cert_request_info = cert_request_info;
25906   ssl1.expected_send_client_cert = false;
25907   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
25908 
25909   // The second connection succeeds and is usable for both requests.
25910   MockWrite mock_writes[] = {
25911       MockWrite("GET /a HTTP/1.1\r\n"
25912                 "Host: www.example.org\r\n"
25913                 "Connection: keep-alive\r\n\r\n"),
25914       MockWrite("GET /b HTTP/1.1\r\n"
25915                 "Host: www.example.org\r\n"
25916                 "Connection: keep-alive\r\n\r\n"),
25917   };
25918   MockRead mock_reads[] = {
25919       MockRead("HTTP/1.1 200 OK\r\n"
25920                "Content-Length: 0\r\n\r\n"),
25921       MockRead("HTTP/1.1 200 OK\r\n"
25922                "Content-Length: 0\r\n\r\n"),
25923   };
25924   StaticSocketDataProvider data2(mock_reads, mock_writes);
25925   session_deps_.socket_factory->AddSocketDataProvider(&data2);
25926   SSLSocketDataProvider ssl2(ASYNC, OK);
25927   ssl2.expected_send_client_cert = true;
25928   ssl2.expected_client_cert = identity->certificate();
25929   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
25930 
25931   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25932 
25933   // Start the first request. It succeeds after providing client certificates.
25934   TestCompletionCallback callback;
25935   auto trans =
25936       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
25937   ASSERT_THAT(callback.GetResult(trans->Start(&request1, callback.callback(),
25938                                               NetLogWithSource())),
25939               IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
25940 
25941   SSLCertRequestInfo* info = trans->GetResponseInfo()->cert_request_info.get();
25942   ASSERT_TRUE(info);
25943   EXPECT_FALSE(info->is_proxy);
25944   EXPECT_EQ(info->host_and_port, cert_request_info->host_and_port);
25945 
25946   ASSERT_THAT(callback.GetResult(trans->RestartWithCertificate(
25947                   identity->certificate(), identity->ssl_private_key(),
25948                   callback.callback())),
25949               IsOk());
25950   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
25951 
25952   // Make the second request. It completes without requesting client
25953   // certificates.
25954   trans =
25955       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
25956   ASSERT_THAT(callback.GetResult(trans->Start(&request2, callback.callback(),
25957                                               NetLogWithSource())),
25958               IsOk());
25959   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
25960 }
25961 
25962 // Test for kPartitionConnectionsByNetworkIsolationKey. Runs 3 requests in
25963 // sequence with two different NetworkAnonymizationKeys, the first and last have
25964 // the same key, the second a different one. Checks that the requests are
25965 // partitioned across sockets as expected.
TEST_P(HttpNetworkTransactionTest,NetworkIsolation)25966 TEST_P(HttpNetworkTransactionTest, NetworkIsolation) {
25967   const SchemefulSite kSite1(GURL("http://origin1/"));
25968   const SchemefulSite kSite2(GURL("http://origin2/"));
25969   const auto network_anonymization_key1 =
25970       net::NetworkAnonymizationKey::CreateSameSite(kSite1);
25971   const auto network_anonymization_key2 =
25972       net::NetworkAnonymizationKey::CreateSameSite(kSite2);
25973   NetworkIsolationKey network_isolation_key1(kSite1, kSite1);
25974   NetworkIsolationKey network_isolation_key2(kSite2, kSite2);
25975 
25976   for (bool partition_connections : {false, true}) {
25977     SCOPED_TRACE(partition_connections);
25978 
25979     base::test::ScopedFeatureList feature_list;
25980     if (partition_connections) {
25981       feature_list.InitAndEnableFeature(
25982           features::kPartitionConnectionsByNetworkIsolationKey);
25983     } else {
25984       feature_list.InitAndDisableFeature(
25985           features::kPartitionConnectionsByNetworkIsolationKey);
25986     }
25987 
25988     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25989 
25990     // Reads and writes for the unpartitioned case, where only one socket is
25991     // used.
25992 
25993     const MockWrite kUnpartitionedWrites[] = {
25994         MockWrite("GET /1 HTTP/1.1\r\n"
25995                   "Host: foo.test\r\n"
25996                   "Connection: keep-alive\r\n\r\n"),
25997         MockWrite("GET /2 HTTP/1.1\r\n"
25998                   "Host: foo.test\r\n"
25999                   "Connection: keep-alive\r\n\r\n"),
26000         MockWrite("GET /3 HTTP/1.1\r\n"
26001                   "Host: foo.test\r\n"
26002                   "Connection: keep-alive\r\n\r\n"),
26003     };
26004 
26005     const MockRead kUnpartitionedReads[] = {
26006         MockRead("HTTP/1.1 200 OK\r\n"
26007                  "Connection: keep-alive\r\n"
26008                  "Content-Length: 1\r\n\r\n"
26009                  "1"),
26010         MockRead("HTTP/1.1 200 OK\r\n"
26011                  "Connection: keep-alive\r\n"
26012                  "Content-Length: 1\r\n\r\n"
26013                  "2"),
26014         MockRead("HTTP/1.1 200 OK\r\n"
26015                  "Connection: keep-alive\r\n"
26016                  "Content-Length: 1\r\n\r\n"
26017                  "3"),
26018     };
26019 
26020     StaticSocketDataProvider unpartitioned_data(kUnpartitionedReads,
26021                                                 kUnpartitionedWrites);
26022 
26023     // Reads and writes for the partitioned case, where two sockets are used.
26024 
26025     const MockWrite kPartitionedWrites1[] = {
26026         MockWrite("GET /1 HTTP/1.1\r\n"
26027                   "Host: foo.test\r\n"
26028                   "Connection: keep-alive\r\n\r\n"),
26029         MockWrite("GET /3 HTTP/1.1\r\n"
26030                   "Host: foo.test\r\n"
26031                   "Connection: keep-alive\r\n\r\n"),
26032     };
26033 
26034     const MockRead kPartitionedReads1[] = {
26035         MockRead("HTTP/1.1 200 OK\r\n"
26036                  "Connection: keep-alive\r\n"
26037                  "Content-Length: 1\r\n\r\n"
26038                  "1"),
26039         MockRead("HTTP/1.1 200 OK\r\n"
26040                  "Connection: keep-alive\r\n"
26041                  "Content-Length: 1\r\n\r\n"
26042                  "3"),
26043     };
26044 
26045     const MockWrite kPartitionedWrites2[] = {
26046         MockWrite("GET /2 HTTP/1.1\r\n"
26047                   "Host: foo.test\r\n"
26048                   "Connection: keep-alive\r\n\r\n"),
26049     };
26050 
26051     const MockRead kPartitionedReads2[] = {
26052         MockRead("HTTP/1.1 200 OK\r\n"
26053                  "Connection: keep-alive\r\n"
26054                  "Content-Length: 1\r\n\r\n"
26055                  "2"),
26056     };
26057 
26058     StaticSocketDataProvider partitioned_data1(kPartitionedReads1,
26059                                                kPartitionedWrites1);
26060     StaticSocketDataProvider partitioned_data2(kPartitionedReads2,
26061                                                kPartitionedWrites2);
26062 
26063     if (partition_connections) {
26064       session_deps_.socket_factory->AddSocketDataProvider(&partitioned_data1);
26065       session_deps_.socket_factory->AddSocketDataProvider(&partitioned_data2);
26066     } else {
26067       session_deps_.socket_factory->AddSocketDataProvider(&unpartitioned_data);
26068     }
26069 
26070     TestCompletionCallback callback;
26071     HttpRequestInfo request1;
26072     request1.method = "GET";
26073     request1.url = GURL("http://foo.test/1");
26074     request1.traffic_annotation =
26075         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26076     request1.network_isolation_key = network_isolation_key1;
26077     request1.network_anonymization_key = network_anonymization_key1;
26078     auto trans1 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
26079                                                            session.get());
26080     int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
26081     EXPECT_THAT(callback.GetResult(rv), IsOk());
26082     std::string response_data1;
26083     EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
26084     EXPECT_EQ("1", response_data1);
26085     trans1.reset();
26086 
26087     HttpRequestInfo request2;
26088     request2.method = "GET";
26089     request2.url = GURL("http://foo.test/2");
26090     request2.traffic_annotation =
26091         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26092     request2.network_isolation_key = network_isolation_key2;
26093     request2.network_anonymization_key = network_anonymization_key2;
26094     auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
26095                                                            session.get());
26096     rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
26097     EXPECT_THAT(callback.GetResult(rv), IsOk());
26098     std::string response_data2;
26099     EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
26100     EXPECT_EQ("2", response_data2);
26101     trans2.reset();
26102 
26103     HttpRequestInfo request3;
26104     request3.method = "GET";
26105     request3.url = GURL("http://foo.test/3");
26106     request3.traffic_annotation =
26107         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26108     request3.network_isolation_key = network_isolation_key1;
26109     request3.network_anonymization_key = network_anonymization_key1;
26110     auto trans3 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
26111                                                            session.get());
26112     rv = trans3->Start(&request3, callback.callback(), NetLogWithSource());
26113     EXPECT_THAT(callback.GetResult(rv), IsOk());
26114     std::string response_data3;
26115     EXPECT_THAT(ReadTransaction(trans3.get(), &response_data3), IsOk());
26116     EXPECT_EQ("3", response_data3);
26117     trans3.reset();
26118   }
26119 }
26120 
TEST_P(HttpNetworkTransactionTest,NetworkIsolationH2)26121 TEST_P(HttpNetworkTransactionTest, NetworkIsolationH2) {
26122   const SchemefulSite kSite1(GURL("http://origin1/"));
26123   const SchemefulSite kSite2(GURL("http://origin2/"));
26124   const auto network_anonymization_key1 =
26125       net::NetworkAnonymizationKey::CreateSameSite(kSite1);
26126   const auto network_anonymization_key2 =
26127       net::NetworkAnonymizationKey::CreateSameSite(kSite2);
26128   NetworkIsolationKey network_isolation_key1(kSite1, kSite1);
26129   NetworkIsolationKey network_isolation_key2(kSite2, kSite2);
26130 
26131   // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
26132   // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
26133   // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
26134   // the same way as the HTTP over H2 proxy case.
26135   for (bool use_proxy : {false, true}) {
26136     SCOPED_TRACE(use_proxy);
26137     if (use_proxy) {
26138       session_deps_.proxy_resolution_service =
26139           ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
26140               "HTTPS proxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
26141     } else {
26142       session_deps_.proxy_resolution_service =
26143           ConfiguredProxyResolutionService::CreateDirect();
26144     }
26145     const char* url1 = nullptr;
26146     const char* url2 = nullptr;
26147     const char* url3 = nullptr;
26148     if (use_proxy) {
26149       url1 = "http://foo.test/1";
26150       url2 = "http://foo.test/2";
26151       url3 = "http://foo.test/3";
26152     } else {
26153       url1 = "https://foo.test/1";
26154       url2 = "https://foo.test/2";
26155       url3 = "https://foo.test/3";
26156     }
26157 
26158     for (bool partition_connections : {false, true}) {
26159       SCOPED_TRACE(partition_connections);
26160 
26161       base::test::ScopedFeatureList feature_list;
26162       if (partition_connections) {
26163         feature_list.InitAndEnableFeature(
26164             features::kPartitionConnectionsByNetworkIsolationKey);
26165       } else {
26166         feature_list.InitAndDisableFeature(
26167             features::kPartitionConnectionsByNetworkIsolationKey);
26168       }
26169 
26170       std::unique_ptr<HttpNetworkSession> session(
26171           CreateSession(&session_deps_));
26172 
26173       // Reads and writes for the unpartitioned case, where only one socket is
26174       // used.
26175 
26176       SpdyTestUtil spdy_util(/*use_priority_header=*/true);
26177       spdy::SpdySerializedFrame unpartitioned_req1(
26178           spdy_util.ConstructSpdyGet(url1, 1, LOWEST));
26179       spdy::SpdySerializedFrame unpartitioned_response1(
26180           spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
26181       spdy::SpdySerializedFrame unpartitioned_body1(
26182           spdy_util.ConstructSpdyDataFrame(1, "1", true));
26183       spdy_util.UpdateWithStreamDestruction(1);
26184 
26185       spdy::SpdySerializedFrame unpartitioned_req2(
26186           spdy_util.ConstructSpdyGet(url2, 3, LOWEST));
26187       spdy::SpdySerializedFrame unpartitioned_response2(
26188           spdy_util.ConstructSpdyGetReply(nullptr, 0, 3));
26189       spdy::SpdySerializedFrame unpartitioned_body2(
26190           spdy_util.ConstructSpdyDataFrame(3, "2", true));
26191       spdy_util.UpdateWithStreamDestruction(3);
26192 
26193       spdy::SpdySerializedFrame unpartitioned_req3(
26194           spdy_util.ConstructSpdyGet(url3, 5, LOWEST));
26195       spdy::SpdySerializedFrame unpartitioned_response3(
26196           spdy_util.ConstructSpdyGetReply(nullptr, 0, 5));
26197       spdy::SpdySerializedFrame unpartitioned_body3(
26198           spdy_util.ConstructSpdyDataFrame(5, "3", true));
26199 
26200       const MockWrite kUnpartitionedWrites[] = {
26201           CreateMockWrite(unpartitioned_req1, 0),
26202           CreateMockWrite(unpartitioned_req2, 3),
26203           CreateMockWrite(unpartitioned_req3, 6),
26204       };
26205 
26206       const MockRead kUnpartitionedReads[] = {
26207           CreateMockRead(unpartitioned_response1, 1),
26208           CreateMockRead(unpartitioned_body1, 2),
26209           CreateMockRead(unpartitioned_response2, 4),
26210           CreateMockRead(unpartitioned_body2, 5),
26211           CreateMockRead(unpartitioned_response3, 7),
26212           CreateMockRead(unpartitioned_body3, 8),
26213           MockRead(SYNCHRONOUS, ERR_IO_PENDING, 9),
26214       };
26215 
26216       SequencedSocketData unpartitioned_data(kUnpartitionedReads,
26217                                              kUnpartitionedWrites);
26218 
26219       // Reads and writes for the partitioned case, where two sockets are used.
26220 
26221       SpdyTestUtil spdy_util2(/*use_priority_header=*/true);
26222       spdy::SpdySerializedFrame partitioned_req1(
26223           spdy_util2.ConstructSpdyGet(url1, 1, LOWEST));
26224       spdy::SpdySerializedFrame partitioned_response1(
26225           spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
26226       spdy::SpdySerializedFrame partitioned_body1(
26227           spdy_util2.ConstructSpdyDataFrame(1, "1", true));
26228       spdy_util2.UpdateWithStreamDestruction(1);
26229 
26230       spdy::SpdySerializedFrame partitioned_req3(
26231           spdy_util2.ConstructSpdyGet(url3, 3, LOWEST));
26232       spdy::SpdySerializedFrame partitioned_response3(
26233           spdy_util2.ConstructSpdyGetReply(nullptr, 0, 3));
26234       spdy::SpdySerializedFrame partitioned_body3(
26235           spdy_util2.ConstructSpdyDataFrame(3, "3", true));
26236 
26237       const MockWrite kPartitionedWrites1[] = {
26238           CreateMockWrite(partitioned_req1, 0),
26239           CreateMockWrite(partitioned_req3, 3),
26240       };
26241 
26242       const MockRead kPartitionedReads1[] = {
26243           CreateMockRead(partitioned_response1, 1),
26244           CreateMockRead(partitioned_body1, 2),
26245           CreateMockRead(partitioned_response3, 4),
26246           CreateMockRead(partitioned_body3, 5),
26247           MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),
26248       };
26249 
26250       SpdyTestUtil spdy_util3(/*use_priority_header=*/true);
26251       spdy::SpdySerializedFrame partitioned_req2(
26252           spdy_util3.ConstructSpdyGet(url2, 1, LOWEST));
26253       spdy::SpdySerializedFrame partitioned_response2(
26254           spdy_util3.ConstructSpdyGetReply(nullptr, 0, 1));
26255       spdy::SpdySerializedFrame partitioned_body2(
26256           spdy_util3.ConstructSpdyDataFrame(1, "2", true));
26257 
26258       const MockWrite kPartitionedWrites2[] = {
26259           CreateMockWrite(partitioned_req2, 0),
26260       };
26261 
26262       const MockRead kPartitionedReads2[] = {
26263           CreateMockRead(partitioned_response2, 1),
26264           CreateMockRead(partitioned_body2, 2),
26265           MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
26266       };
26267 
26268       SequencedSocketData partitioned_data1(kPartitionedReads1,
26269                                             kPartitionedWrites1);
26270       SequencedSocketData partitioned_data2(kPartitionedReads2,
26271                                             kPartitionedWrites2);
26272 
26273       // No need to segment SSLDataProviders by whether or not partitioning is
26274       // enabled.
26275       SSLSocketDataProvider ssl_data1(ASYNC, OK);
26276       ssl_data1.next_proto = kProtoHTTP2;
26277       SSLSocketDataProvider ssl_data2(ASYNC, OK);
26278       ssl_data2.next_proto = kProtoHTTP2;
26279 
26280       if (partition_connections) {
26281         session_deps_.socket_factory->AddSocketDataProvider(&partitioned_data1);
26282         session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
26283         session_deps_.socket_factory->AddSocketDataProvider(&partitioned_data2);
26284         session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
26285       } else {
26286         session_deps_.socket_factory->AddSocketDataProvider(
26287             &unpartitioned_data);
26288         session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
26289       }
26290 
26291       TestCompletionCallback callback;
26292       HttpRequestInfo request1;
26293       request1.method = "GET";
26294       request1.url = GURL(url1);
26295       request1.traffic_annotation =
26296           net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26297       request1.network_isolation_key = network_isolation_key1;
26298       request1.network_anonymization_key = network_anonymization_key1;
26299 
26300       auto trans1 =
26301           std::make_unique<HttpNetworkTransaction>(LOWEST, session.get());
26302       int rv =
26303           trans1->Start(&request1, callback.callback(), NetLogWithSource());
26304       EXPECT_THAT(callback.GetResult(rv), IsOk());
26305       std::string response_data1;
26306       EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
26307       EXPECT_EQ("1", response_data1);
26308       trans1.reset();
26309 
26310       HttpRequestInfo request2;
26311       request2.method = "GET";
26312       request2.url = GURL(url2);
26313       request2.traffic_annotation =
26314           net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26315       request2.network_isolation_key = network_isolation_key2;
26316       request2.network_anonymization_key = network_anonymization_key2;
26317       auto trans2 =
26318           std::make_unique<HttpNetworkTransaction>(LOWEST, session.get());
26319       rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
26320       EXPECT_THAT(callback.GetResult(rv), IsOk());
26321       std::string response_data2;
26322       EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
26323       EXPECT_EQ("2", response_data2);
26324       trans2.reset();
26325 
26326       HttpRequestInfo request3;
26327       request3.method = "GET";
26328       request3.url = GURL(url3);
26329       request3.traffic_annotation =
26330           net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26331       request3.network_isolation_key = network_isolation_key1;
26332       request3.network_anonymization_key = network_anonymization_key1;
26333 
26334       auto trans3 =
26335           std::make_unique<HttpNetworkTransaction>(LOWEST, session.get());
26336       rv = trans3->Start(&request3, callback.callback(), NetLogWithSource());
26337       EXPECT_THAT(callback.GetResult(rv), IsOk());
26338       std::string response_data3;
26339       EXPECT_THAT(ReadTransaction(trans3.get(), &response_data3), IsOk());
26340       EXPECT_EQ("3", response_data3);
26341       trans3.reset();
26342     }
26343   }
26344 }
26345 
26346 // Preconnect two sockets with different NetworkAnonymizationKeys when
26347 // features::kPartitionConnectionsByNetworkIsolationKey is enabled. Then
26348 // issue a request and make sure the correct socket is used. Loops three times,
26349 // expecting to use the first preconnect, second preconnect, and neither.
TEST_P(HttpNetworkTransactionTest,NetworkIsolationPreconnect)26350 TEST_P(HttpNetworkTransactionTest, NetworkIsolationPreconnect) {
26351   base::test::ScopedFeatureList feature_list;
26352   feature_list.InitAndEnableFeature(
26353       features::kPartitionConnectionsByNetworkIsolationKey);
26354 
26355   enum class TestCase {
26356     kUseFirstPreconnect,
26357     kUseSecondPreconnect,
26358     kDontUsePreconnect,
26359   };
26360 
26361   const SchemefulSite kSite1(GURL("http://origin1/"));
26362   const SchemefulSite kSite2(GURL("http://origin2/"));
26363   const SchemefulSite kSite3(GURL("http://origin3/"));
26364   auto preconnect1_anonymization_key =
26365       NetworkAnonymizationKey::CreateSameSite(kSite1);
26366   auto preconnect2_anonymization_key =
26367       NetworkAnonymizationKey::CreateSameSite(kSite2);
26368   auto not_preconnected_anonymization_key =
26369       NetworkAnonymizationKey::CreateSameSite(kSite3);
26370   NetworkIsolationKey preconnect1_isolation_key(kSite1, kSite1);
26371   NetworkIsolationKey preconnect2_isolation_key(kSite2, kSite2);
26372   NetworkIsolationKey not_preconnected_isolation_key(kSite3, kSite3);
26373   // Test that only preconnects with
26374   for (TestCase test_case :
26375        {TestCase::kUseFirstPreconnect, TestCase::kUseSecondPreconnect,
26376         TestCase::kDontUsePreconnect}) {
26377     SpdySessionDependencies session_deps;
26378     // Make DNS lookups completely synchronously, so preconnects complete
26379     // immediately.
26380     session_deps.host_resolver->set_synchronous_mode(true);
26381 
26382     const MockWrite kMockWrites[] = {
26383         MockWrite(ASYNC, 0,
26384                   "GET / HTTP/1.1\r\n"
26385                   "Host: www.foo.com\r\n"
26386                   "Connection: keep-alive\r\n\r\n"),
26387     };
26388 
26389     const MockRead kMockReads[] = {
26390         MockRead(ASYNC, 1,
26391                  "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"
26392                  "hello"),
26393     };
26394 
26395     // Used for the socket that will actually be used, which may or may not be
26396     // one of the preconnects
26397     SequencedSocketData used_socket_data(MockConnect(SYNCHRONOUS, OK),
26398                                          kMockReads, kMockWrites);
26399 
26400     // Used for the preconnects that won't actually be used.
26401     SequencedSocketData preconnect1_data(MockConnect(SYNCHRONOUS, OK),
26402                                          base::span<const MockRead>(),
26403                                          base::span<const MockWrite>());
26404     SequencedSocketData preconnect2_data(MockConnect(SYNCHRONOUS, OK),
26405                                          base::span<const MockRead>(),
26406                                          base::span<const MockWrite>());
26407 
26408     NetworkAnonymizationKey network_anonymization_key_for_request;
26409     NetworkIsolationKey network_isolation_key_for_request;
26410 
26411     switch (test_case) {
26412       case TestCase::kUseFirstPreconnect:
26413         session_deps.socket_factory->AddSocketDataProvider(&used_socket_data);
26414         session_deps.socket_factory->AddSocketDataProvider(&preconnect2_data);
26415         network_isolation_key_for_request = preconnect1_isolation_key;
26416         network_anonymization_key_for_request = preconnect1_anonymization_key;
26417         break;
26418       case TestCase::kUseSecondPreconnect:
26419         session_deps.socket_factory->AddSocketDataProvider(&preconnect1_data);
26420         session_deps.socket_factory->AddSocketDataProvider(&used_socket_data);
26421         network_isolation_key_for_request = preconnect2_isolation_key;
26422         network_anonymization_key_for_request = preconnect2_anonymization_key;
26423         break;
26424       case TestCase::kDontUsePreconnect:
26425         session_deps.socket_factory->AddSocketDataProvider(&preconnect1_data);
26426         session_deps.socket_factory->AddSocketDataProvider(&preconnect2_data);
26427         session_deps.socket_factory->AddSocketDataProvider(&used_socket_data);
26428         network_isolation_key_for_request = not_preconnected_isolation_key;
26429         network_anonymization_key_for_request =
26430             not_preconnected_anonymization_key;
26431         break;
26432     }
26433 
26434     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps));
26435 
26436     // Preconnect sockets.
26437     HttpRequestInfo request;
26438     request.method = "GET";
26439     request.url = GURL("http://www.foo.com/");
26440     request.traffic_annotation =
26441         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26442 
26443     request.network_isolation_key = preconnect1_isolation_key;
26444     request.network_anonymization_key = preconnect1_anonymization_key;
26445     session->http_stream_factory()->PreconnectStreams(1, request);
26446 
26447     request.network_isolation_key = preconnect2_isolation_key;
26448     request.network_anonymization_key = preconnect2_anonymization_key;
26449     session->http_stream_factory()->PreconnectStreams(1, request);
26450 
26451     request.network_isolation_key = network_isolation_key_for_request;
26452     request.network_anonymization_key = network_anonymization_key_for_request;
26453 
26454     EXPECT_EQ(2, GetIdleSocketCountInTransportSocketPool(session.get()));
26455 
26456     // Make the request.
26457     TestCompletionCallback callback;
26458 
26459     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
26460 
26461     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
26462     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
26463 
26464     rv = callback.WaitForResult();
26465     EXPECT_THAT(rv, IsOk());
26466 
26467     const HttpResponseInfo* response = trans.GetResponseInfo();
26468     ASSERT_TRUE(response);
26469     ASSERT_TRUE(response->headers);
26470     EXPECT_EQ(200, response->headers->response_code());
26471 
26472     std::string response_data;
26473     rv = ReadTransaction(&trans, &response_data);
26474     EXPECT_THAT(rv, IsOk());
26475     EXPECT_EQ("hello", response_data);
26476 
26477     if (test_case != TestCase::kDontUsePreconnect) {
26478       EXPECT_EQ(2, GetIdleSocketCountInTransportSocketPool(session.get()));
26479     } else {
26480       EXPECT_EQ(3, GetIdleSocketCountInTransportSocketPool(session.get()));
26481     }
26482   }
26483 }
26484 
26485 // Test that the NetworkAnonymizationKey is passed down to SSLConfig so the
26486 // session cache is isolated.
TEST_P(HttpNetworkTransactionTest,NetworkIsolationSSL)26487 TEST_P(HttpNetworkTransactionTest, NetworkIsolationSSL) {
26488   base::test::ScopedFeatureList feature_list;
26489   feature_list.InitWithFeatures(
26490       {features::kPartitionConnectionsByNetworkIsolationKey,
26491        features::kPartitionSSLSessionsByNetworkIsolationKey},
26492       {});
26493 
26494   const SchemefulSite kSite1(GURL("http://origin1/"));
26495   const SchemefulSite kSite2(GURL("http://origin2/"));
26496   const auto kNetworkAnonymizationKey1 =
26497       NetworkAnonymizationKey::CreateSameSite(kSite1);
26498   const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
26499   const auto kNetworkAnonymizationKey2 =
26500       NetworkAnonymizationKey::CreateSameSite(kSite2);
26501   const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
26502   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
26503 
26504   // The server always sends Connection: close, so each request goes over a
26505   // distinct socket.
26506 
26507   const MockWrite kWrites1[] = {
26508       MockWrite("GET /1 HTTP/1.1\r\n"
26509                 "Host: foo.test\r\n"
26510                 "Connection: keep-alive\r\n\r\n")};
26511 
26512   const MockRead kReads1[] = {
26513       MockRead("HTTP/1.1 200 OK\r\n"
26514                "Connection: close\r\n"
26515                "Content-Length: 1\r\n\r\n"
26516                "1")};
26517 
26518   const MockWrite kWrites2[] = {
26519       MockWrite("GET /2 HTTP/1.1\r\n"
26520                 "Host: foo.test\r\n"
26521                 "Connection: keep-alive\r\n\r\n")};
26522 
26523   const MockRead kReads2[] = {
26524       MockRead("HTTP/1.1 200 OK\r\n"
26525                "Connection: close\r\n"
26526                "Content-Length: 1\r\n\r\n"
26527                "2")};
26528 
26529   const MockWrite kWrites3[] = {
26530       MockWrite("GET /3 HTTP/1.1\r\n"
26531                 "Host: foo.test\r\n"
26532                 "Connection: keep-alive\r\n\r\n")};
26533 
26534   const MockRead kReads3[] = {
26535       MockRead("HTTP/1.1 200 OK\r\n"
26536                "Connection: close\r\n"
26537                "Content-Length: 1\r\n\r\n"
26538                "3")};
26539 
26540   StaticSocketDataProvider data1(kReads1, kWrites1);
26541   StaticSocketDataProvider data2(kReads2, kWrites2);
26542   StaticSocketDataProvider data3(kReads3, kWrites3);
26543   session_deps_.socket_factory->AddSocketDataProvider(&data1);
26544   session_deps_.socket_factory->AddSocketDataProvider(&data2);
26545   session_deps_.socket_factory->AddSocketDataProvider(&data3);
26546 
26547   SSLSocketDataProvider ssl_data1(ASYNC, OK);
26548   ssl_data1.expected_host_and_port = HostPortPair("foo.test", 443);
26549   ssl_data1.expected_network_anonymization_key = kNetworkAnonymizationKey1;
26550   SSLSocketDataProvider ssl_data2(ASYNC, OK);
26551   ssl_data2.expected_host_and_port = HostPortPair("foo.test", 443);
26552   ssl_data2.expected_network_anonymization_key = kNetworkAnonymizationKey2;
26553   SSLSocketDataProvider ssl_data3(ASYNC, OK);
26554   ssl_data3.expected_host_and_port = HostPortPair("foo.test", 443);
26555   ssl_data3.expected_network_anonymization_key = kNetworkAnonymizationKey1;
26556   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
26557   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
26558   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
26559 
26560   TestCompletionCallback callback;
26561   HttpRequestInfo request1;
26562   request1.method = "GET";
26563   request1.url = GURL("https://foo.test/1");
26564   request1.traffic_annotation =
26565       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26566   request1.network_isolation_key = kNetworkIsolationKey1;
26567   request1.network_anonymization_key = kNetworkAnonymizationKey1;
26568 
26569   auto trans1 =
26570       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
26571   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
26572   EXPECT_THAT(callback.GetResult(rv), IsOk());
26573   std::string response_data1;
26574   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
26575   EXPECT_EQ("1", response_data1);
26576   trans1.reset();
26577 
26578   HttpRequestInfo request2;
26579   request2.method = "GET";
26580   request2.url = GURL("https://foo.test/2");
26581   request2.traffic_annotation =
26582       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26583   request2.network_isolation_key = kNetworkIsolationKey2;
26584   request2.network_anonymization_key = kNetworkAnonymizationKey2;
26585   auto trans2 =
26586       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
26587   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
26588   EXPECT_THAT(callback.GetResult(rv), IsOk());
26589   std::string response_data2;
26590   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
26591   EXPECT_EQ("2", response_data2);
26592   trans2.reset();
26593 
26594   HttpRequestInfo request3;
26595   request3.method = "GET";
26596   request3.url = GURL("https://foo.test/3");
26597   request3.traffic_annotation =
26598       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26599   request3.network_isolation_key = kNetworkIsolationKey1;
26600   request3.network_anonymization_key = kNetworkAnonymizationKey1;
26601   auto trans3 =
26602       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
26603   rv = trans3->Start(&request3, callback.callback(), NetLogWithSource());
26604   EXPECT_THAT(callback.GetResult(rv), IsOk());
26605   std::string response_data3;
26606   EXPECT_THAT(ReadTransaction(trans3.get(), &response_data3), IsOk());
26607   EXPECT_EQ("3", response_data3);
26608   trans3.reset();
26609 }
26610 
26611 // Test that the NetworkAnonymizationKey is passed down to SSLConfig so the
26612 // session cache is isolated, for both origins and proxies.
TEST_P(HttpNetworkTransactionTest,NetworkIsolationSSLProxy)26613 TEST_P(HttpNetworkTransactionTest, NetworkIsolationSSLProxy) {
26614   base::test::ScopedFeatureList feature_list;
26615   feature_list.InitWithFeatures(
26616       {features::kPartitionConnectionsByNetworkIsolationKey,
26617        features::kPartitionSSLSessionsByNetworkIsolationKey},
26618       {});
26619 
26620   session_deps_.proxy_resolution_service =
26621       ConfiguredProxyResolutionService::CreateFixedForTest(
26622           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
26623 
26624   const SchemefulSite kSite1(GURL("http://origin1/"));
26625   const SchemefulSite kSite2(GURL("http://origin2/"));
26626   const auto kNetworkAnonymizationKey1 =
26627       NetworkAnonymizationKey::CreateSameSite(kSite1);
26628   const auto kNetworkAnonymizationKey2 =
26629       NetworkAnonymizationKey::CreateSameSite(kSite2);
26630   const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
26631   const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
26632   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
26633 
26634   // Make both a tunneled and non-tunneled request.
26635   HttpRequestInfo request1;
26636   request1.method = "GET";
26637   request1.url = GURL("https://foo.test/1");
26638   request1.traffic_annotation =
26639       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26640   request1.network_isolation_key = kNetworkIsolationKey1;
26641   request1.network_anonymization_key = kNetworkAnonymizationKey1;
26642 
26643   HttpRequestInfo request2;
26644   request2.method = "GET";
26645   request2.url = GURL("http://foo.test/2");
26646   request2.traffic_annotation =
26647       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26648   request2.network_isolation_key = kNetworkIsolationKey2;
26649   request2.network_anonymization_key = kNetworkAnonymizationKey2;
26650 
26651   const MockWrite kWrites1[] = {
26652       MockWrite("CONNECT foo.test:443 HTTP/1.1\r\n"
26653                 "Host: foo.test:443\r\n"
26654                 "Proxy-Connection: keep-alive\r\n\r\n"),
26655       MockWrite("GET /1 HTTP/1.1\r\n"
26656                 "Host: foo.test\r\n"
26657                 "Connection: keep-alive\r\n\r\n")};
26658 
26659   const MockRead kReads1[] = {
26660       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
26661       MockRead("HTTP/1.1 200 OK\r\n"
26662                "Connection: close\r\n"
26663                "Content-Length: 1\r\n\r\n"
26664                "1")};
26665 
26666   const MockWrite kWrites2[] = {
26667       MockWrite("GET http://foo.test/2 HTTP/1.1\r\n"
26668                 "Host: foo.test\r\n"
26669                 "Proxy-Connection: keep-alive\r\n\r\n")};
26670 
26671   const MockRead kReads2[] = {
26672       MockRead("HTTP/1.1 200 OK\r\n"
26673                "Connection: close\r\n"
26674                "Content-Length: 1\r\n\r\n"
26675                "2")};
26676 
26677   StaticSocketDataProvider data1(kReads1, kWrites1);
26678   StaticSocketDataProvider data2(kReads2, kWrites2);
26679   session_deps_.socket_factory->AddSocketDataProvider(&data1);
26680   session_deps_.socket_factory->AddSocketDataProvider(&data2);
26681   session_deps_.socket_factory->AddSocketDataProvider(&data2);
26682 
26683   SSLSocketDataProvider ssl_proxy1(ASYNC, OK);
26684   ssl_proxy1.expected_host_and_port = HostPortPair("myproxy", 70);
26685   ssl_proxy1.expected_network_anonymization_key = kNetworkAnonymizationKey1;
26686   SSLSocketDataProvider ssl_origin1(ASYNC, OK);
26687   ssl_origin1.expected_host_and_port = HostPortPair("foo.test", 443);
26688   ssl_origin1.expected_network_anonymization_key = kNetworkAnonymizationKey1;
26689   SSLSocketDataProvider ssl_proxy2(ASYNC, OK);
26690   ssl_proxy2.expected_host_and_port = HostPortPair("myproxy", 70);
26691   ssl_proxy2.expected_network_anonymization_key = kNetworkAnonymizationKey2;
26692   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy1);
26693   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin1);
26694   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy2);
26695 
26696   TestCompletionCallback callback;
26697   auto trans1 =
26698       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
26699   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
26700   EXPECT_THAT(callback.GetResult(rv), IsOk());
26701   std::string response_data1;
26702   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
26703   EXPECT_EQ("1", response_data1);
26704   trans1.reset();
26705 
26706   auto trans2 =
26707       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
26708   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
26709   EXPECT_THAT(callback.GetResult(rv), IsOk());
26710   std::string response_data2;
26711   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
26712   EXPECT_EQ("2", response_data2);
26713   trans2.reset();
26714 }
26715 
26716 // Test that SSLConfig changes from SSLConfigService are picked up even when
26717 // there are live sockets.
TEST_P(HttpNetworkTransactionTest,SSLConfigChanged)26718 TEST_P(HttpNetworkTransactionTest, SSLConfigChanged) {
26719   SSLContextConfig ssl_context_config;
26720   ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
26721   auto ssl_config_service =
26722       std::make_unique<TestSSLConfigService>(ssl_context_config);
26723   TestSSLConfigService* ssl_config_service_raw = ssl_config_service.get();
26724 
26725   session_deps_.ssl_config_service = std::move(ssl_config_service);
26726 
26727   // Make three requests. Between the second and third, the SSL config will
26728   // change.
26729   HttpRequestInfo request1;
26730   request1.method = "GET";
26731   request1.url = GURL("https://foo.test/1");
26732   request1.traffic_annotation =
26733       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26734 
26735   HttpRequestInfo request2;
26736   request2.method = "GET";
26737   request2.url = GURL("https://foo.test/2");
26738   request2.traffic_annotation =
26739       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26740 
26741   HttpRequestInfo request3;
26742   request3.method = "GET";
26743   request3.url = GURL("https://foo.test/3");
26744   request3.traffic_annotation =
26745       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26746 
26747   const MockWrite kWrites1[] = {
26748       MockWrite("GET /1 HTTP/1.1\r\n"
26749                 "Host: foo.test\r\n"
26750                 "Connection: keep-alive\r\n\r\n"),
26751       MockWrite("GET /2 HTTP/1.1\r\n"
26752                 "Host: foo.test\r\n"
26753                 "Connection: keep-alive\r\n\r\n"),
26754   };
26755 
26756   const MockRead kReads1[] = {
26757       MockRead("HTTP/1.1 200 OK\r\n"
26758                "Connection: keep-alive\r\n"
26759                "Content-Length: 1\r\n\r\n"
26760                "1"),
26761       MockRead("HTTP/1.1 200 OK\r\n"
26762                "Connection: keep-alive\r\n"
26763                "Content-Length: 1\r\n\r\n"
26764                "2"),
26765   };
26766 
26767   // The third request goes on a different socket because the SSL config has
26768   // changed.
26769   const MockWrite kWrites2[] = {
26770       MockWrite("GET /3 HTTP/1.1\r\n"
26771                 "Host: foo.test\r\n"
26772                 "Connection: keep-alive\r\n\r\n")};
26773 
26774   const MockRead kReads2[] = {
26775       MockRead("HTTP/1.1 200 OK\r\n"
26776                "Connection: keep-alive\r\n"
26777                "Content-Length: 1\r\n\r\n"
26778                "3")};
26779 
26780   StaticSocketDataProvider data1(kReads1, kWrites1);
26781   StaticSocketDataProvider data2(kReads2, kWrites2);
26782   session_deps_.socket_factory->AddSocketDataProvider(&data1);
26783   session_deps_.socket_factory->AddSocketDataProvider(&data2);
26784 
26785   SSLSocketDataProvider ssl1(ASYNC, OK);
26786   ssl1.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_3;
26787   SSLSocketDataProvider ssl2(ASYNC, OK);
26788   ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
26789   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
26790   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
26791 
26792   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
26793 
26794   TestCompletionCallback callback;
26795   auto trans1 =
26796       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
26797   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
26798   EXPECT_THAT(callback.GetResult(rv), IsOk());
26799   std::string response_data1;
26800   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
26801   EXPECT_EQ("1", response_data1);
26802   trans1.reset();
26803 
26804   auto trans2 =
26805       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
26806   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
26807   EXPECT_THAT(callback.GetResult(rv), IsOk());
26808   std::string response_data2;
26809   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
26810   EXPECT_EQ("2", response_data2);
26811   trans2.reset();
26812 
26813   ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
26814   ssl_config_service_raw->UpdateSSLConfigAndNotify(ssl_context_config);
26815 
26816   auto trans3 =
26817       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
26818   rv = trans3->Start(&request3, callback.callback(), NetLogWithSource());
26819   EXPECT_THAT(callback.GetResult(rv), IsOk());
26820   std::string response_data3;
26821   EXPECT_THAT(ReadTransaction(trans3.get(), &response_data3), IsOk());
26822   EXPECT_EQ("3", response_data3);
26823   trans3.reset();
26824 }
26825 
TEST_P(HttpNetworkTransactionTest,SSLConfigChangedDuringTransaction)26826 TEST_P(HttpNetworkTransactionTest, SSLConfigChangedDuringTransaction) {
26827   SSLContextConfig ssl_context_config;
26828   ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
26829   auto ssl_config_service =
26830       std::make_unique<TestSSLConfigService>(ssl_context_config);
26831   TestSSLConfigService* ssl_config_service_raw = ssl_config_service.get();
26832   session_deps_.ssl_config_service = std::move(ssl_config_service);
26833 
26834   // First request will start connecting before SSLConfig change.
26835   HttpRequestInfo request1;
26836   request1.method = "GET";
26837   request1.url = GURL("https://foo.test/1");
26838   request1.traffic_annotation =
26839       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26840 
26841   const MockWrite kWrites1[] = {
26842       MockWrite("GET /1 HTTP/1.1\r\n"
26843                 "Host: foo.test\r\n"
26844                 "Connection: keep-alive\r\n\r\n"),
26845   };
26846   const MockRead kReads1[] = {
26847       MockRead(ASYNC, ERR_IO_PENDING, 1),
26848       MockRead(ASYNC, 2,
26849                "HTTP/1.1 200 OK\r\n"
26850                "Connection: keep-alive\r\n"
26851                "Content-Length: 1\r\n\r\n"
26852                "1"),
26853   };
26854 
26855   // Second request will be after SSLConfig changes so it should be on a new
26856   // socket.
26857   HttpRequestInfo request2;
26858   request2.method = "GET";
26859   request2.url = GURL("https://foo.test/2");
26860   request2.traffic_annotation =
26861       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26862 
26863   const MockWrite kWrites2[] = {
26864       MockWrite("GET /2 HTTP/1.1\r\n"
26865                 "Host: foo.test\r\n"
26866                 "Connection: keep-alive\r\n\r\n")};
26867 
26868   const MockRead kReads2[] = {
26869       MockRead("HTTP/1.1 200 OK\r\n"
26870                "Connection: keep-alive\r\n"
26871                "Content-Length: 1\r\n\r\n"
26872                "2")};
26873 
26874   SequencedSocketData data1(kReads1, kWrites1);
26875   StaticSocketDataProvider data2(kReads2, kWrites2);
26876   session_deps_.socket_factory->AddSocketDataProvider(&data1);
26877   session_deps_.socket_factory->AddSocketDataProvider(&data2);
26878 
26879   SSLSocketDataProvider ssl1(ASYNC, OK);
26880   // 1st request starts before config change, so should see the initial
26881   // SSLConfig.
26882   ssl1.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_3;
26883 
26884   SSLSocketDataProvider ssl2(ASYNC, OK);
26885   // 2nd request should be made on a new socket after config change, so should
26886   // see the new SSLConfig.
26887   ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
26888 
26889   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
26890   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
26891 
26892   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
26893 
26894   TestCompletionCallback callback1;
26895   auto trans1 =
26896       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
26897   int rv = trans1->Start(&request1, callback1.callback(), NetLogWithSource());
26898   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
26899 
26900   // Wait for the first transaction to connect and start reading data.
26901   data1.RunUntilPaused();
26902 
26903   // Change network config.
26904   ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
26905   ssl_config_service_raw->UpdateSSLConfigAndNotify(ssl_context_config);
26906 
26907   // Resume the first transaction reads.
26908   data1.Resume();
26909   EXPECT_THAT(callback1.GetResult(rv), IsOk());
26910   std::string response_data1;
26911   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
26912   EXPECT_EQ("1", response_data1);
26913   trans1.reset();
26914 
26915   // Start 2nd transaction. Since the config was changed, it should use a new
26916   // socket.
26917   TestCompletionCallback callback2;
26918   auto trans2 =
26919       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
26920   rv = trans2->Start(&request2, callback2.callback(), NetLogWithSource());
26921   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
26922 
26923   EXPECT_THAT(callback2.GetResult(rv), IsOk());
26924   std::string response_data2;
26925   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
26926   EXPECT_EQ("2", response_data2);
26927   trans2.reset();
26928 }
26929 
TEST_P(HttpNetworkTransactionTest,SSLConfigChangedPendingConnect)26930 TEST_P(HttpNetworkTransactionTest, SSLConfigChangedPendingConnect) {
26931   SSLContextConfig ssl_context_config;
26932   ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
26933   auto ssl_config_service =
26934       std::make_unique<TestSSLConfigService>(ssl_context_config);
26935   TestSSLConfigService* ssl_config_service_raw = ssl_config_service.get();
26936 
26937   session_deps_.ssl_config_service = std::move(ssl_config_service);
26938 
26939   HttpRequestInfo request;
26940   request.method = "GET";
26941   request.url = GURL("https://foo.test/1");
26942   request.traffic_annotation =
26943       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
26944 
26945   const MockWrite kWrites1[] = {
26946       MockWrite("GET /1 HTTP/1.1\r\n"
26947                 "Host: foo.test\r\n"
26948                 "Connection: keep-alive\r\n\r\n"),
26949   };
26950   const MockRead kReads1[] = {
26951       MockRead("HTTP/1.1 200 OK\r\n"
26952                "Connection: keep-alive\r\n"
26953                "Content-Length: 1\r\n\r\n"
26954                "1"),
26955   };
26956 
26957   StaticSocketDataProvider data1(kReads1, kWrites1);
26958   session_deps_.socket_factory->AddSocketDataProvider(&data1);
26959   session_deps_.socket_factory->AddSocketDataProvider(&data1);
26960 
26961   // Even though the transaction was created before the change, the connection
26962   // shouldn't happen until after the SSLConfig change, so expect that the
26963   // socket will be created with the new SSLConfig.
26964   SSLSocketDataProvider ssl_data(ASYNC, OK);
26965   ssl_data.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
26966   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
26967 
26968   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
26969 
26970   TestCompletionCallback callback;
26971   auto trans =
26972       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
26973   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
26974   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
26975 
26976   ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
26977   ssl_config_service_raw->UpdateSSLConfigAndNotify(ssl_context_config);
26978 
26979   EXPECT_THAT(callback.GetResult(rv), IsOk());
26980   std::string response_data;
26981   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
26982   EXPECT_EQ("1", response_data);
26983   trans.reset();
26984 }
26985 
26986 // Test that HttpNetworkTransaction correctly handles existing sockets when the
26987 // server requests a client certificate post-handshake (via a TLS
26988 // renegotiation). This is a regression test for https://crbug.com/829184.
TEST_P(HttpNetworkTransactionTest,PostHandshakeClientCertWithSockets)26989 TEST_P(HttpNetworkTransactionTest, PostHandshakeClientCertWithSockets) {
26990   const MutableNetworkTrafficAnnotationTag kTrafficAnnotation(
26991       TRAFFIC_ANNOTATION_FOR_TESTS);
26992 
26993   auto cert_request_info = base::MakeRefCounted<SSLCertRequestInfo>();
26994   cert_request_info->host_and_port = HostPortPair("foo.test", 443);
26995 
26996   std::unique_ptr<FakeClientCertIdentity> identity =
26997       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
26998           GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
26999   ASSERT_TRUE(identity);
27000 
27001   // This test will make several requests so that, when the client certificate
27002   // request comes in, we have a socket in use, an idle socket, and a socket for
27003   // an unrelated host.
27004   //
27005   // First, two long-lived requests which do not complete until after the client
27006   // certificate request. This arranges for sockets to be in use during the
27007   // request. They should not be interrupted.
27008   HttpRequestInfo request_long_lived;
27009   request_long_lived.method = "GET";
27010   request_long_lived.url = GURL("https://foo.test/long-lived");
27011   request_long_lived.traffic_annotation = kTrafficAnnotation;
27012 
27013   HttpRequestInfo request_long_lived_bar;
27014   request_long_lived_bar.method = "GET";
27015   request_long_lived_bar.url = GURL("https://bar.test/long-lived");
27016   request_long_lived_bar.traffic_annotation = kTrafficAnnotation;
27017 
27018   // Next, make a request that needs client certificates.
27019   HttpRequestInfo request_auth;
27020   request_auth.method = "GET";
27021   request_auth.url = GURL("https://foo.test/auth");
27022   request_auth.traffic_annotation = kTrafficAnnotation;
27023 
27024   // Before responding to the challenge, make a request to an unauthenticated
27025   // endpoint. This will result in an idle socket when the client certificate
27026   // challenge is resolved.
27027   HttpRequestInfo request_unauth;
27028   request_unauth.method = "GET";
27029   request_unauth.url = GURL("https://foo.test/unauth");
27030   request_unauth.traffic_annotation = kTrafficAnnotation;
27031 
27032   // After all the preceding requests complete, end with two additional requests
27033   // to ensure pre-authentication foo.test sockets are not used and bar.test
27034   // sockets are unaffected.
27035   HttpRequestInfo request_post_auth;
27036   request_post_auth.method = "GET";
27037   request_post_auth.url = GURL("https://foo.test/post-auth");
27038   request_post_auth.traffic_annotation = kTrafficAnnotation;
27039 
27040   HttpRequestInfo request_post_auth_bar;
27041   request_post_auth_bar.method = "GET";
27042   request_post_auth_bar.url = GURL("https://bar.test/post-auth");
27043   request_post_auth_bar.traffic_annotation = kTrafficAnnotation;
27044 
27045   // The sockets for /long-lived and /unauth complete their request but are
27046   // not allocated for /post-auth or /retry because SSL state has since changed.
27047   const MockWrite kLongLivedWrites[] = {
27048       MockWrite(ASYNC, 0,
27049                 "GET /long-lived HTTP/1.1\r\n"
27050                 "Host: foo.test\r\n"
27051                 "Connection: keep-alive\r\n\r\n"),
27052   };
27053   const MockRead kLongLivedReads[] = {
27054       // Pause so /long-lived completes after the client presents client
27055       // certificates.
27056       MockRead(ASYNC, ERR_IO_PENDING, 1),
27057       MockRead(ASYNC, 2,
27058                "HTTP/1.1 200 OK\r\n"
27059                "Connection: keep-alive\r\n"
27060                "Content-Length: 10\r\n\r\n"
27061                "long-lived"),
27062   };
27063   SequencedSocketData data_long_lived(kLongLivedReads, kLongLivedWrites);
27064   SSLSocketDataProvider ssl_long_lived(ASYNC, OK);
27065   session_deps_.socket_factory->AddSocketDataProvider(&data_long_lived);
27066   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_long_lived);
27067 
27068   // Requests for bar.test should be unaffected by foo.test and get allocated
27069   // a single socket.
27070   const MockWrite kBarWrites[] = {
27071       MockWrite(ASYNC, 0,
27072                 "GET /long-lived HTTP/1.1\r\n"
27073                 "Host: bar.test\r\n"
27074                 "Connection: keep-alive\r\n\r\n"),
27075       MockWrite(ASYNC, 3,
27076                 "GET /post-auth HTTP/1.1\r\n"
27077                 "Host: bar.test\r\n"
27078                 "Connection: keep-alive\r\n\r\n"),
27079   };
27080   const MockRead kBarReads[] = {
27081       // Pause on /long-lived so it completes after foo.test's authentication.
27082       MockRead(ASYNC, ERR_IO_PENDING, 1),
27083       MockRead(ASYNC, 2,
27084                "HTTP/1.1 200 OK\r\n"
27085                "Connection: keep-alive\r\n"
27086                "Content-Length: 10\r\n\r\n"
27087                "long-lived"),
27088       MockRead(ASYNC, 4,
27089                "HTTP/1.1 200 OK\r\n"
27090                "Connection: keep-alive\r\n"
27091                "Content-Length: 9\r\n\r\n"
27092                "post-auth"),
27093   };
27094   SequencedSocketData data_bar(kBarReads, kBarWrites);
27095   SSLSocketDataProvider ssl_bar(ASYNC, OK);
27096   session_deps_.socket_factory->AddSocketDataProvider(&data_bar);
27097   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bar);
27098 
27099   // Requesting /auth results in a post-handshake client certificate challenge.
27100   const MockWrite kAuthWrites[] = {
27101       MockWrite(ASYNC, 0,
27102                 "GET /auth HTTP/1.1\r\n"
27103                 "Host: foo.test\r\n"
27104                 "Connection: keep-alive\r\n\r\n"),
27105   };
27106   const MockRead kAuthReads[] = {
27107       MockRead(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED, 1),
27108   };
27109   SequencedSocketData data_auth(kAuthReads, kAuthWrites);
27110   SSLSocketDataProvider ssl_auth(ASYNC, OK);
27111   ssl_auth.cert_request_info = cert_request_info;
27112   session_deps_.socket_factory->AddSocketDataProvider(&data_auth);
27113   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_auth);
27114 
27115   // Requesting /unauth completes.
27116   const MockWrite kUnauthWrites[] = {
27117       MockWrite(ASYNC, 0,
27118                 "GET /unauth HTTP/1.1\r\n"
27119                 "Host: foo.test\r\n"
27120                 "Connection: keep-alive\r\n\r\n"),
27121   };
27122   const MockRead kUnauthReads[] = {
27123       MockRead(ASYNC, 1,
27124                "HTTP/1.1 200 OK\r\n"
27125                "Connection: keep-alive\r\n"
27126                "Content-Length: 6\r\n\r\n"
27127                "unauth"),
27128   };
27129   SequencedSocketData data_unauth(kUnauthReads, kUnauthWrites);
27130   SSLSocketDataProvider ssl_unauth(ASYNC, OK);
27131   session_deps_.socket_factory->AddSocketDataProvider(&data_unauth);
27132   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_unauth);
27133 
27134   // When the client certificate is selected, /auth is retried on a new
27135   // connection. In particular, it should not be retried on |data_unauth|,
27136   // which would not honor the new client certificate configuration.
27137   const MockWrite kRetryWrites[] = {
27138       MockWrite(ASYNC, 0,
27139                 "GET /auth HTTP/1.1\r\n"
27140                 "Host: foo.test\r\n"
27141                 "Connection: keep-alive\r\n\r\n"),
27142   };
27143   const MockRead kRetryReads[] = {
27144       MockRead(ASYNC, 1,
27145                "HTTP/1.1 200 OK\r\n"
27146                // Close the connection so we test that /post-auth is not
27147                // allocated to |data_unauth| or |data_long_lived|.
27148                "Connection: close\r\n"
27149                "Content-Length: 4\r\n\r\n"
27150                "auth"),
27151   };
27152   SequencedSocketData data_retry(kRetryReads, kRetryWrites);
27153   SSLSocketDataProvider ssl_retry(ASYNC, OK);
27154   ssl_retry.expected_send_client_cert = true;
27155   ssl_retry.expected_client_cert = identity->certificate();
27156   session_deps_.socket_factory->AddSocketDataProvider(&data_retry);
27157   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_retry);
27158 
27159   // /post-auth gets its own socket.
27160   const MockWrite kPostAuthWrites[] = {
27161       MockWrite(ASYNC, 0,
27162                 "GET /post-auth HTTP/1.1\r\n"
27163                 "Host: foo.test\r\n"
27164                 "Connection: keep-alive\r\n\r\n"),
27165   };
27166   const MockRead kPostAuthReads[] = {
27167       MockRead(ASYNC, 1,
27168                "HTTP/1.1 200 OK\r\n"
27169                "Connection: keep-alive\r\n"
27170                "Content-Length: 9\r\n\r\n"
27171                "post-auth"),
27172   };
27173   SequencedSocketData data_post_auth(kPostAuthReads, kPostAuthWrites);
27174   SSLSocketDataProvider ssl_post_auth(ASYNC, OK);
27175   ssl_post_auth.expected_send_client_cert = true;
27176   ssl_post_auth.expected_client_cert = identity->certificate();
27177   session_deps_.socket_factory->AddSocketDataProvider(&data_post_auth);
27178   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_post_auth);
27179 
27180   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
27181 
27182   // Start the two long-lived requests.
27183   TestCompletionCallback callback_long_lived;
27184   auto trans_long_lived =
27185       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
27186   int rv = trans_long_lived->Start(
27187       &request_long_lived, callback_long_lived.callback(), NetLogWithSource());
27188   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
27189   data_long_lived.RunUntilPaused();
27190 
27191   TestCompletionCallback callback_long_lived_bar;
27192   auto trans_long_lived_bar =
27193       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
27194   rv = trans_long_lived_bar->Start(&request_long_lived_bar,
27195                                    callback_long_lived_bar.callback(),
27196                                    NetLogWithSource());
27197   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
27198   data_bar.RunUntilPaused();
27199 
27200   // Request /auth. This gives a client certificate challenge.
27201   TestCompletionCallback callback_auth;
27202   auto trans_auth =
27203       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
27204   rv = trans_auth->Start(&request_auth, callback_auth.callback(),
27205                          NetLogWithSource());
27206   EXPECT_THAT(callback_auth.GetResult(rv),
27207               IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
27208 
27209   // Make an unauthenticated request. This completes.
27210   TestCompletionCallback callback_unauth;
27211   auto trans_unauth =
27212       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
27213   rv = trans_unauth->Start(&request_unauth, callback_unauth.callback(),
27214                            NetLogWithSource());
27215   EXPECT_THAT(callback_unauth.GetResult(rv), IsOk());
27216   std::string response_unauth;
27217   EXPECT_THAT(ReadTransaction(trans_unauth.get(), &response_unauth), IsOk());
27218   EXPECT_EQ("unauth", response_unauth);
27219   trans_unauth.reset();
27220 
27221   // Complete the authenticated request.
27222   rv = trans_auth->RestartWithCertificate(identity->certificate(),
27223                                           identity->ssl_private_key(),
27224                                           callback_auth.callback());
27225   EXPECT_THAT(callback_auth.GetResult(rv), IsOk());
27226   std::string response_auth;
27227   EXPECT_THAT(ReadTransaction(trans_auth.get(), &response_auth), IsOk());
27228   EXPECT_EQ("auth", response_auth);
27229   trans_auth.reset();
27230 
27231   // Complete the long-lived requests.
27232   data_long_lived.Resume();
27233   EXPECT_THAT(callback_long_lived.GetResult(ERR_IO_PENDING), IsOk());
27234   std::string response_long_lived;
27235   EXPECT_THAT(ReadTransaction(trans_long_lived.get(), &response_long_lived),
27236               IsOk());
27237   EXPECT_EQ("long-lived", response_long_lived);
27238   trans_long_lived.reset();
27239 
27240   data_bar.Resume();
27241   EXPECT_THAT(callback_long_lived_bar.GetResult(ERR_IO_PENDING), IsOk());
27242   std::string response_long_lived_bar;
27243   EXPECT_THAT(
27244       ReadTransaction(trans_long_lived_bar.get(), &response_long_lived_bar),
27245       IsOk());
27246   EXPECT_EQ("long-lived", response_long_lived_bar);
27247   trans_long_lived_bar.reset();
27248 
27249   // Run the post-authentication requests.
27250   TestCompletionCallback callback_post_auth;
27251   auto trans_post_auth =
27252       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
27253   rv = trans_post_auth->Start(&request_post_auth, callback_post_auth.callback(),
27254                               NetLogWithSource());
27255   EXPECT_THAT(callback_post_auth.GetResult(rv), IsOk());
27256   std::string response_post_auth;
27257   EXPECT_THAT(ReadTransaction(trans_post_auth.get(), &response_post_auth),
27258               IsOk());
27259   EXPECT_EQ("post-auth", response_post_auth);
27260   trans_post_auth.reset();
27261 
27262   TestCompletionCallback callback_post_auth_bar;
27263   auto trans_post_auth_bar =
27264       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
27265   rv = trans_post_auth_bar->Start(&request_post_auth_bar,
27266                                   callback_post_auth_bar.callback(),
27267                                   NetLogWithSource());
27268   EXPECT_THAT(callback_post_auth_bar.GetResult(rv), IsOk());
27269   std::string response_post_auth_bar;
27270   EXPECT_THAT(
27271       ReadTransaction(trans_post_auth_bar.get(), &response_post_auth_bar),
27272       IsOk());
27273   EXPECT_EQ("post-auth", response_post_auth_bar);
27274   trans_post_auth_bar.reset();
27275 }
27276 
TEST_P(HttpNetworkTransactionTest,RequestWithDnsAliases)27277 TEST_P(HttpNetworkTransactionTest, RequestWithDnsAliases) {
27278   // Create a request.
27279   HttpRequestInfo request;
27280   request.method = "GET";
27281   request.url = GURL("http://www.example.org/");
27282   request.traffic_annotation =
27283       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
27284 
27285   // Add a rule with DNS aliases to the host resolver.
27286   std::vector<std::string> aliases({"alias1", "alias2", "www.example.org"});
27287   session_deps_.host_resolver->rules()->AddIPLiteralRuleWithDnsAliases(
27288       "www.example.org", "127.0.0.1", std::move(aliases));
27289 
27290   // Create a HttpNetworkSession.
27291   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
27292 
27293   // Create a transaction.
27294   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
27295 
27296   // Prepare the expected data to be written and read. The client should send
27297   // the request below.
27298   MockWrite data_writes[] = {
27299       MockWrite("GET / HTTP/1.1\r\n"
27300                 "Host: www.example.org\r\n"
27301                 "Connection: keep-alive\r\n\r\n"),
27302   };
27303 
27304   // The server should respond with the following.
27305   MockRead data_reads[] = {
27306       MockRead("HTTP/1.0 200 OK\r\n"),
27307       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
27308       MockRead("Content-Length: 100\r\n\r\n"),
27309       MockRead(SYNCHRONOUS, OK),
27310   };
27311 
27312   StaticSocketDataProvider data(data_reads, data_writes);
27313   session_deps_.socket_factory->AddSocketDataProvider(&data);
27314   TestCompletionCallback callback;
27315 
27316   // Start the transaction.
27317   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
27318   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
27319 
27320   // Wait for completion.
27321   rv = callback.WaitForResult();
27322   EXPECT_THAT(rv, IsOk());
27323 
27324   // Get the response info.
27325   const HttpResponseInfo* response = trans.GetResponseInfo();
27326 
27327   // Verify that the alias list was stored in the response info as expected.
27328   ASSERT_TRUE(response);
27329   EXPECT_THAT(response->dns_aliases,
27330               testing::ElementsAre("alias1", "alias2", "www.example.org"));
27331 }
27332 
TEST_P(HttpNetworkTransactionTest,RequestWithNoAdditionalDnsAliases)27333 TEST_P(HttpNetworkTransactionTest, RequestWithNoAdditionalDnsAliases) {
27334   // Create a request.
27335   HttpRequestInfo request;
27336   request.method = "GET";
27337   request.url = GURL("http://www.example.org/");
27338   request.traffic_annotation =
27339       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
27340 
27341   // Add a rule without DNS aliases to the host resolver.
27342   session_deps_.host_resolver->rules()->AddRule("www.example.org", "127.0.0.1");
27343 
27344   // Create a HttpNetworkSession.
27345   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
27346 
27347   // Create a transaction.
27348   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
27349 
27350   // Prepare the expected data to be written and read. The client should send
27351   // the request below.
27352   MockWrite data_writes[] = {
27353       MockWrite("GET / HTTP/1.1\r\n"
27354                 "Host: www.example.org\r\n"
27355                 "Connection: keep-alive\r\n\r\n"),
27356   };
27357 
27358   // The server should respond with the following.
27359   MockRead data_reads[] = {
27360       MockRead("HTTP/1.0 200 OK\r\n"),
27361       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
27362       MockRead("Content-Length: 100\r\n\r\n"),
27363       MockRead(SYNCHRONOUS, OK),
27364   };
27365 
27366   StaticSocketDataProvider data(data_reads, data_writes);
27367   session_deps_.socket_factory->AddSocketDataProvider(&data);
27368   TestCompletionCallback callback;
27369 
27370   // Start the transaction.
27371   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
27372   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
27373 
27374   // Wait for completion.
27375   rv = callback.WaitForResult();
27376   EXPECT_THAT(rv, IsOk());
27377 
27378   // Get the response info.
27379   const HttpResponseInfo* response = trans.GetResponseInfo();
27380 
27381   // Verify that the alias list was stored in the response info as expected.
27382   ASSERT_TRUE(response);
27383   EXPECT_THAT(response->dns_aliases, testing::ElementsAre("www.example.org"));
27384 }
27385 
27386 // Test behavior of SetProxyInfoInResponse with a direct connection.
TEST_P(HttpNetworkTransactionTest,SetProxyInfoInResponse_Direct)27387 TEST_P(HttpNetworkTransactionTest, SetProxyInfoInResponse_Direct) {
27388   ProxyInfo proxy_info;
27389   proxy_info.UseDirect();
27390   HttpResponseInfo response_info;
27391   HttpNetworkTransaction::SetProxyInfoInResponse(proxy_info, &response_info);
27392   EXPECT_EQ(response_info.was_fetched_via_proxy, false);
27393   EXPECT_EQ(response_info.proxy_chain.is_for_ip_protection(), false);
27394   EXPECT_EQ(response_info.proxy_chain, ProxyChain::Direct());
27395 }
27396 
27397 // Test behavior of SetProxyInfoInResponse with a proxied connection.
TEST_P(HttpNetworkTransactionTest,SetProxyInfoInResponse_Proxied)27398 TEST_P(HttpNetworkTransactionTest, SetProxyInfoInResponse_Proxied) {
27399   ProxyInfo proxy_info;
27400   ProxyChain proxy_chain =
27401       ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "prx", 443);
27402   proxy_info.UseProxyChain(proxy_chain);
27403   HttpResponseInfo response_info;
27404   HttpNetworkTransaction::SetProxyInfoInResponse(proxy_info, &response_info);
27405   EXPECT_EQ(response_info.was_fetched_via_proxy, true);
27406   EXPECT_EQ(response_info.proxy_chain.is_for_ip_protection(), false);
27407   EXPECT_EQ(response_info.proxy_chain, proxy_chain);
27408 }
27409 
27410 // Test behavior of SetProxyInfoInResponse with an empty ProxyInfo.
TEST_P(HttpNetworkTransactionTest,SetProxyInfoInResponse_Empty)27411 TEST_P(HttpNetworkTransactionTest, SetProxyInfoInResponse_Empty) {
27412   ProxyInfo empty_proxy_info;
27413   HttpResponseInfo response_info;
27414   HttpNetworkTransaction::SetProxyInfoInResponse(empty_proxy_info,
27415                                                  &response_info);
27416   EXPECT_EQ(response_info.was_fetched_via_proxy, true);
27417   EXPECT_EQ(response_info.proxy_chain.is_for_ip_protection(), false);
27418   EXPECT_FALSE(response_info.proxy_chain.IsValid());
27419 }
27420 
27421 // Test behavior of SetProxyInfoInResponse with a proxied connection for IP
27422 // protection.
TEST_P(HttpNetworkTransactionTest,SetProxyInfoInResponse_IpProtection)27423 TEST_P(HttpNetworkTransactionTest, SetProxyInfoInResponse_IpProtection) {
27424   ProxyInfo proxy_info;
27425   ProxyChain ip_protection_proxy_chain =
27426       ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
27427           ProxyServer::SCHEME_HTTPS, "prx", 443)});
27428   proxy_info.UseProxyChain(ip_protection_proxy_chain);
27429   HttpResponseInfo response_info;
27430   HttpNetworkTransaction::SetProxyInfoInResponse(proxy_info, &response_info);
27431   EXPECT_EQ(response_info.was_fetched_via_proxy, true);
27432   EXPECT_EQ(response_info.proxy_chain.is_for_ip_protection(), true);
27433   EXPECT_EQ(response_info.proxy_chain, ip_protection_proxy_chain);
27434 }
27435 
27436 class IpProtectionProxyDelegate : public TestProxyDelegate {
27437  public:
IpProtectionProxyDelegate()27438   IpProtectionProxyDelegate() {
27439     set_extra_header_name(net::HttpRequestHeaders::kAuthorization);
27440   }
27441 
27442   // ProxyDelegate implementation:
OnResolveProxy(const GURL & url,const NetworkAnonymizationKey & network_anonymization_key,const std::string & method,const ProxyRetryInfoMap & proxy_retry_info,ProxyInfo * result)27443   void OnResolveProxy(const GURL& url,
27444                       const NetworkAnonymizationKey& network_anonymization_key,
27445                       const std::string& method,
27446                       const ProxyRetryInfoMap& proxy_retry_info,
27447                       ProxyInfo* result) override {
27448     ProxyList proxy_list;
27449     proxy_list.AddProxyChain(proxy_chain());
27450 
27451     // For IP Protection we always want to fallback to direct, so emulate the
27452     // behavior of NetworkServiceProxyDelegate where a direct chain will always
27453     // be added as the last ProxyList entry.
27454     if (!proxy_chain().is_direct()) {
27455       proxy_list.AddProxyChain(ProxyChain::Direct());
27456     }
27457 
27458     result->UseProxyList(proxy_list);
27459   }
27460 
GetAuthorizationHeaderValue(const ProxyServer & proxy_server)27461   static std::string GetAuthorizationHeaderValue(
27462       const ProxyServer& proxy_server) {
27463     return GetExtraHeaderValue(proxy_server);
27464   }
27465 };
27466 
27467 // Test that for requests sent through an IP Protection proxy, the
27468 // 'IP-Protection' header is sent as expected when the feature is enabled.
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyIpProtectionRequestHeaderAddedWhenEnabled)27469 TEST_P(HttpNetworkTransactionTest,
27470        HttpsNestedProxyIpProtectionRequestHeaderAddedWhenEnabled) {
27471   base::test::ScopedFeatureList scoped_feature_list;
27472   scoped_feature_list.InitAndEnableFeatureWithParameters(
27473       net::features::kEnableIpProtectionProxy,
27474       {{net::features::kIpPrivacyAddHeaderToProxiedRequests.name, "true"}});
27475 
27476   HttpRequestInfo request;
27477   request.method = "GET";
27478   request.url = GURL("https://www.example.org/");
27479   request.traffic_annotation =
27480       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
27481 
27482   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
27483                                   HostPortPair("proxy1.test", 70)};
27484   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
27485                                   HostPortPair("proxy2.test", 71)};
27486   ProxyChain kNestedProxyChain =
27487       ProxyChain::ForIpProtection({kProxyServer1, kProxyServer2});
27488 
27489   session_deps_.proxy_resolution_service =
27490       ConfiguredProxyResolutionService::CreateFixedForTest(
27491           "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
27492   session_deps_.proxy_delegate = std::make_unique<IpProtectionProxyDelegate>();
27493   auto* proxy_delegate = static_cast<IpProtectionProxyDelegate*>(
27494       session_deps_.proxy_delegate.get());
27495   proxy_delegate->set_proxy_chain(kNestedProxyChain);
27496   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
27497   session_deps_.net_log = NetLog::Get();
27498   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
27499 
27500   const std::string kProxyServer1AuthHeaderValue =
27501       IpProtectionProxyDelegate::GetAuthorizationHeaderValue(kProxyServer1);
27502   const std::string kProxyServer2AuthHeaderValue =
27503       IpProtectionProxyDelegate::GetAuthorizationHeaderValue(kProxyServer2);
27504 
27505   const std::string kProxyServer2Connect = base::StringPrintf(
27506       "CONNECT proxy2.test:71 HTTP/1.1\r\n"
27507       "Host: proxy2.test:71\r\n"
27508       "Proxy-Connection: keep-alive\r\n"
27509       "Authorization: %s\r\n\r\n",
27510       kProxyServer1AuthHeaderValue.c_str());
27511   const std::string kEndpointConnect = base::StringPrintf(
27512       "CONNECT www.example.org:443 HTTP/1.1\r\n"
27513       "Host: www.example.org:443\r\n"
27514       "Proxy-Connection: keep-alive\r\n"
27515       "Authorization: %s\r\n\r\n",
27516       kProxyServer2AuthHeaderValue.c_str());
27517 
27518   MockWrite data_writes[] = {
27519       MockWrite(kProxyServer2Connect.c_str()),
27520       MockWrite(kEndpointConnect.c_str()),
27521       MockWrite("GET / HTTP/1.1\r\n"
27522                 "Host: www.example.org\r\n"
27523                 "Connection: keep-alive\r\n"
27524                 "IP-Protection: 1\r\n\r\n"),
27525   };
27526 
27527   MockRead data_reads[] = {
27528       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
27529       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
27530       MockRead("HTTP/1.1 200\r\n\r\n"),
27531       MockRead(SYNCHRONOUS, OK),
27532   };
27533 
27534   StaticSocketDataProvider data(data_reads, data_writes);
27535   session_deps_.socket_factory->AddSocketDataProvider(&data);
27536 
27537   SSLSocketDataProvider ssl(ASYNC, OK);
27538   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
27539 
27540   SSLSocketDataProvider ssl2(ASYNC, OK);
27541   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
27542 
27543   SSLSocketDataProvider ssl3(ASYNC, OK);
27544   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
27545 
27546   TestCompletionCallback callback;
27547 
27548   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
27549 
27550   int rv = trans.Start(&request, callback.callback(),
27551                        NetLogWithSource::Make(NetLogSourceType::NONE));
27552   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
27553 
27554   rv = callback.WaitForResult();
27555   EXPECT_THAT(rv, IsOk());
27556 
27557   const HttpResponseInfo* response = trans.GetResponseInfo();
27558   ASSERT_TRUE(response);
27559   ASSERT_TRUE(response->headers);
27560   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
27561 }
27562 
27563 // Test that for direct requests that are marked as being for IP Protection, the
27564 // 'IP-Protection' header is not sent even when the feature is enabled. This
27565 // test should be removed once `kIpPrivacyDirectOnly` is.
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyIpProtectionRequestHeaderNotAddedForIpProtectionDirect)27566 TEST_P(HttpNetworkTransactionTest,
27567        HttpsNestedProxyIpProtectionRequestHeaderNotAddedForIpProtectionDirect) {
27568   base::test::ScopedFeatureList scoped_feature_list;
27569   scoped_feature_list.InitAndEnableFeatureWithParameters(
27570       net::features::kEnableIpProtectionProxy,
27571       {{net::features::kIpPrivacyAddHeaderToProxiedRequests.name, "true"},
27572        {net::features::kIpPrivacyDirectOnly.name, "true"}});
27573 
27574   HttpRequestInfo request;
27575   request.method = "GET";
27576   request.url = GURL("https://www.example.org/");
27577   request.traffic_annotation =
27578       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
27579 
27580   auto kIpProtectionDirectChain =
27581       ProxyChain::ForIpProtection(std::vector<ProxyServer>());
27582 
27583   session_deps_.proxy_resolution_service =
27584       ConfiguredProxyResolutionService::CreateFixedForTest(
27585           "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
27586   session_deps_.proxy_delegate = std::make_unique<IpProtectionProxyDelegate>();
27587   auto* proxy_delegate = static_cast<IpProtectionProxyDelegate*>(
27588       session_deps_.proxy_delegate.get());
27589   proxy_delegate->set_proxy_chain(kIpProtectionDirectChain);
27590   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
27591   session_deps_.net_log = NetLog::Get();
27592   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
27593 
27594   MockWrite data_writes[] = {
27595       MockWrite("GET / HTTP/1.1\r\n"
27596                 "Host: www.example.org\r\n"
27597                 "Connection: keep-alive\r\n\r\n"),
27598   };
27599 
27600   MockRead data_reads[] = {
27601       MockRead("HTTP/1.1 200\r\n\r\n"),
27602       MockRead(SYNCHRONOUS, OK),
27603   };
27604 
27605   StaticSocketDataProvider data(data_reads, data_writes);
27606   session_deps_.socket_factory->AddSocketDataProvider(&data);
27607 
27608   SSLSocketDataProvider ssl(ASYNC, OK);
27609   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
27610 
27611   TestCompletionCallback callback;
27612 
27613   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
27614 
27615   int rv = trans.Start(&request, callback.callback(),
27616                        NetLogWithSource::Make(NetLogSourceType::NONE));
27617   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
27618 
27619   rv = callback.WaitForResult();
27620   EXPECT_THAT(rv, IsOk());
27621 
27622   const HttpResponseInfo* response = trans.GetResponseInfo();
27623   ASSERT_TRUE(response);
27624   ASSERT_TRUE(response->headers);
27625   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
27626 }
27627 
27628 // Test that for requests sent through an IP Protection proxy, the
27629 // 'IP-Protection' header is not sent if the feature is disabled.
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyIpProtectionRequestHeaderNotAddedIfFeatureDisabled)27630 TEST_P(HttpNetworkTransactionTest,
27631        HttpsNestedProxyIpProtectionRequestHeaderNotAddedIfFeatureDisabled) {
27632   base::test::ScopedFeatureList scoped_feature_list;
27633   scoped_feature_list.InitAndEnableFeatureWithParameters(
27634       net::features::kEnableIpProtectionProxy,
27635       {{net::features::kIpPrivacyAddHeaderToProxiedRequests.name, "false"}});
27636 
27637   HttpRequestInfo request;
27638   request.method = "GET";
27639   request.url = GURL("https://www.example.org/");
27640   request.traffic_annotation =
27641       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
27642 
27643   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
27644                                   HostPortPair("proxy1.test", 70)};
27645   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
27646                                   HostPortPair("proxy2.test", 71)};
27647   ProxyChain kNestedProxyChain =
27648       ProxyChain::ForIpProtection({kProxyServer1, kProxyServer2});
27649 
27650   session_deps_.proxy_resolution_service =
27651       ConfiguredProxyResolutionService::CreateFixedForTest(
27652           "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
27653   session_deps_.proxy_delegate = std::make_unique<IpProtectionProxyDelegate>();
27654   auto* proxy_delegate = static_cast<IpProtectionProxyDelegate*>(
27655       session_deps_.proxy_delegate.get());
27656   proxy_delegate->set_proxy_chain(kNestedProxyChain);
27657   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
27658   session_deps_.net_log = NetLog::Get();
27659   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
27660 
27661   const std::string kProxyServer1AuthHeaderValue =
27662       IpProtectionProxyDelegate::GetAuthorizationHeaderValue(kProxyServer1);
27663   const std::string kProxyServer2AuthHeaderValue =
27664       IpProtectionProxyDelegate::GetAuthorizationHeaderValue(kProxyServer2);
27665 
27666   const std::string kProxyServer2Connect = base::StringPrintf(
27667       "CONNECT proxy2.test:71 HTTP/1.1\r\n"
27668       "Host: proxy2.test:71\r\n"
27669       "Proxy-Connection: keep-alive\r\n"
27670       "Authorization: %s\r\n\r\n",
27671       kProxyServer1AuthHeaderValue.c_str());
27672   const std::string kEndpointConnect = base::StringPrintf(
27673       "CONNECT www.example.org:443 HTTP/1.1\r\n"
27674       "Host: www.example.org:443\r\n"
27675       "Proxy-Connection: keep-alive\r\n"
27676       "Authorization: %s\r\n\r\n",
27677       kProxyServer2AuthHeaderValue.c_str());
27678 
27679   MockWrite data_writes[] = {
27680       MockWrite(kProxyServer2Connect.c_str()),
27681       MockWrite(kEndpointConnect.c_str()),
27682       MockWrite("GET / HTTP/1.1\r\n"
27683                 "Host: www.example.org\r\n"
27684                 "Connection: keep-alive\r\n\r\n"),
27685   };
27686 
27687   MockRead data_reads[] = {
27688       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
27689       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
27690       MockRead("HTTP/1.1 200\r\n\r\n"),
27691       MockRead(SYNCHRONOUS, OK),
27692   };
27693 
27694   StaticSocketDataProvider data(data_reads, data_writes);
27695   session_deps_.socket_factory->AddSocketDataProvider(&data);
27696 
27697   SSLSocketDataProvider ssl(ASYNC, OK);
27698   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
27699 
27700   SSLSocketDataProvider ssl2(ASYNC, OK);
27701   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
27702 
27703   SSLSocketDataProvider ssl3(ASYNC, OK);
27704   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
27705 
27706   TestCompletionCallback callback;
27707 
27708   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
27709 
27710   int rv = trans.Start(&request, callback.callback(),
27711                        NetLogWithSource::Make(NetLogSourceType::NONE));
27712   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
27713 
27714   rv = callback.WaitForResult();
27715   EXPECT_THAT(rv, IsOk());
27716 
27717   const HttpResponseInfo* response = trans.GetResponseInfo();
27718   ASSERT_TRUE(response);
27719   ASSERT_TRUE(response->headers);
27720   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
27721 }
27722 
27723 // Test that for a request that fails to be sent through an IP Protection proxy,
27724 // after we fallback to direct the 'IP-Protection' header is not added to the
27725 // request headers.
TEST_P(HttpNetworkTransactionTest,HttpsNestedProxyIpProtectionRequestHeaderNotAddedAfterFallback)27726 TEST_P(HttpNetworkTransactionTest,
27727        HttpsNestedProxyIpProtectionRequestHeaderNotAddedAfterFallback) {
27728   base::test::ScopedFeatureList scoped_feature_list;
27729   scoped_feature_list.InitAndEnableFeatureWithParameters(
27730       net::features::kEnableIpProtectionProxy,
27731       {{net::features::kIpPrivacyAddHeaderToProxiedRequests.name, "true"}});
27732   HttpRequestInfo request;
27733   request.method = "GET";
27734   request.url = GURL("https://www.example.org/");
27735   request.traffic_annotation =
27736       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
27737 
27738   const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
27739                                   HostPortPair("proxy1.test", 70)};
27740   const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
27741                                   HostPortPair("proxy2.test", 71)};
27742   ProxyChain kNestedProxyChain =
27743       ProxyChain::ForIpProtection({kProxyServer1, kProxyServer2});
27744 
27745   session_deps_.proxy_resolution_service =
27746       ConfiguredProxyResolutionService::CreateFixedForTest(
27747           "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
27748   session_deps_.proxy_delegate = std::make_unique<IpProtectionProxyDelegate>();
27749   auto* proxy_delegate = static_cast<IpProtectionProxyDelegate*>(
27750       session_deps_.proxy_delegate.get());
27751   proxy_delegate->set_proxy_chain(kNestedProxyChain);
27752   session_deps_.proxy_resolution_service->SetProxyDelegate(proxy_delegate);
27753   session_deps_.net_log = NetLog::Get();
27754   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
27755 
27756   const std::string kProxyServer1AuthHeaderValue =
27757       IpProtectionProxyDelegate::GetAuthorizationHeaderValue(kProxyServer1);
27758 
27759   const std::string kProxyServer2Connect = base::StringPrintf(
27760       "CONNECT proxy2.test:71 HTTP/1.1\r\n"
27761       "Host: proxy2.test:71\r\n"
27762       "Proxy-Connection: keep-alive\r\n"
27763       "Authorization: %s\r\n\r\n",
27764       kProxyServer1AuthHeaderValue.c_str());
27765 
27766   MockWrite data_writes1[] = {
27767       MockWrite(kProxyServer2Connect.c_str()),
27768   };
27769 
27770   MockRead data_reads1[] = {
27771       MockRead("HTTP/1.1 401 Not Authorized\r\n\r\n"),
27772       MockRead(SYNCHRONOUS, OK),
27773   };
27774 
27775   StaticSocketDataProvider data1(data_reads1, data_writes1);
27776   session_deps_.socket_factory->AddSocketDataProvider(&data1);
27777 
27778   SSLSocketDataProvider ssl1(ASYNC, OK);
27779   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
27780 
27781   // The proxy delegate should implement falling back to direct after an error,
27782   // and we don't expect any proxying or an IP Protection request header on the
27783   // GET.
27784   MockWrite data_writes2[] = {
27785       MockWrite("GET / HTTP/1.1\r\n"
27786                 "Host: www.example.org\r\n"
27787                 "Connection: keep-alive\r\n\r\n"),
27788   };
27789 
27790   MockRead data_reads2[] = {
27791       MockRead("HTTP/1.1 200\r\n\r\n"),
27792       MockRead(SYNCHRONOUS, OK),
27793   };
27794 
27795   StaticSocketDataProvider data2(data_reads2, data_writes2);
27796   session_deps_.socket_factory->AddSocketDataProvider(&data2);
27797 
27798   SSLSocketDataProvider ssl2(ASYNC, OK);
27799   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
27800 
27801   TestCompletionCallback callback;
27802 
27803   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
27804 
27805   int rv = trans.Start(&request, callback.callback(),
27806                        NetLogWithSource::Make(NetLogSourceType::NONE));
27807   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
27808 
27809   rv = callback.WaitForResult();
27810   EXPECT_THAT(rv, IsOk());
27811 
27812   const HttpResponseInfo* response = trans.GetResponseInfo();
27813   ASSERT_TRUE(response);
27814   ASSERT_TRUE(response->headers);
27815   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
27816 }
27817 
27818 }  // namespace net
27819