1 // Copyright 2013 The Chromium Authors. All rights reserved.
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 <set>
13 #include <string>
14 #include <utility>
15 #include <vector>
16 
17 #include "base/bind.h"
18 #include "base/compiler_specific.h"
19 #include "base/files/file_path.h"
20 #include "base/files/file_util.h"
21 #include "base/json/json_writer.h"
22 #include "base/logging.h"
23 #include "base/memory/ptr_util.h"
24 #include "base/memory/weak_ptr.h"
25 #include "base/optional.h"
26 #include "base/run_loop.h"
27 #include "base/stl_util.h"
28 #include "base/strings/string_piece.h"
29 #include "base/strings/string_util.h"
30 #include "base/strings/stringprintf.h"
31 #include "base/strings/utf_string_conversions.h"
32 #include "base/test/metrics/histogram_tester.h"
33 #include "base/test/scoped_feature_list.h"
34 #include "base/test/simple_test_clock.h"
35 #include "base/test/simple_test_tick_clock.h"
36 #include "base/test/task_environment.h"
37 #include "base/test/test_file_util.h"
38 #include "base/threading/thread_task_runner_handle.h"
39 #include "build/build_config.h"
40 #include "net/base/auth.h"
41 #include "net/base/chunked_upload_data_stream.h"
42 #include "net/base/completion_once_callback.h"
43 #include "net/base/elements_upload_data_stream.h"
44 #include "net/base/features.h"
45 #include "net/base/host_port_pair.h"
46 #include "net/base/ip_endpoint.h"
47 #include "net/base/load_timing_info.h"
48 #include "net/base/load_timing_info_test_util.h"
49 #include "net/base/net_errors.h"
50 #include "net/base/privacy_mode.h"
51 #include "net/base/proxy_delegate.h"
52 #include "net/base/proxy_server.h"
53 #include "net/base/request_priority.h"
54 #include "net/base/test_completion_callback.h"
55 #include "net/base/test_proxy_delegate.h"
56 #include "net/base/upload_bytes_element_reader.h"
57 #include "net/base/upload_file_element_reader.h"
58 #include "net/cert/cert_status_flags.h"
59 #include "net/cert/mock_cert_verifier.h"
60 #include "net/dns/mock_host_resolver.h"
61 #include "net/http/http_auth_challenge_tokenizer.h"
62 #include "net/http/http_auth_handler_digest.h"
63 #include "net/http/http_auth_handler_mock.h"
64 #include "net/http/http_auth_handler_ntlm.h"
65 #include "net/http/http_auth_ntlm_mechanism.h"
66 #include "net/http/http_auth_scheme.h"
67 #include "net/http/http_basic_stream.h"
68 #include "net/http/http_network_session.h"
69 #include "net/http/http_network_session_peer.h"
70 #include "net/http/http_proxy_connect_job.h"
71 #include "net/http/http_request_headers.h"
72 #include "net/http/http_response_info.h"
73 #include "net/http/http_server_properties.h"
74 #include "net/http/http_stream.h"
75 #include "net/http/http_stream_factory.h"
76 #include "net/http/http_transaction_test_util.h"
77 #include "net/log/net_log.h"
78 #include "net/log/net_log_event_type.h"
79 #include "net/log/net_log_source.h"
80 #include "net/log/test_net_log.h"
81 #include "net/log/test_net_log_util.h"
82 #include "net/proxy_resolution/configured_proxy_resolution_service.h"
83 #include "net/proxy_resolution/mock_proxy_resolver.h"
84 #include "net/proxy_resolution/proxy_config_service_fixed.h"
85 #include "net/proxy_resolution/proxy_info.h"
86 #include "net/proxy_resolution/proxy_resolver.h"
87 #include "net/proxy_resolution/proxy_resolver_factory.h"
88 #include "net/socket/client_socket_factory.h"
89 #include "net/socket/client_socket_pool.h"
90 #include "net/socket/client_socket_pool_manager.h"
91 #include "net/socket/connect_job.h"
92 #include "net/socket/connection_attempts.h"
93 #include "net/socket/mock_client_socket_pool_manager.h"
94 #include "net/socket/next_proto.h"
95 #include "net/socket/socket_tag.h"
96 #include "net/socket/socket_test_util.h"
97 #include "net/socket/socks_connect_job.h"
98 #include "net/socket/ssl_client_socket.h"
99 #include "net/spdy/spdy_session.h"
100 #include "net/spdy/spdy_session_pool.h"
101 #include "net/spdy/spdy_test_util_common.h"
102 #include "net/ssl/client_cert_identity_test_util.h"
103 #include "net/ssl/ssl_cert_request_info.h"
104 #include "net/ssl/ssl_config.h"
105 #include "net/ssl/ssl_config_service.h"
106 #include "net/ssl/ssl_info.h"
107 #include "net/ssl/ssl_private_key.h"
108 #include "net/ssl/test_ssl_config_service.h"
109 #include "net/test/cert_test_util.h"
110 #include "net/test/gtest_util.h"
111 #include "net/test/test_data_directory.h"
112 #include "net/test/test_with_task_environment.h"
113 #include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
114 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
115 #include "net/url_request/static_http_user_agent_settings.h"
116 #include "net/websockets/websocket_handshake_stream_base.h"
117 #include "net/websockets/websocket_test_util.h"
118 #include "testing/gmock/include/gmock/gmock.h"
119 #include "testing/gtest/include/gtest/gtest.h"
120 #include "testing/platform_test.h"
121 #include "url/gurl.h"
122 
123 #if defined(NTLM_PORTABLE)
124 #include "base/base64.h"
125 #include "net/ntlm/ntlm_test_data.h"
126 #endif
127 
128 #if BUILDFLAG(ENABLE_REPORTING)
129 #include "net/network_error_logging/network_error_logging_service.h"
130 #include "net/network_error_logging/network_error_logging_test_util.h"
131 #include "net/reporting/reporting_cache.h"
132 #include "net/reporting/reporting_endpoint.h"
133 #include "net/reporting/reporting_header_parser.h"
134 #include "net/reporting/reporting_service.h"
135 #include "net/reporting/reporting_test_util.h"
136 #endif  // BUILDFLAG(ENABLE_REPORTING)
137 
138 using net::test::IsError;
139 using net::test::IsOk;
140 
141 using base::ASCIIToUTF16;
142 
143 using testing::AnyOf;
144 
145 //-----------------------------------------------------------------------------
146 
147 namespace net {
148 
149 namespace {
150 
151 const base::string16 kBar(ASCIIToUTF16("bar"));
152 const base::string16 kBar2(ASCIIToUTF16("bar2"));
153 const base::string16 kBar3(ASCIIToUTF16("bar3"));
154 const base::string16 kBaz(ASCIIToUTF16("baz"));
155 const base::string16 kFirst(ASCIIToUTF16("first"));
156 const base::string16 kFoo(ASCIIToUTF16("foo"));
157 const base::string16 kFoo2(ASCIIToUTF16("foo2"));
158 const base::string16 kFoo3(ASCIIToUTF16("foo3"));
159 const base::string16 kFou(ASCIIToUTF16("fou"));
160 const base::string16 kSecond(ASCIIToUTF16("second"));
161 const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
162 
163 const char kAlternativeServiceHttpHeader[] =
164     "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
165 
GetIdleSocketCountInTransportSocketPool(HttpNetworkSession * session)166 int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
167   return session
168       ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
169                       ProxyServer::Direct())
170       ->IdleSocketCount();
171 }
172 
IsTransportSocketPoolStalled(HttpNetworkSession * session)173 bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
174   return session
175       ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
176                       ProxyServer::Direct())
177       ->IsStalled();
178 }
179 
180 // Takes in a Value created from a NetLogHttpResponseParameter, and returns
181 // a JSONified list of headers as a single string.  Uses single quotes instead
182 // of double quotes for easier comparison.
GetHeaders(const base::Value & params)183 std::string GetHeaders(const base::Value& params) {
184   if (!params.is_dict())
185     return "";
186   const base::Value* header_list = params.FindListKey("headers");
187   if (!header_list)
188     return "";
189   std::string headers;
190   base::JSONWriter::Write(*header_list, &headers);
191   base::ReplaceChars(headers, "\"", "'", &headers);
192   return headers;
193 }
194 
195 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is
196 // used.
TestLoadTimingReused(const LoadTimingInfo & load_timing_info)197 void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
198   EXPECT_TRUE(load_timing_info.socket_reused);
199   EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
200 
201   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
202   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
203 
204   ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
205   EXPECT_FALSE(load_timing_info.send_start.is_null());
206 
207   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
208 
209   // Set at a higher level.
210   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
211   EXPECT_TRUE(load_timing_info.request_start.is_null());
212   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
213 }
214 
215 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is
216 // used.
TestLoadTimingNotReused(const LoadTimingInfo & load_timing_info,int connect_timing_flags)217 void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
218                              int connect_timing_flags) {
219   EXPECT_FALSE(load_timing_info.socket_reused);
220   EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
221 
222   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
223   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
224 
225   ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
226                               connect_timing_flags);
227   EXPECT_LE(load_timing_info.connect_timing.connect_end,
228             load_timing_info.send_start);
229 
230   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
231 
232   // Set at a higher level.
233   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
234   EXPECT_TRUE(load_timing_info.request_start.is_null());
235   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
236 }
237 
238 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is
239 // used.
TestLoadTimingReusedWithPac(const LoadTimingInfo & load_timing_info)240 void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
241   EXPECT_TRUE(load_timing_info.socket_reused);
242   EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
243 
244   ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
245 
246   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
247   EXPECT_LE(load_timing_info.proxy_resolve_start,
248             load_timing_info.proxy_resolve_end);
249   EXPECT_LE(load_timing_info.proxy_resolve_end,
250             load_timing_info.send_start);
251   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
252 
253   // Set at a higher level.
254   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
255   EXPECT_TRUE(load_timing_info.request_start.is_null());
256   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
257 }
258 
259 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is
260 // used.
TestLoadTimingNotReusedWithPac(const LoadTimingInfo & load_timing_info,int connect_timing_flags)261 void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
262                                     int connect_timing_flags) {
263   EXPECT_FALSE(load_timing_info.socket_reused);
264   EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
265 
266   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
267   EXPECT_LE(load_timing_info.proxy_resolve_start,
268             load_timing_info.proxy_resolve_end);
269   EXPECT_LE(load_timing_info.proxy_resolve_end,
270             load_timing_info.connect_timing.connect_start);
271   ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
272                               connect_timing_flags);
273   EXPECT_LE(load_timing_info.connect_timing.connect_end,
274             load_timing_info.send_start);
275 
276   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
277 
278   // Set at a higher level.
279   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
280   EXPECT_TRUE(load_timing_info.request_start.is_null());
281   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
282 }
283 
284 // ProxyResolver that records URLs passed to it, and that can be told what
285 // result to return.
286 class CapturingProxyResolver : public ProxyResolver {
287  public:
288   struct LookupInfo {
289     GURL url;
290     NetworkIsolationKey network_isolation_key;
291   };
292 
CapturingProxyResolver()293   CapturingProxyResolver()
294       : proxy_server_(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 80)) {}
295   ~CapturingProxyResolver() override = default;
296 
GetProxyForURL(const GURL & url,const NetworkIsolationKey & network_isolation_key,ProxyInfo * results,CompletionOnceCallback callback,std::unique_ptr<Request> * request,const NetLogWithSource & net_log)297   int GetProxyForURL(const GURL& url,
298                      const NetworkIsolationKey& network_isolation_key,
299                      ProxyInfo* results,
300                      CompletionOnceCallback callback,
301                      std::unique_ptr<Request>* request,
302                      const NetLogWithSource& net_log) override {
303     results->UseProxyServer(proxy_server_);
304     lookup_info_.push_back(LookupInfo{url, network_isolation_key});
305     return OK;
306   }
307 
308   // Sets whether the resolver should use direct connections, instead of a
309   // proxy.
set_proxy_server(ProxyServer proxy_server)310   void set_proxy_server(ProxyServer proxy_server) {
311     proxy_server_ = proxy_server;
312   }
313 
lookup_info() const314   const std::vector<LookupInfo>& lookup_info() const { return lookup_info_; }
315 
316  private:
317   std::vector<LookupInfo> lookup_info_;
318 
319   ProxyServer proxy_server_;
320 
321   DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
322 };
323 
324 class CapturingProxyResolverFactory : public ProxyResolverFactory {
325  public:
CapturingProxyResolverFactory(CapturingProxyResolver * resolver)326   explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
327       : ProxyResolverFactory(false), resolver_(resolver) {}
328 
CreateProxyResolver(const scoped_refptr<PacFileData> & pac_script,std::unique_ptr<ProxyResolver> * resolver,CompletionOnceCallback callback,std::unique_ptr<Request> * request)329   int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
330                           std::unique_ptr<ProxyResolver>* resolver,
331                           CompletionOnceCallback callback,
332                           std::unique_ptr<Request>* request) override {
333     *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
334     return OK;
335   }
336 
337  private:
338   ProxyResolver* resolver_;
339 };
340 
CreateSession(SpdySessionDependencies * session_deps)341 std::unique_ptr<HttpNetworkSession> CreateSession(
342     SpdySessionDependencies* session_deps) {
343   return SpdySessionDependencies::SpdyCreateSession(session_deps);
344 }
345 
346 class FailingProxyResolverFactory : public ProxyResolverFactory {
347  public:
FailingProxyResolverFactory()348   FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
349 
350   // ProxyResolverFactory override.
CreateProxyResolver(const scoped_refptr<PacFileData> & script_data,std::unique_ptr<ProxyResolver> * result,CompletionOnceCallback callback,std::unique_ptr<Request> * request)351   int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
352                           std::unique_ptr<ProxyResolver>* result,
353                           CompletionOnceCallback callback,
354                           std::unique_ptr<Request>* request) override {
355     return ERR_PAC_SCRIPT_FAILED;
356   }
357 };
358 
359 }  // namespace
360 
361 class HttpNetworkTransactionTest : public PlatformTest,
362                                    public WithTaskEnvironment {
363  public:
~HttpNetworkTransactionTest()364   ~HttpNetworkTransactionTest() override {
365     // Important to restore the per-pool limit first, since the pool limit must
366     // always be greater than group limit, and the tests reduce both limits.
367     ClientSocketPoolManager::set_max_sockets_per_pool(
368         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
369     ClientSocketPoolManager::set_max_sockets_per_group(
370         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
371   }
372 
373  protected:
HttpNetworkTransactionTest()374   HttpNetworkTransactionTest()
375       : WithTaskEnvironment(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
376         dummy_connect_job_params_(
377             nullptr /* client_socket_factory */,
378             nullptr /* host_resolver */,
379             nullptr /* http_auth_cache */,
380             nullptr /* http_auth_handler_factory */,
381             nullptr /* spdy_session_pool */,
382             nullptr /* quic_supported_versions */,
383             nullptr /* quic_stream_factory */,
384             nullptr /* proxy_delegate */,
385             nullptr /* http_user_agent_settings */,
386             nullptr /* ssl_client_context */,
387             nullptr /* socket_performance_watcher_factory */,
388             nullptr /* network_quality_estimator */,
389             nullptr /* net_log */,
390             nullptr /* websocket_endpoint_lock_manager */),
391         ssl_(ASYNC, OK),
392         old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
393             HttpNetworkSession::NORMAL_SOCKET_POOL)),
394         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
395             HttpNetworkSession::NORMAL_SOCKET_POOL)) {
396     session_deps_.enable_http2_alternative_service = true;
397   }
398 
399   struct SimpleGetHelperResult {
400     int rv;
401     std::string status_line;
402     std::string response_data;
403     int64_t total_received_bytes;
404     int64_t total_sent_bytes;
405     LoadTimingInfo load_timing_info;
406     ConnectionAttempts connection_attempts;
407     IPEndPoint remote_endpoint_after_start;
408   };
409 
SetUp()410   void SetUp() override {
411     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
412     base::RunLoop().RunUntilIdle();
413     // Set an initial delay to ensure that the first call to TimeTicks::Now()
414     // before incrementing the counter does not return a null value.
415     FastForwardBy(base::TimeDelta::FromSeconds(1));
416   }
417 
TearDown()418   void TearDown() override {
419     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
420     base::RunLoop().RunUntilIdle();
421     // Empty the current queue.
422     base::RunLoop().RunUntilIdle();
423     PlatformTest::TearDown();
424     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
425     base::RunLoop().RunUntilIdle();
426   }
427 
428   void Check100ResponseTiming(bool use_spdy);
429 
430   // Either |write_failure| specifies a write failure or |read_failure|
431   // specifies a read failure when using a reused socket.  In either case, the
432   // failure should cause the network transaction to resend the request, and the
433   // other argument should be NULL.
434   void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
435                                             const MockRead* read_failure);
436 
437   // Either |write_failure| specifies a write failure or |read_failure|
438   // specifies a read failure when using a reused socket.  In either case, the
439   // failure should cause the network transaction to resend the request, and the
440   // other argument should be NULL.
441   void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
442                                         const MockRead* read_failure,
443                                         bool use_spdy);
444 
SimpleGetHelperForData(base::span<StaticSocketDataProvider * > providers)445   SimpleGetHelperResult SimpleGetHelperForData(
446       base::span<StaticSocketDataProvider*> providers) {
447     SimpleGetHelperResult out;
448 
449     HttpRequestInfo request;
450     request.method = "GET";
451     request.url = GURL("http://www.example.org/");
452     request.traffic_annotation =
453         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
454 
455     RecordingBoundTestNetLog log;
456     session_deps_.net_log = log.bound().net_log();
457     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
458     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
459 
460     for (auto* provider : providers) {
461       session_deps_.socket_factory->AddSocketDataProvider(provider);
462     }
463 
464     TestCompletionCallback callback;
465 
466     EXPECT_TRUE(log.bound().IsCapturing());
467     int rv = trans.Start(&request, callback.callback(), log.bound());
468     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
469 
470     out.rv = callback.WaitForResult();
471     out.total_received_bytes = trans.GetTotalReceivedBytes();
472     out.total_sent_bytes = trans.GetTotalSentBytes();
473 
474     // Even in the failure cases that use this function, connections are always
475     // successfully established before the error.
476     EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
477     TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
478 
479     if (out.rv != OK)
480       return out;
481 
482     const HttpResponseInfo* response = trans.GetResponseInfo();
483     // Can't use ASSERT_* inside helper functions like this, so
484     // return an error.
485     if (!response || !response->headers) {
486       out.rv = ERR_UNEXPECTED;
487       return out;
488     }
489     out.status_line = response->headers->GetStatusLine();
490 
491     EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
492     EXPECT_EQ(80, response->remote_endpoint.port());
493 
494     bool got_endpoint =
495         trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
496     EXPECT_EQ(got_endpoint,
497               out.remote_endpoint_after_start.address().size() > 0);
498 
499     rv = ReadTransaction(&trans, &out.response_data);
500     EXPECT_THAT(rv, IsOk());
501 
502     auto entries = log.GetEntries();
503     size_t pos = ExpectLogContainsSomewhere(
504         entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
505         NetLogEventPhase::NONE);
506     ExpectLogContainsSomewhere(
507         entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
508         NetLogEventPhase::NONE);
509 
510     EXPECT_EQ("GET / HTTP/1.1\r\n",
511               GetStringValueFromParams(entries[pos], "line"));
512 
513     EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
514               GetHeaders(entries[pos].params));
515 
516     out.total_received_bytes = trans.GetTotalReceivedBytes();
517     // The total number of sent bytes should not have changed.
518     EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
519 
520     trans.GetConnectionAttempts(&out.connection_attempts);
521     return out;
522   }
523 
SimpleGetHelper(base::span<const MockRead> data_reads)524   SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
525     MockWrite data_writes[] = {
526         MockWrite("GET / HTTP/1.1\r\n"
527                   "Host: www.example.org\r\n"
528                   "Connection: keep-alive\r\n\r\n"),
529     };
530 
531     StaticSocketDataProvider reads(data_reads, data_writes);
532     StaticSocketDataProvider* data[] = {&reads};
533     SimpleGetHelperResult out = SimpleGetHelperForData(data);
534 
535     EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
536     return out;
537   }
538 
AddSSLSocketData()539   void AddSSLSocketData() {
540     ssl_.next_proto = kProtoHTTP2;
541     ssl_.ssl_info.cert =
542         ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
543     ASSERT_TRUE(ssl_.ssl_info.cert);
544     session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
545   }
546 
547   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
548                                              int expected_status);
549 
550   void ConnectStatusHelper(const MockRead& status);
551 
552   void CheckErrorIsPassedBack(int error, IoMode mode);
553 
FastForwardByCallback(base::TimeDelta delta)554   base::RepeatingClosure FastForwardByCallback(base::TimeDelta delta) {
555     return base::BindRepeating(&HttpNetworkTransactionTest::FastForwardBy,
556                                base::Unretained(this), delta);
557   }
558 
559   const CommonConnectJobParams dummy_connect_job_params_;
560 
561   // These clocks are defined here, even though they're only used in the
562   // Reporting tests below, since they need to be destroyed after
563   // |session_deps_|.
564   base::SimpleTestClock clock_;
565   base::SimpleTestTickClock tick_clock_;
566 
567   SpdyTestUtil spdy_util_;
568   SpdySessionDependencies session_deps_;
569   SSLSocketDataProvider ssl_;
570 
571   // Original socket limits.  Some tests set these.  Safest to always restore
572   // them once each test has been run.
573   int old_max_group_sockets_;
574   int old_max_pool_sockets_;
575 };
576 
577 namespace {
578 
579 // Fill |str| with a long header list that consumes >= |size| bytes.
FillLargeHeadersString(std::string * str,int size)580 void FillLargeHeadersString(std::string* str, int size) {
581   const char row[] =
582       "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
583   const int sizeof_row = strlen(row);
584   const int num_rows = static_cast<int>(
585       ceil(static_cast<float>(size) / sizeof_row));
586   const int sizeof_data = num_rows * sizeof_row;
587   DCHECK(sizeof_data >= size);
588   str->reserve(sizeof_data);
589 
590   for (int i = 0; i < num_rows; ++i)
591     str->append(row, sizeof_row);
592 }
593 
594 #if defined(NTLM_PORTABLE)
MockGetMSTime()595 uint64_t MockGetMSTime() {
596   // Tue, 23 May 2017 20:13:07 +0000
597   return 131400439870000000;
598 }
599 
600 // Alternative functions that eliminate randomness and dependency on the local
601 // host name so that the generated NTLM messages are reproducible.
MockGenerateRandom(uint8_t * output,size_t n)602 void MockGenerateRandom(uint8_t* output, size_t n) {
603   // This is set to 0xaa because the client challenge for testing in
604   // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
605   memset(output, 0xaa, n);
606 }
607 
MockGetHostName()608 std::string MockGetHostName() {
609   return ntlm::test::kHostnameAscii;
610 }
611 #endif  // defined(NTLM_PORTABLE)
612 
613 class CaptureGroupIdTransportSocketPool : public TransportClientSocketPool {
614  public:
CaptureGroupIdTransportSocketPool(const CommonConnectJobParams * common_connect_job_params)615   explicit CaptureGroupIdTransportSocketPool(
616       const CommonConnectJobParams* common_connect_job_params)
617       : TransportClientSocketPool(0,
618                                   0,
619                                   base::TimeDelta(),
620                                   ProxyServer::Direct(),
621                                   false /* is_for_websockets */,
622                                   common_connect_job_params) {}
623 
last_group_id_received() const624   const ClientSocketPool::GroupId& last_group_id_received() const {
625     return last_group_id_;
626   }
627 
socket_requested() const628   bool socket_requested() const { return socket_requested_; }
629 
RequestSocket(const ClientSocketPool::GroupId & group_id,scoped_refptr<ClientSocketPool::SocketParams> socket_params,const base::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)630   int RequestSocket(
631       const ClientSocketPool::GroupId& group_id,
632       scoped_refptr<ClientSocketPool::SocketParams> socket_params,
633       const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
634       RequestPriority priority,
635       const SocketTag& socket_tag,
636       ClientSocketPool::RespectLimits respect_limits,
637       ClientSocketHandle* handle,
638       CompletionOnceCallback callback,
639       const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback,
640       const NetLogWithSource& net_log) override {
641     last_group_id_ = group_id;
642     socket_requested_ = true;
643     return ERR_IO_PENDING;
644   }
CancelRequest(const ClientSocketPool::GroupId & group_id,ClientSocketHandle * handle,bool cancel_connect_job)645   void CancelRequest(const ClientSocketPool::GroupId& group_id,
646                      ClientSocketHandle* handle,
647                      bool cancel_connect_job) override {}
ReleaseSocket(const ClientSocketPool::GroupId & group_id,std::unique_ptr<StreamSocket> socket,int64_t generation)648   void ReleaseSocket(const ClientSocketPool::GroupId& group_id,
649                      std::unique_ptr<StreamSocket> socket,
650                      int64_t generation) override {}
CloseIdleSockets(const char * net_log_reason_utf8)651   void CloseIdleSockets(const char* net_log_reason_utf8) override {}
CloseIdleSocketsInGroup(const ClientSocketPool::GroupId & group_id,const char * net_log_reason_utf8)652   void CloseIdleSocketsInGroup(const ClientSocketPool::GroupId& group_id,
653                                const char* net_log_reason_utf8) override {}
IdleSocketCount() const654   int IdleSocketCount() const override { return 0; }
IdleSocketCountInGroup(const ClientSocketPool::GroupId & group_id) const655   size_t IdleSocketCountInGroup(
656       const ClientSocketPool::GroupId& group_id) const override {
657     return 0;
658   }
GetLoadState(const ClientSocketPool::GroupId & group_id,const ClientSocketHandle * handle) const659   LoadState GetLoadState(const ClientSocketPool::GroupId& group_id,
660                          const ClientSocketHandle* handle) const override {
661     return LOAD_STATE_IDLE;
662   }
663 
664  private:
665   ClientSocketPool::GroupId last_group_id_;
666   bool socket_requested_ = false;
667 };
668 
669 //-----------------------------------------------------------------------------
670 
671 // Helper functions for validating that AuthChallengeInfo's are correctly
672 // configured for common cases.
CheckBasicServerAuth(const base::Optional<AuthChallengeInfo> & auth_challenge)673 bool CheckBasicServerAuth(
674     const base::Optional<AuthChallengeInfo>& auth_challenge) {
675   if (!auth_challenge)
676     return false;
677   EXPECT_FALSE(auth_challenge->is_proxy);
678   EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
679   EXPECT_EQ("MyRealm1", auth_challenge->realm);
680   EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
681   return true;
682 }
683 
CheckBasicSecureServerAuth(const base::Optional<AuthChallengeInfo> & auth_challenge)684 bool CheckBasicSecureServerAuth(
685     const base::Optional<AuthChallengeInfo>& auth_challenge) {
686   if (!auth_challenge)
687     return false;
688   EXPECT_FALSE(auth_challenge->is_proxy);
689   EXPECT_EQ("https://www.example.org", auth_challenge->challenger.Serialize());
690   EXPECT_EQ("MyRealm1", auth_challenge->realm);
691   EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
692   return true;
693 }
694 
CheckBasicProxyAuth(const base::Optional<AuthChallengeInfo> & auth_challenge)695 bool CheckBasicProxyAuth(
696     const base::Optional<AuthChallengeInfo>& auth_challenge) {
697   if (!auth_challenge)
698     return false;
699   EXPECT_TRUE(auth_challenge->is_proxy);
700   EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
701   EXPECT_EQ("MyRealm1", auth_challenge->realm);
702   EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
703   return true;
704 }
705 
CheckBasicSecureProxyAuth(const base::Optional<AuthChallengeInfo> & auth_challenge)706 bool CheckBasicSecureProxyAuth(
707     const base::Optional<AuthChallengeInfo>& auth_challenge) {
708   if (!auth_challenge)
709     return false;
710   EXPECT_TRUE(auth_challenge->is_proxy);
711   EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
712   EXPECT_EQ("MyRealm1", auth_challenge->realm);
713   EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
714   return true;
715 }
716 
CheckDigestServerAuth(const base::Optional<AuthChallengeInfo> & auth_challenge)717 bool CheckDigestServerAuth(
718     const base::Optional<AuthChallengeInfo>& auth_challenge) {
719   if (!auth_challenge)
720     return false;
721   EXPECT_FALSE(auth_challenge->is_proxy);
722   EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
723   EXPECT_EQ("digestive", auth_challenge->realm);
724   EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
725   return true;
726 }
727 
728 #if defined(NTLM_PORTABLE)
CheckNTLMServerAuth(const base::Optional<AuthChallengeInfo> & auth_challenge)729 bool CheckNTLMServerAuth(
730     const base::Optional<AuthChallengeInfo>& auth_challenge) {
731   if (!auth_challenge)
732     return false;
733   EXPECT_FALSE(auth_challenge->is_proxy);
734   EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
735   EXPECT_EQ(std::string(), auth_challenge->realm);
736   EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
737   return true;
738 }
739 
CheckNTLMProxyAuth(const base::Optional<AuthChallengeInfo> & auth_challenge)740 bool CheckNTLMProxyAuth(
741     const base::Optional<AuthChallengeInfo>& auth_challenge) {
742   if (!auth_challenge)
743     return false;
744   EXPECT_TRUE(auth_challenge->is_proxy);
745   EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
746   EXPECT_EQ(std::string(), auth_challenge->realm);
747   EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
748   return true;
749 }
750 #endif  // defined(NTLM_PORTABLE)
751 
752 }  // namespace
753 
754 // TODO(950069): Add testing for frame_origin in NetworkIsolationKey
755 // using kAppendInitiatingFrameOriginToNetworkIsolationKey.
756 
TEST_F(HttpNetworkTransactionTest,Basic)757 TEST_F(HttpNetworkTransactionTest, Basic) {
758   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
759   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
760 }
761 
TEST_F(HttpNetworkTransactionTest,SimpleGET)762 TEST_F(HttpNetworkTransactionTest, SimpleGET) {
763   MockRead data_reads[] = {
764     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
765     MockRead("hello world"),
766     MockRead(SYNCHRONOUS, OK),
767   };
768   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
769   EXPECT_THAT(out.rv, IsOk());
770   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
771   EXPECT_EQ("hello world", out.response_data);
772   int64_t reads_size = CountReadBytes(data_reads);
773   EXPECT_EQ(reads_size, out.total_received_bytes);
774   EXPECT_EQ(0u, out.connection_attempts.size());
775 
776   EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
777 }
778 
779 // Response with no status line.
TEST_F(HttpNetworkTransactionTest,SimpleGETNoHeaders)780 TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
781   MockRead data_reads[] = {
782     MockRead("hello world"),
783     MockRead(SYNCHRONOUS, OK),
784   };
785   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
786   EXPECT_THAT(out.rv, IsOk());
787   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
788   EXPECT_EQ("hello world", out.response_data);
789   int64_t reads_size = CountReadBytes(data_reads);
790   EXPECT_EQ(reads_size, out.total_received_bytes);
791 }
792 
793 // Response with no status line, and a weird port.  Should fail by default.
TEST_F(HttpNetworkTransactionTest,SimpleGETNoHeadersWeirdPort)794 TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
795   MockRead data_reads[] = {
796       MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
797   };
798 
799   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
800   session_deps_.socket_factory->AddSocketDataProvider(&data);
801 
802   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
803 
804   HttpRequestInfo request;
805   auto trans =
806       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
807 
808   request.method = "GET";
809   request.url = GURL("http://www.example.com:2000/");
810   request.traffic_annotation =
811       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
812 
813   TestCompletionCallback callback;
814   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
815   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
816 }
817 
818 // Tests that request info can be destroyed after the headers phase is complete.
TEST_F(HttpNetworkTransactionTest,SimpleGETNoReadDestroyRequestInfo)819 TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
820   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
821   auto trans =
822       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
823 
824   MockRead data_reads[] = {
825       MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
826       MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
827   };
828   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
829   session_deps_.socket_factory->AddSocketDataProvider(&data);
830 
831   TestCompletionCallback callback;
832 
833   {
834     auto request = std::make_unique<HttpRequestInfo>();
835     request->method = "GET";
836     request->url = GURL("http://www.example.org/");
837     request->traffic_annotation =
838         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
839 
840     int rv =
841         trans->Start(request.get(), callback.callback(), NetLogWithSource());
842 
843     EXPECT_THAT(callback.GetResult(rv), IsOk());
844   }  // Let request info be destroyed.
845 
846   trans.reset();
847 }
848 
849 // Test that a failure in resolving the hostname is retrievable.
TEST_F(HttpNetworkTransactionTest,SimpleGETHostResolutionFailure)850 TEST_F(HttpNetworkTransactionTest, SimpleGETHostResolutionFailure) {
851   HttpRequestInfo request;
852   request.method = "GET";
853   request.url = GURL("http://www.example.org/");
854   request.traffic_annotation =
855       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
856 
857   RecordingTestNetLog log;
858   MockHostResolver* resolver = new MockHostResolver();
859   resolver->rules()->AddSimulatedTimeoutFailure("www.example.org");
860   session_deps_.net_log = &log;
861   session_deps_.host_resolver.reset(resolver);
862   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
863   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
864   TestCompletionCallback callback;
865 
866   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
867   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
868   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
869 
870   const HttpResponseInfo* response = trans.GetResponseInfo();
871   ASSERT_TRUE(response);
872   EXPECT_THAT(response->resolve_error_info.error, IsError(ERR_DNS_TIMED_OUT));
873 }
874 
875 // Allow up to 4 bytes of junk to precede status line.
TEST_F(HttpNetworkTransactionTest,StatusLineJunk3Bytes)876 TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
877   MockRead data_reads[] = {
878     MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
879     MockRead(SYNCHRONOUS, OK),
880   };
881   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
882   EXPECT_THAT(out.rv, IsOk());
883   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
884   EXPECT_EQ("DATA", out.response_data);
885   int64_t reads_size = CountReadBytes(data_reads);
886   EXPECT_EQ(reads_size, out.total_received_bytes);
887 }
888 
889 // Allow up to 4 bytes of junk to precede status line.
TEST_F(HttpNetworkTransactionTest,StatusLineJunk4Bytes)890 TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
891   MockRead data_reads[] = {
892     MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
893     MockRead(SYNCHRONOUS, OK),
894   };
895   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
896   EXPECT_THAT(out.rv, IsOk());
897   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
898   EXPECT_EQ("DATA", out.response_data);
899   int64_t reads_size = CountReadBytes(data_reads);
900   EXPECT_EQ(reads_size, out.total_received_bytes);
901 }
902 
903 // Beyond 4 bytes of slop and it should fail to find a status line.
TEST_F(HttpNetworkTransactionTest,StatusLineJunk5Bytes)904 TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
905   MockRead data_reads[] = {
906     MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
907     MockRead(SYNCHRONOUS, OK),
908   };
909   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
910   EXPECT_THAT(out.rv, IsOk());
911   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
912   EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
913   int64_t reads_size = CountReadBytes(data_reads);
914   EXPECT_EQ(reads_size, out.total_received_bytes);
915 }
916 
917 // Same as StatusLineJunk4Bytes, except the read chunks are smaller.
TEST_F(HttpNetworkTransactionTest,StatusLineJunk4Bytes_Slow)918 TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
919   MockRead data_reads[] = {
920     MockRead("\n"),
921     MockRead("\n"),
922     MockRead("Q"),
923     MockRead("J"),
924     MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
925     MockRead(SYNCHRONOUS, OK),
926   };
927   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
928   EXPECT_THAT(out.rv, IsOk());
929   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
930   EXPECT_EQ("DATA", out.response_data);
931   int64_t reads_size = CountReadBytes(data_reads);
932   EXPECT_EQ(reads_size, out.total_received_bytes);
933 }
934 
935 // Close the connection before enough bytes to have a status line.
TEST_F(HttpNetworkTransactionTest,StatusLinePartial)936 TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
937   MockRead data_reads[] = {
938     MockRead("HTT"),
939     MockRead(SYNCHRONOUS, OK),
940   };
941   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
942   EXPECT_THAT(out.rv, IsOk());
943   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
944   EXPECT_EQ("HTT", out.response_data);
945   int64_t reads_size = CountReadBytes(data_reads);
946   EXPECT_EQ(reads_size, out.total_received_bytes);
947 }
948 
949 // Simulate a 204 response, lacking a Content-Length header, sent over a
950 // persistent connection.  The response should still terminate since a 204
951 // cannot have a response body.
TEST_F(HttpNetworkTransactionTest,StopsReading204)952 TEST_F(HttpNetworkTransactionTest, StopsReading204) {
953   char junk[] = "junk";
954   MockRead data_reads[] = {
955     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
956     MockRead(junk),  // Should not be read!!
957     MockRead(SYNCHRONOUS, OK),
958   };
959   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
960   EXPECT_THAT(out.rv, IsOk());
961   EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
962   EXPECT_EQ("", out.response_data);
963   int64_t reads_size = CountReadBytes(data_reads);
964   int64_t response_size = reads_size - strlen(junk);
965   EXPECT_EQ(response_size, out.total_received_bytes);
966 }
967 
968 // A simple request using chunked encoding with some extra data after.
TEST_F(HttpNetworkTransactionTest,ChunkedEncoding)969 TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
970   std::string final_chunk = "0\r\n\r\n";
971   std::string extra_data = "HTTP/1.1 200 OK\r\n";
972   std::string last_read = final_chunk + extra_data;
973   MockRead data_reads[] = {
974     MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
975     MockRead("5\r\nHello\r\n"),
976     MockRead("1\r\n"),
977     MockRead(" \r\n"),
978     MockRead("5\r\nworld\r\n"),
979     MockRead(last_read.data()),
980     MockRead(SYNCHRONOUS, OK),
981   };
982   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
983   EXPECT_THAT(out.rv, IsOk());
984   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
985   EXPECT_EQ("Hello world", out.response_data);
986   int64_t reads_size = CountReadBytes(data_reads);
987   int64_t response_size = reads_size - extra_data.size();
988   EXPECT_EQ(response_size, out.total_received_bytes);
989 }
990 
991 // Next tests deal with http://crbug.com/56344.
992 
TEST_F(HttpNetworkTransactionTest,MultipleContentLengthHeadersNoTransferEncoding)993 TEST_F(HttpNetworkTransactionTest,
994        MultipleContentLengthHeadersNoTransferEncoding) {
995   MockRead data_reads[] = {
996     MockRead("HTTP/1.1 200 OK\r\n"),
997     MockRead("Content-Length: 10\r\n"),
998     MockRead("Content-Length: 5\r\n\r\n"),
999   };
1000   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1001   EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
1002 }
1003 
TEST_F(HttpNetworkTransactionTest,DuplicateContentLengthHeadersNoTransferEncoding)1004 TEST_F(HttpNetworkTransactionTest,
1005        DuplicateContentLengthHeadersNoTransferEncoding) {
1006   MockRead data_reads[] = {
1007     MockRead("HTTP/1.1 200 OK\r\n"),
1008     MockRead("Content-Length: 5\r\n"),
1009     MockRead("Content-Length: 5\r\n\r\n"),
1010     MockRead("Hello"),
1011   };
1012   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1013   EXPECT_THAT(out.rv, IsOk());
1014   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1015   EXPECT_EQ("Hello", out.response_data);
1016 }
1017 
TEST_F(HttpNetworkTransactionTest,ComplexContentLengthHeadersNoTransferEncoding)1018 TEST_F(HttpNetworkTransactionTest,
1019        ComplexContentLengthHeadersNoTransferEncoding) {
1020   // More than 2 dupes.
1021   {
1022     MockRead data_reads[] = {
1023       MockRead("HTTP/1.1 200 OK\r\n"),
1024       MockRead("Content-Length: 5\r\n"),
1025       MockRead("Content-Length: 5\r\n"),
1026       MockRead("Content-Length: 5\r\n\r\n"),
1027       MockRead("Hello"),
1028     };
1029     SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1030     EXPECT_THAT(out.rv, IsOk());
1031     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1032     EXPECT_EQ("Hello", out.response_data);
1033   }
1034   // HTTP/1.0
1035   {
1036     MockRead data_reads[] = {
1037       MockRead("HTTP/1.0 200 OK\r\n"),
1038       MockRead("Content-Length: 5\r\n"),
1039       MockRead("Content-Length: 5\r\n"),
1040       MockRead("Content-Length: 5\r\n\r\n"),
1041       MockRead("Hello"),
1042     };
1043     SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1044     EXPECT_THAT(out.rv, IsOk());
1045     EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1046     EXPECT_EQ("Hello", out.response_data);
1047   }
1048   // 2 dupes and one mismatched.
1049   {
1050     MockRead data_reads[] = {
1051       MockRead("HTTP/1.1 200 OK\r\n"),
1052       MockRead("Content-Length: 10\r\n"),
1053       MockRead("Content-Length: 10\r\n"),
1054       MockRead("Content-Length: 5\r\n\r\n"),
1055     };
1056     SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1057     EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
1058   }
1059 }
1060 
TEST_F(HttpNetworkTransactionTest,MultipleContentLengthHeadersTransferEncoding)1061 TEST_F(HttpNetworkTransactionTest,
1062        MultipleContentLengthHeadersTransferEncoding) {
1063   MockRead data_reads[] = {
1064     MockRead("HTTP/1.1 200 OK\r\n"),
1065     MockRead("Content-Length: 666\r\n"),
1066     MockRead("Content-Length: 1337\r\n"),
1067     MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1068     MockRead("5\r\nHello\r\n"),
1069     MockRead("1\r\n"),
1070     MockRead(" \r\n"),
1071     MockRead("5\r\nworld\r\n"),
1072     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
1073     MockRead(SYNCHRONOUS, OK),
1074   };
1075   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1076   EXPECT_THAT(out.rv, IsOk());
1077   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1078   EXPECT_EQ("Hello world", out.response_data);
1079 }
1080 
1081 // Next tests deal with http://crbug.com/98895.
1082 
1083 // Checks that a single Content-Disposition header results in no error.
TEST_F(HttpNetworkTransactionTest,SingleContentDispositionHeader)1084 TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
1085   MockRead data_reads[] = {
1086     MockRead("HTTP/1.1 200 OK\r\n"),
1087     MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1088     MockRead("Content-Length: 5\r\n\r\n"),
1089     MockRead("Hello"),
1090   };
1091   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1092   EXPECT_THAT(out.rv, IsOk());
1093   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1094   EXPECT_EQ("Hello", out.response_data);
1095 }
1096 
1097 // Checks that two identical Content-Disposition headers result in no error.
TEST_F(HttpNetworkTransactionTest,TwoIdenticalContentDispositionHeaders)1098 TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
1099   MockRead data_reads[] = {
1100     MockRead("HTTP/1.1 200 OK\r\n"),
1101     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1102     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1103     MockRead("Content-Length: 5\r\n\r\n"),
1104     MockRead("Hello"),
1105   };
1106   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1107   EXPECT_THAT(out.rv, IsOk());
1108   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1109   EXPECT_EQ("Hello", out.response_data);
1110 }
1111 
1112 // Checks that two distinct Content-Disposition headers result in an error.
TEST_F(HttpNetworkTransactionTest,TwoDistinctContentDispositionHeaders)1113 TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
1114   MockRead data_reads[] = {
1115     MockRead("HTTP/1.1 200 OK\r\n"),
1116     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1117     MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1118     MockRead("Content-Length: 5\r\n\r\n"),
1119     MockRead("Hello"),
1120   };
1121   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1122   EXPECT_THAT(out.rv,
1123               IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
1124 }
1125 
1126 // Checks that two identical Location headers result in no error.
1127 // Also tests Location header behavior.
TEST_F(HttpNetworkTransactionTest,TwoIdenticalLocationHeaders)1128 TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
1129   MockRead data_reads[] = {
1130     MockRead("HTTP/1.1 302 Redirect\r\n"),
1131     MockRead("Location: http://good.com/\r\n"),
1132     MockRead("Location: http://good.com/\r\n"),
1133     MockRead("Content-Length: 0\r\n\r\n"),
1134     MockRead(SYNCHRONOUS, OK),
1135   };
1136 
1137   HttpRequestInfo request;
1138   request.method = "GET";
1139   request.url = GURL("http://redirect.com/");
1140   request.traffic_annotation =
1141       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1142 
1143   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1144   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1145 
1146   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1147   session_deps_.socket_factory->AddSocketDataProvider(&data);
1148 
1149   TestCompletionCallback callback;
1150 
1151   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1152   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1153 
1154   EXPECT_THAT(callback.WaitForResult(), IsOk());
1155 
1156   const HttpResponseInfo* response = trans.GetResponseInfo();
1157   ASSERT_TRUE(response);
1158   ASSERT_TRUE(response->headers);
1159   EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1160   std::string url;
1161   EXPECT_TRUE(response->headers->IsRedirect(&url));
1162   EXPECT_EQ("http://good.com/", url);
1163   EXPECT_TRUE(response->proxy_server.is_direct());
1164 }
1165 
1166 // Checks that two distinct Location headers result in an error.
TEST_F(HttpNetworkTransactionTest,TwoDistinctLocationHeaders)1167 TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
1168   MockRead data_reads[] = {
1169     MockRead("HTTP/1.1 302 Redirect\r\n"),
1170     MockRead("Location: http://good.com/\r\n"),
1171     MockRead("Location: http://evil.com/\r\n"),
1172     MockRead("Content-Length: 0\r\n\r\n"),
1173     MockRead(SYNCHRONOUS, OK),
1174   };
1175   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
1176   EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
1177 }
1178 
1179 // Do a request using the HEAD method. Verify that we don't try to read the
1180 // message body (since HEAD has none).
TEST_F(HttpNetworkTransactionTest,Head)1181 TEST_F(HttpNetworkTransactionTest, Head) {
1182   HttpRequestInfo request;
1183   request.method = "HEAD";
1184   request.url = GURL("http://www.example.org/");
1185   request.traffic_annotation =
1186       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1187 
1188   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1189   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1190 
1191   MockWrite data_writes1[] = {
1192       MockWrite("HEAD / HTTP/1.1\r\n"
1193                 "Host: www.example.org\r\n"
1194                 "Connection: keep-alive\r\n\r\n"),
1195   };
1196   MockRead data_reads1[] = {
1197       MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1198       MockRead("Content-Length: 1234\r\n\r\n"),
1199 
1200       // No response body because the test stops reading here.
1201       MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
1202   };
1203 
1204   StaticSocketDataProvider data1(data_reads1, data_writes1);
1205   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1206 
1207   TestCompletionCallback callback1;
1208 
1209   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
1210   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1211 
1212   rv = callback1.WaitForResult();
1213   EXPECT_THAT(rv, IsOk());
1214 
1215   const HttpResponseInfo* response = trans.GetResponseInfo();
1216   ASSERT_TRUE(response);
1217 
1218   // Check that the headers got parsed.
1219   EXPECT_TRUE(response->headers);
1220   EXPECT_EQ(1234, response->headers->GetContentLength());
1221   EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
1222   EXPECT_TRUE(response->proxy_server.is_direct());
1223 
1224   std::string server_header;
1225   size_t iter = 0;
1226   bool has_server_header = response->headers->EnumerateHeader(
1227       &iter, "Server", &server_header);
1228   EXPECT_TRUE(has_server_header);
1229   EXPECT_EQ("Blah", server_header);
1230 
1231   // Reading should give EOF right away, since there is no message body
1232   // (despite non-zero content-length).
1233   std::string response_data;
1234   rv = ReadTransaction(&trans, &response_data);
1235   EXPECT_THAT(rv, IsOk());
1236   EXPECT_EQ("", response_data);
1237 }
1238 
TEST_F(HttpNetworkTransactionTest,ReuseConnection)1239 TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
1240   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1241 
1242   MockRead data_reads[] = {
1243     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1244     MockRead("hello"),
1245     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1246     MockRead("world"),
1247     MockRead(SYNCHRONOUS, OK),
1248   };
1249   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1250   session_deps_.socket_factory->AddSocketDataProvider(&data);
1251 
1252   const char* const kExpectedResponseData[] = {
1253     "hello", "world"
1254   };
1255 
1256   for (int i = 0; i < 2; ++i) {
1257     HttpRequestInfo request;
1258     request.method = "GET";
1259     request.url = GURL("http://www.example.org/");
1260     request.traffic_annotation =
1261         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1262 
1263     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1264 
1265     TestCompletionCallback callback;
1266 
1267     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1268     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1269 
1270     rv = callback.WaitForResult();
1271     EXPECT_THAT(rv, IsOk());
1272 
1273     const HttpResponseInfo* response = trans.GetResponseInfo();
1274     ASSERT_TRUE(response);
1275 
1276     EXPECT_TRUE(response->headers);
1277     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1278     EXPECT_TRUE(response->proxy_server.is_direct());
1279 
1280     std::string response_data;
1281     rv = ReadTransaction(&trans, &response_data);
1282     EXPECT_THAT(rv, IsOk());
1283     EXPECT_EQ(kExpectedResponseData[i], response_data);
1284   }
1285 }
1286 
TEST_F(HttpNetworkTransactionTest,Ignores100)1287 TEST_F(HttpNetworkTransactionTest, Ignores100) {
1288   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
1289   element_readers.push_back(
1290       std::make_unique<UploadBytesElementReader>("foo", 3));
1291   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
1292 
1293   HttpRequestInfo request;
1294   request.method = "POST";
1295   request.url = GURL("http://www.foo.com/");
1296   request.upload_data_stream = &upload_data_stream;
1297   request.traffic_annotation =
1298       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1299 
1300   // Check the upload progress returned before initialization is correct.
1301   UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1302   EXPECT_EQ(0u, progress.size());
1303   EXPECT_EQ(0u, progress.position());
1304 
1305   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1306   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1307 
1308   MockRead data_reads[] = {
1309     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1310     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1311     MockRead("hello world"),
1312     MockRead(SYNCHRONOUS, OK),
1313   };
1314   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1315   session_deps_.socket_factory->AddSocketDataProvider(&data);
1316 
1317   TestCompletionCallback callback;
1318 
1319   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1320   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1321 
1322   rv = callback.WaitForResult();
1323   EXPECT_THAT(rv, IsOk());
1324 
1325   const HttpResponseInfo* response = trans.GetResponseInfo();
1326   ASSERT_TRUE(response);
1327 
1328   EXPECT_TRUE(response->headers);
1329   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
1330 
1331   std::string response_data;
1332   rv = ReadTransaction(&trans, &response_data);
1333   EXPECT_THAT(rv, IsOk());
1334   EXPECT_EQ("hello world", response_data);
1335 }
1336 
1337 // This test is almost the same as Ignores100 above, but the response contains
1338 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
1339 // HTTP/1.1 and the two status headers are read in one read.
TEST_F(HttpNetworkTransactionTest,Ignores1xx)1340 TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
1341   HttpRequestInfo request;
1342   request.method = "GET";
1343   request.url = GURL("http://www.foo.com/");
1344   request.traffic_annotation =
1345       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1346 
1347   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1348   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1349 
1350   MockRead data_reads[] = {
1351     MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1352              "HTTP/1.1 200 OK\r\n\r\n"),
1353     MockRead("hello world"),
1354     MockRead(SYNCHRONOUS, OK),
1355   };
1356   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1357   session_deps_.socket_factory->AddSocketDataProvider(&data);
1358 
1359   TestCompletionCallback callback;
1360 
1361   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1362   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1363 
1364   rv = callback.WaitForResult();
1365   EXPECT_THAT(rv, IsOk());
1366 
1367   const HttpResponseInfo* response = trans.GetResponseInfo();
1368   ASSERT_TRUE(response);
1369 
1370   EXPECT_TRUE(response->headers);
1371   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1372 
1373   std::string response_data;
1374   rv = ReadTransaction(&trans, &response_data);
1375   EXPECT_THAT(rv, IsOk());
1376   EXPECT_EQ("hello world", response_data);
1377 }
1378 
TEST_F(HttpNetworkTransactionTest,LoadTimingMeasuresTimeToFirstByteForHttp)1379 TEST_F(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1380   static const base::TimeDelta kDelayAfterFirstByte =
1381       base::TimeDelta::FromMilliseconds(10);
1382 
1383   HttpRequestInfo request;
1384   request.method = "GET";
1385   request.url = GURL("http://www.foo.com/");
1386   request.traffic_annotation =
1387       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1388 
1389   std::vector<MockWrite> data_writes = {
1390       MockWrite(ASYNC, 0,
1391                 "GET / HTTP/1.1\r\n"
1392                 "Host: www.foo.com\r\n"
1393                 "Connection: keep-alive\r\n\r\n"),
1394   };
1395 
1396   std::vector<MockRead> data_reads = {
1397       // Write one byte of the status line, followed by a pause.
1398       MockRead(ASYNC, 1, "H"),
1399       MockRead(ASYNC, ERR_IO_PENDING, 2),
1400       MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1401       MockRead(ASYNC, 4, "hello world"),
1402       MockRead(SYNCHRONOUS, OK, 5),
1403   };
1404 
1405   SequencedSocketData data(data_reads, data_writes);
1406   session_deps_.socket_factory->AddSocketDataProvider(&data);
1407 
1408   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1409 
1410   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1411 
1412   TestCompletionCallback callback;
1413 
1414   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1415   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1416 
1417   data.RunUntilPaused();
1418   ASSERT_TRUE(data.IsPaused());
1419   FastForwardBy(kDelayAfterFirstByte);
1420   data.Resume();
1421 
1422   rv = callback.WaitForResult();
1423   EXPECT_THAT(rv, IsOk());
1424 
1425   const HttpResponseInfo* response = trans.GetResponseInfo();
1426   ASSERT_TRUE(response);
1427 
1428   EXPECT_TRUE(response->headers);
1429   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1430 
1431   LoadTimingInfo load_timing_info;
1432   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1433   EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1434   EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
1435   // Ensure we didn't include the delay in the TTFB time.
1436   EXPECT_EQ(load_timing_info.receive_headers_start,
1437             load_timing_info.connect_timing.connect_end);
1438   // Ensure that the mock clock advanced at all.
1439   EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1440             kDelayAfterFirstByte);
1441 
1442   std::string response_data;
1443   rv = ReadTransaction(&trans, &response_data);
1444   EXPECT_THAT(rv, IsOk());
1445   EXPECT_EQ("hello world", response_data);
1446 }
1447 
1448 // Tests that the time-to-first-byte reported in a transaction's load timing
1449 // info uses the first response, even if 1XX/informational.
Check100ResponseTiming(bool use_spdy)1450 void HttpNetworkTransactionTest::Check100ResponseTiming(bool use_spdy) {
1451   static const base::TimeDelta kDelayAfter100Response =
1452       base::TimeDelta::FromMilliseconds(10);
1453 
1454   HttpRequestInfo request;
1455   request.method = "GET";
1456   request.url = GURL("https://www.foo.com/");
1457   request.traffic_annotation =
1458       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1459 
1460   SSLSocketDataProvider ssl(ASYNC, OK);
1461   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1462 
1463   std::vector<MockWrite> data_writes;
1464   std::vector<MockRead> data_reads;
1465 
1466   spdy::SpdySerializedFrame spdy_req(
1467       spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1468 
1469   spdy::SpdyHeaderBlock spdy_resp1_headers;
1470   spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1471   spdy::SpdySerializedFrame spdy_resp1(
1472       spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1473   spdy::SpdySerializedFrame spdy_resp2(
1474       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1475   spdy::SpdySerializedFrame spdy_data(
1476       spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1477 
1478   if (use_spdy) {
1479     ssl.next_proto = kProtoHTTP2;
1480 
1481     data_writes = {CreateMockWrite(spdy_req, 0)};
1482 
1483     data_reads = {
1484         CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1485         CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1486         MockRead(SYNCHRONOUS, OK, 5),
1487     };
1488   } else {
1489     data_writes = {
1490         MockWrite(ASYNC, 0,
1491                   "GET / HTTP/1.1\r\n"
1492                   "Host: www.foo.com\r\n"
1493                   "Connection: keep-alive\r\n\r\n"),
1494     };
1495 
1496     data_reads = {
1497         MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1498         MockRead(ASYNC, ERR_IO_PENDING, 2),
1499 
1500         MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1501         MockRead(ASYNC, 4, "hello world"),
1502         MockRead(SYNCHRONOUS, OK, 5),
1503     };
1504   }
1505 
1506   SequencedSocketData data(data_reads, data_writes);
1507   session_deps_.socket_factory->AddSocketDataProvider(&data);
1508 
1509   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1510 
1511   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1512 
1513   TestCompletionCallback callback;
1514 
1515   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1516   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1517 
1518   data.RunUntilPaused();
1519   // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1520   // the delay before parsing the 200 response.
1521   ASSERT_TRUE(data.IsPaused());
1522   FastForwardBy(kDelayAfter100Response);
1523   data.Resume();
1524 
1525   rv = callback.WaitForResult();
1526   EXPECT_THAT(rv, IsOk());
1527 
1528   const HttpResponseInfo* response = trans.GetResponseInfo();
1529   ASSERT_TRUE(response);
1530 
1531   LoadTimingInfo load_timing_info;
1532   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1533   EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1534   EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
1535   // Ensure we didn't include the delay in the TTFB time.
1536   EXPECT_EQ(load_timing_info.receive_headers_start,
1537             load_timing_info.connect_timing.connect_end);
1538   // Ensure that the mock clock advanced at all.
1539   EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1540             kDelayAfter100Response);
1541 
1542   std::string response_data;
1543   rv = ReadTransaction(&trans, &response_data);
1544   EXPECT_THAT(rv, IsOk());
1545   EXPECT_EQ("hello world", response_data);
1546 }
1547 
TEST_F(HttpNetworkTransactionTest,MeasuresTimeToFirst100ResponseForHttp)1548 TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
1549   Check100ResponseTiming(false /* use_spdy */);
1550 }
1551 
TEST_F(HttpNetworkTransactionTest,MeasuresTimeToFirst100ResponseForSpdy)1552 TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
1553   Check100ResponseTiming(true /* use_spdy */);
1554 }
1555 
TEST_F(HttpNetworkTransactionTest,Incomplete100ThenEOF)1556 TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
1557   HttpRequestInfo request;
1558   request.method = "POST";
1559   request.url = GURL("http://www.foo.com/");
1560   request.traffic_annotation =
1561       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1562 
1563   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1564   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1565 
1566   MockRead data_reads[] = {
1567     MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1568     MockRead(ASYNC, 0),
1569   };
1570   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1571   session_deps_.socket_factory->AddSocketDataProvider(&data);
1572 
1573   TestCompletionCallback callback;
1574 
1575   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1576   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1577 
1578   rv = callback.WaitForResult();
1579   EXPECT_THAT(rv, IsOk());
1580 
1581   std::string response_data;
1582   rv = ReadTransaction(&trans, &response_data);
1583   EXPECT_THAT(rv, IsOk());
1584   EXPECT_EQ("", response_data);
1585 }
1586 
TEST_F(HttpNetworkTransactionTest,EmptyResponse)1587 TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
1588   HttpRequestInfo request;
1589   request.method = "POST";
1590   request.url = GURL("http://www.foo.com/");
1591   request.traffic_annotation =
1592       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1593 
1594   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1595   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1596 
1597   MockRead data_reads[] = {
1598     MockRead(ASYNC, 0),
1599   };
1600   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
1601   session_deps_.socket_factory->AddSocketDataProvider(&data);
1602 
1603   TestCompletionCallback callback;
1604 
1605   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1606   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1607 
1608   rv = callback.WaitForResult();
1609   EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
1610 }
1611 
KeepAliveConnectionResendRequestTest(const MockWrite * write_failure,const MockRead * read_failure)1612 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
1613     const MockWrite* write_failure,
1614     const MockRead* read_failure) {
1615   HttpRequestInfo request;
1616   request.method = "GET";
1617   request.url = GURL("http://www.foo.com/");
1618   request.traffic_annotation =
1619       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1620 
1621   RecordingTestNetLog net_log;
1622   session_deps_.net_log = &net_log;
1623   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1624 
1625   // Written data for successfully sending both requests.
1626   MockWrite data1_writes[] = {
1627     MockWrite("GET / HTTP/1.1\r\n"
1628               "Host: www.foo.com\r\n"
1629               "Connection: keep-alive\r\n\r\n"),
1630     MockWrite("GET / HTTP/1.1\r\n"
1631               "Host: www.foo.com\r\n"
1632               "Connection: keep-alive\r\n\r\n")
1633   };
1634 
1635   // Read results for the first request.
1636   MockRead data1_reads[] = {
1637     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1638     MockRead("hello"),
1639     MockRead(ASYNC, OK),
1640   };
1641 
1642   if (write_failure) {
1643     ASSERT_FALSE(read_failure);
1644     data1_writes[1] = *write_failure;
1645   } else {
1646     ASSERT_TRUE(read_failure);
1647     data1_reads[2] = *read_failure;
1648   }
1649 
1650   StaticSocketDataProvider data1(data1_reads, data1_writes);
1651   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1652 
1653   MockRead data2_reads[] = {
1654     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1655     MockRead("world"),
1656     MockRead(ASYNC, OK),
1657   };
1658   StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
1659   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1660 
1661   const char* const kExpectedResponseData[] = {
1662     "hello", "world"
1663   };
1664 
1665   uint32_t first_socket_log_id = NetLogSource::kInvalidId;
1666   for (int i = 0; i < 2; ++i) {
1667     TestCompletionCallback callback;
1668 
1669     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1670 
1671     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1672     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1673 
1674     rv = callback.WaitForResult();
1675     EXPECT_THAT(rv, IsOk());
1676 
1677     LoadTimingInfo load_timing_info;
1678     EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1679     TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1680     if (i == 0) {
1681       first_socket_log_id = load_timing_info.socket_log_id;
1682     } else {
1683       // The second request should be using a new socket.
1684       EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1685     }
1686 
1687     const HttpResponseInfo* response = trans.GetResponseInfo();
1688     ASSERT_TRUE(response);
1689 
1690     EXPECT_TRUE(response->headers);
1691     EXPECT_TRUE(response->proxy_server.is_direct());
1692     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1693 
1694     std::string response_data;
1695     rv = ReadTransaction(&trans, &response_data);
1696     EXPECT_THAT(rv, IsOk());
1697     EXPECT_EQ(kExpectedResponseData[i], response_data);
1698   }
1699 }
1700 
PreconnectErrorResendRequestTest(const MockWrite * write_failure,const MockRead * read_failure,bool use_spdy)1701 void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1702     const MockWrite* write_failure,
1703     const MockRead* read_failure,
1704     bool use_spdy) {
1705   HttpRequestInfo request;
1706   request.method = "GET";
1707   request.url = GURL("https://www.foo.com/");
1708   request.traffic_annotation =
1709       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1710 
1711   RecordingTestNetLog net_log;
1712   session_deps_.net_log = &net_log;
1713   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1714 
1715   SSLSocketDataProvider ssl1(ASYNC, OK);
1716   SSLSocketDataProvider ssl2(ASYNC, OK);
1717   if (use_spdy) {
1718     ssl1.next_proto = kProtoHTTP2;
1719     ssl2.next_proto = kProtoHTTP2;
1720   }
1721   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1722   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
1723 
1724   // SPDY versions of the request and response.
1725   spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1726       request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1727   spdy::SpdySerializedFrame spdy_response(
1728       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1729   spdy::SpdySerializedFrame spdy_data(
1730       spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
1731 
1732   // HTTP/1.1 versions of the request and response.
1733   const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1734       "Host: www.foo.com\r\n"
1735       "Connection: keep-alive\r\n\r\n";
1736   const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1737   const char kHttpData[] = "hello";
1738 
1739   std::vector<MockRead> data1_reads;
1740   std::vector<MockWrite> data1_writes;
1741   if (write_failure) {
1742     ASSERT_FALSE(read_failure);
1743     data1_writes.push_back(*write_failure);
1744     data1_reads.push_back(MockRead(ASYNC, OK));
1745   } else {
1746     ASSERT_TRUE(read_failure);
1747     if (use_spdy) {
1748       data1_writes.push_back(CreateMockWrite(spdy_request));
1749     } else {
1750       data1_writes.push_back(MockWrite(kHttpRequest));
1751     }
1752     data1_reads.push_back(*read_failure);
1753   }
1754 
1755   StaticSocketDataProvider data1(data1_reads, data1_writes);
1756   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1757 
1758   std::vector<MockRead> data2_reads;
1759   std::vector<MockWrite> data2_writes;
1760 
1761   if (use_spdy) {
1762     data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
1763 
1764     data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1765     data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
1766     data2_reads.push_back(MockRead(ASYNC, OK, 3));
1767   } else {
1768     data2_writes.push_back(
1769         MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1770 
1771     data2_reads.push_back(
1772         MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1773     data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1774     data2_reads.push_back(MockRead(ASYNC, OK, 3));
1775   }
1776   SequencedSocketData data2(data2_reads, data2_writes);
1777   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1778 
1779   // Preconnect a socket.
1780   session->http_stream_factory()->PreconnectStreams(1, request);
1781   // Wait for the preconnect to complete.
1782   // TODO(davidben): Some way to wait for an idle socket count might be handy.
1783   base::RunLoop().RunUntilIdle();
1784   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
1785 
1786   // Make the request.
1787   TestCompletionCallback callback;
1788 
1789   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1790 
1791   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1792   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1793 
1794   rv = callback.WaitForResult();
1795   EXPECT_THAT(rv, IsOk());
1796 
1797   LoadTimingInfo load_timing_info;
1798   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1799   TestLoadTimingNotReused(
1800       load_timing_info,
1801       CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
1802 
1803   const HttpResponseInfo* response = trans.GetResponseInfo();
1804   ASSERT_TRUE(response);
1805 
1806   EXPECT_TRUE(response->headers);
1807   if (response->was_fetched_via_spdy) {
1808     EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1809   } else {
1810     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1811   }
1812 
1813   std::string response_data;
1814   rv = ReadTransaction(&trans, &response_data);
1815   EXPECT_THAT(rv, IsOk());
1816   EXPECT_EQ(kHttpData, response_data);
1817 }
1818 
1819 // Test that we do not retry indefinitely when a server sends an error like
1820 // ERR_HTTP2_PING_FAILED, ERR_HTTP2_SERVER_REFUSED_STREAM,
1821 // ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
TEST_F(HttpNetworkTransactionTest,FiniteRetriesOnIOError)1822 TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1823   HttpRequestInfo request;
1824   request.method = "GET";
1825   request.url = GURL("https://www.foo.com/");
1826   request.traffic_annotation =
1827       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1828 
1829   // Check whether we give up after the third try.
1830 
1831   // Construct an HTTP2 request and a "Go away" response.
1832   spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1833       request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1834   spdy::SpdySerializedFrame spdy_response_go_away(
1835       spdy_util_.ConstructSpdyGoAway(0));
1836   MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1837   MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
1838 
1839   // Three go away responses.
1840   StaticSocketDataProvider data1(data_read1, data_write);
1841   StaticSocketDataProvider data2(data_read1, data_write);
1842   StaticSocketDataProvider data3(data_read1, data_write);
1843 
1844   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1845   AddSSLSocketData();
1846   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1847   AddSSLSocketData();
1848   session_deps_.socket_factory->AddSocketDataProvider(&data3);
1849   AddSSLSocketData();
1850 
1851   TestCompletionCallback callback;
1852   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1853   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1854 
1855   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1856   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1857 
1858   rv = callback.WaitForResult();
1859   EXPECT_THAT(rv, IsError(ERR_HTTP2_SERVER_REFUSED_STREAM));
1860 }
1861 
TEST_F(HttpNetworkTransactionTest,RetryTwiceOnIOError)1862 TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1863   HttpRequestInfo request;
1864   request.method = "GET";
1865   request.url = GURL("https://www.foo.com/");
1866   request.traffic_annotation =
1867       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1868 
1869   // Check whether we try atleast thrice before giving up.
1870 
1871   // Construct an HTTP2 request and a "Go away" response.
1872   spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1873       request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1874   spdy::SpdySerializedFrame spdy_response_go_away(
1875       spdy_util_.ConstructSpdyGoAway(0));
1876   MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1877   MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
1878 
1879   // Construct a non error HTTP2 response.
1880   spdy::SpdySerializedFrame spdy_response_no_error(
1881       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1882   spdy::SpdySerializedFrame spdy_data(
1883       spdy_util_.ConstructSpdyDataFrame(1, true));
1884   MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1885                            CreateMockRead(spdy_data, 2)};
1886 
1887   // Two error responses.
1888   StaticSocketDataProvider data1(data_read1, data_write);
1889   StaticSocketDataProvider data2(data_read1, data_write);
1890   // Followed by a success response.
1891   SequencedSocketData data3(data_read2, data_write);
1892 
1893   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1894   AddSSLSocketData();
1895   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1896   AddSSLSocketData();
1897   session_deps_.socket_factory->AddSocketDataProvider(&data3);
1898   AddSSLSocketData();
1899 
1900   TestCompletionCallback callback;
1901   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1902   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1903 
1904   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1905   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1906 
1907   rv = callback.WaitForResult();
1908   EXPECT_THAT(rv, IsOk());
1909 }
1910 
TEST_F(HttpNetworkTransactionTest,KeepAliveConnectionNotConnectedOnWrite)1911 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
1912   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1913   KeepAliveConnectionResendRequestTest(&write_failure, nullptr);
1914 }
1915 
TEST_F(HttpNetworkTransactionTest,KeepAliveConnectionReset)1916 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
1917   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1918   KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
1919 }
1920 
TEST_F(HttpNetworkTransactionTest,KeepAliveConnectionEOF)1921 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
1922   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1923   KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
1924 }
1925 
1926 // Make sure that on a 408 response (Request Timeout), the request is retried,
1927 // if the socket was a reused keep alive socket.
TEST_F(HttpNetworkTransactionTest,KeepAlive408)1928 TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
1929   MockRead read_failure(SYNCHRONOUS,
1930                         "HTTP/1.1 408 Request Timeout\r\n"
1931                         "Connection: Keep-Alive\r\n"
1932                         "Content-Length: 6\r\n\r\n"
1933                         "Pickle");
1934   KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
1935 }
1936 
TEST_F(HttpNetworkTransactionTest,PreconnectErrorNotConnectedOnWrite)1937 TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
1938   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1939   PreconnectErrorResendRequestTest(&write_failure, nullptr, false);
1940 }
1941 
TEST_F(HttpNetworkTransactionTest,PreconnectErrorReset)1942 TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
1943   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1944   PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
1945 }
1946 
TEST_F(HttpNetworkTransactionTest,PreconnectErrorEOF)1947 TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1948   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1949   PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
1950 }
1951 
TEST_F(HttpNetworkTransactionTest,PreconnectErrorAsyncEOF)1952 TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1953   MockRead read_failure(ASYNC, OK);  // EOF
1954   PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
1955 }
1956 
1957 // Make sure that on a 408 response (Request Timeout), the request is retried,
1958 // if the socket was a preconnected (UNUSED_IDLE) socket.
TEST_F(HttpNetworkTransactionTest,RetryOnIdle408)1959 TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
1960   MockRead read_failure(SYNCHRONOUS,
1961                         "HTTP/1.1 408 Request Timeout\r\n"
1962                         "Connection: Keep-Alive\r\n"
1963                         "Content-Length: 6\r\n\r\n"
1964                         "Pickle");
1965   KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
1966   PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
1967 }
1968 
TEST_F(HttpNetworkTransactionTest,SpdyPreconnectErrorNotConnectedOnWrite)1969 TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
1970   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1971   PreconnectErrorResendRequestTest(&write_failure, nullptr, true);
1972 }
1973 
TEST_F(HttpNetworkTransactionTest,SpdyPreconnectErrorReset)1974 TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1975   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1976   PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
1977 }
1978 
TEST_F(HttpNetworkTransactionTest,SpdyPreconnectErrorEOF)1979 TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1980   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1981   PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
1982 }
1983 
TEST_F(HttpNetworkTransactionTest,SpdyPreconnectErrorAsyncEOF)1984 TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1985   MockRead read_failure(ASYNC, OK);  // EOF
1986   PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
1987 }
1988 
TEST_F(HttpNetworkTransactionTest,NonKeepAliveConnectionReset)1989 TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
1990   HttpRequestInfo request;
1991   request.method = "GET";
1992   request.url = GURL("http://www.example.org/");
1993   request.traffic_annotation =
1994       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1995 
1996   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1997   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1998 
1999   MockRead data_reads[] = {
2000     MockRead(ASYNC, ERR_CONNECTION_RESET),
2001     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
2002     MockRead("hello world"),
2003     MockRead(SYNCHRONOUS, OK),
2004   };
2005   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
2006   session_deps_.socket_factory->AddSocketDataProvider(&data);
2007 
2008   TestCompletionCallback callback;
2009 
2010   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
2011   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2012 
2013   rv = callback.WaitForResult();
2014   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
2015 
2016   IPEndPoint endpoint;
2017   EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
2018   EXPECT_LT(0u, endpoint.address().size());
2019 }
2020 
2021 // What do various browsers do when the server closes a non-keepalive
2022 // connection without sending any response header or body?
2023 //
2024 // IE7: error page
2025 // Safari 3.1.2 (Windows): error page
2026 // Firefox 3.0.1: blank page
2027 // Opera 9.52: after five attempts, blank page
2028 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2029 // Us: error page (EMPTY_RESPONSE)
TEST_F(HttpNetworkTransactionTest,NonKeepAliveConnectionEOF)2030 TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
2031   MockRead data_reads[] = {
2032     MockRead(SYNCHRONOUS, OK),  // EOF
2033     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
2034     MockRead("hello world"),
2035     MockRead(SYNCHRONOUS, OK),
2036   };
2037   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
2038   EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
2039 }
2040 
2041 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2042 // tests. There was a bug causing HttpNetworkTransaction to hang in the
2043 // destructor in such situations.
2044 // See http://crbug.com/154712 and http://crbug.com/156609.
TEST_F(HttpNetworkTransactionTest,KeepAliveEarlyClose)2045 TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
2046   HttpRequestInfo request;
2047   request.method = "GET";
2048   request.url = GURL("http://www.example.org/");
2049   request.traffic_annotation =
2050       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2051 
2052   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2053   auto trans =
2054       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2055 
2056   MockRead data_reads[] = {
2057     MockRead("HTTP/1.0 200 OK\r\n"),
2058     MockRead("Connection: keep-alive\r\n"),
2059     MockRead("Content-Length: 100\r\n\r\n"),
2060     MockRead("hello"),
2061     MockRead(SYNCHRONOUS, 0),
2062   };
2063   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
2064   session_deps_.socket_factory->AddSocketDataProvider(&data);
2065 
2066   TestCompletionCallback callback;
2067 
2068   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
2069   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2070 
2071   rv = callback.WaitForResult();
2072   EXPECT_THAT(rv, IsOk());
2073 
2074   scoped_refptr<IOBufferWithSize> io_buf =
2075       base::MakeRefCounted<IOBufferWithSize>(100);
2076   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
2077   if (rv == ERR_IO_PENDING)
2078     rv = callback.WaitForResult();
2079   EXPECT_EQ(5, rv);
2080   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
2081   EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
2082 
2083   trans.reset();
2084   base::RunLoop().RunUntilIdle();
2085   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2086 }
2087 
TEST_F(HttpNetworkTransactionTest,KeepAliveEarlyClose2)2088 TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
2089   HttpRequestInfo request;
2090   request.method = "GET";
2091   request.url = GURL("http://www.example.org/");
2092   request.traffic_annotation =
2093       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2094 
2095   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2096   auto trans =
2097       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2098 
2099   MockRead data_reads[] = {
2100     MockRead("HTTP/1.0 200 OK\r\n"),
2101     MockRead("Connection: keep-alive\r\n"),
2102     MockRead("Content-Length: 100\r\n\r\n"),
2103     MockRead(SYNCHRONOUS, 0),
2104   };
2105   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
2106   session_deps_.socket_factory->AddSocketDataProvider(&data);
2107 
2108   TestCompletionCallback callback;
2109 
2110   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
2111   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2112 
2113   rv = callback.WaitForResult();
2114   EXPECT_THAT(rv, IsOk());
2115 
2116   scoped_refptr<IOBufferWithSize> io_buf(
2117       base::MakeRefCounted<IOBufferWithSize>(100));
2118   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
2119   if (rv == ERR_IO_PENDING)
2120     rv = callback.WaitForResult();
2121   EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
2122 
2123   trans.reset();
2124   base::RunLoop().RunUntilIdle();
2125   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2126 }
2127 
2128 // Test that we correctly reuse a keep-alive connection after not explicitly
2129 // reading the body.
TEST_F(HttpNetworkTransactionTest,KeepAliveAfterUnreadBody)2130 TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
2131   HttpRequestInfo request;
2132   request.method = "GET";
2133   request.url = GURL("http://www.foo.com/");
2134   request.traffic_annotation =
2135       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2136 
2137   RecordingTestNetLog net_log;
2138   session_deps_.net_log = &net_log;
2139   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2140 
2141   const char* request_data =
2142       "GET / HTTP/1.1\r\n"
2143       "Host: www.foo.com\r\n"
2144       "Connection: keep-alive\r\n\r\n";
2145   MockWrite data_writes[] = {
2146       MockWrite(ASYNC, 0, request_data),  MockWrite(ASYNC, 2, request_data),
2147       MockWrite(ASYNC, 4, request_data),  MockWrite(ASYNC, 6, request_data),
2148       MockWrite(ASYNC, 8, request_data),  MockWrite(ASYNC, 10, request_data),
2149       MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2150       MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2151   };
2152 
2153   // Note that because all these reads happen in the same
2154   // StaticSocketDataProvider, it shows that the same socket is being reused for
2155   // all transactions.
2156   MockRead data_reads[] = {
2157       MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2158       MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2159       MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2160       MockRead(ASYNC, 7,
2161                "HTTP/1.1 302 Found\r\n"
2162                "Content-Length: 0\r\n\r\n"),
2163       MockRead(ASYNC, 9,
2164                "HTTP/1.1 302 Found\r\n"
2165                "Content-Length: 5\r\n\r\n"
2166                "hello"),
2167       MockRead(ASYNC, 11,
2168                "HTTP/1.1 301 Moved Permanently\r\n"
2169                "Content-Length: 0\r\n\r\n"),
2170       MockRead(ASYNC, 13,
2171                "HTTP/1.1 301 Moved Permanently\r\n"
2172                "Content-Length: 5\r\n\r\n"
2173                "hello"),
2174 
2175       // In the next two rounds, IsConnectedAndIdle returns false, due to
2176       // the set_busy_before_sync_reads(true) call, while the
2177       // HttpNetworkTransaction is being shut down, but the socket is still
2178       // reuseable.  See http://crbug.com/544255.
2179       MockRead(ASYNC, 15,
2180                "HTTP/1.1 200 Hunky-Dory\r\n"
2181                "Content-Length: 5\r\n\r\n"),
2182       MockRead(SYNCHRONOUS, 16, "hello"),
2183 
2184       MockRead(ASYNC, 18,
2185                "HTTP/1.1 200 Hunky-Dory\r\n"
2186                "Content-Length: 5\r\n\r\n"
2187                "he"),
2188       MockRead(SYNCHRONOUS, 19, "llo"),
2189 
2190       // The body of the final request is actually read.
2191       MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2192       MockRead(ASYNC, 22, "hello"),
2193   };
2194   SequencedSocketData data(data_reads, data_writes);
2195   data.set_busy_before_sync_reads(true);
2196   session_deps_.socket_factory->AddSocketDataProvider(&data);
2197 
2198   const int kNumUnreadBodies = base::size(data_writes) - 1;
2199   std::string response_lines[kNumUnreadBodies];
2200 
2201   uint32_t first_socket_log_id = NetLogSource::kInvalidId;
2202   for (size_t i = 0; i < kNumUnreadBodies; ++i) {
2203     TestCompletionCallback callback;
2204 
2205     auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
2206                                                           session.get());
2207 
2208     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
2209     EXPECT_THAT(callback.GetResult(rv), IsOk());
2210 
2211     LoadTimingInfo load_timing_info;
2212     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2213     if (i == 0) {
2214       TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2215       first_socket_log_id = load_timing_info.socket_log_id;
2216     } else {
2217       TestLoadTimingReused(load_timing_info);
2218       EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2219     }
2220 
2221     const HttpResponseInfo* response = trans->GetResponseInfo();
2222     ASSERT_TRUE(response);
2223 
2224     ASSERT_TRUE(response->headers);
2225     response_lines[i] = response->headers->GetStatusLine();
2226 
2227     // Delete the transaction without reading the response bodies.  Then spin
2228     // the message loop, so the response bodies are drained.
2229     trans.reset();
2230     base::RunLoop().RunUntilIdle();
2231   }
2232 
2233   const char* const kStatusLines[] = {
2234       "HTTP/1.1 204 No Content",
2235       "HTTP/1.1 205 Reset Content",
2236       "HTTP/1.1 304 Not Modified",
2237       "HTTP/1.1 302 Found",
2238       "HTTP/1.1 302 Found",
2239       "HTTP/1.1 301 Moved Permanently",
2240       "HTTP/1.1 301 Moved Permanently",
2241       "HTTP/1.1 200 Hunky-Dory",
2242       "HTTP/1.1 200 Hunky-Dory",
2243   };
2244 
2245   static_assert(kNumUnreadBodies == base::size(kStatusLines),
2246                 "forgot to update kStatusLines");
2247 
2248   for (int i = 0; i < kNumUnreadBodies; ++i)
2249     EXPECT_EQ(kStatusLines[i], response_lines[i]);
2250 
2251   TestCompletionCallback callback;
2252   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2253   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
2254   EXPECT_THAT(callback.GetResult(rv), IsOk());
2255   const HttpResponseInfo* response = trans.GetResponseInfo();
2256   ASSERT_TRUE(response);
2257   ASSERT_TRUE(response->headers);
2258   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2259   std::string response_data;
2260   rv = ReadTransaction(&trans, &response_data);
2261   EXPECT_THAT(rv, IsOk());
2262   EXPECT_EQ("hello", response_data);
2263 }
2264 
2265 // Sockets that receive extra data after a response is complete should not be
2266 // reused.
TEST_F(HttpNetworkTransactionTest,KeepAliveWithUnusedData1)2267 TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
2268   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2269   MockWrite data_writes1[] = {
2270       MockWrite("HEAD / HTTP/1.1\r\n"
2271                 "Host: www.borked.com\r\n"
2272                 "Connection: keep-alive\r\n\r\n"),
2273   };
2274 
2275   MockRead data_reads1[] = {
2276       MockRead("HTTP/1.1 200 OK\r\n"
2277                "Connection: keep-alive\r\n"
2278                "Content-Length: 22\r\n\r\n"
2279                "This server is borked."),
2280   };
2281 
2282   MockWrite data_writes2[] = {
2283       MockWrite("GET /foo HTTP/1.1\r\n"
2284                 "Host: www.borked.com\r\n"
2285                 "Connection: keep-alive\r\n\r\n"),
2286   };
2287 
2288   MockRead data_reads2[] = {
2289       MockRead("HTTP/1.1 200 OK\r\n"
2290                "Content-Length: 3\r\n\r\n"
2291                "foo"),
2292   };
2293   StaticSocketDataProvider data1(data_reads1, data_writes1);
2294   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2295   StaticSocketDataProvider data2(data_reads2, data_writes2);
2296   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2297 
2298   TestCompletionCallback callback;
2299   HttpRequestInfo request1;
2300   request1.method = "HEAD";
2301   request1.url = GURL("http://www.borked.com/");
2302   request1.traffic_annotation =
2303       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2304 
2305   auto trans1 =
2306       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2307   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
2308   EXPECT_THAT(callback.GetResult(rv), IsOk());
2309 
2310   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2311   ASSERT_TRUE(response1);
2312   ASSERT_TRUE(response1->headers);
2313   EXPECT_EQ(200, response1->headers->response_code());
2314   EXPECT_TRUE(response1->headers->IsKeepAlive());
2315 
2316   std::string response_data1;
2317   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
2318   EXPECT_EQ("", response_data1);
2319   // Deleting the transaction attempts to release the socket back into the
2320   // socket pool.
2321   trans1.reset();
2322 
2323   HttpRequestInfo request2;
2324   request2.method = "GET";
2325   request2.url = GURL("http://www.borked.com/foo");
2326   request2.traffic_annotation =
2327       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2328 
2329   auto trans2 =
2330       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2331   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
2332   EXPECT_THAT(callback.GetResult(rv), IsOk());
2333 
2334   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2335   ASSERT_TRUE(response2);
2336   ASSERT_TRUE(response2->headers);
2337   EXPECT_EQ(200, response2->headers->response_code());
2338 
2339   std::string response_data2;
2340   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
2341   EXPECT_EQ("foo", response_data2);
2342 }
2343 
TEST_F(HttpNetworkTransactionTest,KeepAliveWithUnusedData2)2344 TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
2345   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2346   MockWrite data_writes1[] = {
2347       MockWrite("GET / HTTP/1.1\r\n"
2348                 "Host: www.borked.com\r\n"
2349                 "Connection: keep-alive\r\n\r\n"),
2350   };
2351 
2352   MockRead data_reads1[] = {
2353       MockRead("HTTP/1.1 200 OK\r\n"
2354                "Connection: keep-alive\r\n"
2355                "Content-Length: 22\r\n\r\n"
2356                "This server is borked."
2357                "Bonus data!"),
2358   };
2359 
2360   MockWrite data_writes2[] = {
2361       MockWrite("GET /foo HTTP/1.1\r\n"
2362                 "Host: www.borked.com\r\n"
2363                 "Connection: keep-alive\r\n\r\n"),
2364   };
2365 
2366   MockRead data_reads2[] = {
2367       MockRead("HTTP/1.1 200 OK\r\n"
2368                "Content-Length: 3\r\n\r\n"
2369                "foo"),
2370   };
2371   StaticSocketDataProvider data1(data_reads1, data_writes1);
2372   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2373   StaticSocketDataProvider data2(data_reads2, data_writes2);
2374   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2375 
2376   TestCompletionCallback callback;
2377   HttpRequestInfo request1;
2378   request1.method = "GET";
2379   request1.url = GURL("http://www.borked.com/");
2380   request1.traffic_annotation =
2381       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2382 
2383   auto trans1 =
2384       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2385   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
2386   EXPECT_THAT(callback.GetResult(rv), IsOk());
2387 
2388   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2389   ASSERT_TRUE(response1);
2390   ASSERT_TRUE(response1->headers);
2391   EXPECT_EQ(200, response1->headers->response_code());
2392   EXPECT_TRUE(response1->headers->IsKeepAlive());
2393 
2394   std::string response_data1;
2395   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
2396   EXPECT_EQ("This server is borked.", response_data1);
2397   // Deleting the transaction attempts to release the socket back into the
2398   // socket pool.
2399   trans1.reset();
2400 
2401   HttpRequestInfo request2;
2402   request2.method = "GET";
2403   request2.url = GURL("http://www.borked.com/foo");
2404   request2.traffic_annotation =
2405       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2406 
2407   auto trans2 =
2408       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2409   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
2410   EXPECT_THAT(callback.GetResult(rv), IsOk());
2411 
2412   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2413   ASSERT_TRUE(response2);
2414   ASSERT_TRUE(response2->headers);
2415   EXPECT_EQ(200, response2->headers->response_code());
2416 
2417   std::string response_data2;
2418   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
2419   EXPECT_EQ("foo", response_data2);
2420 }
2421 
TEST_F(HttpNetworkTransactionTest,KeepAliveWithUnusedData3)2422 TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
2423   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2424   MockWrite data_writes1[] = {
2425       MockWrite("GET / HTTP/1.1\r\n"
2426                 "Host: www.borked.com\r\n"
2427                 "Connection: keep-alive\r\n\r\n"),
2428   };
2429 
2430   MockRead data_reads1[] = {
2431       MockRead("HTTP/1.1 200 OK\r\n"
2432                "Connection: keep-alive\r\n"
2433                "Transfer-Encoding: chunked\r\n\r\n"),
2434       MockRead("16\r\nThis server is borked.\r\n"),
2435       MockRead("0\r\n\r\nBonus data!"),
2436   };
2437 
2438   MockWrite data_writes2[] = {
2439       MockWrite("GET /foo HTTP/1.1\r\n"
2440                 "Host: www.borked.com\r\n"
2441                 "Connection: keep-alive\r\n\r\n"),
2442   };
2443 
2444   MockRead data_reads2[] = {
2445       MockRead("HTTP/1.1 200 OK\r\n"
2446                "Content-Length: 3\r\n\r\n"
2447                "foo"),
2448   };
2449   StaticSocketDataProvider data1(data_reads1, data_writes1);
2450   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2451   StaticSocketDataProvider data2(data_reads2, data_writes2);
2452   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2453 
2454   TestCompletionCallback callback;
2455   HttpRequestInfo request1;
2456   request1.method = "GET";
2457   request1.url = GURL("http://www.borked.com/");
2458   request1.traffic_annotation =
2459       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2460 
2461   auto trans1 =
2462       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2463   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
2464   EXPECT_THAT(callback.GetResult(rv), IsOk());
2465 
2466   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2467   ASSERT_TRUE(response1);
2468   ASSERT_TRUE(response1->headers);
2469   EXPECT_EQ(200, response1->headers->response_code());
2470   EXPECT_TRUE(response1->headers->IsKeepAlive());
2471 
2472   std::string response_data1;
2473   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
2474   EXPECT_EQ("This server is borked.", response_data1);
2475   // Deleting the transaction attempts to release the socket back into the
2476   // socket pool.
2477   trans1.reset();
2478 
2479   HttpRequestInfo request2;
2480   request2.method = "GET";
2481   request2.url = GURL("http://www.borked.com/foo");
2482   request2.traffic_annotation =
2483       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2484 
2485   auto trans2 =
2486       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2487   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
2488   EXPECT_THAT(callback.GetResult(rv), IsOk());
2489 
2490   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2491   ASSERT_TRUE(response2);
2492   ASSERT_TRUE(response2->headers);
2493   EXPECT_EQ(200, response2->headers->response_code());
2494 
2495   std::string response_data2;
2496   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
2497   EXPECT_EQ("foo", response_data2);
2498 }
2499 
2500 // This is a little different from the others - it tests the case that the
2501 // HttpStreamParser doesn't know if there's extra data on a socket or not when
2502 // the HttpNetworkTransaction is torn down, because the response body hasn't
2503 // been read from yet, but the request goes through the HttpResponseBodyDrainer.
TEST_F(HttpNetworkTransactionTest,KeepAliveWithUnusedData4)2504 TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
2505   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2506   MockWrite data_writes1[] = {
2507       MockWrite("GET / HTTP/1.1\r\n"
2508                 "Host: www.borked.com\r\n"
2509                 "Connection: keep-alive\r\n\r\n"),
2510   };
2511 
2512   MockRead data_reads1[] = {
2513       MockRead("HTTP/1.1 200 OK\r\n"
2514                "Connection: keep-alive\r\n"
2515                "Transfer-Encoding: chunked\r\n\r\n"),
2516       MockRead("16\r\nThis server is borked.\r\n"),
2517       MockRead("0\r\n\r\nBonus data!"),
2518   };
2519   StaticSocketDataProvider data1(data_reads1, data_writes1);
2520   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2521 
2522   TestCompletionCallback callback;
2523   HttpRequestInfo request1;
2524   request1.method = "GET";
2525   request1.url = GURL("http://www.borked.com/");
2526   request1.traffic_annotation =
2527       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2528 
2529   auto trans =
2530       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2531   int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
2532   EXPECT_THAT(callback.GetResult(rv), IsOk());
2533 
2534   const HttpResponseInfo* response1 = trans->GetResponseInfo();
2535   ASSERT_TRUE(response1);
2536   ASSERT_TRUE(response1->headers);
2537   EXPECT_EQ(200, response1->headers->response_code());
2538   EXPECT_TRUE(response1->headers->IsKeepAlive());
2539 
2540   // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2541   // response body.
2542   trans.reset();
2543 
2544   // Let the HttpResponseBodyDrainer drain the socket.  It should determine the
2545   // socket can't be reused, rather than returning it to the socket pool.
2546   base::RunLoop().RunUntilIdle();
2547 
2548   // There should be no idle sockets in the pool.
2549   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2550 }
2551 
2552 // Test the request-challenge-retry sequence for basic auth.
2553 // (basic auth is the easiest to mock, because it has no randomness).
TEST_F(HttpNetworkTransactionTest,BasicAuth)2554 TEST_F(HttpNetworkTransactionTest, BasicAuth) {
2555   HttpRequestInfo request;
2556   request.method = "GET";
2557   request.url = GURL("http://www.example.org/");
2558   request.traffic_annotation =
2559       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2560 
2561   RecordingTestNetLog log;
2562   session_deps_.net_log = &log;
2563   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2564   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2565 
2566   MockWrite data_writes1[] = {
2567       MockWrite(
2568           "GET / HTTP/1.1\r\n"
2569           "Host: www.example.org\r\n"
2570           "Connection: keep-alive\r\n\r\n"),
2571   };
2572 
2573   MockRead data_reads1[] = {
2574     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2575     // Give a couple authenticate options (only the middle one is actually
2576     // supported).
2577     MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
2578     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2579     MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2580     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2581     // Large content-length -- won't matter, as connection will be reset.
2582     MockRead("Content-Length: 10000\r\n\r\n"),
2583     MockRead(SYNCHRONOUS, ERR_FAILED),
2584   };
2585 
2586   // After calling trans->RestartWithAuth(), this is the request we should
2587   // be issuing -- the final header line contains the credentials.
2588   MockWrite data_writes2[] = {
2589       MockWrite(
2590           "GET / HTTP/1.1\r\n"
2591           "Host: www.example.org\r\n"
2592           "Connection: keep-alive\r\n"
2593           "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2594   };
2595 
2596   // Lastly, the server responds with the actual content.
2597   MockRead data_reads2[] = {
2598     MockRead("HTTP/1.0 200 OK\r\n"),
2599     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2600     MockRead("Content-Length: 100\r\n\r\n"),
2601     MockRead(SYNCHRONOUS, OK),
2602   };
2603 
2604   StaticSocketDataProvider data1(data_reads1, data_writes1);
2605   StaticSocketDataProvider data2(data_reads2, data_writes2);
2606   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2607   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2608 
2609   TestCompletionCallback callback1;
2610 
2611   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
2612   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2613 
2614   rv = callback1.WaitForResult();
2615   EXPECT_THAT(rv, IsOk());
2616 
2617   LoadTimingInfo load_timing_info1;
2618   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
2619   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2620 
2621   int64_t writes_size1 = CountWriteBytes(data_writes1);
2622   EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
2623   int64_t reads_size1 = CountReadBytes(data_reads1);
2624   EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
2625 
2626   const HttpResponseInfo* response = trans.GetResponseInfo();
2627   ASSERT_TRUE(response);
2628   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
2629 
2630   TestCompletionCallback callback2;
2631 
2632   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2633   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2634 
2635   rv = callback2.WaitForResult();
2636   EXPECT_THAT(rv, IsOk());
2637 
2638   LoadTimingInfo load_timing_info2;
2639   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
2640   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2641   // The load timing after restart should have a new socket ID, and times after
2642   // those of the first load timing.
2643   EXPECT_LE(load_timing_info1.receive_headers_end,
2644             load_timing_info2.connect_timing.connect_start);
2645   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2646 
2647   int64_t writes_size2 = CountWriteBytes(data_writes2);
2648   EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
2649   int64_t reads_size2 = CountReadBytes(data_reads2);
2650   EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
2651 
2652   response = trans.GetResponseInfo();
2653   ASSERT_TRUE(response);
2654   EXPECT_FALSE(response->auth_challenge.has_value());
2655   EXPECT_EQ(100, response->headers->GetContentLength());
2656 }
2657 
2658 // Test the request-challenge-retry sequence for basic auth.
2659 // (basic auth is the easiest to mock, because it has no randomness).
TEST_F(HttpNetworkTransactionTest,BasicAuthWithAddressChange)2660 TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
2661   HttpRequestInfo request;
2662   request.method = "GET";
2663   request.url = GURL("http://www.example.org/");
2664   request.traffic_annotation =
2665       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2666 
2667   RecordingTestNetLog log;
2668   MockHostResolver* resolver = new MockHostResolver();
2669   session_deps_.net_log = &log;
2670   session_deps_.host_resolver.reset(resolver);
2671   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
2672   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2673 
2674   resolver->rules()->ClearRules();
2675   resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2676 
2677   MockWrite data_writes1[] = {
2678       MockWrite("GET / HTTP/1.1\r\n"
2679                 "Host: www.example.org\r\n"
2680                 "Connection: keep-alive\r\n\r\n"),
2681   };
2682 
2683   MockRead data_reads1[] = {
2684       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2685       // Give a couple authenticate options (only the middle one is actually
2686       // supported).
2687       MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
2688       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2689       MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2690       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2691       // Large content-length -- won't matter, as connection will be reset.
2692       MockRead("Content-Length: 10000\r\n\r\n"),
2693       MockRead(SYNCHRONOUS, ERR_FAILED),
2694   };
2695 
2696   // After calling trans->RestartWithAuth(), this is the request we should
2697   // be issuing -- the final header line contains the credentials.
2698   MockWrite data_writes2[] = {
2699       MockWrite("GET / HTTP/1.1\r\n"
2700                 "Host: www.example.org\r\n"
2701                 "Connection: keep-alive\r\n"
2702                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2703   };
2704 
2705   // Lastly, the server responds with the actual content.
2706   MockRead data_reads2[] = {
2707       MockRead("HTTP/1.0 200 OK\r\n"),
2708       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2709       MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2710   };
2711 
2712   StaticSocketDataProvider data1(data_reads1, data_writes1);
2713   StaticSocketDataProvider data2(data_reads2, data_writes2);
2714   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2715   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2716 
2717   TestCompletionCallback callback1;
2718 
2719   EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
2720                                                 NetLogWithSource())));
2721 
2722   LoadTimingInfo load_timing_info1;
2723   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
2724   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2725 
2726   int64_t writes_size1 = CountWriteBytes(data_writes1);
2727   EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
2728   int64_t reads_size1 = CountReadBytes(data_reads1);
2729   EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
2730 
2731   const HttpResponseInfo* response = trans.GetResponseInfo();
2732   ASSERT_TRUE(response);
2733   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
2734 
2735   IPEndPoint endpoint;
2736   EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
2737   ASSERT_FALSE(endpoint.address().empty());
2738   EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2739 
2740   resolver->rules()->ClearRules();
2741   resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2742 
2743   TestCompletionCallback callback2;
2744 
2745   EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
2746                     AuthCredentials(kFoo, kBar), callback2.callback())));
2747 
2748   LoadTimingInfo load_timing_info2;
2749   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
2750   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2751   // The load timing after restart should have a new socket ID, and times after
2752   // those of the first load timing.
2753   EXPECT_LE(load_timing_info1.receive_headers_end,
2754             load_timing_info2.connect_timing.connect_start);
2755   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2756 
2757   int64_t writes_size2 = CountWriteBytes(data_writes2);
2758   EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
2759   int64_t reads_size2 = CountReadBytes(data_reads2);
2760   EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
2761 
2762   response = trans.GetResponseInfo();
2763   ASSERT_TRUE(response);
2764   EXPECT_FALSE(response->auth_challenge.has_value());
2765   EXPECT_EQ(100, response->headers->GetContentLength());
2766 
2767   EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
2768   ASSERT_FALSE(endpoint.address().empty());
2769   EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2770 }
2771 
2772 // Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2773 // will eventually give up.
TEST_F(HttpNetworkTransactionTest,BasicAuthForever)2774 TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2775   HttpRequestInfo request;
2776   request.method = "GET";
2777   request.url = GURL("http://www.example.org/");
2778   request.traffic_annotation =
2779       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2780 
2781   RecordingTestNetLog log;
2782   session_deps_.net_log = &log;
2783   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2784   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2785 
2786   MockWrite data_writes[] = {
2787       MockWrite("GET / HTTP/1.1\r\n"
2788                 "Host: www.example.org\r\n"
2789                 "Connection: keep-alive\r\n\r\n"),
2790   };
2791 
2792   MockRead data_reads[] = {
2793       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2794       // Give a couple authenticate options (only the middle one is actually
2795       // supported).
2796       MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
2797       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2798       MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2799       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2800       // Large content-length -- won't matter, as connection will be reset.
2801       MockRead("Content-Length: 10000\r\n\r\n"),
2802       MockRead(SYNCHRONOUS, ERR_FAILED),
2803   };
2804 
2805   // After calling trans->RestartWithAuth(), this is the request we should
2806   // be issuing -- the final header line contains the credentials.
2807   MockWrite data_writes_restart[] = {
2808       MockWrite("GET / HTTP/1.1\r\n"
2809                 "Host: www.example.org\r\n"
2810                 "Connection: keep-alive\r\n"
2811                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2812   };
2813 
2814   StaticSocketDataProvider data(data_reads, data_writes);
2815   session_deps_.socket_factory->AddSocketDataProvider(&data);
2816 
2817   TestCompletionCallback callback;
2818   int rv = callback.GetResult(
2819       trans.Start(&request, callback.callback(), NetLogWithSource()));
2820 
2821   std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2822   for (int i = 0; i < 32; i++) {
2823     // Check the previous response was a 401.
2824     EXPECT_THAT(rv, IsOk());
2825     const HttpResponseInfo* response = trans.GetResponseInfo();
2826     ASSERT_TRUE(response);
2827     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
2828 
2829     data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
2830         data_reads, data_writes_restart));
2831     session_deps_.socket_factory->AddSocketDataProvider(
2832         data_restarts.back().get());
2833     rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2834                                                   callback.callback()));
2835   }
2836 
2837   // After too many tries, the transaction should have given up.
2838   EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2839 }
2840 
TEST_F(HttpNetworkTransactionTest,DoNotSendAuth)2841 TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
2842   HttpRequestInfo request;
2843   request.method = "GET";
2844   request.url = GURL("http://www.example.org/");
2845   request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
2846   request.traffic_annotation =
2847       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2848 
2849   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2850   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2851 
2852   MockWrite data_writes[] = {
2853       MockWrite(
2854           "GET / HTTP/1.1\r\n"
2855           "Host: www.example.org\r\n"
2856           "Connection: keep-alive\r\n\r\n"),
2857   };
2858 
2859   MockRead data_reads[] = {
2860     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2861     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2862     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2863     // Large content-length -- won't matter, as connection will be reset.
2864     MockRead("Content-Length: 10000\r\n\r\n"),
2865     MockRead(SYNCHRONOUS, ERR_FAILED),
2866   };
2867 
2868   StaticSocketDataProvider data(data_reads, data_writes);
2869   session_deps_.socket_factory->AddSocketDataProvider(&data);
2870   TestCompletionCallback callback;
2871 
2872   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
2873   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2874 
2875   rv = callback.WaitForResult();
2876   EXPECT_EQ(0, rv);
2877 
2878   int64_t writes_size = CountWriteBytes(data_writes);
2879   EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
2880   int64_t reads_size = CountReadBytes(data_reads);
2881   EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
2882 
2883   const HttpResponseInfo* response = trans.GetResponseInfo();
2884   ASSERT_TRUE(response);
2885   EXPECT_FALSE(response->auth_challenge.has_value());
2886 }
2887 
2888 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2889 // connection.
TEST_F(HttpNetworkTransactionTest,BasicAuthKeepAlive)2890 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
2891   // On the second pass, the body read of the auth challenge is synchronous, so
2892   // IsConnectedAndIdle returns false.  The socket should still be drained and
2893   // reused.  See http://crbug.com/544255.
2894   for (int i = 0; i < 2; ++i) {
2895     HttpRequestInfo request;
2896     request.method = "GET";
2897     request.url = GURL("http://www.example.org/");
2898     request.traffic_annotation =
2899         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2900 
2901     RecordingTestNetLog log;
2902     session_deps_.net_log = &log;
2903     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2904 
2905     MockWrite data_writes[] = {
2906         MockWrite(ASYNC, 0,
2907                   "GET / HTTP/1.1\r\n"
2908                   "Host: www.example.org\r\n"
2909                   "Connection: keep-alive\r\n\r\n"),
2910 
2911         // After calling trans.RestartWithAuth(), this is the request we should
2912         // be issuing -- the final header line contains the credentials.
2913         MockWrite(ASYNC, 6,
2914                   "GET / HTTP/1.1\r\n"
2915                   "Host: www.example.org\r\n"
2916                   "Connection: keep-alive\r\n"
2917                   "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2918     };
2919 
2920     MockRead data_reads[] = {
2921         MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2922         MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2923         MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2924         MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2925         MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
2926 
2927         // Lastly, the server responds with the actual content.
2928         MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2929         MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2930         MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2931         MockRead(ASYNC, 10, "Hello"),
2932     };
2933 
2934     SequencedSocketData data(data_reads, data_writes);
2935     data.set_busy_before_sync_reads(true);
2936     session_deps_.socket_factory->AddSocketDataProvider(&data);
2937 
2938     TestCompletionCallback callback1;
2939 
2940     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2941     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
2942     ASSERT_THAT(callback1.GetResult(rv), IsOk());
2943 
2944     LoadTimingInfo load_timing_info1;
2945     EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
2946     TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2947 
2948     const HttpResponseInfo* response = trans.GetResponseInfo();
2949     ASSERT_TRUE(response);
2950     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
2951 
2952     TestCompletionCallback callback2;
2953 
2954     rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2955                                callback2.callback());
2956     ASSERT_THAT(callback2.GetResult(rv), IsOk());
2957 
2958     LoadTimingInfo load_timing_info2;
2959     EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
2960     TestLoadTimingReused(load_timing_info2);
2961     // The load timing after restart should have the same socket ID, and times
2962     // those of the first load timing.
2963     EXPECT_LE(load_timing_info1.receive_headers_end,
2964               load_timing_info2.send_start);
2965     EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2966 
2967     response = trans.GetResponseInfo();
2968     ASSERT_TRUE(response);
2969     EXPECT_FALSE(response->auth_challenge.has_value());
2970     EXPECT_EQ(5, response->headers->GetContentLength());
2971 
2972     std::string response_data;
2973     EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
2974 
2975     int64_t writes_size = CountWriteBytes(data_writes);
2976     EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
2977     int64_t reads_size = CountReadBytes(data_reads);
2978     EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
2979   }
2980 }
2981 
2982 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2983 // connection and with no response body to drain.
TEST_F(HttpNetworkTransactionTest,BasicAuthKeepAliveNoBody)2984 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
2985   HttpRequestInfo request;
2986   request.method = "GET";
2987   request.url = GURL("http://www.example.org/");
2988   request.traffic_annotation =
2989       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2990 
2991   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2992 
2993   MockWrite data_writes1[] = {
2994       MockWrite("GET / HTTP/1.1\r\n"
2995                 "Host: www.example.org\r\n"
2996                 "Connection: keep-alive\r\n\r\n"),
2997 
2998       // After calling trans.RestartWithAuth(), this is the request we should
2999       // be issuing -- the final header line contains the credentials.
3000       MockWrite("GET / HTTP/1.1\r\n"
3001                 "Host: www.example.org\r\n"
3002                 "Connection: keep-alive\r\n"
3003                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3004   };
3005 
3006   MockRead data_reads1[] = {
3007     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3008     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3009     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
3010 
3011     // Lastly, the server responds with the actual content.
3012     MockRead("HTTP/1.1 200 OK\r\n"),
3013     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3014     MockRead("Content-Length: 5\r\n\r\n"),
3015     MockRead("hello"),
3016   };
3017 
3018   // An incorrect reconnect would cause this to be read.
3019   MockRead data_reads2[] = {
3020     MockRead(SYNCHRONOUS, ERR_FAILED),
3021   };
3022 
3023   StaticSocketDataProvider data1(data_reads1, data_writes1);
3024   StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
3025   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3026   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3027 
3028   TestCompletionCallback callback1;
3029 
3030   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3031   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
3032   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3033 
3034   rv = callback1.WaitForResult();
3035   EXPECT_THAT(rv, IsOk());
3036 
3037   const HttpResponseInfo* response = trans.GetResponseInfo();
3038   ASSERT_TRUE(response);
3039   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
3040 
3041   TestCompletionCallback callback2;
3042 
3043   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3044   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3045 
3046   rv = callback2.WaitForResult();
3047   EXPECT_THAT(rv, IsOk());
3048 
3049   response = trans.GetResponseInfo();
3050   ASSERT_TRUE(response);
3051   EXPECT_FALSE(response->auth_challenge.has_value());
3052   EXPECT_EQ(5, response->headers->GetContentLength());
3053 }
3054 
3055 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
3056 // connection and with a large response body to drain.
TEST_F(HttpNetworkTransactionTest,BasicAuthKeepAliveLargeBody)3057 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
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   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3065 
3066   MockWrite data_writes1[] = {
3067       MockWrite("GET / HTTP/1.1\r\n"
3068                 "Host: www.example.org\r\n"
3069                 "Connection: keep-alive\r\n\r\n"),
3070 
3071       // After calling trans.RestartWithAuth(), this is the request we should
3072       // be issuing -- the final header line contains the credentials.
3073       MockWrite("GET / HTTP/1.1\r\n"
3074                 "Host: www.example.org\r\n"
3075                 "Connection: keep-alive\r\n"
3076                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3077   };
3078 
3079   // Respond with 5 kb of response body.
3080   std::string large_body_string("Unauthorized");
3081   large_body_string.append(5 * 1024, ' ');
3082   large_body_string.append("\r\n");
3083 
3084   MockRead data_reads1[] = {
3085     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3086     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3087     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3088     // 5134 = 12 + 5 * 1024 + 2
3089     MockRead("Content-Length: 5134\r\n\r\n"),
3090     MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
3091 
3092     // Lastly, the server responds with the actual content.
3093     MockRead("HTTP/1.1 200 OK\r\n"),
3094     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3095     MockRead("Content-Length: 5\r\n\r\n"),
3096     MockRead("hello"),
3097   };
3098 
3099   // An incorrect reconnect would cause this to be read.
3100   MockRead data_reads2[] = {
3101     MockRead(SYNCHRONOUS, ERR_FAILED),
3102   };
3103 
3104   StaticSocketDataProvider data1(data_reads1, data_writes1);
3105   StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
3106   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3107   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3108 
3109   TestCompletionCallback callback1;
3110 
3111   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3112   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
3113   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3114 
3115   rv = callback1.WaitForResult();
3116   EXPECT_THAT(rv, IsOk());
3117 
3118   const HttpResponseInfo* response = trans.GetResponseInfo();
3119   ASSERT_TRUE(response);
3120   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
3121 
3122   TestCompletionCallback callback2;
3123 
3124   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3125   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3126 
3127   rv = callback2.WaitForResult();
3128   EXPECT_THAT(rv, IsOk());
3129 
3130   response = trans.GetResponseInfo();
3131   ASSERT_TRUE(response);
3132   EXPECT_FALSE(response->auth_challenge.has_value());
3133   EXPECT_EQ(5, response->headers->GetContentLength());
3134 }
3135 
3136 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
3137 // connection, but the server gets impatient and closes the connection.
TEST_F(HttpNetworkTransactionTest,BasicAuthKeepAliveImpatientServer)3138 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
3139   HttpRequestInfo request;
3140   request.method = "GET";
3141   request.url = GURL("http://www.example.org/");
3142   request.traffic_annotation =
3143       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3144 
3145   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3146 
3147   MockWrite data_writes1[] = {
3148       MockWrite(
3149           "GET / HTTP/1.1\r\n"
3150           "Host: www.example.org\r\n"
3151           "Connection: keep-alive\r\n\r\n"),
3152       // This simulates the seemingly successful write to a closed connection
3153       // if the bug is not fixed.
3154       MockWrite(
3155           "GET / HTTP/1.1\r\n"
3156           "Host: www.example.org\r\n"
3157           "Connection: keep-alive\r\n"
3158           "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3159   };
3160 
3161   MockRead data_reads1[] = {
3162     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3163     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3164     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3165     MockRead("Content-Length: 14\r\n\r\n"),
3166     // Tell MockTCPClientSocket to simulate the server closing the connection.
3167     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3168     MockRead("Unauthorized\r\n"),
3169     MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
3170   };
3171 
3172   // After calling trans.RestartWithAuth(), this is the request we should
3173   // be issuing -- the final header line contains the credentials.
3174   MockWrite data_writes2[] = {
3175       MockWrite(
3176           "GET / HTTP/1.1\r\n"
3177           "Host: www.example.org\r\n"
3178           "Connection: keep-alive\r\n"
3179           "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3180   };
3181 
3182   // Lastly, the server responds with the actual content.
3183   MockRead data_reads2[] = {
3184     MockRead("HTTP/1.1 200 OK\r\n"),
3185     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3186     MockRead("Content-Length: 5\r\n\r\n"),
3187     MockRead("hello"),
3188   };
3189 
3190   StaticSocketDataProvider data1(data_reads1, data_writes1);
3191   StaticSocketDataProvider data2(data_reads2, data_writes2);
3192   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3193   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3194 
3195   TestCompletionCallback callback1;
3196 
3197   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3198   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
3199   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3200 
3201   rv = callback1.WaitForResult();
3202   EXPECT_THAT(rv, IsOk());
3203 
3204   const HttpResponseInfo* response = trans.GetResponseInfo();
3205   ASSERT_TRUE(response);
3206   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
3207 
3208   TestCompletionCallback callback2;
3209 
3210   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3211   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3212 
3213   rv = callback2.WaitForResult();
3214   EXPECT_THAT(rv, IsOk());
3215 
3216   response = trans.GetResponseInfo();
3217   ASSERT_TRUE(response);
3218   EXPECT_FALSE(response->auth_challenge.has_value());
3219   EXPECT_EQ(5, response->headers->GetContentLength());
3220 }
3221 
3222 // Test the request-challenge-retry sequence for basic auth, over a connection
3223 // that requires a restart when setting up an SSL tunnel.
TEST_F(HttpNetworkTransactionTest,BasicAuthProxyNoKeepAliveHttp10)3224 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
3225   HttpRequestInfo request;
3226   request.method = "GET";
3227   request.url = GURL("https://www.example.org/");
3228   // when the no authentication data flag is set.
3229   request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3230   request.traffic_annotation =
3231       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3232 
3233   // Configure against proxy server "myproxy:70".
3234   session_deps_.proxy_resolution_service =
3235       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
3236           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
3237   RecordingBoundTestNetLog log;
3238   session_deps_.net_log = log.bound().net_log();
3239   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3240 
3241   // Since we have proxy, should try to establish tunnel.
3242   MockWrite data_writes1[] = {
3243       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3244                 "Host: www.example.org:443\r\n"
3245                 "Proxy-Connection: keep-alive\r\n\r\n"),
3246   };
3247 
3248   // The proxy responds to the connect with a 407, using a non-persistent
3249   // connection.
3250   MockRead data_reads1[] = {
3251       // No credentials.
3252       MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3253       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
3254   };
3255 
3256   // Since the first connection couldn't be reused, need to establish another
3257   // once given credentials.
3258   MockWrite data_writes2[] = {
3259       // After calling trans->RestartWithAuth(), this is the request we should
3260       // be issuing -- the final header line contains the credentials.
3261       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3262                 "Host: www.example.org:443\r\n"
3263                 "Proxy-Connection: keep-alive\r\n"
3264                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3265 
3266       MockWrite("GET / HTTP/1.1\r\n"
3267                 "Host: www.example.org\r\n"
3268                 "Connection: keep-alive\r\n\r\n"),
3269   };
3270 
3271   MockRead data_reads2[] = {
3272       MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3273 
3274       MockRead("HTTP/1.1 200 OK\r\n"),
3275       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3276       MockRead("Content-Length: 5\r\n\r\n"),
3277       MockRead(SYNCHRONOUS, "hello"),
3278   };
3279 
3280   StaticSocketDataProvider data1(data_reads1, data_writes1);
3281   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3282   StaticSocketDataProvider data2(data_reads2, data_writes2);
3283   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3284   SSLSocketDataProvider ssl(ASYNC, OK);
3285   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3286 
3287   TestCompletionCallback callback1;
3288 
3289   auto trans =
3290       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
3291 
3292   int rv = trans->Start(&request, callback1.callback(), log.bound());
3293   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3294 
3295   rv = callback1.WaitForResult();
3296   EXPECT_THAT(rv, IsOk());
3297   auto entries = log.GetEntries();
3298   size_t pos = ExpectLogContainsSomewhere(
3299       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3300       NetLogEventPhase::NONE);
3301   ExpectLogContainsSomewhere(
3302       entries, pos,
3303       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3304       NetLogEventPhase::NONE);
3305 
3306   const HttpResponseInfo* response = trans->GetResponseInfo();
3307   ASSERT_TRUE(response);
3308   EXPECT_FALSE(response->headers->IsKeepAlive());
3309   ASSERT_TRUE(response->headers);
3310   EXPECT_EQ(407, response->headers->response_code());
3311   EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3312   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
3313 
3314   LoadTimingInfo load_timing_info;
3315   // CONNECT requests and responses are handled at the connect job level, so
3316   // the transaction does not yet have a connection.
3317   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3318 
3319   TestCompletionCallback callback2;
3320 
3321   rv =
3322       trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3323   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3324 
3325   rv = callback2.WaitForResult();
3326   EXPECT_THAT(rv, IsOk());
3327 
3328   response = trans->GetResponseInfo();
3329   ASSERT_TRUE(response);
3330 
3331   EXPECT_TRUE(response->headers->IsKeepAlive());
3332   EXPECT_EQ(200, response->headers->response_code());
3333   EXPECT_EQ(5, response->headers->GetContentLength());
3334   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3335 
3336   // Check that credentials were successfully cached, with the right target.
3337   HttpAuthCache::Entry* entry = session->http_auth_cache()->Lookup(
3338       GURL("http://myproxy:70"), HttpAuth::AUTH_PROXY, "MyRealm1",
3339       HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
3340   ASSERT_TRUE(entry);
3341   ASSERT_EQ(kFoo, entry->credentials().username());
3342   ASSERT_EQ(kBar, entry->credentials().password());
3343 
3344   // The password prompt info should not be set.
3345   EXPECT_FALSE(response->auth_challenge.has_value());
3346 
3347   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3348   TestLoadTimingNotReusedWithPac(load_timing_info,
3349                                  CONNECT_TIMING_HAS_SSL_TIMES);
3350 
3351   trans.reset();
3352   session->CloseAllConnections(ERR_FAILED, "Very good reason");
3353 }
3354 
3355 // Test the request-challenge-retry sequence for basic auth, over a connection
3356 // that requires a restart when setting up an SSL tunnel.
TEST_F(HttpNetworkTransactionTest,BasicAuthProxyNoKeepAliveHttp11)3357 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
3358   HttpRequestInfo request;
3359   request.method = "GET";
3360   request.url = GURL("https://www.example.org/");
3361   // when the no authentication data flag is set.
3362   request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3363   request.traffic_annotation =
3364       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3365 
3366   // Configure against proxy server "myproxy:70".
3367   session_deps_.proxy_resolution_service =
3368       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
3369           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
3370   RecordingBoundTestNetLog log;
3371   session_deps_.net_log = log.bound().net_log();
3372   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3373 
3374   // Since we have proxy, should try to establish tunnel.
3375   MockWrite data_writes1[] = {
3376       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3377                 "Host: www.example.org:443\r\n"
3378                 "Proxy-Connection: keep-alive\r\n\r\n"),
3379   };
3380 
3381   // The proxy responds to the connect with a 407, using a non-persistent
3382   // connection.
3383   MockRead data_reads1[] = {
3384       // No credentials.
3385       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3386       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3387       MockRead("Proxy-Connection: close\r\n\r\n"),
3388   };
3389 
3390   MockWrite data_writes2[] = {
3391       // After calling trans->RestartWithAuth(), this is the request we should
3392       // be issuing -- the final header line contains the credentials.
3393       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3394                 "Host: www.example.org:443\r\n"
3395                 "Proxy-Connection: keep-alive\r\n"
3396                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3397 
3398       MockWrite("GET / HTTP/1.1\r\n"
3399                 "Host: www.example.org\r\n"
3400                 "Connection: keep-alive\r\n\r\n"),
3401   };
3402 
3403   MockRead data_reads2[] = {
3404       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3405 
3406       MockRead("HTTP/1.1 200 OK\r\n"),
3407       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3408       MockRead("Content-Length: 5\r\n\r\n"),
3409       MockRead(SYNCHRONOUS, "hello"),
3410   };
3411 
3412   StaticSocketDataProvider data1(data_reads1, data_writes1);
3413   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3414   StaticSocketDataProvider data2(data_reads2, data_writes2);
3415   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3416   SSLSocketDataProvider ssl(ASYNC, OK);
3417   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3418 
3419   TestCompletionCallback callback1;
3420 
3421   auto trans =
3422       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
3423 
3424   int rv = trans->Start(&request, callback1.callback(), log.bound());
3425   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3426 
3427   rv = callback1.WaitForResult();
3428   EXPECT_THAT(rv, IsOk());
3429   auto entries = log.GetEntries();
3430   size_t pos = ExpectLogContainsSomewhere(
3431       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3432       NetLogEventPhase::NONE);
3433   ExpectLogContainsSomewhere(
3434       entries, pos,
3435       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3436       NetLogEventPhase::NONE);
3437 
3438   const HttpResponseInfo* response = trans->GetResponseInfo();
3439   ASSERT_TRUE(response);
3440   EXPECT_FALSE(response->headers->IsKeepAlive());
3441   ASSERT_TRUE(response->headers);
3442   EXPECT_EQ(407, response->headers->response_code());
3443   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3444   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
3445 
3446   LoadTimingInfo load_timing_info;
3447   // CONNECT requests and responses are handled at the connect job level, so
3448   // the transaction does not yet have a connection.
3449   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3450 
3451   TestCompletionCallback callback2;
3452 
3453   rv = trans->RestartWithAuth(
3454       AuthCredentials(kFoo, kBar), callback2.callback());
3455   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3456 
3457   rv = callback2.WaitForResult();
3458   EXPECT_THAT(rv, IsOk());
3459 
3460   response = trans->GetResponseInfo();
3461   ASSERT_TRUE(response);
3462 
3463   EXPECT_TRUE(response->headers->IsKeepAlive());
3464   EXPECT_EQ(200, response->headers->response_code());
3465   EXPECT_EQ(5, response->headers->GetContentLength());
3466   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3467 
3468   // The password prompt info should not be set.
3469   EXPECT_FALSE(response->auth_challenge.has_value());
3470 
3471   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3472   TestLoadTimingNotReusedWithPac(load_timing_info,
3473                                  CONNECT_TIMING_HAS_SSL_TIMES);
3474 
3475   trans.reset();
3476   session->CloseAllConnections(ERR_FAILED, "Very good reason");
3477 }
3478 
3479 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
3480 // proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
TEST_F(HttpNetworkTransactionTest,BasicAuthProxyKeepAliveHttp10)3481 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
3482   // On the second pass, the body read of the auth challenge is synchronous, so
3483   // IsConnectedAndIdle returns false.  The socket should still be drained and
3484   // reused.  See http://crbug.com/544255.
3485   for (int i = 0; i < 2; ++i) {
3486     HttpRequestInfo request;
3487     request.method = "GET";
3488     request.url = GURL("https://www.example.org/");
3489     // Ensure that proxy authentication is attempted even
3490     // when the no authentication data flag is set.
3491     request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3492     request.traffic_annotation =
3493         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3494 
3495     // Configure against proxy server "myproxy:70".
3496     session_deps_.proxy_resolution_service =
3497         ConfiguredProxyResolutionService::CreateFixed(
3498             "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
3499     RecordingBoundTestNetLog log;
3500     session_deps_.net_log = log.bound().net_log();
3501     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3502 
3503     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3504 
3505     // Since we have proxy, should try to establish tunnel.
3506     MockWrite data_writes1[] = {
3507         MockWrite(ASYNC, 0,
3508                   "CONNECT www.example.org:443 HTTP/1.1\r\n"
3509                   "Host: www.example.org:443\r\n"
3510                   "Proxy-Connection: keep-alive\r\n\r\n"),
3511 
3512         // After calling trans.RestartWithAuth(), this is the request we should
3513         // be issuing -- the final header line contains the credentials.
3514         MockWrite(ASYNC, 3,
3515                   "CONNECT www.example.org:443 HTTP/1.1\r\n"
3516                   "Host: www.example.org:443\r\n"
3517                   "Proxy-Connection: keep-alive\r\n"
3518                   "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3519     };
3520 
3521     // The proxy responds to the connect with a 407, using a persistent
3522     // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3523     MockRead data_reads1[] = {
3524         // No credentials.
3525         MockRead(ASYNC, 1,
3526                  "HTTP/1.0 407 Proxy Authentication Required\r\n"
3527                  "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3528                  "Proxy-Connection: keep-alive\r\n"
3529                  "Content-Length: 10\r\n\r\n"),
3530         MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3531 
3532         // Wrong credentials (wrong password).
3533         MockRead(ASYNC, 4,
3534                  "HTTP/1.0 407 Proxy Authentication Required\r\n"
3535                  "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3536                  "Proxy-Connection: keep-alive\r\n"
3537                  "Content-Length: 10\r\n\r\n"),
3538         // No response body because the test stops reading here.
3539         MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3540     };
3541 
3542     SequencedSocketData data1(data_reads1, data_writes1);
3543     data1.set_busy_before_sync_reads(true);
3544     session_deps_.socket_factory->AddSocketDataProvider(&data1);
3545 
3546     TestCompletionCallback callback1;
3547 
3548     int rv = trans.Start(&request, callback1.callback(), log.bound());
3549     EXPECT_THAT(callback1.GetResult(rv), IsOk());
3550 
3551     auto entries = log.GetEntries();
3552     size_t pos = ExpectLogContainsSomewhere(
3553         entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3554         NetLogEventPhase::NONE);
3555     ExpectLogContainsSomewhere(
3556         entries, pos,
3557         NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3558         NetLogEventPhase::NONE);
3559 
3560     const HttpResponseInfo* response = trans.GetResponseInfo();
3561     ASSERT_TRUE(response);
3562     ASSERT_TRUE(response->headers);
3563     EXPECT_TRUE(response->headers->IsKeepAlive());
3564     EXPECT_EQ(407, response->headers->response_code());
3565     EXPECT_EQ(10, response->headers->GetContentLength());
3566     EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3567     EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
3568 
3569     TestCompletionCallback callback2;
3570 
3571     // Wrong password (should be "bar").
3572     rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3573                                callback2.callback());
3574     EXPECT_THAT(callback2.GetResult(rv), IsOk());
3575 
3576     response = trans.GetResponseInfo();
3577     ASSERT_TRUE(response);
3578     ASSERT_TRUE(response->headers);
3579     EXPECT_TRUE(response->headers->IsKeepAlive());
3580     EXPECT_EQ(407, response->headers->response_code());
3581     EXPECT_EQ(10, response->headers->GetContentLength());
3582     EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3583     EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
3584 
3585     // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3586     // out of scope.
3587     session->CloseAllConnections(ERR_FAILED, "Very good reason");
3588   }
3589 }
3590 
3591 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
3592 // proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
TEST_F(HttpNetworkTransactionTest,BasicAuthProxyKeepAliveHttp11)3593 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
3594   // On the second pass, the body read of the auth challenge is synchronous, so
3595   // IsConnectedAndIdle returns false.  The socket should still be drained and
3596   // reused.  See http://crbug.com/544255.
3597   for (int i = 0; i < 2; ++i) {
3598     HttpRequestInfo request;
3599     request.method = "GET";
3600     request.url = GURL("https://www.example.org/");
3601     // Ensure that proxy authentication is attempted even
3602     // when the no authentication data flag is set.
3603     request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3604     request.traffic_annotation =
3605         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3606 
3607     // Configure against proxy server "myproxy:70".
3608     session_deps_.proxy_resolution_service =
3609         ConfiguredProxyResolutionService::CreateFixed(
3610             "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
3611     RecordingBoundTestNetLog log;
3612     session_deps_.net_log = log.bound().net_log();
3613     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3614 
3615     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3616 
3617     // Since we have proxy, should try to establish tunnel.
3618     MockWrite data_writes1[] = {
3619         MockWrite(ASYNC, 0,
3620                   "CONNECT www.example.org:443 HTTP/1.1\r\n"
3621                   "Host: www.example.org:443\r\n"
3622                   "Proxy-Connection: keep-alive\r\n\r\n"),
3623 
3624         // After calling trans.RestartWithAuth(), this is the request we should
3625         // be issuing -- the final header line contains the credentials.
3626         MockWrite(ASYNC, 3,
3627                   "CONNECT www.example.org:443 HTTP/1.1\r\n"
3628                   "Host: www.example.org:443\r\n"
3629                   "Proxy-Connection: keep-alive\r\n"
3630                   "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3631     };
3632 
3633     // The proxy responds to the connect with a 407, using a persistent
3634     // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3635     MockRead data_reads1[] = {
3636         // No credentials.
3637         MockRead(ASYNC, 1,
3638                  "HTTP/1.1 407 Proxy Authentication Required\r\n"
3639                  "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3640                  "Content-Length: 10\r\n\r\n"),
3641         MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3642 
3643         // Wrong credentials (wrong password).
3644         MockRead(ASYNC, 4,
3645                  "HTTP/1.1 407 Proxy Authentication Required\r\n"
3646                  "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3647                  "Content-Length: 10\r\n\r\n"),
3648         // No response body because the test stops reading here.
3649         MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3650     };
3651 
3652     SequencedSocketData data1(data_reads1, data_writes1);
3653     data1.set_busy_before_sync_reads(true);
3654     session_deps_.socket_factory->AddSocketDataProvider(&data1);
3655 
3656     TestCompletionCallback callback1;
3657 
3658     int rv = trans.Start(&request, callback1.callback(), log.bound());
3659     EXPECT_THAT(callback1.GetResult(rv), IsOk());
3660 
3661     auto entries = log.GetEntries();
3662     size_t pos = ExpectLogContainsSomewhere(
3663         entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3664         NetLogEventPhase::NONE);
3665     ExpectLogContainsSomewhere(
3666         entries, pos,
3667         NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3668         NetLogEventPhase::NONE);
3669 
3670     const HttpResponseInfo* response = trans.GetResponseInfo();
3671     ASSERT_TRUE(response);
3672     ASSERT_TRUE(response->headers);
3673     EXPECT_TRUE(response->headers->IsKeepAlive());
3674     EXPECT_EQ(407, response->headers->response_code());
3675     EXPECT_EQ(10, response->headers->GetContentLength());
3676     EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3677     EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
3678     EXPECT_FALSE(response->did_use_http_auth);
3679 
3680     TestCompletionCallback callback2;
3681 
3682     // Wrong password (should be "bar").
3683     rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3684                                callback2.callback());
3685     EXPECT_THAT(callback2.GetResult(rv), IsOk());
3686 
3687     response = trans.GetResponseInfo();
3688     ASSERT_TRUE(response);
3689     ASSERT_TRUE(response->headers);
3690     EXPECT_TRUE(response->headers->IsKeepAlive());
3691     EXPECT_EQ(407, response->headers->response_code());
3692     EXPECT_EQ(10, response->headers->GetContentLength());
3693     EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3694     EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
3695     EXPECT_TRUE(response->did_use_http_auth);
3696 
3697     // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3698     // out of scope.
3699     session->CloseAllConnections(ERR_FAILED, "Very good reason");
3700   }
3701 }
3702 
3703 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
3704 // proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3705 // the case the server sends extra data on the original socket, so it can't be
3706 // reused.
TEST_F(HttpNetworkTransactionTest,BasicAuthProxyKeepAliveExtraData)3707 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
3708   HttpRequestInfo request;
3709   request.method = "GET";
3710   request.url = GURL("https://www.example.org/");
3711   // when the no authentication data flag is set.
3712   request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3713   request.traffic_annotation =
3714       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3715 
3716   // Configure against proxy server "myproxy:70".
3717   session_deps_.proxy_resolution_service =
3718       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
3719           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
3720   RecordingBoundTestNetLog log;
3721   session_deps_.net_log = log.bound().net_log();
3722   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3723 
3724   // Since we have proxy, should try to establish tunnel.
3725   MockWrite data_writes1[] = {
3726       MockWrite(ASYNC, 0,
3727                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3728                 "Host: www.example.org:443\r\n"
3729                 "Proxy-Connection: keep-alive\r\n\r\n"),
3730   };
3731 
3732   // The proxy responds to the connect with a 407, using a persistent, but sends
3733   // extra data, so the socket cannot be reused.
3734   MockRead data_reads1[] = {
3735       // No credentials.
3736       MockRead(ASYNC, 1,
3737                "HTTP/1.1 407 Proxy Authentication Required\r\n"
3738                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3739                "Content-Length: 10\r\n\r\n"),
3740       MockRead(SYNCHRONOUS, 2, "0123456789"),
3741       MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3742   };
3743 
3744   MockWrite data_writes2[] = {
3745       // After calling trans->RestartWithAuth(), this is the request we should
3746       // be issuing -- the final header line contains the credentials.
3747       MockWrite(ASYNC, 0,
3748                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3749                 "Host: www.example.org:443\r\n"
3750                 "Proxy-Connection: keep-alive\r\n"
3751                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3752 
3753       MockWrite(ASYNC, 2,
3754                 "GET / HTTP/1.1\r\n"
3755                 "Host: www.example.org\r\n"
3756                 "Connection: keep-alive\r\n\r\n"),
3757   };
3758 
3759   MockRead data_reads2[] = {
3760       MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
3761 
3762       MockRead(ASYNC, 3,
3763                "HTTP/1.1 200 OK\r\n"
3764                "Content-Type: text/html; charset=iso-8859-1\r\n"
3765                "Content-Length: 5\r\n\r\n"),
3766       // No response body because the test stops reading here.
3767       MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
3768   };
3769 
3770   SequencedSocketData data1(data_reads1, data_writes1);
3771   data1.set_busy_before_sync_reads(true);
3772   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3773   SequencedSocketData data2(data_reads2, data_writes2);
3774   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3775   SSLSocketDataProvider ssl(ASYNC, OK);
3776   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3777 
3778   TestCompletionCallback callback1;
3779 
3780   auto trans =
3781       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
3782 
3783   int rv = trans->Start(&request, callback1.callback(), log.bound());
3784   EXPECT_THAT(callback1.GetResult(rv), IsOk());
3785 
3786   auto entries = log.GetEntries();
3787   size_t pos = ExpectLogContainsSomewhere(
3788       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3789       NetLogEventPhase::NONE);
3790   ExpectLogContainsSomewhere(
3791       entries, pos,
3792       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3793       NetLogEventPhase::NONE);
3794 
3795   const HttpResponseInfo* response = trans->GetResponseInfo();
3796   ASSERT_TRUE(response);
3797   ASSERT_TRUE(response->headers);
3798   EXPECT_TRUE(response->headers->IsKeepAlive());
3799   EXPECT_EQ(407, response->headers->response_code());
3800   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3801   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
3802 
3803   LoadTimingInfo load_timing_info;
3804   // CONNECT requests and responses are handled at the connect job level, so
3805   // the transaction does not yet have a connection.
3806   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3807 
3808   TestCompletionCallback callback2;
3809 
3810   rv =
3811       trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3812   EXPECT_THAT(callback2.GetResult(rv), IsOk());
3813 
3814   EXPECT_TRUE(response->headers->IsKeepAlive());
3815   EXPECT_EQ(200, response->headers->response_code());
3816   EXPECT_EQ(5, response->headers->GetContentLength());
3817   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3818 
3819   // The password prompt info should not be set.
3820   EXPECT_FALSE(response->auth_challenge.has_value());
3821 
3822   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3823   TestLoadTimingNotReusedWithPac(load_timing_info,
3824                                  CONNECT_TIMING_HAS_SSL_TIMES);
3825 
3826   trans.reset();
3827   session->CloseAllConnections(ERR_FAILED, "Very good reason");
3828 }
3829 
3830 // Test the case a proxy closes a socket while the challenge body is being
3831 // drained.
TEST_F(HttpNetworkTransactionTest,BasicAuthProxyKeepAliveHangupDuringBody)3832 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
3833   HttpRequestInfo request;
3834   request.method = "GET";
3835   request.url = GURL("https://www.example.org/");
3836   // Ensure that proxy authentication is attempted even
3837   // when the no authentication data flag is set.
3838   request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3839   request.traffic_annotation =
3840       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3841 
3842   // Configure against proxy server "myproxy:70".
3843   session_deps_.proxy_resolution_service =
3844       ConfiguredProxyResolutionService::CreateFixed(
3845           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
3846   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
3847 
3848   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3849 
3850   // Since we have proxy, should try to establish tunnel.
3851   MockWrite data_writes1[] = {
3852       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3853                 "Host: www.example.org:443\r\n"
3854                 "Proxy-Connection: keep-alive\r\n\r\n"),
3855   };
3856 
3857   // The proxy responds to the connect with a 407, using a persistent
3858   // connection.
3859   MockRead data_reads1[] = {
3860       // No credentials.
3861       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3862       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3863       MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3864       // Server hands up in the middle of the body.
3865       MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3866   };
3867 
3868   MockWrite data_writes2[] = {
3869       // After calling trans.RestartWithAuth(), this is the request we should
3870       // be issuing -- the final header line contains the credentials.
3871       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3872                 "Host: www.example.org:443\r\n"
3873                 "Proxy-Connection: keep-alive\r\n"
3874                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3875 
3876       MockWrite("GET / HTTP/1.1\r\n"
3877                 "Host: www.example.org\r\n"
3878                 "Connection: keep-alive\r\n\r\n"),
3879   };
3880 
3881   MockRead data_reads2[] = {
3882       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3883 
3884       MockRead("HTTP/1.1 200 OK\r\n"),
3885       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3886       MockRead("Content-Length: 5\r\n\r\n"),
3887       MockRead(SYNCHRONOUS, "hello"),
3888   };
3889 
3890   StaticSocketDataProvider data1(data_reads1, data_writes1);
3891   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3892   StaticSocketDataProvider data2(data_reads2, data_writes2);
3893   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3894   SSLSocketDataProvider ssl(ASYNC, OK);
3895   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3896 
3897   TestCompletionCallback callback;
3898 
3899   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
3900   EXPECT_THAT(callback.GetResult(rv), IsOk());
3901 
3902   const HttpResponseInfo* response = trans.GetResponseInfo();
3903   ASSERT_TRUE(response);
3904   ASSERT_TRUE(response->headers);
3905   EXPECT_TRUE(response->headers->IsKeepAlive());
3906   EXPECT_EQ(407, response->headers->response_code());
3907   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
3908 
3909   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
3910   EXPECT_THAT(callback.GetResult(rv), IsOk());
3911 
3912   response = trans.GetResponseInfo();
3913   ASSERT_TRUE(response);
3914   ASSERT_TRUE(response->headers);
3915   EXPECT_TRUE(response->headers->IsKeepAlive());
3916   EXPECT_EQ(200, response->headers->response_code());
3917   std::string body;
3918   EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
3919   EXPECT_EQ("hello", body);
3920 }
3921 
3922 // Test that we don't read the response body when we fail to establish a tunnel,
3923 // even if the user cancels the proxy's auth attempt.
TEST_F(HttpNetworkTransactionTest,BasicAuthProxyCancelTunnel)3924 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
3925   HttpRequestInfo request;
3926   request.method = "GET";
3927   request.url = GURL("https://www.example.org/");
3928   request.traffic_annotation =
3929       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3930 
3931   // Configure against proxy server "myproxy:70".
3932   session_deps_.proxy_resolution_service =
3933       ConfiguredProxyResolutionService::CreateFixed(
3934           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
3935 
3936   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3937 
3938   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
3939 
3940   // Since we have proxy, should try to establish tunnel.
3941   MockWrite data_writes[] = {
3942       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3943                 "Host: www.example.org:443\r\n"
3944                 "Proxy-Connection: keep-alive\r\n\r\n"),
3945   };
3946 
3947   // The proxy responds to the connect with a 407.
3948   MockRead data_reads[] = {
3949       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3950       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3951       MockRead("Content-Length: 10\r\n\r\n"),
3952       MockRead("0123456789"),
3953       MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
3954   };
3955 
3956   StaticSocketDataProvider data(data_reads, data_writes);
3957   session_deps_.socket_factory->AddSocketDataProvider(&data);
3958 
3959   TestCompletionCallback callback;
3960 
3961   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
3962   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3963 
3964   rv = callback.WaitForResult();
3965   EXPECT_THAT(rv, IsOk());
3966 
3967   const HttpResponseInfo* response = trans.GetResponseInfo();
3968   ASSERT_TRUE(response);
3969   ASSERT_TRUE(response->headers);
3970   EXPECT_TRUE(response->headers->IsKeepAlive());
3971   EXPECT_EQ(407, response->headers->response_code());
3972   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3973 
3974   std::string response_data;
3975   rv = ReadTransaction(&trans, &response_data);
3976   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
3977 
3978   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3979   session->CloseAllConnections(ERR_FAILED, "Very good reason");
3980 }
3981 
3982 // Test the no-tunnel HTTP auth case where proxy and server origins and realms
3983 // are the same, but the user/passwords are different. Serves to verify
3984 // credentials are correctly separated based on HttpAuth::Target.
TEST_F(HttpNetworkTransactionTest,BasicAuthProxyMatchesServerAuthNoTunnel)3985 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyMatchesServerAuthNoTunnel) {
3986   HttpRequestInfo request;
3987   request.method = "GET";
3988   request.url = GURL("http://myproxy:70/");
3989   request.traffic_annotation =
3990       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3991 
3992   // Proxy matches request URL.
3993   session_deps_.proxy_resolution_service =
3994       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
3995           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
3996   RecordingBoundTestNetLog log;
3997   session_deps_.net_log = log.bound().net_log();
3998   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3999 
4000   MockWrite data_writes[] = {
4001       // Initial request gets a proxy auth challenge.
4002       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4003                 "Host: myproxy:70\r\n"
4004                 "Proxy-Connection: keep-alive\r\n\r\n"),
4005       // Retry with proxy auth credentials, which will result in a server auth
4006       // challenge.
4007       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4008                 "Host: myproxy:70\r\n"
4009                 "Proxy-Connection: keep-alive\r\n"
4010                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4011       // Retry with proxy and server auth credentials, which gets a response.
4012       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4013                 "Host: myproxy:70\r\n"
4014                 "Proxy-Connection: keep-alive\r\n"
4015                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4016                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4017       // A second request should preemptively send the correct proxy and server
4018       // auth headers.
4019       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4020                 "Host: myproxy:70\r\n"
4021                 "Proxy-Connection: keep-alive\r\n"
4022                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4023                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4024   };
4025 
4026   MockRead data_reads[] = {
4027       // Proxy auth challenge.
4028       MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"
4029                "Proxy-Connection: keep-alive\r\n"
4030                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4031                "Content-Length: 0\r\n\r\n"),
4032       // Server auth challenge.
4033       MockRead("HTTP/1.0 401 Authentication Required\r\n"
4034                "Proxy-Connection: keep-alive\r\n"
4035                "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4036                "Content-Length: 0\r\n\r\n"),
4037       // Response.
4038       MockRead("HTTP/1.1 200 OK\r\n"
4039                "Proxy-Connection: keep-alive\r\n"
4040                "Content-Length: 5\r\n\r\n"
4041                "hello"),
4042       // Response to second request.
4043       MockRead("HTTP/1.1 200 OK\r\n"
4044                "Proxy-Connection: keep-alive\r\n"
4045                "Content-Length: 2\r\n\r\n"
4046                "hi"),
4047   };
4048 
4049   StaticSocketDataProvider data(data_reads, data_writes);
4050   session_deps_.socket_factory->AddSocketDataProvider(&data);
4051 
4052   TestCompletionCallback callback;
4053 
4054   auto trans =
4055       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4056   int rv = trans->Start(&request, callback.callback(), log.bound());
4057   EXPECT_THAT(callback.GetResult(rv), IsOk());
4058   const HttpResponseInfo* response = trans->GetResponseInfo();
4059   ASSERT_TRUE(response);
4060   ASSERT_TRUE(response->headers);
4061   EXPECT_EQ(407, response->headers->response_code());
4062   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
4063 
4064   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
4065   EXPECT_THAT(callback.GetResult(rv), IsOk());
4066   response = trans->GetResponseInfo();
4067   ASSERT_TRUE(response);
4068   EXPECT_EQ(401, response->headers->response_code());
4069   EXPECT_FALSE(response->auth_challenge->is_proxy);
4070   EXPECT_EQ("http://myproxy:70",
4071             response->auth_challenge->challenger.Serialize());
4072   EXPECT_EQ("MyRealm1", response->auth_challenge->realm);
4073   EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
4074 
4075   rv = trans->RestartWithAuth(AuthCredentials(kFoo2, kBar2),
4076                               callback.callback());
4077   EXPECT_THAT(callback.GetResult(rv), IsOk());
4078   response = trans->GetResponseInfo();
4079   ASSERT_TRUE(response);
4080   EXPECT_EQ(200, response->headers->response_code());
4081   // The password prompt info should not be set.
4082   EXPECT_FALSE(response->auth_challenge.has_value());
4083 
4084   std::string response_data;
4085   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4086   EXPECT_EQ("hello", response_data);
4087 
4088   // Check that the credentials were cached correctly.
4089   HttpAuthCache::Entry* entry = session->http_auth_cache()->Lookup(
4090       GURL("http://myproxy:70"), HttpAuth::AUTH_PROXY, "MyRealm1",
4091       HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
4092   ASSERT_TRUE(entry);
4093   ASSERT_EQ(kFoo, entry->credentials().username());
4094   ASSERT_EQ(kBar, entry->credentials().password());
4095   entry = session->http_auth_cache()->Lookup(
4096       GURL("http://myproxy:70"), HttpAuth::AUTH_SERVER, "MyRealm1",
4097       HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey());
4098   ASSERT_TRUE(entry);
4099   ASSERT_EQ(kFoo2, entry->credentials().username());
4100   ASSERT_EQ(kBar2, entry->credentials().password());
4101 
4102   // Make another request, which should automatically send the correct proxy and
4103   // server auth credentials and get another response.
4104   trans =
4105       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4106   rv = trans->Start(&request, callback.callback(), log.bound());
4107   EXPECT_THAT(callback.GetResult(rv), IsOk());
4108   response = trans->GetResponseInfo();
4109   ASSERT_TRUE(response);
4110   EXPECT_EQ(200, response->headers->response_code());
4111   // The password prompt info should not be set.
4112   EXPECT_FALSE(response->auth_challenge.has_value());
4113 
4114   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4115   EXPECT_EQ("hi", response_data);
4116 
4117   trans.reset();
4118   session->CloseAllConnections(ERR_FAILED, "Very good reason");
4119 }
4120 
4121 // Test the no-tunnel HTTP auth case where proxy and server origins and realms
4122 // are the same, but the user/passwords are different, and with different
4123 // NetworkIsolationKeys. Sends one request with a NIK, response to both proxy
4124 // and auth challenges, sends another request with another NIK, expecting only
4125 // the proxy credentials to be cached, and thus sees only a server auth
4126 // challenge. Then sends a request with the original NIK, expecting cached proxy
4127 // and auth credentials that match the ones used in the first request.
4128 //
4129 // Serves to verify credentials are correctly separated based on
4130 // HttpAuth::Target and NetworkIsolationKeys, but NetworkIsolationKey only
4131 // affects server credentials, not proxy credentials.
TEST_F(HttpNetworkTransactionTest,BasicAuthProxyMatchesServerAuthWithNetworkIsolationKeyNoTunnel)4132 TEST_F(HttpNetworkTransactionTest,
4133        BasicAuthProxyMatchesServerAuthWithNetworkIsolationKeyNoTunnel) {
4134   const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
4135   const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
4136   const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
4137   const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
4138 
4139   // This test would need to use a single socket without this option enabled.
4140   // Best to use this option when it would affect a test, as it will eventually
4141   // become the default behavior.
4142   base::test::ScopedFeatureList feature_list;
4143   feature_list.InitAndEnableFeature(
4144       features::kPartitionConnectionsByNetworkIsolationKey);
4145 
4146   // Proxy matches request URL.
4147   session_deps_.proxy_resolution_service =
4148       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
4149           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4150   RecordingBoundTestNetLog log;
4151   session_deps_.net_log = log.bound().net_log();
4152   session_deps_.key_auth_cache_server_entries_by_network_isolation_key = true;
4153   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4154 
4155   MockWrite data_writes[] = {
4156       // Initial request gets a proxy auth challenge.
4157       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4158                 "Host: myproxy:70\r\n"
4159                 "Proxy-Connection: keep-alive\r\n\r\n"),
4160       // Retry with proxy auth credentials, which will result in a server auth
4161       // challenge.
4162       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4163                 "Host: myproxy:70\r\n"
4164                 "Proxy-Connection: keep-alive\r\n"
4165                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4166       // Retry with proxy and server auth credentials, which gets a response.
4167       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4168                 "Host: myproxy:70\r\n"
4169                 "Proxy-Connection: keep-alive\r\n"
4170                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4171                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4172       // Another request to the same server and using the same NIK should
4173       // preemptively send the correct cached proxy and server
4174       // auth headers.
4175       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4176                 "Host: myproxy:70\r\n"
4177                 "Proxy-Connection: keep-alive\r\n"
4178                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4179                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4180   };
4181 
4182   MockRead data_reads[] = {
4183       // Proxy auth challenge.
4184       MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"
4185                "Proxy-Connection: keep-alive\r\n"
4186                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4187                "Content-Length: 0\r\n\r\n"),
4188       // Server auth challenge.
4189       MockRead("HTTP/1.0 401 Authentication Required\r\n"
4190                "Proxy-Connection: keep-alive\r\n"
4191                "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4192                "Content-Length: 0\r\n\r\n"),
4193       // Response.
4194       MockRead("HTTP/1.1 200 OK\r\n"
4195                "Proxy-Connection: keep-alive\r\n"
4196                "Content-Length: 5\r\n\r\n"
4197                "hello"),
4198       // Response to second request.
4199       MockRead("HTTP/1.1 200 OK\r\n"
4200                "Proxy-Connection: keep-alive\r\n"
4201                "Content-Length: 2\r\n\r\n"
4202                "hi"),
4203   };
4204 
4205   StaticSocketDataProvider data(data_reads, data_writes);
4206   session_deps_.socket_factory->AddSocketDataProvider(&data);
4207 
4208   MockWrite data_writes2[] = {
4209       // Initial request using a different NetworkIsolationKey includes the
4210       // cached proxy credentials, but not server credentials.
4211       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4212                 "Host: myproxy:70\r\n"
4213                 "Proxy-Connection: keep-alive\r\n"
4214                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4215       // Retry with proxy and new server auth credentials, which gets a
4216       // response.
4217       MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n"
4218                 "Host: myproxy:70\r\n"
4219                 "Proxy-Connection: keep-alive\r\n"
4220                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4221                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
4222   };
4223 
4224   MockRead data_reads2[] = {
4225       // Server auth challenge.
4226       MockRead("HTTP/1.0 401 Authentication Required\r\n"
4227                "Proxy-Connection: keep-alive\r\n"
4228                "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4229                "Content-Length: 0\r\n\r\n"),
4230       // Response.
4231       MockRead("HTTP/1.1 200 OK\r\n"
4232                "Proxy-Connection: keep-alive\r\n"
4233                "Content-Length: 9\r\n\r\n"
4234                "greetings"),
4235   };
4236 
4237   StaticSocketDataProvider data2(data_reads2, data_writes2);
4238   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4239 
4240   TestCompletionCallback callback;
4241 
4242   HttpRequestInfo request;
4243   request.method = "GET";
4244   request.url = GURL("http://myproxy:70/");
4245   request.traffic_annotation =
4246       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4247   request.network_isolation_key = kNetworkIsolationKey1;
4248 
4249   auto trans =
4250       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4251   int rv = trans->Start(&request, callback.callback(), log.bound());
4252   EXPECT_THAT(callback.GetResult(rv), IsOk());
4253   const HttpResponseInfo* response = trans->GetResponseInfo();
4254   ASSERT_TRUE(response);
4255   ASSERT_TRUE(response->headers);
4256   EXPECT_EQ(407, response->headers->response_code());
4257   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
4258 
4259   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
4260   EXPECT_THAT(callback.GetResult(rv), IsOk());
4261   response = trans->GetResponseInfo();
4262   ASSERT_TRUE(response);
4263   EXPECT_EQ(401, response->headers->response_code());
4264   EXPECT_FALSE(response->auth_challenge->is_proxy);
4265   EXPECT_EQ("http://myproxy:70",
4266             response->auth_challenge->challenger.Serialize());
4267   EXPECT_EQ("MyRealm1", response->auth_challenge->realm);
4268   EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
4269 
4270   rv = trans->RestartWithAuth(AuthCredentials(kFoo2, kBar2),
4271                               callback.callback());
4272   EXPECT_THAT(callback.GetResult(rv), IsOk());
4273   response = trans->GetResponseInfo();
4274   ASSERT_TRUE(response);
4275   EXPECT_EQ(200, response->headers->response_code());
4276   // The password prompt info should not be set.
4277   EXPECT_FALSE(response->auth_challenge.has_value());
4278   std::string response_data;
4279   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4280   EXPECT_EQ("hello", response_data);
4281 
4282   // Check that the proxy credentials were cached correctly. The should be
4283   // accessible with any NetworkIsolationKey.
4284   HttpAuthCache::Entry* entry = session->http_auth_cache()->Lookup(
4285       GURL("http://myproxy:70"), HttpAuth::AUTH_PROXY, "MyRealm1",
4286       HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1);
4287   ASSERT_TRUE(entry);
4288   ASSERT_EQ(kFoo, entry->credentials().username());
4289   ASSERT_EQ(kBar, entry->credentials().password());
4290   EXPECT_EQ(entry,
4291             session->http_auth_cache()->Lookup(
4292                 GURL("http://myproxy:70"), HttpAuth::AUTH_PROXY, "MyRealm1",
4293                 HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2));
4294 
4295   // Check that the server credentials were cached correctly. The should be
4296   // accessible with only kNetworkIsolationKey1.
4297   entry = session->http_auth_cache()->Lookup(
4298       GURL("http://myproxy:70"), HttpAuth::AUTH_SERVER, "MyRealm1",
4299       HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1);
4300   ASSERT_TRUE(entry);
4301   ASSERT_EQ(kFoo2, entry->credentials().username());
4302   ASSERT_EQ(kBar2, entry->credentials().password());
4303   // Looking up the server entry with another NetworkIsolationKey should fail.
4304   EXPECT_FALSE(session->http_auth_cache()->Lookup(
4305       GURL("http://myproxy:70"), HttpAuth::AUTH_SERVER, "MyRealm1",
4306       HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2));
4307 
4308   // Make another request with a different NetworkIsolationKey. It should use
4309   // another socket, reuse the cached proxy credentials, but result in a server
4310   // auth challenge.
4311   request.network_isolation_key = kNetworkIsolationKey2;
4312   trans =
4313       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4314   rv = trans->Start(&request, callback.callback(), log.bound());
4315   EXPECT_THAT(callback.GetResult(rv), IsOk());
4316   response = trans->GetResponseInfo();
4317   ASSERT_TRUE(response);
4318   EXPECT_EQ(401, response->headers->response_code());
4319   EXPECT_FALSE(response->auth_challenge->is_proxy);
4320   EXPECT_EQ("http://myproxy:70",
4321             response->auth_challenge->challenger.Serialize());
4322   EXPECT_EQ("MyRealm1", response->auth_challenge->realm);
4323   EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
4324 
4325   rv = trans->RestartWithAuth(AuthCredentials(kFoo3, kBar3),
4326                               callback.callback());
4327   EXPECT_THAT(callback.GetResult(rv), IsOk());
4328   response = trans->GetResponseInfo();
4329   ASSERT_TRUE(response);
4330   EXPECT_EQ(200, response->headers->response_code());
4331   // The password prompt info should not be set.
4332   EXPECT_FALSE(response->auth_challenge.has_value());
4333   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4334   EXPECT_EQ("greetings", response_data);
4335 
4336   // Check that the proxy credentials are still cached.
4337   entry = session->http_auth_cache()->Lookup(
4338       GURL("http://myproxy:70"), HttpAuth::AUTH_PROXY, "MyRealm1",
4339       HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1);
4340   ASSERT_TRUE(entry);
4341   ASSERT_EQ(kFoo, entry->credentials().username());
4342   ASSERT_EQ(kBar, entry->credentials().password());
4343   EXPECT_EQ(entry,
4344             session->http_auth_cache()->Lookup(
4345                 GURL("http://myproxy:70"), HttpAuth::AUTH_PROXY, "MyRealm1",
4346                 HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2));
4347 
4348   // Check that the correct server credentials are cached for each
4349   // NetworkIsolationKey.
4350   entry = session->http_auth_cache()->Lookup(
4351       GURL("http://myproxy:70"), HttpAuth::AUTH_SERVER, "MyRealm1",
4352       HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1);
4353   ASSERT_TRUE(entry);
4354   ASSERT_EQ(kFoo2, entry->credentials().username());
4355   ASSERT_EQ(kBar2, entry->credentials().password());
4356   entry = session->http_auth_cache()->Lookup(
4357       GURL("http://myproxy:70"), HttpAuth::AUTH_SERVER, "MyRealm1",
4358       HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2);
4359   ASSERT_TRUE(entry);
4360   ASSERT_EQ(kFoo3, entry->credentials().username());
4361   ASSERT_EQ(kBar3, entry->credentials().password());
4362 
4363   // Make a request with the original NetworkIsolationKey. It should reuse the
4364   // first socket, and the proxy credentials sent on the first socket.
4365   request.network_isolation_key = kNetworkIsolationKey1;
4366   trans =
4367       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4368   rv = trans->Start(&request, callback.callback(), log.bound());
4369   EXPECT_THAT(callback.GetResult(rv), IsOk());
4370   response = trans->GetResponseInfo();
4371   ASSERT_TRUE(response);
4372   EXPECT_EQ(200, response->headers->response_code());
4373   // The password prompt info should not be set.
4374   EXPECT_FALSE(response->auth_challenge.has_value());
4375   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4376   EXPECT_EQ("hi", response_data);
4377 
4378   trans.reset();
4379   session->CloseAllConnections(ERR_FAILED, "Very good reason");
4380 }
4381 
4382 // Much like the test above, but uses tunnelled connections.
TEST_F(HttpNetworkTransactionTest,BasicAuthProxyMatchesServerAuthWithNetworkIsolationKeyWithTunnel)4383 TEST_F(HttpNetworkTransactionTest,
4384        BasicAuthProxyMatchesServerAuthWithNetworkIsolationKeyWithTunnel) {
4385   const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
4386   const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
4387   const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
4388   const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
4389 
4390   // This test would need to use a single socket without this option enabled.
4391   // Best to use this option when it would affect a test, as it will eventually
4392   // become the default behavior.
4393   base::test::ScopedFeatureList feature_list;
4394   feature_list.InitAndEnableFeature(
4395       features::kPartitionConnectionsByNetworkIsolationKey);
4396 
4397   // Proxy matches request URL.
4398   session_deps_.proxy_resolution_service =
4399       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
4400           "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4401   RecordingBoundTestNetLog log;
4402   session_deps_.net_log = log.bound().net_log();
4403   session_deps_.key_auth_cache_server_entries_by_network_isolation_key = true;
4404   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4405 
4406   MockWrite data_writes[] = {
4407       // Initial tunnel request gets a proxy auth challenge.
4408       MockWrite("CONNECT myproxy:70 HTTP/1.1\r\n"
4409                 "Host: myproxy:70\r\n"
4410                 "Proxy-Connection: keep-alive\r\n\r\n"),
4411       // Retry with proxy auth credentials, which will result in establishing a
4412       // tunnel.
4413       MockWrite("CONNECT myproxy:70 HTTP/1.1\r\n"
4414                 "Host: myproxy:70\r\n"
4415                 "Proxy-Connection: keep-alive\r\n"
4416                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4417       // Request over the tunnel, which gets a server auth challenge.
4418       MockWrite("GET / HTTP/1.1\r\n"
4419                 "Host: myproxy:70\r\n"
4420                 "Connection: keep-alive\r\n\r\n"),
4421       // Retry with server auth credentials, which gets a response.
4422       MockWrite("GET / HTTP/1.1\r\n"
4423                 "Host: myproxy:70\r\n"
4424                 "Connection: keep-alive\r\n"
4425                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4426       // Another request to the same server and using the same NIK should
4427       // preemptively send the correct cached server
4428       // auth header. Since a tunnel was already established, the proxy headers
4429       // won't be sent again except when establishing another tunnel.
4430       MockWrite("GET / HTTP/1.1\r\n"
4431                 "Host: myproxy:70\r\n"
4432                 "Connection: keep-alive\r\n"
4433                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4434   };
4435 
4436   MockRead data_reads[] = {
4437       // Proxy auth challenge.
4438       MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"
4439                "Proxy-Connection: keep-alive\r\n"
4440                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4441                "Content-Length: 0\r\n\r\n"),
4442       // Tunnel success
4443       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4444       // Server auth challenge.
4445       MockRead("HTTP/1.0 401 Authentication Required\r\n"
4446                "Connection: keep-alive\r\n"
4447                "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4448                "Content-Length: 0\r\n\r\n"),
4449       // Response.
4450       MockRead("HTTP/1.1 200 OK\r\n"
4451                "Connection: keep-alive\r\n"
4452                "Content-Length: 5\r\n\r\n"
4453                "hello"),
4454       // Response to second request.
4455       MockRead("HTTP/1.1 200 OK\r\n"
4456                "Connection: keep-alive\r\n"
4457                "Content-Length: 2\r\n\r\n"
4458                "hi"),
4459   };
4460 
4461   StaticSocketDataProvider data(data_reads, data_writes);
4462   session_deps_.socket_factory->AddSocketDataProvider(&data);
4463   // One for the proxy connection, one of the server connection.
4464   SSLSocketDataProvider ssl(ASYNC, OK);
4465   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4466   SSLSocketDataProvider ssl2(ASYNC, OK);
4467   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
4468 
4469   MockWrite data_writes2[] = {
4470       // Initial request using a different NetworkIsolationKey includes the
4471       // cached proxy credentials when establishing a tunnel.
4472       MockWrite("CONNECT myproxy:70 HTTP/1.1\r\n"
4473                 "Host: myproxy:70\r\n"
4474                 "Proxy-Connection: keep-alive\r\n"
4475                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4476       // Request over the tunnel, which gets a server auth challenge. Cached
4477       // credentials cannot be used, since the NIK is different.
4478       MockWrite("GET / HTTP/1.1\r\n"
4479                 "Host: myproxy:70\r\n"
4480                 "Connection: keep-alive\r\n\r\n"),
4481       // Retry with server auth credentials, which gets a response.
4482       MockWrite("GET / HTTP/1.1\r\n"
4483                 "Host: myproxy:70\r\n"
4484                 "Connection: keep-alive\r\n"
4485                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
4486   };
4487 
4488   MockRead data_reads2[] = {
4489       // Tunnel success
4490       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4491       // Server auth challenge.
4492       MockRead("HTTP/1.0 401 Authentication Required\r\n"
4493                "Connection: keep-alive\r\n"
4494                "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
4495                "Content-Length: 0\r\n\r\n"),
4496       // Response.
4497       MockRead("HTTP/1.1 200 OK\r\n"
4498                "Connection: keep-alive\r\n"
4499                "Content-Length: 9\r\n\r\n"
4500                "greetings"),
4501   };
4502 
4503   StaticSocketDataProvider data2(data_reads2, data_writes2);
4504   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4505   // One for the proxy connection, one of the server connection.
4506   SSLSocketDataProvider ssl3(ASYNC, OK);
4507   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
4508   SSLSocketDataProvider ssl4(ASYNC, OK);
4509   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl4);
4510 
4511   TestCompletionCallback callback;
4512 
4513   HttpRequestInfo request;
4514   request.method = "GET";
4515   request.url = GURL("https://myproxy:70/");
4516   request.traffic_annotation =
4517       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4518   request.network_isolation_key = kNetworkIsolationKey1;
4519 
4520   auto trans =
4521       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4522   int rv = trans->Start(&request, callback.callback(), log.bound());
4523   EXPECT_THAT(callback.GetResult(rv), IsOk());
4524   const HttpResponseInfo* response = trans->GetResponseInfo();
4525   ASSERT_TRUE(response);
4526   ASSERT_TRUE(response->headers);
4527   EXPECT_EQ(407, response->headers->response_code());
4528   EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
4529 
4530   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
4531   EXPECT_THAT(callback.GetResult(rv), IsOk());
4532   response = trans->GetResponseInfo();
4533   ASSERT_TRUE(response);
4534   EXPECT_EQ(401, response->headers->response_code());
4535   EXPECT_FALSE(response->auth_challenge->is_proxy);
4536   EXPECT_EQ("https://myproxy:70",
4537             response->auth_challenge->challenger.Serialize());
4538   EXPECT_EQ("MyRealm1", response->auth_challenge->realm);
4539   EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
4540 
4541   rv = trans->RestartWithAuth(AuthCredentials(kFoo2, kBar2),
4542                               callback.callback());
4543   EXPECT_THAT(callback.GetResult(rv), IsOk());
4544   response = trans->GetResponseInfo();
4545   ASSERT_TRUE(response);
4546   EXPECT_EQ(200, response->headers->response_code());
4547   // The password prompt info should not be set.
4548   EXPECT_FALSE(response->auth_challenge.has_value());
4549   std::string response_data;
4550   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4551   EXPECT_EQ("hello", response_data);
4552 
4553   // Check that the proxy credentials were cached correctly. The should be
4554   // accessible with any NetworkIsolationKey.
4555   HttpAuthCache::Entry* entry = session->http_auth_cache()->Lookup(
4556       GURL("https://myproxy:70"), HttpAuth::AUTH_PROXY, "MyRealm1",
4557       HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1);
4558   ASSERT_TRUE(entry);
4559   ASSERT_EQ(kFoo, entry->credentials().username());
4560   ASSERT_EQ(kBar, entry->credentials().password());
4561   EXPECT_EQ(entry,
4562             session->http_auth_cache()->Lookup(
4563                 GURL("https://myproxy:70"), HttpAuth::AUTH_PROXY, "MyRealm1",
4564                 HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2));
4565 
4566   // Check that the server credentials were cached correctly. The should be
4567   // accessible with only kNetworkIsolationKey1.
4568   entry = session->http_auth_cache()->Lookup(
4569       GURL("https://myproxy:70"), HttpAuth::AUTH_SERVER, "MyRealm1",
4570       HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1);
4571   ASSERT_TRUE(entry);
4572   ASSERT_EQ(kFoo2, entry->credentials().username());
4573   ASSERT_EQ(kBar2, entry->credentials().password());
4574   // Looking up the server entry with another NetworkIsolationKey should fail.
4575   EXPECT_FALSE(session->http_auth_cache()->Lookup(
4576       GURL("https://myproxy:70"), HttpAuth::AUTH_SERVER, "MyRealm1",
4577       HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2));
4578 
4579   // Make another request with a different NetworkIsolationKey. It should use
4580   // another socket, reuse the cached proxy credentials, but result in a server
4581   // auth challenge.
4582   request.network_isolation_key = kNetworkIsolationKey2;
4583   trans =
4584       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4585   rv = trans->Start(&request, callback.callback(), log.bound());
4586   EXPECT_THAT(callback.GetResult(rv), IsOk());
4587   response = trans->GetResponseInfo();
4588   ASSERT_TRUE(response);
4589   EXPECT_EQ(401, response->headers->response_code());
4590   EXPECT_FALSE(response->auth_challenge->is_proxy);
4591   EXPECT_EQ("https://myproxy:70",
4592             response->auth_challenge->challenger.Serialize());
4593   EXPECT_EQ("MyRealm1", response->auth_challenge->realm);
4594   EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
4595 
4596   rv = trans->RestartWithAuth(AuthCredentials(kFoo3, kBar3),
4597                               callback.callback());
4598   EXPECT_THAT(callback.GetResult(rv), IsOk());
4599   response = trans->GetResponseInfo();
4600   ASSERT_TRUE(response);
4601   EXPECT_EQ(200, response->headers->response_code());
4602   // The password prompt info should not be set.
4603   EXPECT_FALSE(response->auth_challenge.has_value());
4604   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4605   EXPECT_EQ("greetings", response_data);
4606 
4607   // Check that the proxy credentials are still cached.
4608   entry = session->http_auth_cache()->Lookup(
4609       GURL("https://myproxy:70"), HttpAuth::AUTH_PROXY, "MyRealm1",
4610       HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1);
4611   ASSERT_TRUE(entry);
4612   ASSERT_EQ(kFoo, entry->credentials().username());
4613   ASSERT_EQ(kBar, entry->credentials().password());
4614   EXPECT_EQ(entry,
4615             session->http_auth_cache()->Lookup(
4616                 GURL("https://myproxy:70"), HttpAuth::AUTH_PROXY, "MyRealm1",
4617                 HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2));
4618 
4619   // Check that the correct server credentials are cached for each
4620   // NetworkIsolationKey.
4621   entry = session->http_auth_cache()->Lookup(
4622       GURL("https://myproxy:70"), HttpAuth::AUTH_SERVER, "MyRealm1",
4623       HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey1);
4624   ASSERT_TRUE(entry);
4625   ASSERT_EQ(kFoo2, entry->credentials().username());
4626   ASSERT_EQ(kBar2, entry->credentials().password());
4627   entry = session->http_auth_cache()->Lookup(
4628       GURL("https://myproxy:70"), HttpAuth::AUTH_SERVER, "MyRealm1",
4629       HttpAuth::AUTH_SCHEME_BASIC, kNetworkIsolationKey2);
4630   ASSERT_TRUE(entry);
4631   ASSERT_EQ(kFoo3, entry->credentials().username());
4632   ASSERT_EQ(kBar3, entry->credentials().password());
4633 
4634   // Make a request with the original NetworkIsolationKey. It should reuse the
4635   // first socket, and the proxy credentials sent on the first socket.
4636   request.network_isolation_key = kNetworkIsolationKey1;
4637   trans =
4638       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4639   rv = trans->Start(&request, callback.callback(), log.bound());
4640   EXPECT_THAT(callback.GetResult(rv), IsOk());
4641   response = trans->GetResponseInfo();
4642   ASSERT_TRUE(response);
4643   EXPECT_EQ(200, response->headers->response_code());
4644   // The password prompt info should not be set.
4645   EXPECT_FALSE(response->auth_challenge.has_value());
4646   EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4647   EXPECT_EQ("hi", response_data);
4648 
4649   trans.reset();
4650   session->CloseAllConnections(ERR_FAILED, "Very good reason");
4651 }
4652 
4653 // Test that we don't pass extraneous headers from the proxy's response to the
4654 // caller when the proxy responds to CONNECT with 407.
TEST_F(HttpNetworkTransactionTest,SanitizeProxyAuthHeaders)4655 TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
4656   HttpRequestInfo request;
4657   request.method = "GET";
4658   request.url = GURL("https://www.example.org/");
4659   request.traffic_annotation =
4660       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4661 
4662   // Configure against proxy server "myproxy:70".
4663   session_deps_.proxy_resolution_service =
4664       ConfiguredProxyResolutionService::CreateFixed(
4665           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4666 
4667   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4668 
4669   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
4670 
4671   // Since we have proxy, should try to establish tunnel.
4672   MockWrite data_writes[] = {
4673       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4674                 "Host: www.example.org:443\r\n"
4675                 "Proxy-Connection: keep-alive\r\n\r\n"),
4676   };
4677 
4678   // The proxy responds to the connect with a 407.
4679   MockRead data_reads[] = {
4680       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4681       MockRead("X-Foo: bar\r\n"),
4682       MockRead("Set-Cookie: foo=bar\r\n"),
4683       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4684       MockRead("Content-Length: 10\r\n\r\n"),
4685       MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4686   };
4687 
4688   StaticSocketDataProvider data(data_reads, data_writes);
4689   session_deps_.socket_factory->AddSocketDataProvider(&data);
4690 
4691   TestCompletionCallback callback;
4692 
4693   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
4694   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4695 
4696   rv = callback.WaitForResult();
4697   EXPECT_THAT(rv, IsOk());
4698 
4699   const HttpResponseInfo* response = trans.GetResponseInfo();
4700   ASSERT_TRUE(response);
4701   ASSERT_TRUE(response->headers);
4702   EXPECT_TRUE(response->headers->IsKeepAlive());
4703   EXPECT_EQ(407, response->headers->response_code());
4704   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4705   EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
4706   EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
4707 
4708   std::string response_data;
4709   rv = ReadTransaction(&trans, &response_data);
4710   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
4711 
4712   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4713   session->CloseAllConnections(ERR_FAILED, "Very good reason");
4714 }
4715 
4716 // Test when a server (non-proxy) returns a 407 (proxy-authenticate).
4717 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
TEST_F(HttpNetworkTransactionTest,UnexpectedProxyAuth)4718 TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
4719   HttpRequestInfo request;
4720   request.method = "GET";
4721   request.url = GURL("http://www.example.org/");
4722   request.traffic_annotation =
4723       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4724 
4725   // We are using a DIRECT connection (i.e. no proxy) for this session.
4726   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4727   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
4728 
4729   MockWrite data_writes1[] = {
4730       MockWrite(
4731           "GET / HTTP/1.1\r\n"
4732           "Host: www.example.org\r\n"
4733           "Connection: keep-alive\r\n\r\n"),
4734   };
4735 
4736   MockRead data_reads1[] = {
4737     MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4738     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4739     // Large content-length -- won't matter, as connection will be reset.
4740     MockRead("Content-Length: 10000\r\n\r\n"),
4741     MockRead(SYNCHRONOUS, ERR_FAILED),
4742   };
4743 
4744   StaticSocketDataProvider data1(data_reads1, data_writes1);
4745   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4746 
4747   TestCompletionCallback callback;
4748 
4749   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
4750   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4751 
4752   rv = callback.WaitForResult();
4753   EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
4754 }
4755 
4756 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4757 // through a non-authenticating proxy. The request should fail with
4758 // ERR_UNEXPECTED_PROXY_AUTH.
4759 // Note that it is impossible to detect if an HTTP server returns a 407 through
4760 // a non-authenticating proxy - there is nothing to indicate whether the
4761 // response came from the proxy or the server, so it is treated as if the proxy
4762 // issued the challenge.
TEST_F(HttpNetworkTransactionTest,HttpsServerRequestsProxyAuthThroughProxy)4763 TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
4764   HttpRequestInfo request;
4765   request.method = "GET";
4766   request.url = GURL("https://www.example.org/");
4767   request.traffic_annotation =
4768       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4769 
4770   session_deps_.proxy_resolution_service =
4771       ConfiguredProxyResolutionService::CreateFixed(
4772           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4773   RecordingBoundTestNetLog log;
4774   session_deps_.net_log = log.bound().net_log();
4775   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4776 
4777   // Since we have proxy, should try to establish tunnel.
4778   MockWrite data_writes1[] = {
4779       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4780                 "Host: www.example.org:443\r\n"
4781                 "Proxy-Connection: keep-alive\r\n\r\n"),
4782 
4783       MockWrite("GET / HTTP/1.1\r\n"
4784                 "Host: www.example.org\r\n"
4785                 "Connection: keep-alive\r\n\r\n"),
4786   };
4787 
4788   MockRead data_reads1[] = {
4789     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4790 
4791     MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4792     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4793     MockRead("\r\n"),
4794     MockRead(SYNCHRONOUS, OK),
4795   };
4796 
4797   StaticSocketDataProvider data1(data_reads1, data_writes1);
4798   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4799   SSLSocketDataProvider ssl(ASYNC, OK);
4800   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4801 
4802   TestCompletionCallback callback1;
4803 
4804   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
4805 
4806   int rv = trans.Start(&request, callback1.callback(), log.bound());
4807   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4808 
4809   rv = callback1.WaitForResult();
4810   EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
4811   auto entries = log.GetEntries();
4812   size_t pos = ExpectLogContainsSomewhere(
4813       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4814       NetLogEventPhase::NONE);
4815   ExpectLogContainsSomewhere(
4816       entries, pos,
4817       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4818       NetLogEventPhase::NONE);
4819 }
4820 
4821 // Test a proxy auth scheme that allows default credentials and a proxy server
4822 // that uses non-persistent connections.
TEST_F(HttpNetworkTransactionTest,AuthAllowsDefaultCredentialsTunnelConnectionClose)4823 TEST_F(HttpNetworkTransactionTest,
4824        AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4825   HttpRequestInfo request;
4826   request.method = "GET";
4827   request.url = GURL("https://www.example.org/");
4828   request.traffic_annotation =
4829       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4830 
4831   // Configure against proxy server "myproxy:70".
4832   session_deps_.proxy_resolution_service =
4833       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
4834           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4835 
4836   auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4837   auth_handler_factory->set_do_init_from_challenge(true);
4838   auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4839   mock_handler->set_allows_default_credentials(true);
4840   auth_handler_factory->AddMockHandler(mock_handler.release(),
4841                                        HttpAuth::AUTH_PROXY);
4842   session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4843 
4844   // Add NetLog just so can verify load timing information gets a NetLog ID.
4845   session_deps_.net_log = NetLog::Get();
4846   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4847 
4848   // Since we have proxy, should try to establish tunnel.
4849   MockWrite data_writes1[] = {
4850       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4851                 "Host: www.example.org:443\r\n"
4852                 "Proxy-Connection: keep-alive\r\n\r\n"),
4853   };
4854 
4855   // The proxy responds to the connect with a 407, using a non-persistent
4856   // connection.
4857   MockRead data_reads1[] = {
4858       // No credentials.
4859       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4860       MockRead("Proxy-Authenticate: Mock\r\n"),
4861       MockRead("Proxy-Connection: close\r\n\r\n"),
4862   };
4863 
4864   // Since the first connection couldn't be reused, need to establish another
4865   // once given credentials.
4866   MockWrite data_writes2[] = {
4867       // After calling trans->RestartWithAuth(), this is the request we should
4868       // be issuing -- the final header line contains the credentials.
4869       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4870                 "Host: www.example.org:443\r\n"
4871                 "Proxy-Connection: keep-alive\r\n"
4872                 "Proxy-Authorization: auth_token\r\n\r\n"),
4873 
4874       MockWrite("GET / HTTP/1.1\r\n"
4875                 "Host: www.example.org\r\n"
4876                 "Connection: keep-alive\r\n\r\n"),
4877   };
4878 
4879   MockRead data_reads2[] = {
4880       MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4881 
4882       MockRead("HTTP/1.1 200 OK\r\n"),
4883       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4884       MockRead("Content-Length: 5\r\n\r\n"),
4885       MockRead(SYNCHRONOUS, "hello"),
4886   };
4887 
4888   StaticSocketDataProvider data1(data_reads1, data_writes1);
4889   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4890   StaticSocketDataProvider data2(data_reads2, data_writes2);
4891   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4892   SSLSocketDataProvider ssl(ASYNC, OK);
4893   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4894 
4895   auto trans =
4896       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4897 
4898   TestCompletionCallback callback;
4899   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4900   EXPECT_THAT(callback.GetResult(rv), IsOk());
4901 
4902   const HttpResponseInfo* response = trans->GetResponseInfo();
4903   ASSERT_TRUE(response);
4904   ASSERT_TRUE(response->headers);
4905   EXPECT_FALSE(response->headers->IsKeepAlive());
4906   EXPECT_EQ(407, response->headers->response_code());
4907   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4908   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4909   EXPECT_FALSE(response->auth_challenge.has_value());
4910 
4911   LoadTimingInfo load_timing_info;
4912   // CONNECT requests and responses are handled at the connect job level, so
4913   // the transaction does not yet have a connection.
4914   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4915 
4916   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4917   EXPECT_THAT(callback.GetResult(rv), IsOk());
4918   response = trans->GetResponseInfo();
4919   ASSERT_TRUE(response);
4920   ASSERT_TRUE(response->headers);
4921   EXPECT_TRUE(response->headers->IsKeepAlive());
4922   EXPECT_EQ(200, response->headers->response_code());
4923   EXPECT_EQ(5, response->headers->GetContentLength());
4924   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4925 
4926   // The password prompt info should not be set.
4927   EXPECT_FALSE(response->auth_challenge.has_value());
4928 
4929   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4930   TestLoadTimingNotReusedWithPac(load_timing_info,
4931                                  CONNECT_TIMING_HAS_SSL_TIMES);
4932 
4933   trans.reset();
4934   session->CloseAllConnections(ERR_FAILED, "Very good reason");
4935 }
4936 
4937 // Test a proxy auth scheme that allows default credentials and a proxy server
4938 // that hangs up when credentials are initially sent.
TEST_F(HttpNetworkTransactionTest,AuthAllowsDefaultCredentialsTunnelServerClosesConnection)4939 TEST_F(HttpNetworkTransactionTest,
4940        AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4941   HttpRequestInfo request;
4942   request.method = "GET";
4943   request.url = GURL("https://www.example.org/");
4944   request.traffic_annotation =
4945       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4946 
4947   // Configure against proxy server "myproxy:70".
4948   session_deps_.proxy_resolution_service =
4949       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
4950           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4951 
4952   auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4953   auth_handler_factory->set_do_init_from_challenge(true);
4954   auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4955   mock_handler->set_allows_default_credentials(true);
4956   auth_handler_factory->AddMockHandler(mock_handler.release(),
4957                                        HttpAuth::AUTH_PROXY);
4958   session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4959 
4960   // Add NetLog just so can verify load timing information gets a NetLog ID.
4961   session_deps_.net_log = NetLog::Get();
4962   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4963 
4964   // Should try to establish tunnel.
4965   MockWrite data_writes1[] = {
4966       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4967                 "Host: www.example.org:443\r\n"
4968                 "Proxy-Connection: keep-alive\r\n\r\n"),
4969 
4970       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4971                 "Host: www.example.org:443\r\n"
4972                 "Proxy-Connection: keep-alive\r\n"
4973                 "Proxy-Authorization: auth_token\r\n\r\n"),
4974   };
4975 
4976   // The proxy responds to the connect with a 407, using a non-persistent
4977   // connection.
4978   MockRead data_reads1[] = {
4979       // No credentials.
4980       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4981       MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4982       MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4983   };
4984 
4985   // Since the first connection was closed, need to establish another once given
4986   // credentials.
4987   MockWrite data_writes2[] = {
4988       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4989                 "Host: www.example.org:443\r\n"
4990                 "Proxy-Connection: keep-alive\r\n"
4991                 "Proxy-Authorization: auth_token\r\n\r\n"),
4992 
4993       MockWrite("GET / HTTP/1.1\r\n"
4994                 "Host: www.example.org\r\n"
4995                 "Connection: keep-alive\r\n\r\n"),
4996   };
4997 
4998   MockRead data_reads2[] = {
4999       MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
5000 
5001       MockRead("HTTP/1.1 200 OK\r\n"),
5002       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5003       MockRead("Content-Length: 5\r\n\r\n"),
5004       MockRead(SYNCHRONOUS, "hello"),
5005   };
5006 
5007   StaticSocketDataProvider data1(data_reads1, data_writes1);
5008   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5009   StaticSocketDataProvider data2(data_reads2, data_writes2);
5010   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5011   SSLSocketDataProvider ssl(ASYNC, OK);
5012   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5013 
5014   auto trans =
5015       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5016 
5017   TestCompletionCallback callback;
5018   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5019   EXPECT_THAT(callback.GetResult(rv), IsOk());
5020 
5021   const HttpResponseInfo* response = trans->GetResponseInfo();
5022   ASSERT_TRUE(response);
5023   ASSERT_TRUE(response->headers);
5024   EXPECT_TRUE(response->headers->IsKeepAlive());
5025   EXPECT_EQ(407, response->headers->response_code());
5026   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5027   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5028   EXPECT_FALSE(response->auth_challenge.has_value());
5029 
5030   LoadTimingInfo load_timing_info;
5031   // CONNECT requests and responses are handled at the connect job level, so
5032   // the transaction does not yet have a connection.
5033   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
5034 
5035   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5036   EXPECT_THAT(callback.GetResult(rv), IsOk());
5037 
5038   response = trans->GetResponseInfo();
5039   ASSERT_TRUE(response);
5040   ASSERT_TRUE(response->headers);
5041   EXPECT_TRUE(response->headers->IsKeepAlive());
5042   EXPECT_EQ(200, response->headers->response_code());
5043   EXPECT_EQ(5, response->headers->GetContentLength());
5044   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5045 
5046   // The password prompt info should not be set.
5047   EXPECT_FALSE(response->auth_challenge.has_value());
5048 
5049   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5050   TestLoadTimingNotReusedWithPac(load_timing_info,
5051                                  CONNECT_TIMING_HAS_SSL_TIMES);
5052 
5053   trans.reset();
5054   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5055 }
5056 
5057 // Test a proxy auth scheme that allows default credentials and a proxy server
5058 // that hangs up when credentials are initially sent, and hangs up again when
5059 // they are retried.
TEST_F(HttpNetworkTransactionTest,AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice)5060 TEST_F(HttpNetworkTransactionTest,
5061        AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
5062   HttpRequestInfo request;
5063   request.method = "GET";
5064   request.url = GURL("https://www.example.org/");
5065   request.traffic_annotation =
5066       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5067 
5068   // Configure against proxy server "myproxy:70".
5069   session_deps_.proxy_resolution_service =
5070       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
5071           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
5072 
5073   auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
5074   auth_handler_factory->set_do_init_from_challenge(true);
5075   auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
5076   mock_handler->set_allows_default_credentials(true);
5077   auth_handler_factory->AddMockHandler(mock_handler.release(),
5078                                        HttpAuth::AUTH_PROXY);
5079   session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
5080 
5081   // Add NetLog just so can verify load timing information gets a NetLog ID.
5082   session_deps_.net_log = NetLog::Get();
5083   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
5084 
5085   // Should try to establish tunnel.
5086   MockWrite data_writes1[] = {
5087       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5088                 "Host: www.example.org:443\r\n"
5089                 "Proxy-Connection: keep-alive\r\n\r\n"),
5090 
5091       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5092                 "Host: www.example.org:443\r\n"
5093                 "Proxy-Connection: keep-alive\r\n"
5094                 "Proxy-Authorization: auth_token\r\n\r\n"),
5095   };
5096 
5097   // The proxy responds to the connect with a 407, and then hangs up after the
5098   // second request is sent.
5099   MockRead data_reads1[] = {
5100       // No credentials.
5101       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5102       MockRead("Content-Length: 0\r\n"),
5103       MockRead("Proxy-Connection: keep-alive\r\n"),
5104       MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
5105       MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
5106   };
5107 
5108   // HttpNetworkTransaction sees a reused connection that was closed with
5109   // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
5110   // request.
5111   MockWrite data_writes2[] = {
5112       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5113                 "Host: www.example.org:443\r\n"
5114                 "Proxy-Connection: keep-alive\r\n\r\n"),
5115   };
5116 
5117   // The proxy, having had more than enough of us, just hangs up.
5118   MockRead data_reads2[] = {
5119       // No credentials.
5120       MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
5121   };
5122 
5123   StaticSocketDataProvider data1(data_reads1, data_writes1);
5124   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5125   StaticSocketDataProvider data2(data_reads2, data_writes2);
5126   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5127 
5128   auto trans =
5129       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5130 
5131   TestCompletionCallback callback;
5132   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5133   EXPECT_THAT(callback.GetResult(rv), IsOk());
5134 
5135   const HttpResponseInfo* response = trans->GetResponseInfo();
5136   ASSERT_TRUE(response);
5137   ASSERT_TRUE(response->headers);
5138   EXPECT_TRUE(response->headers->IsKeepAlive());
5139   EXPECT_EQ(407, response->headers->response_code());
5140   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5141   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5142   EXPECT_FALSE(response->auth_challenge.has_value());
5143 
5144   LoadTimingInfo load_timing_info;
5145   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
5146 
5147   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5148   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
5149 
5150   trans.reset();
5151   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5152 }
5153 
5154 // This test exercises an odd edge case where the proxy closes the connection
5155 // after the authentication handshake is complete. Presumably this technique is
5156 // used in lieu of returning a 403 or 5xx status code when the authentication
5157 // succeeds, but the user is not authorized to connect to the destination
5158 // server. There's no standard for what a proxy should do to indicate a blocked
5159 // site.
TEST_F(HttpNetworkTransactionTest,AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody)5160 TEST_F(HttpNetworkTransactionTest,
5161        AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
5162   HttpRequestInfo request;
5163   request.method = "GET";
5164   request.url = GURL("https://www.example.org/");
5165   request.traffic_annotation =
5166       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5167 
5168   // Configure against proxy server "myproxy:70".
5169   session_deps_.proxy_resolution_service =
5170       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
5171           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
5172 
5173   auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
5174   auth_handler_factory->set_do_init_from_challenge(true);
5175 
5176   // Create two mock AuthHandlers. This is because the transaction gets retried
5177   // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
5178   // was a real network error.
5179   //
5180   // The handlers support both default and explicit credentials. The retry
5181   // mentioned above should be able to reuse the default identity. Thus there
5182   // should never be a need to prompt for explicit credentials.
5183   auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
5184   mock_handler->set_allows_default_credentials(true);
5185   mock_handler->set_allows_explicit_credentials(true);
5186   mock_handler->set_connection_based(true);
5187   auth_handler_factory->AddMockHandler(mock_handler.release(),
5188                                        HttpAuth::AUTH_PROXY);
5189   mock_handler = std::make_unique<HttpAuthHandlerMock>();
5190   mock_handler->set_allows_default_credentials(true);
5191   mock_handler->set_allows_explicit_credentials(true);
5192   mock_handler->set_connection_based(true);
5193   auth_handler_factory->AddMockHandler(mock_handler.release(),
5194                                        HttpAuth::AUTH_PROXY);
5195   session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
5196 
5197   session_deps_.net_log = NetLog::Get();
5198   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
5199 
5200   // Data for both sockets.
5201   //
5202   // Writes are for the tunnel establishment attempts and the
5203   // authentication handshake.
5204   MockWrite data_writes1[] = {
5205       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5206                 "Host: www.example.org:443\r\n"
5207                 "Proxy-Connection: keep-alive\r\n\r\n"),
5208 
5209       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5210                 "Host: www.example.org:443\r\n"
5211                 "Proxy-Connection: keep-alive\r\n"
5212                 "Proxy-Authorization: auth_token\r\n\r\n"),
5213 
5214       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5215                 "Host: www.example.org:443\r\n"
5216                 "Proxy-Connection: keep-alive\r\n"
5217                 "Proxy-Authorization: auth_token\r\n\r\n"),
5218   };
5219 
5220   // The server side of the authentication handshake. Note that the response to
5221   // the final CONNECT request is ERR_CONNECTION_CLOSED.
5222   MockRead data_reads1[] = {
5223       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5224       MockRead("Content-Length: 0\r\n"),
5225       MockRead("Proxy-Connection: keep-alive\r\n"),
5226       MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
5227 
5228       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5229       MockRead("Content-Length: 0\r\n"),
5230       MockRead("Proxy-Connection: keep-alive\r\n"),
5231       MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
5232 
5233       MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
5234   };
5235 
5236   StaticSocketDataProvider data1(data_reads1, data_writes1);
5237   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5238 
5239   // The second socket is for the reconnection attempt. Data is identical to the
5240   // first attempt.
5241   StaticSocketDataProvider data2(data_reads1, data_writes1);
5242   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5243 
5244   auto trans =
5245       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5246 
5247   TestCompletionCallback callback;
5248   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5249 
5250   // Two rounds per handshake. After one retry, the error is propagated up the
5251   // stack.
5252   for (int i = 0; i < 4; ++i) {
5253     EXPECT_THAT(callback.GetResult(rv), IsOk());
5254 
5255     const HttpResponseInfo* response = trans->GetResponseInfo();
5256     ASSERT_TRUE(response);
5257     ASSERT_TRUE(response->headers);
5258     EXPECT_EQ(407, response->headers->response_code());
5259     ASSERT_TRUE(trans->IsReadyToRestartForAuth());
5260 
5261     rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5262   }
5263 
5264   // One shall be the number thou shalt retry, and the number of the retrying
5265   // shall be one.  Two shalt thou not retry, neither retry thou zero, excepting
5266   // that thou then proceed to one.  Three is right out.  Once the number one,
5267   // being the first number, be reached, then lobbest thou thy
5268   // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
5269   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
5270 
5271   trans.reset();
5272   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5273 }
5274 
5275 // Test a proxy auth scheme that allows default credentials and a proxy server
5276 // that hangs up when credentials are initially sent, and sends a challenge
5277 // again they are retried.
TEST_F(HttpNetworkTransactionTest,AuthAllowsDefaultCredentialsTunnelServerChallengesTwice)5278 TEST_F(HttpNetworkTransactionTest,
5279        AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
5280   HttpRequestInfo request;
5281   request.method = "GET";
5282   request.url = GURL("https://www.example.org/");
5283   request.traffic_annotation =
5284       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5285 
5286   // Configure against proxy server "myproxy:70".
5287   session_deps_.proxy_resolution_service =
5288       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
5289           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
5290 
5291   auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
5292   auth_handler_factory->set_do_init_from_challenge(true);
5293   auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
5294   mock_handler->set_allows_default_credentials(true);
5295   auth_handler_factory->AddMockHandler(mock_handler.release(),
5296                                        HttpAuth::AUTH_PROXY);
5297   // Add another handler for the second challenge. It supports default
5298   // credentials, but they shouldn't be used, since they were already tried.
5299   mock_handler = std::make_unique<HttpAuthHandlerMock>();
5300   mock_handler->set_allows_default_credentials(true);
5301   auth_handler_factory->AddMockHandler(mock_handler.release(),
5302                                        HttpAuth::AUTH_PROXY);
5303   session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
5304 
5305   // Add NetLog just so can verify load timing information gets a NetLog ID.
5306   session_deps_.net_log = NetLog::Get();
5307   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
5308 
5309   // Should try to establish tunnel.
5310   MockWrite data_writes1[] = {
5311       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5312                 "Host: www.example.org:443\r\n"
5313                 "Proxy-Connection: keep-alive\r\n\r\n"),
5314   };
5315 
5316   // The proxy responds to the connect with a 407, using a non-persistent
5317   // connection.
5318   MockRead data_reads1[] = {
5319       // No credentials.
5320       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5321       MockRead("Proxy-Authenticate: Mock\r\n"),
5322       MockRead("Proxy-Connection: close\r\n\r\n"),
5323   };
5324 
5325   // Since the first connection was closed, need to establish another once given
5326   // credentials.
5327   MockWrite data_writes2[] = {
5328       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5329                 "Host: www.example.org:443\r\n"
5330                 "Proxy-Connection: keep-alive\r\n"
5331                 "Proxy-Authorization: auth_token\r\n\r\n"),
5332   };
5333 
5334   MockRead data_reads2[] = {
5335       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5336       MockRead("Proxy-Authenticate: Mock\r\n"),
5337       MockRead("Proxy-Connection: close\r\n\r\n"),
5338   };
5339 
5340   StaticSocketDataProvider data1(data_reads1, data_writes1);
5341   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5342   StaticSocketDataProvider data2(data_reads2, data_writes2);
5343   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5344   SSLSocketDataProvider ssl(ASYNC, OK);
5345   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5346 
5347   auto trans =
5348       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5349 
5350   TestCompletionCallback callback;
5351   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5352   EXPECT_THAT(callback.GetResult(rv), IsOk());
5353 
5354   const HttpResponseInfo* response = trans->GetResponseInfo();
5355   ASSERT_TRUE(response);
5356   ASSERT_TRUE(response->headers);
5357   EXPECT_EQ(407, response->headers->response_code());
5358   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5359   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5360   EXPECT_FALSE(response->auth_challenge.has_value());
5361 
5362   LoadTimingInfo load_timing_info;
5363   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
5364 
5365   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5366   EXPECT_THAT(callback.GetResult(rv), IsOk());
5367   response = trans->GetResponseInfo();
5368   ASSERT_TRUE(response);
5369   ASSERT_TRUE(response->headers);
5370   EXPECT_EQ(407, response->headers->response_code());
5371   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5372   EXPECT_TRUE(response->auth_challenge.has_value());
5373 
5374   trans.reset();
5375   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5376 }
5377 
5378 // A more nuanced test than GenerateAuthToken test which asserts that
5379 // ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
5380 // unnecessarily invalidated, and that if the server co-operates, the
5381 // authentication handshake can continue with the same scheme but with a
5382 // different identity.
TEST_F(HttpNetworkTransactionTest,NonPermanentGenerateAuthTokenError)5383 TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
5384   HttpRequestInfo request;
5385   request.method = "GET";
5386   request.url = GURL("http://www.example.org/");
5387   request.traffic_annotation =
5388       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5389 
5390   auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
5391   auth_handler_factory->set_do_init_from_challenge(true);
5392 
5393   // First handler. Uses default credentials, but barfs at generate auth token.
5394   auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
5395   mock_handler->set_allows_default_credentials(true);
5396   mock_handler->set_allows_explicit_credentials(true);
5397   mock_handler->set_connection_based(true);
5398   mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
5399   auth_handler_factory->AddMockHandler(mock_handler.release(),
5400                                        HttpAuth::AUTH_SERVER);
5401 
5402   // Add another handler for the second challenge. It supports default
5403   // credentials, but they shouldn't be used, since they were already tried.
5404   mock_handler = std::make_unique<HttpAuthHandlerMock>();
5405   mock_handler->set_allows_default_credentials(true);
5406   mock_handler->set_allows_explicit_credentials(true);
5407   mock_handler->set_connection_based(true);
5408   auth_handler_factory->AddMockHandler(mock_handler.release(),
5409                                        HttpAuth::AUTH_SERVER);
5410   session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
5411 
5412   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
5413 
5414   MockWrite data_writes1[] = {
5415       MockWrite("GET / HTTP/1.1\r\n"
5416                 "Host: www.example.org\r\n"
5417                 "Connection: keep-alive\r\n\r\n"),
5418   };
5419 
5420   MockRead data_reads1[] = {
5421       MockRead("HTTP/1.1 401 Authentication Required\r\n"
5422                "WWW-Authenticate: Mock\r\n"
5423                "Connection: keep-alive\r\n\r\n"),
5424   };
5425 
5426   // Identical to data_writes1[]. The AuthHandler encounters a
5427   // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
5428   // transaction procceds without an authorization header.
5429   MockWrite data_writes2[] = {
5430       MockWrite("GET / HTTP/1.1\r\n"
5431                 "Host: www.example.org\r\n"
5432                 "Connection: keep-alive\r\n\r\n"),
5433   };
5434 
5435   MockRead data_reads2[] = {
5436       MockRead("HTTP/1.1 401 Authentication Required\r\n"
5437                "WWW-Authenticate: Mock\r\n"
5438                "Connection: keep-alive\r\n\r\n"),
5439   };
5440 
5441   MockWrite data_writes3[] = {
5442       MockWrite("GET / HTTP/1.1\r\n"
5443                 "Host: www.example.org\r\n"
5444                 "Connection: keep-alive\r\n"
5445                 "Authorization: auth_token\r\n\r\n"),
5446   };
5447 
5448   MockRead data_reads3[] = {
5449       MockRead("HTTP/1.1 200 OK\r\n"
5450                "Content-Length: 5\r\n"
5451                "Content-Type: text/plain\r\n"
5452                "Connection: keep-alive\r\n\r\n"
5453                "Hello"),
5454   };
5455 
5456   StaticSocketDataProvider data1(data_reads1, data_writes1);
5457   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5458 
5459   StaticSocketDataProvider data2(data_reads2, data_writes2);
5460   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5461 
5462   StaticSocketDataProvider data3(data_reads3, data_writes3);
5463   session_deps_.socket_factory->AddSocketDataProvider(&data3);
5464 
5465   auto trans =
5466       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5467 
5468   TestCompletionCallback callback;
5469   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5470   EXPECT_THAT(callback.GetResult(rv), IsOk());
5471 
5472   const HttpResponseInfo* response = trans->GetResponseInfo();
5473   ASSERT_TRUE(response);
5474   ASSERT_TRUE(response->headers);
5475   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5476 
5477   // The following three tests assert that an authentication challenge was
5478   // received and that the stack is ready to respond to the challenge using
5479   // ambient credentials.
5480   EXPECT_EQ(401, response->headers->response_code());
5481   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5482   EXPECT_FALSE(response->auth_challenge.has_value());
5483 
5484   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5485   EXPECT_THAT(callback.GetResult(rv), IsOk());
5486   response = trans->GetResponseInfo();
5487   ASSERT_TRUE(response);
5488   ASSERT_TRUE(response->headers);
5489 
5490   // The following three tests assert that an authentication challenge was
5491   // received and that the stack needs explicit credentials before it is ready
5492   // to respond to the challenge.
5493   EXPECT_EQ(401, response->headers->response_code());
5494   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5495   EXPECT_TRUE(response->auth_challenge.has_value());
5496 
5497   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
5498   EXPECT_THAT(callback.GetResult(rv), IsOk());
5499   response = trans->GetResponseInfo();
5500   ASSERT_TRUE(response);
5501   ASSERT_TRUE(response->headers);
5502   EXPECT_EQ(200, response->headers->response_code());
5503 
5504   trans.reset();
5505   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5506 }
5507 
5508 // Proxy resolver that returns a proxy with the same host and port for different
5509 // schemes, based on the path of the URL being requests.
5510 class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
5511  public:
SameProxyWithDifferentSchemesProxyResolver()5512   SameProxyWithDifferentSchemesProxyResolver() {}
~SameProxyWithDifferentSchemesProxyResolver()5513   ~SameProxyWithDifferentSchemesProxyResolver() override {}
5514 
ProxyHostPortPairAsString()5515   static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
5516 
ProxyHostPortPair()5517   static HostPortPair ProxyHostPortPair() {
5518     return HostPortPair::FromString(ProxyHostPortPairAsString());
5519   }
5520 
5521   // ProxyResolver implementation.
GetProxyForURL(const GURL & url,const NetworkIsolationKey & network_isolation_key,ProxyInfo * results,CompletionOnceCallback callback,std::unique_ptr<Request> * request,const NetLogWithSource &)5522   int GetProxyForURL(const GURL& url,
5523                      const NetworkIsolationKey& network_isolation_key,
5524                      ProxyInfo* results,
5525                      CompletionOnceCallback callback,
5526                      std::unique_ptr<Request>* request,
5527                      const NetLogWithSource& /*net_log*/) override {
5528     *results = ProxyInfo();
5529     results->set_traffic_annotation(
5530         MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
5531     if (url.path() == "/socks4") {
5532       results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
5533       return OK;
5534     }
5535     if (url.path() == "/socks5") {
5536       results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
5537       return OK;
5538     }
5539     if (url.path() == "/http") {
5540       results->UsePacString("PROXY " + ProxyHostPortPairAsString());
5541       return OK;
5542     }
5543     if (url.path() == "/https") {
5544       results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
5545       return OK;
5546     }
5547     if (url.path() == "/https_trusted") {
5548       results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
5549                                           ProxyHostPortPair(),
5550                                           true /* is_trusted_proxy */));
5551       return OK;
5552     }
5553     NOTREACHED();
5554     return ERR_NOT_IMPLEMENTED;
5555   }
5556 
5557  private:
5558   DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
5559 };
5560 
5561 class SameProxyWithDifferentSchemesProxyResolverFactory
5562     : public ProxyResolverFactory {
5563  public:
SameProxyWithDifferentSchemesProxyResolverFactory()5564   SameProxyWithDifferentSchemesProxyResolverFactory()
5565       : ProxyResolverFactory(false) {}
5566 
CreateProxyResolver(const scoped_refptr<PacFileData> & pac_script,std::unique_ptr<ProxyResolver> * resolver,CompletionOnceCallback callback,std::unique_ptr<Request> * request)5567   int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
5568                           std::unique_ptr<ProxyResolver>* resolver,
5569                           CompletionOnceCallback callback,
5570                           std::unique_ptr<Request>* request) override {
5571     *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
5572     return OK;
5573   }
5574 
5575  private:
5576   DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
5577 };
5578 
5579 // Check that when different proxy schemes are all applied to a proxy at the
5580 // same address, the connections are not grouped together.  i.e., a request to
5581 // foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
5582 // request to foo.com using proxy.com as an HTTP proxy.
TEST_F(HttpNetworkTransactionTest,SameDestinationForDifferentProxyTypes)5583 TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
5584   session_deps_.proxy_resolution_service =
5585       std::make_unique<ConfiguredProxyResolutionService>(
5586           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
5587               ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
5588           std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
5589           nullptr);
5590 
5591   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
5592 
5593   MockWrite socks_writes[] = {
5594       MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
5595                 kSOCKS4OkRequestLocalHostPort80Length),
5596       MockWrite(SYNCHRONOUS,
5597                 "GET /socks4 HTTP/1.1\r\n"
5598                 "Host: test\r\n"
5599                 "Connection: keep-alive\r\n\r\n"),
5600   };
5601   MockRead socks_reads[] = {
5602       MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
5603       MockRead("HTTP/1.0 200 OK\r\n"
5604                "Connection: keep-alive\r\n"
5605                "Content-Length: 15\r\n\r\n"
5606                "SOCKS4 Response"),
5607   };
5608   StaticSocketDataProvider socks_data(socks_reads, socks_writes);
5609   session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
5610 
5611   const char kSOCKS5Request[] = {
5612       0x05,                  // Version
5613       0x01,                  // Command (CONNECT)
5614       0x00,                  // Reserved
5615       0x03,                  // Address type (DOMAINNAME)
5616       0x04,                  // Length of domain (4)
5617       't',  'e',  's', 't',  // Domain string
5618       0x00, 0x50,            // 16-bit port (80)
5619   };
5620   MockWrite socks5_writes[] = {
5621       MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
5622       MockWrite(ASYNC, kSOCKS5Request, base::size(kSOCKS5Request)),
5623       MockWrite(SYNCHRONOUS,
5624                 "GET /socks5 HTTP/1.1\r\n"
5625                 "Host: test\r\n"
5626                 "Connection: keep-alive\r\n\r\n"),
5627   };
5628   MockRead socks5_reads[] = {
5629       MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
5630       MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
5631       MockRead("HTTP/1.0 200 OK\r\n"
5632                "Connection: keep-alive\r\n"
5633                "Content-Length: 15\r\n\r\n"
5634                "SOCKS5 Response"),
5635   };
5636   StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
5637   session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
5638 
5639   MockWrite http_writes[] = {
5640       MockWrite(SYNCHRONOUS,
5641                 "GET http://test/http HTTP/1.1\r\n"
5642                 "Host: test\r\n"
5643                 "Proxy-Connection: keep-alive\r\n\r\n"),
5644   };
5645   MockRead http_reads[] = {
5646       MockRead("HTTP/1.1 200 OK\r\n"
5647                "Proxy-Connection: keep-alive\r\n"
5648                "Content-Length: 13\r\n\r\n"
5649                "HTTP Response"),
5650   };
5651   StaticSocketDataProvider http_data(http_reads, http_writes);
5652   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
5653 
5654   MockWrite https_writes[] = {
5655       MockWrite(SYNCHRONOUS,
5656                 "GET http://test/https HTTP/1.1\r\n"
5657                 "Host: test\r\n"
5658                 "Proxy-Connection: keep-alive\r\n\r\n"),
5659   };
5660   MockRead https_reads[] = {
5661       MockRead("HTTP/1.1 200 OK\r\n"
5662                "Proxy-Connection: keep-alive\r\n"
5663                "Content-Length: 14\r\n\r\n"
5664                "HTTPS Response"),
5665   };
5666   StaticSocketDataProvider https_data(https_reads, https_writes);
5667   session_deps_.socket_factory->AddSocketDataProvider(&https_data);
5668   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
5669   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5670 
5671   MockWrite https_trusted_writes[] = {
5672       MockWrite(SYNCHRONOUS,
5673                 "GET http://test/https_trusted HTTP/1.1\r\n"
5674                 "Host: test\r\n"
5675                 "Proxy-Connection: keep-alive\r\n\r\n"),
5676   };
5677   MockRead https_trusted_reads[] = {
5678       MockRead("HTTP/1.1 200 OK\r\n"
5679                "Proxy-Connection: keep-alive\r\n"
5680                "Content-Length: 22\r\n\r\n"
5681                "HTTPS Trusted Response"),
5682   };
5683   StaticSocketDataProvider trusted_https_data(https_trusted_reads,
5684                                               https_trusted_writes);
5685   session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
5686   SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
5687   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
5688 
5689   struct TestCase {
5690     GURL url;
5691     std::string expected_response;
5692     // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
5693     // after the test.
5694     int expected_idle_socks4_sockets;
5695     int expected_idle_socks5_sockets;
5696     // How many idle sockets there should be in the HTTP/HTTPS proxy socket
5697     // pools after the test.
5698     int expected_idle_http_sockets;
5699     int expected_idle_https_sockets;
5700     // How many idle sockets there should be in the HTTPS proxy socket pool with
5701     // the ProxyServer's |is_trusted_proxy| bit set after the test.
5702     int expected_idle_trusted_https_sockets;
5703   } const kTestCases[] = {
5704       {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
5705       {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
5706       {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
5707       {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
5708       {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
5709        1},
5710   };
5711 
5712   for (const auto& test_case : kTestCases) {
5713     HttpRequestInfo request;
5714     request.method = "GET";
5715     request.url = test_case.url;
5716     request.traffic_annotation =
5717         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5718     std::unique_ptr<HttpNetworkTransaction> trans =
5719         std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5720                                                  session.get());
5721     TestCompletionCallback callback;
5722     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5723     EXPECT_THAT(callback.GetResult(rv), IsOk());
5724 
5725     const HttpResponseInfo* response = trans->GetResponseInfo();
5726     ASSERT_TRUE(response);
5727     ASSERT_TRUE(response->headers);
5728     EXPECT_EQ(200, response->headers->response_code());
5729     std::string response_data;
5730     EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5731     EXPECT_EQ(test_case.expected_response, response_data);
5732 
5733     // Return the socket to the socket pool, so can make sure it's not used for
5734     // the next requests.
5735     trans.reset();
5736     base::RunLoop().RunUntilIdle();
5737 
5738     // Check the number of idle sockets in the pool, to make sure that used
5739     // sockets are indeed being returned to the socket pool.  If each request
5740     // doesn't return an idle socket to the pool, the test would incorrectly
5741     // pass.
5742     EXPECT_EQ(test_case.expected_idle_socks4_sockets,
5743               session
5744                   ->GetSocketPool(
5745                       HttpNetworkSession::NORMAL_SOCKET_POOL,
5746                       ProxyServer(ProxyServer::SCHEME_SOCKS4,
5747                                   SameProxyWithDifferentSchemesProxyResolver::
5748                                       ProxyHostPortPair()))
5749                   ->IdleSocketCount());
5750     EXPECT_EQ(test_case.expected_idle_socks5_sockets,
5751               session
5752                   ->GetSocketPool(
5753                       HttpNetworkSession::NORMAL_SOCKET_POOL,
5754                       ProxyServer(ProxyServer::SCHEME_SOCKS5,
5755                                   SameProxyWithDifferentSchemesProxyResolver::
5756                                       ProxyHostPortPair()))
5757                   ->IdleSocketCount());
5758     EXPECT_EQ(test_case.expected_idle_http_sockets,
5759               session
5760                   ->GetSocketPool(
5761                       HttpNetworkSession::NORMAL_SOCKET_POOL,
5762                       ProxyServer(ProxyServer::SCHEME_HTTP,
5763                                   SameProxyWithDifferentSchemesProxyResolver::
5764                                       ProxyHostPortPair()))
5765                   ->IdleSocketCount());
5766     EXPECT_EQ(test_case.expected_idle_https_sockets,
5767               session
5768                   ->GetSocketPool(
5769                       HttpNetworkSession::NORMAL_SOCKET_POOL,
5770                       ProxyServer(ProxyServer::SCHEME_HTTPS,
5771                                   SameProxyWithDifferentSchemesProxyResolver::
5772                                       ProxyHostPortPair()))
5773                   ->IdleSocketCount());
5774     EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
5775               session
5776                   ->GetSocketPool(
5777                       HttpNetworkSession::NORMAL_SOCKET_POOL,
5778                       ProxyServer(ProxyServer::SCHEME_HTTPS,
5779                                   SameProxyWithDifferentSchemesProxyResolver::
5780                                       ProxyHostPortPair(),
5781                                   true /* is_trusted_proxy */))
5782                   ->IdleSocketCount());
5783   }
5784 }
5785 
5786 // Test the load timing for HTTPS requests with an HTTP proxy.
TEST_F(HttpNetworkTransactionTest,HttpProxyLoadTimingNoPacTwoRequests)5787 TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
5788   HttpRequestInfo request1;
5789   request1.method = "GET";
5790   request1.url = GURL("https://www.example.org/1");
5791   request1.traffic_annotation =
5792       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5793 
5794   HttpRequestInfo request2;
5795   request2.method = "GET";
5796   request2.url = GURL("https://www.example.org/2");
5797   request2.traffic_annotation =
5798       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5799 
5800   // Configure against proxy server "myproxy:70".
5801   session_deps_.proxy_resolution_service =
5802       ConfiguredProxyResolutionService::CreateFixed(
5803           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
5804   RecordingBoundTestNetLog log;
5805   session_deps_.net_log = log.bound().net_log();
5806   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5807 
5808   // Since we have proxy, should try to establish tunnel.
5809   MockWrite data_writes1[] = {
5810       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5811                 "Host: www.example.org:443\r\n"
5812                 "Proxy-Connection: keep-alive\r\n\r\n"),
5813 
5814       MockWrite("GET /1 HTTP/1.1\r\n"
5815                 "Host: www.example.org\r\n"
5816                 "Connection: keep-alive\r\n\r\n"),
5817 
5818       MockWrite("GET /2 HTTP/1.1\r\n"
5819                 "Host: www.example.org\r\n"
5820                 "Connection: keep-alive\r\n\r\n"),
5821   };
5822 
5823   // The proxy responds to the connect with a 407, using a persistent
5824   // connection.
5825   MockRead data_reads1[] = {
5826     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5827 
5828     MockRead("HTTP/1.1 200 OK\r\n"),
5829     MockRead("Content-Length: 1\r\n\r\n"),
5830     MockRead(SYNCHRONOUS, "1"),
5831 
5832     MockRead("HTTP/1.1 200 OK\r\n"),
5833     MockRead("Content-Length: 2\r\n\r\n"),
5834     MockRead(SYNCHRONOUS, "22"),
5835   };
5836 
5837   StaticSocketDataProvider data1(data_reads1, data_writes1);
5838   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5839   SSLSocketDataProvider ssl(ASYNC, OK);
5840   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5841 
5842   TestCompletionCallback callback1;
5843   auto trans1 =
5844       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5845 
5846   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
5847   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5848 
5849   rv = callback1.WaitForResult();
5850   EXPECT_THAT(rv, IsOk());
5851 
5852   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
5853   ASSERT_TRUE(response1);
5854   EXPECT_TRUE(response1->proxy_server.is_http());
5855   ASSERT_TRUE(response1->headers);
5856   EXPECT_EQ(1, response1->headers->GetContentLength());
5857 
5858   LoadTimingInfo load_timing_info1;
5859   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5860   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
5861 
5862   trans1.reset();
5863 
5864   TestCompletionCallback callback2;
5865   auto trans2 =
5866       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5867 
5868   rv = trans2->Start(&request2, callback2.callback(), log.bound());
5869   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5870 
5871   rv = callback2.WaitForResult();
5872   EXPECT_THAT(rv, IsOk());
5873 
5874   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
5875   ASSERT_TRUE(response2);
5876   EXPECT_TRUE(response2->proxy_server.is_http());
5877   ASSERT_TRUE(response2->headers);
5878   EXPECT_EQ(2, response2->headers->GetContentLength());
5879 
5880   LoadTimingInfo load_timing_info2;
5881   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5882   TestLoadTimingReused(load_timing_info2);
5883 
5884   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5885 
5886   trans2.reset();
5887   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5888 }
5889 
5890 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
TEST_F(HttpNetworkTransactionTest,HttpProxyLoadTimingWithPacTwoRequests)5891 TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
5892   HttpRequestInfo request1;
5893   request1.method = "GET";
5894   request1.url = GURL("https://www.example.org/1");
5895   request1.traffic_annotation =
5896       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5897 
5898   HttpRequestInfo request2;
5899   request2.method = "GET";
5900   request2.url = GURL("https://www.example.org/2");
5901   request2.traffic_annotation =
5902       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5903 
5904   // Configure against proxy server "myproxy:70".
5905   session_deps_.proxy_resolution_service =
5906       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
5907           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
5908   RecordingBoundTestNetLog log;
5909   session_deps_.net_log = log.bound().net_log();
5910   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5911 
5912   // Since we have proxy, should try to establish tunnel.
5913   MockWrite data_writes1[] = {
5914       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5915                 "Host: www.example.org:443\r\n"
5916                 "Proxy-Connection: keep-alive\r\n\r\n"),
5917 
5918       MockWrite("GET /1 HTTP/1.1\r\n"
5919                 "Host: www.example.org\r\n"
5920                 "Connection: keep-alive\r\n\r\n"),
5921 
5922       MockWrite("GET /2 HTTP/1.1\r\n"
5923                 "Host: www.example.org\r\n"
5924                 "Connection: keep-alive\r\n\r\n"),
5925   };
5926 
5927   // The proxy responds to the connect with a 407, using a persistent
5928   // connection.
5929   MockRead data_reads1[] = {
5930     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5931 
5932     MockRead("HTTP/1.1 200 OK\r\n"),
5933     MockRead("Content-Length: 1\r\n\r\n"),
5934     MockRead(SYNCHRONOUS, "1"),
5935 
5936     MockRead("HTTP/1.1 200 OK\r\n"),
5937     MockRead("Content-Length: 2\r\n\r\n"),
5938     MockRead(SYNCHRONOUS, "22"),
5939   };
5940 
5941   StaticSocketDataProvider data1(data_reads1, data_writes1);
5942   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5943   SSLSocketDataProvider ssl(ASYNC, OK);
5944   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5945 
5946   TestCompletionCallback callback1;
5947   auto trans1 =
5948       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5949 
5950   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
5951   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5952 
5953   rv = callback1.WaitForResult();
5954   EXPECT_THAT(rv, IsOk());
5955 
5956   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
5957   ASSERT_TRUE(response1);
5958   ASSERT_TRUE(response1->headers);
5959   EXPECT_EQ(1, response1->headers->GetContentLength());
5960 
5961   LoadTimingInfo load_timing_info1;
5962   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5963   TestLoadTimingNotReusedWithPac(load_timing_info1,
5964                                  CONNECT_TIMING_HAS_SSL_TIMES);
5965 
5966   trans1.reset();
5967 
5968   TestCompletionCallback callback2;
5969   auto trans2 =
5970       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
5971 
5972   rv = trans2->Start(&request2, callback2.callback(), log.bound());
5973   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5974 
5975   rv = callback2.WaitForResult();
5976   EXPECT_THAT(rv, IsOk());
5977 
5978   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
5979   ASSERT_TRUE(response2);
5980   ASSERT_TRUE(response2->headers);
5981   EXPECT_EQ(2, response2->headers->GetContentLength());
5982 
5983   LoadTimingInfo load_timing_info2;
5984   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5985   TestLoadTimingReusedWithPac(load_timing_info2);
5986 
5987   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5988 
5989   trans2.reset();
5990   session->CloseAllConnections(ERR_FAILED, "Very good reason");
5991 }
5992 
5993 // Make sure that NetworkIsolationKeys are passed down to the proxy layer.
TEST_F(HttpNetworkTransactionTest,ProxyResolvedWithNetworkIsolationKey)5994 TEST_F(HttpNetworkTransactionTest, ProxyResolvedWithNetworkIsolationKey) {
5995   const url::Origin kOrigin = url::Origin::Create(GURL("https://foo.test/"));
5996   const net::NetworkIsolationKey kNetworkIsolationKey(kOrigin, kOrigin);
5997 
5998   ProxyConfig proxy_config;
5999   proxy_config.set_auto_detect(true);
6000   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6001 
6002   CapturingProxyResolver capturing_proxy_resolver;
6003   capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6004   session_deps_.proxy_resolution_service =
6005       std::make_unique<ConfiguredProxyResolutionService>(
6006           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6007               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6008           std::make_unique<CapturingProxyResolverFactory>(
6009               &capturing_proxy_resolver),
6010           nullptr);
6011 
6012   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6013 
6014   // No need to continue with the network request - proxy resolution occurs
6015   // before establishing a data.
6016   StaticSocketDataProvider data{base::span<MockRead>(),
6017                                 base::span<MockWrite>()};
6018   data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_FAILED));
6019   session_deps_.socket_factory->AddSocketDataProvider(&data);
6020 
6021   // Run first request until an auth challenge is observed.
6022   HttpRequestInfo request;
6023   request.method = "GET";
6024   request.url = GURL("http://foo.test/");
6025   request.traffic_annotation =
6026       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6027   HttpNetworkTransaction trans(LOWEST, session.get());
6028   TestCompletionCallback callback;
6029   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
6030   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_FAILED));
6031 }
6032 
6033 // Test that a failure in resolving the proxy hostname is retrievable.
TEST_F(HttpNetworkTransactionTest,ProxyHostResolutionFailure)6034 TEST_F(HttpNetworkTransactionTest, ProxyHostResolutionFailure) {
6035   HttpRequestInfo request;
6036   request.method = "GET";
6037   request.url = GURL("http://www.example.org/");
6038   request.traffic_annotation =
6039       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6040 
6041   RecordingTestNetLog log;
6042   // Configure against https proxy server "proxy:70".
6043   session_deps_.proxy_resolution_service =
6044       ConfiguredProxyResolutionService::CreateFixed(
6045           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6046   MockHostResolver* resolver = new MockHostResolver();
6047   resolver->rules()->AddSimulatedTimeoutFailure("proxy");
6048   session_deps_.net_log = &log;
6049   session_deps_.host_resolver.reset(resolver);
6050   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
6051   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6052   TestCompletionCallback callback;
6053 
6054   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
6055   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6056   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_CONNECTION_FAILED));
6057 
6058   const HttpResponseInfo* response = trans.GetResponseInfo();
6059   ASSERT_TRUE(response);
6060   EXPECT_THAT(response->resolve_error_info.error, IsError(ERR_DNS_TIMED_OUT));
6061 }
6062 
6063 // Test a simple get through an HTTPS Proxy.
TEST_F(HttpNetworkTransactionTest,HttpsProxyGet)6064 TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
6065   HttpRequestInfo request;
6066   request.method = "GET";
6067   request.url = GURL("http://www.example.org/");
6068   request.traffic_annotation =
6069       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6070 
6071   // Configure against https proxy server "proxy:70".
6072   session_deps_.proxy_resolution_service =
6073       ConfiguredProxyResolutionService::CreateFixed(
6074           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6075   RecordingBoundTestNetLog log;
6076   session_deps_.net_log = log.bound().net_log();
6077   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6078 
6079   // Since we have proxy, should use full url
6080   MockWrite data_writes1[] = {
6081       MockWrite(
6082           "GET http://www.example.org/ HTTP/1.1\r\n"
6083           "Host: www.example.org\r\n"
6084           "Proxy-Connection: keep-alive\r\n\r\n"),
6085   };
6086 
6087   MockRead data_reads1[] = {
6088     MockRead("HTTP/1.1 200 OK\r\n"),
6089     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6090     MockRead("Content-Length: 100\r\n\r\n"),
6091     MockRead(SYNCHRONOUS, OK),
6092   };
6093 
6094   StaticSocketDataProvider data1(data_reads1, data_writes1);
6095   session_deps_.socket_factory->AddSocketDataProvider(&data1);
6096   SSLSocketDataProvider ssl(ASYNC, OK);
6097   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6098 
6099   TestCompletionCallback callback1;
6100 
6101   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6102 
6103   int rv = trans.Start(&request, callback1.callback(), log.bound());
6104   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6105 
6106   rv = callback1.WaitForResult();
6107   EXPECT_THAT(rv, IsOk());
6108 
6109   LoadTimingInfo load_timing_info;
6110   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
6111   TestLoadTimingNotReused(load_timing_info,
6112                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6113 
6114   const HttpResponseInfo* response = trans.GetResponseInfo();
6115   ASSERT_TRUE(response);
6116 
6117   EXPECT_TRUE(response->proxy_server.is_https());
6118   EXPECT_TRUE(response->headers->IsKeepAlive());
6119   EXPECT_EQ(200, response->headers->response_code());
6120   EXPECT_EQ(100, response->headers->GetContentLength());
6121   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6122 
6123   // The password prompt info should not be set.
6124   EXPECT_FALSE(response->auth_challenge.has_value());
6125 }
6126 
6127 // Test a SPDY get through an HTTPS Proxy.
TEST_F(HttpNetworkTransactionTest,HttpsProxySpdyGet)6128 TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
6129   HttpRequestInfo request;
6130   request.method = "GET";
6131   request.url = GURL("http://www.example.org/");
6132   request.traffic_annotation =
6133       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6134 
6135   // Configure against https proxy server "proxy:70".
6136   session_deps_.proxy_resolution_service =
6137       ConfiguredProxyResolutionService::CreateFixed(
6138           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6139   RecordingBoundTestNetLog log;
6140   session_deps_.net_log = log.bound().net_log();
6141   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6142 
6143   // fetch http://www.example.org/ via SPDY
6144   spdy::SpdySerializedFrame req(
6145       spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
6146   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
6147 
6148   spdy::SpdySerializedFrame resp(
6149       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6150   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
6151   MockRead spdy_reads[] = {
6152       CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
6153   };
6154 
6155   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
6156   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6157 
6158   SSLSocketDataProvider ssl(ASYNC, OK);
6159   ssl.next_proto = kProtoHTTP2;
6160   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6161 
6162   TestCompletionCallback callback1;
6163 
6164   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6165 
6166   int rv = trans.Start(&request, callback1.callback(), log.bound());
6167   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6168 
6169   rv = callback1.WaitForResult();
6170   EXPECT_THAT(rv, IsOk());
6171 
6172   LoadTimingInfo load_timing_info;
6173   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
6174   TestLoadTimingNotReused(load_timing_info,
6175                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6176 
6177   const HttpResponseInfo* response = trans.GetResponseInfo();
6178   ASSERT_TRUE(response);
6179   EXPECT_TRUE(response->proxy_server.is_https());
6180   ASSERT_TRUE(response->headers);
6181   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6182 
6183   std::string response_data;
6184   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
6185   EXPECT_EQ(kUploadData, response_data);
6186 }
6187 
6188 // Verifies that a session which races and wins against the owning transaction
6189 // (completing prior to host resolution), doesn't fail the transaction.
6190 // Regression test for crbug.com/334413.
TEST_F(HttpNetworkTransactionTest,HttpsProxySpdyGetWithSessionRace)6191 TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
6192   HttpRequestInfo request;
6193   request.method = "GET";
6194   request.url = GURL("http://www.example.org/");
6195   request.traffic_annotation =
6196       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6197 
6198   // Configure SPDY proxy server "proxy:70".
6199   session_deps_.proxy_resolution_service =
6200       ConfiguredProxyResolutionService::CreateFixed(
6201           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6202   RecordingBoundTestNetLog log;
6203   session_deps_.net_log = log.bound().net_log();
6204   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6205 
6206   // Fetch http://www.example.org/ through the SPDY proxy.
6207   spdy::SpdySerializedFrame req(
6208       spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
6209   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
6210 
6211   spdy::SpdySerializedFrame resp(
6212       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6213   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
6214   MockRead spdy_reads[] = {
6215       CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
6216   };
6217 
6218   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
6219   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6220 
6221   SSLSocketDataProvider ssl(ASYNC, OK);
6222   ssl.next_proto = kProtoHTTP2;
6223   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6224 
6225   TestCompletionCallback callback1;
6226 
6227   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6228 
6229   // Stall the hostname resolution begun by the transaction.
6230   session_deps_.host_resolver->set_ondemand_mode(true);
6231 
6232   int rv = trans.Start(&request, callback1.callback(), log.bound());
6233   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6234 
6235   // Race a session to the proxy, which completes first.
6236   session_deps_.host_resolver->set_ondemand_mode(false);
6237   SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
6238                      PRIVACY_MODE_DISABLED,
6239                      SpdySessionKey::IsProxySession::kTrue, SocketTag(),
6240                      NetworkIsolationKey(), false /* disable_secure_dns */);
6241   base::WeakPtr<SpdySession> spdy_session =
6242       CreateSpdySession(session.get(), key, log.bound());
6243 
6244   // Unstall the resolution begun by the transaction.
6245   session_deps_.host_resolver->set_ondemand_mode(true);
6246   session_deps_.host_resolver->ResolveAllPending();
6247 
6248   EXPECT_FALSE(callback1.have_result());
6249   rv = callback1.WaitForResult();
6250   EXPECT_THAT(rv, IsOk());
6251 
6252   const HttpResponseInfo* response = trans.GetResponseInfo();
6253   ASSERT_TRUE(response);
6254   ASSERT_TRUE(response->headers);
6255   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6256 
6257   std::string response_data;
6258   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
6259   EXPECT_EQ(kUploadData, response_data);
6260 }
6261 
6262 // Test a SPDY get through an HTTPS Proxy.
TEST_F(HttpNetworkTransactionTest,HttpsProxySpdyGetWithProxyAuth)6263 TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
6264   HttpRequestInfo request;
6265   request.method = "GET";
6266   request.url = GURL("http://www.example.org/");
6267   request.traffic_annotation =
6268       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6269 
6270   // Configure against https proxy server "myproxy:70".
6271   session_deps_.proxy_resolution_service =
6272       ConfiguredProxyResolutionService::CreateFixed(
6273           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6274   RecordingBoundTestNetLog log;
6275   session_deps_.net_log = log.bound().net_log();
6276   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6277 
6278   // The first request will be a bare GET, the second request will be a
6279   // GET with a Proxy-Authorization header.
6280   spdy_util_.set_default_url(request.url);
6281   spdy::SpdySerializedFrame req_get(
6282       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
6283   spdy_util_.UpdateWithStreamDestruction(1);
6284   const char* const kExtraAuthorizationHeaders[] = {
6285     "proxy-authorization", "Basic Zm9vOmJhcg=="
6286   };
6287   spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
6288       kExtraAuthorizationHeaders, base::size(kExtraAuthorizationHeaders) / 2, 3,
6289       LOWEST));
6290   MockWrite spdy_writes[] = {
6291       CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
6292   };
6293 
6294   // The first response is a 407 proxy authentication challenge, and the second
6295   // response will be a 200 response since the second request includes a valid
6296   // Authorization header.
6297   const char* const kExtraAuthenticationHeaders[] = {
6298     "proxy-authenticate", "Basic realm=\"MyRealm1\""
6299   };
6300   spdy::SpdySerializedFrame resp_authentication(
6301       spdy_util_.ConstructSpdyReplyError(
6302           "407", kExtraAuthenticationHeaders,
6303           base::size(kExtraAuthenticationHeaders) / 2, 1));
6304   spdy::SpdySerializedFrame body_authentication(
6305       spdy_util_.ConstructSpdyDataFrame(1, true));
6306   spdy::SpdySerializedFrame resp_data(
6307       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
6308   spdy::SpdySerializedFrame body_data(
6309       spdy_util_.ConstructSpdyDataFrame(3, true));
6310   MockRead spdy_reads[] = {
6311       CreateMockRead(resp_authentication, 1),
6312       CreateMockRead(body_authentication, 2, SYNCHRONOUS),
6313       CreateMockRead(resp_data, 4),
6314       CreateMockRead(body_data, 5),
6315       MockRead(ASYNC, 0, 6),
6316   };
6317 
6318   SequencedSocketData data(spdy_reads, spdy_writes);
6319   session_deps_.socket_factory->AddSocketDataProvider(&data);
6320 
6321   SSLSocketDataProvider ssl(ASYNC, OK);
6322   ssl.next_proto = kProtoHTTP2;
6323   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6324 
6325   TestCompletionCallback callback1;
6326 
6327   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6328 
6329   int rv = trans.Start(&request, callback1.callback(), log.bound());
6330   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6331 
6332   rv = callback1.WaitForResult();
6333   EXPECT_THAT(rv, IsOk());
6334 
6335   const HttpResponseInfo* const response = trans.GetResponseInfo();
6336 
6337   ASSERT_TRUE(response);
6338   ASSERT_TRUE(response->headers);
6339   EXPECT_EQ(407, response->headers->response_code());
6340   EXPECT_TRUE(response->was_fetched_via_spdy);
6341   EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
6342 
6343   TestCompletionCallback callback2;
6344 
6345   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
6346   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6347 
6348   rv = callback2.WaitForResult();
6349   EXPECT_THAT(rv, IsOk());
6350 
6351   const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
6352 
6353   ASSERT_TRUE(response_restart);
6354   ASSERT_TRUE(response_restart->headers);
6355   EXPECT_EQ(200, response_restart->headers->response_code());
6356   // The password prompt info should not be set.
6357   EXPECT_FALSE(response_restart->auth_challenge.has_value());
6358 }
6359 
6360 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
TEST_F(HttpNetworkTransactionTest,HttpsProxySpdyConnectHttps)6361 TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
6362   HttpRequestInfo request;
6363   request.method = "GET";
6364   request.url = GURL("https://www.example.org/");
6365   request.traffic_annotation =
6366       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6367 
6368   // Configure against https proxy server "proxy:70".
6369   session_deps_.proxy_resolution_service =
6370       ConfiguredProxyResolutionService::CreateFixed(
6371           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6372   RecordingBoundTestNetLog log;
6373   session_deps_.net_log = log.bound().net_log();
6374   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6375 
6376   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6377 
6378   // CONNECT to www.example.org:443 via SPDY
6379   spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
6380       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6381       HostPortPair("www.example.org", 443)));
6382   // fetch https://www.example.org/ via HTTP
6383 
6384   const char get[] =
6385       "GET / HTTP/1.1\r\n"
6386       "Host: www.example.org\r\n"
6387       "Connection: keep-alive\r\n\r\n";
6388   spdy::SpdySerializedFrame wrapped_get(
6389       spdy_util_.ConstructSpdyDataFrame(1, get, false));
6390   spdy::SpdySerializedFrame conn_resp(
6391       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6392   const char resp[] = "HTTP/1.1 200 OK\r\n"
6393       "Content-Length: 10\r\n\r\n";
6394   spdy::SpdySerializedFrame wrapped_get_resp(
6395       spdy_util_.ConstructSpdyDataFrame(1, resp, false));
6396   spdy::SpdySerializedFrame wrapped_body(
6397       spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
6398   spdy::SpdySerializedFrame window_update(
6399       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6400 
6401   MockWrite spdy_writes[] = {
6402       CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
6403       CreateMockWrite(window_update, 6),
6404   };
6405 
6406   MockRead spdy_reads[] = {
6407       CreateMockRead(conn_resp, 1, ASYNC),
6408       CreateMockRead(wrapped_get_resp, 3, ASYNC),
6409       CreateMockRead(wrapped_body, 4, ASYNC),
6410       CreateMockRead(wrapped_body, 5, ASYNC),
6411       MockRead(ASYNC, 0, 7),
6412   };
6413 
6414   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
6415   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6416 
6417   SSLSocketDataProvider ssl(ASYNC, OK);
6418   ssl.next_proto = kProtoHTTP2;
6419   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6420   SSLSocketDataProvider ssl2(ASYNC, OK);
6421   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6422 
6423   TestCompletionCallback callback1;
6424 
6425   int rv = trans.Start(&request, callback1.callback(), log.bound());
6426   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6427 
6428   rv = callback1.WaitForResult();
6429   ASSERT_THAT(rv, IsOk());
6430 
6431   LoadTimingInfo load_timing_info;
6432   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
6433   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6434 
6435   const HttpResponseInfo* response = trans.GetResponseInfo();
6436   ASSERT_TRUE(response);
6437   ASSERT_TRUE(response->headers);
6438   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6439 
6440   std::string response_data;
6441   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
6442   EXPECT_EQ("1234567890", response_data);
6443 }
6444 
6445 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
TEST_F(HttpNetworkTransactionTest,HttpsProxySpdyConnectSpdy)6446 TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
6447   SpdyTestUtil spdy_util_wrapped;
6448 
6449   HttpRequestInfo request;
6450   request.method = "GET";
6451   request.url = GURL("https://www.example.org/");
6452   request.traffic_annotation =
6453       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6454 
6455   // Configure against https proxy server "proxy:70".
6456   session_deps_.proxy_resolution_service =
6457       ConfiguredProxyResolutionService::CreateFixed(
6458           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6459   RecordingBoundTestNetLog log;
6460   session_deps_.net_log = log.bound().net_log();
6461   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6462 
6463   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6464 
6465   // CONNECT to www.example.org:443 via SPDY
6466   spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
6467       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6468       HostPortPair("www.example.org", 443)));
6469   // fetch https://www.example.org/ via SPDY
6470   const char kMyUrl[] = "https://www.example.org/";
6471   spdy::SpdySerializedFrame get(
6472       spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6473   spdy::SpdySerializedFrame wrapped_get(
6474       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6475   spdy::SpdySerializedFrame conn_resp(
6476       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6477   spdy::SpdySerializedFrame get_resp(
6478       spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
6479   spdy::SpdySerializedFrame wrapped_get_resp(
6480       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6481   spdy::SpdySerializedFrame body(
6482       spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
6483   spdy::SpdySerializedFrame wrapped_body(
6484       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6485   spdy::SpdySerializedFrame window_update_get_resp(
6486       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6487   spdy::SpdySerializedFrame window_update_body(
6488       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6489 
6490   MockWrite spdy_writes[] = {
6491       CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
6492       CreateMockWrite(window_update_get_resp, 6),
6493       CreateMockWrite(window_update_body, 7),
6494   };
6495 
6496   MockRead spdy_reads[] = {
6497       CreateMockRead(conn_resp, 1, ASYNC),
6498       MockRead(ASYNC, ERR_IO_PENDING, 3),
6499       CreateMockRead(wrapped_get_resp, 4, ASYNC),
6500       CreateMockRead(wrapped_body, 5, ASYNC),
6501       MockRead(ASYNC, 0, 8),
6502   };
6503 
6504   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
6505   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6506 
6507   SSLSocketDataProvider ssl(ASYNC, OK);
6508   ssl.next_proto = kProtoHTTP2;
6509   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6510   SSLSocketDataProvider ssl2(ASYNC, OK);
6511   ssl2.next_proto = kProtoHTTP2;
6512   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6513 
6514   TestCompletionCallback callback1;
6515 
6516   int rv = trans.Start(&request, callback1.callback(), log.bound());
6517   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6518 
6519   // Allow the SpdyProxyClientSocket's write callback to complete.
6520   base::RunLoop().RunUntilIdle();
6521   // Now allow the read of the response to complete.
6522   spdy_data.Resume();
6523   rv = callback1.WaitForResult();
6524   EXPECT_THAT(rv, IsOk());
6525 
6526   LoadTimingInfo load_timing_info;
6527   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
6528   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6529 
6530   const HttpResponseInfo* response = trans.GetResponseInfo();
6531   ASSERT_TRUE(response);
6532   ASSERT_TRUE(response->headers);
6533   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6534 
6535   std::string response_data;
6536   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
6537   EXPECT_EQ(kUploadData, response_data);
6538 }
6539 
6540 // Test a SPDY CONNECT failure through an HTTPS Proxy.
TEST_F(HttpNetworkTransactionTest,HttpsProxySpdyConnectFailure)6541 TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
6542   HttpRequestInfo request;
6543   request.method = "GET";
6544   request.url = GURL("https://www.example.org/");
6545   request.traffic_annotation =
6546       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6547 
6548   // Configure against https proxy server "proxy:70".
6549   session_deps_.proxy_resolution_service =
6550       ConfiguredProxyResolutionService::CreateFixed(
6551           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6552   RecordingBoundTestNetLog log;
6553   session_deps_.net_log = log.bound().net_log();
6554   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6555 
6556   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6557 
6558   // CONNECT to www.example.org:443 via SPDY
6559   spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
6560       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6561       HostPortPair("www.example.org", 443)));
6562   spdy::SpdySerializedFrame get(
6563       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
6564 
6565   MockWrite spdy_writes[] = {
6566       CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
6567   };
6568 
6569   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
6570   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
6571   MockRead spdy_reads[] = {
6572       CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
6573   };
6574 
6575   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
6576   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6577 
6578   SSLSocketDataProvider ssl(ASYNC, OK);
6579   ssl.next_proto = kProtoHTTP2;
6580   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6581   SSLSocketDataProvider ssl2(ASYNC, OK);
6582   ssl2.next_proto = kProtoHTTP2;
6583   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6584 
6585   TestCompletionCallback callback1;
6586 
6587   int rv = trans.Start(&request, callback1.callback(), log.bound());
6588   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6589 
6590   rv = callback1.WaitForResult();
6591   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
6592 
6593   // TODO(juliatuttle): Anything else to check here?
6594 }
6595 
6596 // Test the case where a proxied H2 session doesn't exist when an auth challenge
6597 // is observed, but does exist by the time auth credentials are provided. In
6598 // this case, auth and SSL are fully negotated on the second request, but then
6599 // the socket is discarded to use the shared session.
TEST_F(HttpNetworkTransactionTest,ProxiedH2SessionAppearsDuringAuth)6600 TEST_F(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
6601   ProxyConfig proxy_config;
6602   proxy_config.set_auto_detect(true);
6603   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6604 
6605   CapturingProxyResolver capturing_proxy_resolver;
6606   capturing_proxy_resolver.set_proxy_server(
6607       ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
6608   session_deps_.proxy_resolution_service =
6609       std::make_unique<ConfiguredProxyResolutionService>(
6610           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6611               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6612           std::make_unique<CapturingProxyResolverFactory>(
6613               &capturing_proxy_resolver),
6614           nullptr);
6615 
6616   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6617 
6618   const char kMyUrl[] = "https://www.example.org/";
6619   spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6620   spdy::SpdySerializedFrame get_resp(
6621       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6622   spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
6623 
6624   spdy_util_.UpdateWithStreamDestruction(1);
6625   spdy::SpdySerializedFrame get2(
6626       spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
6627   spdy::SpdySerializedFrame get_resp2(
6628       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
6629   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
6630 
6631   MockWrite auth_challenge_writes[] = {
6632       MockWrite(ASYNC, 0,
6633                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6634                 "Host: www.example.org:443\r\n"
6635                 "Proxy-Connection: keep-alive\r\n\r\n"),
6636       MockWrite(ASYNC, 2,
6637                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6638                 "Host: www.example.org:443\r\n"
6639                 "Proxy-Connection: keep-alive\r\n\r\n"),
6640   };
6641 
6642   MockRead auth_challenge_reads[] = {
6643       MockRead(ASYNC, 1,
6644                "HTTP/1.1 407 Authentication Required\r\n"
6645                "Content-Length: 0\r\n"
6646                "Proxy-Connection: close\r\n"
6647                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
6648   };
6649 
6650   MockWrite spdy_writes[] = {
6651       MockWrite(ASYNC, 0,
6652                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6653                 "Host: www.example.org:443\r\n"
6654                 "Proxy-Connection: keep-alive\r\n"
6655                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
6656       CreateMockWrite(get, 2),
6657       CreateMockWrite(get2, 5),
6658   };
6659 
6660   MockRead spdy_reads[] = {
6661       MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
6662       CreateMockRead(get_resp, 3, ASYNC),
6663       CreateMockRead(body, 4, ASYNC),
6664       CreateMockRead(get_resp2, 6, ASYNC),
6665       CreateMockRead(body2, 7, ASYNC),
6666 
6667       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
6668   };
6669 
6670   MockWrite auth_response_writes_discarded_socket[] = {
6671       MockWrite(ASYNC, 0,
6672                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6673                 "Host: www.example.org:443\r\n"
6674                 "Proxy-Connection: keep-alive\r\n"
6675                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
6676   };
6677 
6678   MockRead auth_response_reads_discarded_socket[] = {
6679       MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
6680   };
6681 
6682   SequencedSocketData auth_challenge1(auth_challenge_reads,
6683                                       auth_challenge_writes);
6684   session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
6685 
6686   SequencedSocketData auth_challenge2(auth_challenge_reads,
6687                                       auth_challenge_writes);
6688   session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
6689 
6690   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
6691   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6692 
6693   SequencedSocketData auth_response_discarded_socket(
6694       auth_response_reads_discarded_socket,
6695       auth_response_writes_discarded_socket);
6696   session_deps_.socket_factory->AddSocketDataProvider(
6697       &auth_response_discarded_socket);
6698 
6699   SSLSocketDataProvider ssl(ASYNC, OK);
6700   ssl.next_proto = kProtoHTTP2;
6701   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6702 
6703   SSLSocketDataProvider ssl2(ASYNC, OK);
6704   ssl2.next_proto = kProtoHTTP2;
6705   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6706 
6707   TestCompletionCallback callback;
6708   std::string response_data;
6709 
6710   // Run first request until an auth challenge is observed.
6711   HttpRequestInfo request1;
6712   request1.method = "GET";
6713   request1.url = GURL(kMyUrl);
6714   request1.traffic_annotation =
6715       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6716   HttpNetworkTransaction trans1(LOWEST, session.get());
6717   int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
6718   EXPECT_THAT(callback.GetResult(rv), IsOk());
6719   const HttpResponseInfo* response = trans1.GetResponseInfo();
6720   ASSERT_TRUE(response);
6721   ASSERT_TRUE(response->headers);
6722   EXPECT_EQ(407, response->headers->response_code());
6723   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6724   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
6725 
6726   // Run second request until an auth challenge is observed.
6727   HttpRequestInfo request2;
6728   request2.method = "GET";
6729   request2.url = GURL(kMyUrl);
6730   request2.traffic_annotation =
6731       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6732   HttpNetworkTransaction trans2(LOWEST, session.get());
6733   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6734   EXPECT_THAT(callback.GetResult(rv), IsOk());
6735   response = trans2.GetResponseInfo();
6736   ASSERT_TRUE(response);
6737   ASSERT_TRUE(response->headers);
6738   EXPECT_EQ(407, response->headers->response_code());
6739   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6740   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
6741 
6742   // Now provide credentials for the first request, and wait for it to complete.
6743   rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6744   rv = callback.GetResult(rv);
6745   EXPECT_THAT(rv, IsOk());
6746   response = trans1.GetResponseInfo();
6747   ASSERT_TRUE(response);
6748   ASSERT_TRUE(response->headers);
6749   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6750   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6751   EXPECT_EQ(kUploadData, response_data);
6752 
6753   // Now provide credentials for the second request. It should notice the
6754   // existing session, and reuse it.
6755   rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6756   EXPECT_THAT(callback.GetResult(rv), IsOk());
6757   response = trans2.GetResponseInfo();
6758   ASSERT_TRUE(response);
6759   ASSERT_TRUE(response->headers);
6760   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6761   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6762   EXPECT_EQ(kUploadData, response_data);
6763 }
6764 
6765 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6766 // HTTPS Proxy to different servers.
TEST_F(HttpNetworkTransactionTest,HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers)6767 TEST_F(HttpNetworkTransactionTest,
6768        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
6769   // Configure against https proxy server "proxy:70".
6770   session_deps_.proxy_resolution_service =
6771       ConfiguredProxyResolutionService::CreateFixed(
6772           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6773   RecordingBoundTestNetLog log;
6774   session_deps_.net_log = log.bound().net_log();
6775   std::unique_ptr<HttpNetworkSession> session(
6776       SpdySessionDependencies::SpdyCreateSession(&session_deps_));
6777 
6778   HttpRequestInfo request1;
6779   request1.method = "GET";
6780   request1.url = GURL("https://www.example.org/");
6781   request1.load_flags = 0;
6782   request1.traffic_annotation =
6783       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6784 
6785   HttpRequestInfo request2;
6786   request2.method = "GET";
6787   request2.url = GURL("https://mail.example.org/");
6788   request2.load_flags = 0;
6789   request2.traffic_annotation =
6790       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6791 
6792   // CONNECT to www.example.org:443 via SPDY.
6793   spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
6794       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6795       HostPortPair("www.example.org", 443)));
6796   spdy::SpdySerializedFrame conn_resp1(
6797       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6798 
6799   // Fetch https://www.example.org/ via HTTP.
6800   const char get1[] =
6801       "GET / HTTP/1.1\r\n"
6802       "Host: www.example.org\r\n"
6803       "Connection: keep-alive\r\n\r\n";
6804   spdy::SpdySerializedFrame wrapped_get1(
6805       spdy_util_.ConstructSpdyDataFrame(1, get1, false));
6806   const char resp1[] = "HTTP/1.1 200 OK\r\n"
6807       "Content-Length: 1\r\n\r\n";
6808   spdy::SpdySerializedFrame wrapped_get_resp1(
6809       spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
6810   spdy::SpdySerializedFrame wrapped_body1(
6811       spdy_util_.ConstructSpdyDataFrame(1, "1", false));
6812   spdy::SpdySerializedFrame window_update(
6813       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
6814 
6815   // CONNECT to mail.example.org:443 via SPDY.
6816   spdy::SpdyHeaderBlock connect2_block;
6817   connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
6818   connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
6819   spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
6820       3, std::move(connect2_block), HttpProxyConnectJob::kH2QuicTunnelPriority,
6821       false));
6822 
6823   spdy::SpdySerializedFrame conn_resp2(
6824       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
6825 
6826   // Fetch https://mail.example.org/ via HTTP.
6827   const char get2[] =
6828       "GET / HTTP/1.1\r\n"
6829       "Host: mail.example.org\r\n"
6830       "Connection: keep-alive\r\n\r\n";
6831   spdy::SpdySerializedFrame wrapped_get2(
6832       spdy_util_.ConstructSpdyDataFrame(3, get2, false));
6833   const char resp2[] = "HTTP/1.1 200 OK\r\n"
6834       "Content-Length: 2\r\n\r\n";
6835   spdy::SpdySerializedFrame wrapped_get_resp2(
6836       spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
6837   spdy::SpdySerializedFrame wrapped_body2(
6838       spdy_util_.ConstructSpdyDataFrame(3, "22", false));
6839 
6840   MockWrite spdy_writes[] = {
6841       CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6842       CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
6843   };
6844 
6845   MockRead spdy_reads[] = {
6846       CreateMockRead(conn_resp1, 1, ASYNC),
6847       CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6848       CreateMockRead(wrapped_body1, 4, ASYNC),
6849       CreateMockRead(conn_resp2, 6, ASYNC),
6850       CreateMockRead(wrapped_get_resp2, 8, ASYNC),
6851       CreateMockRead(wrapped_body2, 9, ASYNC),
6852       MockRead(ASYNC, 0, 10),
6853   };
6854 
6855   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
6856   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6857 
6858   SSLSocketDataProvider ssl(ASYNC, OK);
6859   ssl.next_proto = kProtoHTTP2;
6860   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6861   SSLSocketDataProvider ssl2(ASYNC, OK);
6862   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6863   SSLSocketDataProvider ssl3(ASYNC, OK);
6864   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6865 
6866   TestCompletionCallback callback;
6867 
6868   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6869   int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
6870   EXPECT_THAT(callback.GetResult(rv), IsOk());
6871 
6872   LoadTimingInfo load_timing_info;
6873   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
6874   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6875 
6876   const HttpResponseInfo* response = trans.GetResponseInfo();
6877   ASSERT_TRUE(response);
6878   ASSERT_TRUE(response->headers);
6879   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6880 
6881   std::string response_data;
6882   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
6883   rv = trans.Read(buf.get(), 256, callback.callback());
6884   EXPECT_EQ(1, callback.GetResult(rv));
6885 
6886   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
6887   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6888   EXPECT_THAT(callback.GetResult(rv), IsOk());
6889 
6890   LoadTimingInfo load_timing_info2;
6891   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
6892   // Even though the SPDY connection is reused, a new tunnelled connection has
6893   // to be created, so the socket's load timing looks like a fresh connection.
6894   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
6895 
6896   // The requests should have different IDs, since they each are using their own
6897   // separate stream.
6898   EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6899 
6900   rv = trans2.Read(buf.get(), 256, callback.callback());
6901   EXPECT_EQ(2, callback.GetResult(rv));
6902 }
6903 
6904 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6905 // HTTPS Proxy to the same server.
TEST_F(HttpNetworkTransactionTest,HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer)6906 TEST_F(HttpNetworkTransactionTest,
6907        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
6908   // Configure against https proxy server "proxy:70".
6909   session_deps_.proxy_resolution_service =
6910       ConfiguredProxyResolutionService::CreateFixed(
6911           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6912   RecordingBoundTestNetLog log;
6913   session_deps_.net_log = log.bound().net_log();
6914   std::unique_ptr<HttpNetworkSession> session(
6915       SpdySessionDependencies::SpdyCreateSession(&session_deps_));
6916 
6917   HttpRequestInfo request1;
6918   request1.method = "GET";
6919   request1.url = GURL("https://www.example.org/");
6920   request1.load_flags = 0;
6921   request1.traffic_annotation =
6922       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6923 
6924   HttpRequestInfo request2;
6925   request2.method = "GET";
6926   request2.url = GURL("https://www.example.org/2");
6927   request2.load_flags = 0;
6928   request2.traffic_annotation =
6929       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6930 
6931   // CONNECT to www.example.org:443 via SPDY.
6932   spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
6933       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6934       HostPortPair("www.example.org", 443)));
6935   spdy::SpdySerializedFrame conn_resp1(
6936       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6937 
6938   // Fetch https://www.example.org/ via HTTP.
6939   const char get1[] =
6940       "GET / HTTP/1.1\r\n"
6941       "Host: www.example.org\r\n"
6942       "Connection: keep-alive\r\n\r\n";
6943   spdy::SpdySerializedFrame wrapped_get1(
6944       spdy_util_.ConstructSpdyDataFrame(1, get1, false));
6945   const char resp1[] = "HTTP/1.1 200 OK\r\n"
6946       "Content-Length: 1\r\n\r\n";
6947   spdy::SpdySerializedFrame wrapped_get_resp1(
6948       spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
6949   spdy::SpdySerializedFrame wrapped_body1(
6950       spdy_util_.ConstructSpdyDataFrame(1, "1", false));
6951   spdy::SpdySerializedFrame window_update(
6952       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
6953 
6954   // Fetch https://www.example.org/2 via HTTP.
6955   const char get2[] =
6956       "GET /2 HTTP/1.1\r\n"
6957       "Host: www.example.org\r\n"
6958       "Connection: keep-alive\r\n\r\n";
6959   spdy::SpdySerializedFrame wrapped_get2(
6960       spdy_util_.ConstructSpdyDataFrame(1, get2, false));
6961   const char resp2[] = "HTTP/1.1 200 OK\r\n"
6962       "Content-Length: 2\r\n\r\n";
6963   spdy::SpdySerializedFrame wrapped_get_resp2(
6964       spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
6965   spdy::SpdySerializedFrame wrapped_body2(
6966       spdy_util_.ConstructSpdyDataFrame(1, "22", false));
6967 
6968   MockWrite spdy_writes[] = {
6969       CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6970       CreateMockWrite(wrapped_get2, 5),
6971   };
6972 
6973   MockRead spdy_reads[] = {
6974       CreateMockRead(conn_resp1, 1, ASYNC),
6975       CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6976       CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
6977       CreateMockRead(wrapped_get_resp2, 6, ASYNC),
6978       CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
6979       MockRead(ASYNC, 0, 8),
6980   };
6981 
6982   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
6983   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6984 
6985   SSLSocketDataProvider ssl(ASYNC, OK);
6986   ssl.next_proto = kProtoHTTP2;
6987   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6988   SSLSocketDataProvider ssl2(ASYNC, OK);
6989   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6990 
6991   TestCompletionCallback callback;
6992 
6993   auto trans =
6994       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
6995   int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
6996   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6997 
6998   rv = callback.WaitForResult();
6999   EXPECT_THAT(rv, IsOk());
7000 
7001   LoadTimingInfo load_timing_info;
7002   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7003   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
7004 
7005   const HttpResponseInfo* response = trans->GetResponseInfo();
7006   ASSERT_TRUE(response);
7007   ASSERT_TRUE(response->headers);
7008   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7009 
7010   std::string response_data;
7011   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
7012   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
7013   trans.reset();
7014 
7015   auto trans2 =
7016       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
7017   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
7018   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7019 
7020   rv = callback.WaitForResult();
7021   EXPECT_THAT(rv, IsOk());
7022 
7023   LoadTimingInfo load_timing_info2;
7024   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
7025   TestLoadTimingReused(load_timing_info2);
7026 
7027   // The requests should have the same ID.
7028   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
7029 
7030   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
7031 }
7032 
7033 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS
7034 // Proxy to different servers.
TEST_F(HttpNetworkTransactionTest,HttpsProxySpdyLoadTimingTwoHttpRequests)7035 TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
7036   // Configure against https proxy server "proxy:70".
7037   session_deps_.proxy_resolution_service =
7038       ConfiguredProxyResolutionService::CreateFixed(
7039           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
7040   RecordingBoundTestNetLog log;
7041   session_deps_.net_log = log.bound().net_log();
7042   std::unique_ptr<HttpNetworkSession> session(
7043       SpdySessionDependencies::SpdyCreateSession(&session_deps_));
7044 
7045   HttpRequestInfo request1;
7046   request1.method = "GET";
7047   request1.url = GURL("http://www.example.org/");
7048   request1.load_flags = 0;
7049   request1.traffic_annotation =
7050       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7051 
7052   HttpRequestInfo request2;
7053   request2.method = "GET";
7054   request2.url = GURL("http://mail.example.org/");
7055   request2.load_flags = 0;
7056   request2.traffic_annotation =
7057       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7058 
7059   // http://www.example.org/
7060   spdy::SpdyHeaderBlock headers(
7061       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
7062   spdy::SpdySerializedFrame get1(
7063       spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
7064   spdy::SpdySerializedFrame get_resp1(
7065       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7066   spdy::SpdySerializedFrame body1(
7067       spdy_util_.ConstructSpdyDataFrame(1, "1", true));
7068   spdy_util_.UpdateWithStreamDestruction(1);
7069 
7070   // http://mail.example.org/
7071   spdy::SpdyHeaderBlock headers2(
7072       spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
7073   spdy::SpdySerializedFrame get2(
7074       spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
7075   spdy::SpdySerializedFrame get_resp2(
7076       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
7077   spdy::SpdySerializedFrame body2(
7078       spdy_util_.ConstructSpdyDataFrame(3, "22", true));
7079 
7080   MockWrite spdy_writes[] = {
7081       CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
7082   };
7083 
7084   MockRead spdy_reads[] = {
7085       CreateMockRead(get_resp1, 1, ASYNC),
7086       CreateMockRead(body1, 2, ASYNC),
7087       CreateMockRead(get_resp2, 4, ASYNC),
7088       CreateMockRead(body2, 5, ASYNC),
7089       MockRead(ASYNC, 0, 6),
7090   };
7091 
7092   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
7093   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7094 
7095   SSLSocketDataProvider ssl(ASYNC, OK);
7096   ssl.next_proto = kProtoHTTP2;
7097   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7098 
7099   TestCompletionCallback callback;
7100 
7101   auto trans =
7102       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
7103   int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
7104   EXPECT_THAT(callback.GetResult(rv), IsOk());
7105 
7106   LoadTimingInfo load_timing_info;
7107   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7108   TestLoadTimingNotReused(load_timing_info,
7109                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7110 
7111   const HttpResponseInfo* response = trans->GetResponseInfo();
7112   ASSERT_TRUE(response);
7113   ASSERT_TRUE(response->headers);
7114   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
7115 
7116   std::string response_data;
7117   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
7118   rv = trans->Read(buf.get(), 256, callback.callback());
7119   EXPECT_EQ(1, callback.GetResult(rv));
7120   // Delete the first request, so the second one can reuse the socket.
7121   trans.reset();
7122 
7123   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
7124   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
7125   EXPECT_THAT(callback.GetResult(rv), IsOk());
7126 
7127   LoadTimingInfo load_timing_info2;
7128   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
7129   TestLoadTimingReused(load_timing_info2);
7130 
7131   // The requests should have the same ID.
7132   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
7133 
7134   rv = trans2.Read(buf.get(), 256, callback.callback());
7135   EXPECT_EQ(2, callback.GetResult(rv));
7136 }
7137 
7138 // Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
7139 // direct (non-proxied) request to the proxy server are not pooled, as that
7140 // would break socket pool isolation.
TEST_F(HttpNetworkTransactionTest,SpdyProxyIsolation1)7141 TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
7142   ProxyConfig proxy_config;
7143   proxy_config.set_auto_detect(true);
7144   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
7145 
7146   CapturingProxyResolver capturing_proxy_resolver;
7147   session_deps_.proxy_resolution_service =
7148       std::make_unique<ConfiguredProxyResolutionService>(
7149           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
7150               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
7151           std::make_unique<CapturingProxyResolverFactory>(
7152               &capturing_proxy_resolver),
7153           nullptr);
7154 
7155   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7156 
7157   SpdyTestUtil spdy_util1;
7158   // CONNECT to www.example.org:443 via HTTP/2.
7159   spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
7160       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
7161       HostPortPair("www.example.org", 443)));
7162   // fetch https://www.example.org/ via HTTP/2.
7163   const char kMyUrl[] = "https://www.example.org/";
7164   spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
7165   spdy::SpdySerializedFrame wrapped_get(
7166       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
7167   spdy::SpdySerializedFrame conn_resp(
7168       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7169   spdy::SpdySerializedFrame get_resp(
7170       spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
7171   spdy::SpdySerializedFrame wrapped_get_resp(
7172       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
7173   spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
7174   spdy::SpdySerializedFrame wrapped_body(
7175       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
7176   spdy::SpdySerializedFrame window_update_get_resp(
7177       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
7178   spdy::SpdySerializedFrame window_update_body(
7179       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
7180 
7181   MockWrite spdy_writes1[] = {
7182       CreateMockWrite(connect, 0),
7183       CreateMockWrite(wrapped_get, 2),
7184       CreateMockWrite(window_update_get_resp, 6),
7185       CreateMockWrite(window_update_body, 7),
7186   };
7187 
7188   MockRead spdy_reads1[] = {
7189       CreateMockRead(conn_resp, 1, ASYNC),
7190       MockRead(ASYNC, ERR_IO_PENDING, 3),
7191       CreateMockRead(wrapped_get_resp, 4, ASYNC),
7192       CreateMockRead(wrapped_body, 5, ASYNC),
7193       MockRead(ASYNC, 0, 8),
7194   };
7195 
7196   SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
7197   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
7198 
7199   // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
7200   // a new pipe.
7201   SpdyTestUtil spdy_util2;
7202   spdy::SpdySerializedFrame req(
7203       spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
7204   MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
7205 
7206   spdy::SpdySerializedFrame resp(
7207       spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
7208   spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
7209   MockRead spdy_reads2[] = {
7210       CreateMockRead(resp, 1),
7211       CreateMockRead(data, 2),
7212       MockRead(ASYNC, 0, 3),
7213   };
7214   SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
7215   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
7216 
7217   SSLSocketDataProvider ssl(ASYNC, OK);
7218   ssl.next_proto = kProtoHTTP2;
7219   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7220   SSLSocketDataProvider ssl2(ASYNC, OK);
7221   ssl2.next_proto = kProtoHTTP2;
7222   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7223   SSLSocketDataProvider ssl3(ASYNC, OK);
7224   ssl3.next_proto = kProtoHTTP2;
7225   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7226 
7227   TestCompletionCallback callback;
7228   std::string response_data;
7229 
7230   // Make a request using proxy:70 as a HTTP/2 proxy.
7231   capturing_proxy_resolver.set_proxy_server(
7232       ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
7233   HttpRequestInfo request1;
7234   request1.method = "GET";
7235   request1.url = GURL("https://www.example.org/");
7236   request1.traffic_annotation =
7237       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7238 
7239   HttpNetworkTransaction trans1(LOWEST, session.get());
7240   int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
7241   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7242 
7243   // Allow the SpdyProxyClientSocket's write callback to complete.
7244   base::RunLoop().RunUntilIdle();
7245   // Now allow the read of the response to complete.
7246   spdy_data1.Resume();
7247   rv = callback.WaitForResult();
7248   EXPECT_THAT(rv, IsOk());
7249 
7250   const HttpResponseInfo* response = trans1.GetResponseInfo();
7251   ASSERT_TRUE(response);
7252   ASSERT_TRUE(response->headers);
7253   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
7254 
7255   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
7256   EXPECT_EQ(kUploadData, response_data);
7257   RunUntilIdle();
7258 
7259   // Make a direct HTTP/2 request to proxy:70.
7260   capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
7261   HttpRequestInfo request2;
7262   request2.method = "GET";
7263   request2.url = GURL("https://proxy:70/");
7264   request2.traffic_annotation =
7265       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7266   HttpNetworkTransaction trans2(LOWEST, session.get());
7267   EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
7268                                               NetLogWithSource())),
7269               IsOk());
7270   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
7271 }
7272 
7273 // Same as above, but reverse request order, since the code to check for an
7274 // existing session is different for tunnels and direct connections.
TEST_F(HttpNetworkTransactionTest,SpdyProxyIsolation2)7275 TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
7276   // Configure against https proxy server "myproxy:80".
7277   ProxyConfig proxy_config;
7278   proxy_config.set_auto_detect(true);
7279   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
7280 
7281   CapturingProxyResolver capturing_proxy_resolver;
7282   session_deps_.proxy_resolution_service =
7283       std::make_unique<ConfiguredProxyResolutionService>(
7284           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
7285               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
7286           std::make_unique<CapturingProxyResolverFactory>(
7287               &capturing_proxy_resolver),
7288           nullptr);
7289 
7290   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7291   // Fetch https://proxy:70/ via HTTP/2.
7292   SpdyTestUtil spdy_util1;
7293   spdy::SpdySerializedFrame req(
7294       spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
7295   MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
7296 
7297   spdy::SpdySerializedFrame resp(
7298       spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
7299   spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
7300   MockRead spdy_reads1[] = {
7301       CreateMockRead(resp, 1),
7302       CreateMockRead(data, 2),
7303       MockRead(ASYNC, 0, 3),
7304   };
7305   SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
7306   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
7307 
7308   SpdyTestUtil spdy_util2;
7309   // CONNECT to www.example.org:443 via HTTP/2.
7310   spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
7311       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
7312       HostPortPair("www.example.org", 443)));
7313   // fetch https://www.example.org/ via HTTP/2.
7314   const char kMyUrl[] = "https://www.example.org/";
7315   spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
7316   spdy::SpdySerializedFrame wrapped_get(
7317       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
7318   spdy::SpdySerializedFrame conn_resp(
7319       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
7320   spdy::SpdySerializedFrame get_resp(
7321       spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
7322   spdy::SpdySerializedFrame wrapped_get_resp(
7323       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
7324   spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
7325   spdy::SpdySerializedFrame wrapped_body(
7326       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
7327   spdy::SpdySerializedFrame window_update_get_resp(
7328       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
7329   spdy::SpdySerializedFrame window_update_body(
7330       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
7331 
7332   MockWrite spdy_writes2[] = {
7333       CreateMockWrite(connect, 0),
7334       CreateMockWrite(wrapped_get, 2),
7335       CreateMockWrite(window_update_get_resp, 6),
7336       CreateMockWrite(window_update_body, 7),
7337   };
7338 
7339   MockRead spdy_reads2[] = {
7340       CreateMockRead(conn_resp, 1, ASYNC),
7341       MockRead(ASYNC, ERR_IO_PENDING, 3),
7342       CreateMockRead(wrapped_get_resp, 4, ASYNC),
7343       CreateMockRead(wrapped_body, 5, ASYNC),
7344       MockRead(ASYNC, 0, 8),
7345   };
7346 
7347   SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
7348   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
7349 
7350   SSLSocketDataProvider ssl(ASYNC, OK);
7351   ssl.next_proto = kProtoHTTP2;
7352   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7353   SSLSocketDataProvider ssl2(ASYNC, OK);
7354   ssl2.next_proto = kProtoHTTP2;
7355   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7356   SSLSocketDataProvider ssl3(ASYNC, OK);
7357   ssl3.next_proto = kProtoHTTP2;
7358   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7359 
7360   TestCompletionCallback callback;
7361   std::string response_data;
7362 
7363   // Make a direct HTTP/2 request to proxy:70.
7364   capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
7365   HttpRequestInfo request1;
7366   request1.method = "GET";
7367   request1.url = GURL("https://proxy:70/");
7368   request1.traffic_annotation =
7369       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7370   HttpNetworkTransaction trans1(LOWEST, session.get());
7371   EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
7372                                               NetLogWithSource())),
7373               IsOk());
7374   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
7375   RunUntilIdle();
7376 
7377   // Make a request using proxy:70 as a HTTP/2 proxy.
7378   capturing_proxy_resolver.set_proxy_server(
7379       ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
7380   HttpRequestInfo request2;
7381   request2.method = "GET";
7382   request2.url = GURL("https://www.example.org/");
7383   request2.traffic_annotation =
7384       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7385 
7386   HttpNetworkTransaction trans2(LOWEST, session.get());
7387   int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
7388   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7389 
7390   // Allow the SpdyProxyClientSocket's write callback to complete.
7391   base::RunLoop().RunUntilIdle();
7392   // Now allow the read of the response to complete.
7393   spdy_data2.Resume();
7394   rv = callback.WaitForResult();
7395   EXPECT_THAT(rv, IsOk());
7396 
7397   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
7398   ASSERT_TRUE(response2);
7399   ASSERT_TRUE(response2->headers);
7400   EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
7401 
7402   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
7403   EXPECT_EQ(kUploadData, response_data);
7404 }
7405 
7406 // Test the challenge-response-retry sequence through an HTTPS Proxy
TEST_F(HttpNetworkTransactionTest,HttpsProxyAuthRetry)7407 TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
7408   HttpRequestInfo request;
7409   request.method = "GET";
7410   request.url = GURL("http://www.example.org/");
7411   // when the no authentication data flag is set.
7412   request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
7413   request.traffic_annotation =
7414       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7415 
7416   // Configure against https proxy server "myproxy:70".
7417   session_deps_.proxy_resolution_service =
7418       ConfiguredProxyResolutionService::CreateFixed(
7419           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
7420   RecordingBoundTestNetLog log;
7421   session_deps_.net_log = log.bound().net_log();
7422   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7423 
7424   // Since we have proxy, should use full url
7425   MockWrite data_writes1[] = {
7426       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
7427                 "Host: www.example.org\r\n"
7428                 "Proxy-Connection: keep-alive\r\n\r\n"),
7429 
7430       // After calling trans.RestartWithAuth(), this is the request we should
7431       // be issuing -- the final header line contains the credentials.
7432       MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
7433                 "Host: www.example.org\r\n"
7434                 "Proxy-Connection: keep-alive\r\n"
7435                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7436   };
7437 
7438   // The proxy responds to the GET with a 407, using a persistent
7439   // connection.
7440   MockRead data_reads1[] = {
7441     // No credentials.
7442     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7443     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7444     MockRead("Proxy-Connection: keep-alive\r\n"),
7445     MockRead("Content-Length: 0\r\n\r\n"),
7446 
7447     MockRead("HTTP/1.1 200 OK\r\n"),
7448     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7449     MockRead("Content-Length: 100\r\n\r\n"),
7450     MockRead(SYNCHRONOUS, OK),
7451   };
7452 
7453   StaticSocketDataProvider data1(data_reads1, data_writes1);
7454   session_deps_.socket_factory->AddSocketDataProvider(&data1);
7455   SSLSocketDataProvider ssl(ASYNC, OK);
7456   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7457 
7458   TestCompletionCallback callback1;
7459 
7460   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7461 
7462   int rv = trans.Start(&request, callback1.callback(), log.bound());
7463   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7464 
7465   rv = callback1.WaitForResult();
7466   EXPECT_THAT(rv, IsOk());
7467 
7468   LoadTimingInfo load_timing_info;
7469   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
7470   TestLoadTimingNotReused(load_timing_info,
7471                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7472 
7473   const HttpResponseInfo* response = trans.GetResponseInfo();
7474   ASSERT_TRUE(response);
7475   ASSERT_TRUE(response->headers);
7476   EXPECT_EQ(407, response->headers->response_code());
7477   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7478   EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
7479   EXPECT_FALSE(response->did_use_http_auth);
7480 
7481   TestCompletionCallback callback2;
7482 
7483   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
7484   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7485 
7486   rv = callback2.WaitForResult();
7487   EXPECT_THAT(rv, IsOk());
7488 
7489   load_timing_info = LoadTimingInfo();
7490   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
7491   // Retrying with HTTP AUTH is considered to be reusing a socket.
7492   TestLoadTimingReused(load_timing_info);
7493 
7494   response = trans.GetResponseInfo();
7495   ASSERT_TRUE(response);
7496 
7497   EXPECT_TRUE(response->headers->IsKeepAlive());
7498   EXPECT_EQ(200, response->headers->response_code());
7499   EXPECT_EQ(100, response->headers->GetContentLength());
7500   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7501   EXPECT_TRUE(response->did_use_http_auth);
7502 
7503   // The password prompt info should not be set.
7504   EXPECT_FALSE(response->auth_challenge.has_value());
7505 }
7506 
ConnectStatusHelperWithExpectedStatus(const MockRead & status,int expected_status)7507 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
7508     const MockRead& status, int expected_status) {
7509   HttpRequestInfo request;
7510   request.method = "GET";
7511   request.url = GURL("https://www.example.org/");
7512   request.traffic_annotation =
7513       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7514 
7515   // Configure against proxy server "myproxy:70".
7516   session_deps_.proxy_resolution_service =
7517       ConfiguredProxyResolutionService::CreateFixed(
7518           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
7519   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7520 
7521   // Since we have proxy, should try to establish tunnel.
7522   MockWrite data_writes[] = {
7523       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7524                 "Host: www.example.org:443\r\n"
7525                 "Proxy-Connection: keep-alive\r\n\r\n"),
7526   };
7527 
7528   MockRead data_reads[] = {
7529       status, MockRead("Content-Length: 10\r\n\r\n"),
7530       // No response body because the test stops reading here.
7531       MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
7532   };
7533 
7534   StaticSocketDataProvider data(data_reads, data_writes);
7535   session_deps_.socket_factory->AddSocketDataProvider(&data);
7536 
7537   TestCompletionCallback callback;
7538 
7539   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7540 
7541   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7542   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7543 
7544   rv = callback.WaitForResult();
7545   EXPECT_EQ(expected_status, rv);
7546 }
7547 
ConnectStatusHelper(const MockRead & status)7548 void HttpNetworkTransactionTest::ConnectStatusHelper(
7549     const MockRead& status) {
7550   ConnectStatusHelperWithExpectedStatus(
7551       status, ERR_TUNNEL_CONNECTION_FAILED);
7552 }
7553 
TEST_F(HttpNetworkTransactionTest,ConnectStatus100)7554 TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
7555   ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
7556 }
7557 
TEST_F(HttpNetworkTransactionTest,ConnectStatus101)7558 TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
7559   ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
7560 }
7561 
TEST_F(HttpNetworkTransactionTest,ConnectStatus201)7562 TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
7563   ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
7564 }
7565 
TEST_F(HttpNetworkTransactionTest,ConnectStatus202)7566 TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
7567   ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
7568 }
7569 
TEST_F(HttpNetworkTransactionTest,ConnectStatus203)7570 TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
7571   ConnectStatusHelper(
7572       MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
7573 }
7574 
TEST_F(HttpNetworkTransactionTest,ConnectStatus204)7575 TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
7576   ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
7577 }
7578 
TEST_F(HttpNetworkTransactionTest,ConnectStatus205)7579 TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
7580   ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
7581 }
7582 
TEST_F(HttpNetworkTransactionTest,ConnectStatus206)7583 TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
7584   ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
7585 }
7586 
TEST_F(HttpNetworkTransactionTest,ConnectStatus300)7587 TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
7588   ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
7589 }
7590 
TEST_F(HttpNetworkTransactionTest,ConnectStatus301)7591 TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
7592   ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
7593 }
7594 
TEST_F(HttpNetworkTransactionTest,ConnectStatus302)7595 TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
7596   ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
7597 }
7598 
TEST_F(HttpNetworkTransactionTest,ConnectStatus303)7599 TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
7600   ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
7601 }
7602 
TEST_F(HttpNetworkTransactionTest,ConnectStatus304)7603 TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
7604   ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
7605 }
7606 
TEST_F(HttpNetworkTransactionTest,ConnectStatus305)7607 TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
7608   ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
7609 }
7610 
TEST_F(HttpNetworkTransactionTest,ConnectStatus306)7611 TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
7612   ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
7613 }
7614 
TEST_F(HttpNetworkTransactionTest,ConnectStatus307)7615 TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
7616   ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
7617 }
7618 
TEST_F(HttpNetworkTransactionTest,ConnectStatus308)7619 TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
7620   ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
7621 }
7622 
TEST_F(HttpNetworkTransactionTest,ConnectStatus400)7623 TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
7624   ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
7625 }
7626 
TEST_F(HttpNetworkTransactionTest,ConnectStatus401)7627 TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
7628   ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
7629 }
7630 
TEST_F(HttpNetworkTransactionTest,ConnectStatus402)7631 TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
7632   ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
7633 }
7634 
TEST_F(HttpNetworkTransactionTest,ConnectStatus403)7635 TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
7636   ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
7637 }
7638 
TEST_F(HttpNetworkTransactionTest,ConnectStatus404)7639 TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
7640   ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
7641 }
7642 
TEST_F(HttpNetworkTransactionTest,ConnectStatus405)7643 TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
7644   ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
7645 }
7646 
TEST_F(HttpNetworkTransactionTest,ConnectStatus406)7647 TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
7648   ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
7649 }
7650 
TEST_F(HttpNetworkTransactionTest,ConnectStatus407)7651 TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
7652   ConnectStatusHelperWithExpectedStatus(
7653       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7654       ERR_PROXY_AUTH_UNSUPPORTED);
7655 }
7656 
TEST_F(HttpNetworkTransactionTest,ConnectStatus408)7657 TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
7658   ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
7659 }
7660 
TEST_F(HttpNetworkTransactionTest,ConnectStatus409)7661 TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
7662   ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
7663 }
7664 
TEST_F(HttpNetworkTransactionTest,ConnectStatus410)7665 TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
7666   ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
7667 }
7668 
TEST_F(HttpNetworkTransactionTest,ConnectStatus411)7669 TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
7670   ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
7671 }
7672 
TEST_F(HttpNetworkTransactionTest,ConnectStatus412)7673 TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
7674   ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
7675 }
7676 
TEST_F(HttpNetworkTransactionTest,ConnectStatus413)7677 TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
7678   ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
7679 }
7680 
TEST_F(HttpNetworkTransactionTest,ConnectStatus414)7681 TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
7682   ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
7683 }
7684 
TEST_F(HttpNetworkTransactionTest,ConnectStatus415)7685 TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
7686   ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
7687 }
7688 
TEST_F(HttpNetworkTransactionTest,ConnectStatus416)7689 TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
7690   ConnectStatusHelper(
7691       MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
7692 }
7693 
TEST_F(HttpNetworkTransactionTest,ConnectStatus417)7694 TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
7695   ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
7696 }
7697 
TEST_F(HttpNetworkTransactionTest,ConnectStatus500)7698 TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
7699   ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
7700 }
7701 
TEST_F(HttpNetworkTransactionTest,ConnectStatus501)7702 TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
7703   ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
7704 }
7705 
TEST_F(HttpNetworkTransactionTest,ConnectStatus502)7706 TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
7707   ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
7708 }
7709 
TEST_F(HttpNetworkTransactionTest,ConnectStatus503)7710 TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
7711   ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
7712 }
7713 
TEST_F(HttpNetworkTransactionTest,ConnectStatus504)7714 TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
7715   ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
7716 }
7717 
TEST_F(HttpNetworkTransactionTest,ConnectStatus505)7718 TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
7719   ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
7720 }
7721 
7722 // Test the flow when both the proxy server AND origin server require
7723 // authentication. Again, this uses basic auth for both since that is
7724 // the simplest to mock.
TEST_F(HttpNetworkTransactionTest,BasicAuthProxyThenServer)7725 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
7726   HttpRequestInfo request;
7727   request.method = "GET";
7728   request.url = GURL("http://www.example.org/");
7729   request.traffic_annotation =
7730       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7731 
7732   // Configure against proxy server "myproxy:70".
7733   session_deps_.proxy_resolution_service =
7734       ConfiguredProxyResolutionService::CreateFixed(
7735           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
7736   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7737 
7738   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7739 
7740   MockWrite data_writes1[] = {
7741       MockWrite(
7742           "GET http://www.example.org/ HTTP/1.1\r\n"
7743           "Host: www.example.org\r\n"
7744           "Proxy-Connection: keep-alive\r\n\r\n"),
7745   };
7746 
7747   MockRead data_reads1[] = {
7748     MockRead("HTTP/1.0 407 Unauthorized\r\n"),
7749     // Give a couple authenticate options (only the middle one is actually
7750     // supported).
7751     MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
7752     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7753     MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
7754     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7755     // Large content-length -- won't matter, as connection will be reset.
7756     MockRead("Content-Length: 10000\r\n\r\n"),
7757     MockRead(SYNCHRONOUS, ERR_FAILED),
7758   };
7759 
7760   // After calling trans.RestartWithAuth() the first time, this is the
7761   // request we should be issuing -- the final header line contains the
7762   // proxy's credentials.
7763   MockWrite data_writes2[] = {
7764       MockWrite(
7765           "GET http://www.example.org/ HTTP/1.1\r\n"
7766           "Host: www.example.org\r\n"
7767           "Proxy-Connection: keep-alive\r\n"
7768           "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7769   };
7770 
7771   // Now the proxy server lets the request pass through to origin server.
7772   // The origin server responds with a 401.
7773   MockRead data_reads2[] = {
7774     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7775     // Note: We are using the same realm-name as the proxy server. This is
7776     // completely valid, as realms are unique across hosts.
7777     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7778     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7779     MockRead("Content-Length: 2000\r\n\r\n"),
7780     MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
7781   };
7782 
7783   // After calling trans.RestartWithAuth() the second time, we should send
7784   // the credentials for both the proxy and origin server.
7785   MockWrite data_writes3[] = {
7786       MockWrite(
7787           "GET http://www.example.org/ HTTP/1.1\r\n"
7788           "Host: www.example.org\r\n"
7789           "Proxy-Connection: keep-alive\r\n"
7790           "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
7791           "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
7792   };
7793 
7794   // Lastly we get the desired content.
7795   MockRead data_reads3[] = {
7796     MockRead("HTTP/1.0 200 OK\r\n"),
7797     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7798     MockRead("Content-Length: 100\r\n\r\n"),
7799     MockRead(SYNCHRONOUS, OK),
7800   };
7801 
7802   StaticSocketDataProvider data1(data_reads1, data_writes1);
7803   StaticSocketDataProvider data2(data_reads2, data_writes2);
7804   StaticSocketDataProvider data3(data_reads3, data_writes3);
7805   session_deps_.socket_factory->AddSocketDataProvider(&data1);
7806   session_deps_.socket_factory->AddSocketDataProvider(&data2);
7807   session_deps_.socket_factory->AddSocketDataProvider(&data3);
7808 
7809   TestCompletionCallback callback1;
7810 
7811   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7812   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7813 
7814   rv = callback1.WaitForResult();
7815   EXPECT_THAT(rv, IsOk());
7816 
7817   const HttpResponseInfo* response = trans.GetResponseInfo();
7818   ASSERT_TRUE(response);
7819   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
7820 
7821   TestCompletionCallback callback2;
7822 
7823   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
7824   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7825 
7826   rv = callback2.WaitForResult();
7827   EXPECT_THAT(rv, IsOk());
7828 
7829   response = trans.GetResponseInfo();
7830   ASSERT_TRUE(response);
7831   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
7832 
7833   TestCompletionCallback callback3;
7834 
7835   rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7836                              callback3.callback());
7837   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7838 
7839   rv = callback3.WaitForResult();
7840   EXPECT_THAT(rv, IsOk());
7841 
7842   response = trans.GetResponseInfo();
7843   EXPECT_FALSE(response->auth_challenge.has_value());
7844   EXPECT_EQ(100, response->headers->GetContentLength());
7845 }
7846 
7847 // For the NTLM implementation using SSPI, we skip the NTLM tests since we
7848 // can't hook into its internals to cause it to generate predictable NTLM
7849 // authorization headers.
7850 #if defined(NTLM_PORTABLE)
7851 // The NTLM authentication unit tests are based on known test data from the
7852 // [MS-NLMP] Specification [1]. These tests are primarily of the authentication
7853 // flow rather than the implementation of the NTLM protocol. See net/ntlm
7854 // for the implementation and testing of the protocol.
7855 //
7856 // [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
7857 
7858 // Enter the correct password and authenticate successfully.
TEST_F(HttpNetworkTransactionTest,NTLMAuthV2)7859 TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
7860   HttpRequestInfo request;
7861   request.method = "GET";
7862   request.url = GURL("https://server/kids/login.aspx");
7863   request.traffic_annotation =
7864       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7865 
7866   // Ensure load is not disrupted by flags which suppress behaviour specific
7867   // to other auth schemes.
7868   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7869 
7870   HttpAuthNtlmMechanism::ScopedProcSetter proc_setter(
7871       MockGetMSTime, MockGenerateRandom, MockGetHostName);
7872   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7873 
7874   // Generate the NTLM messages based on known test data.
7875   std::string negotiate_msg;
7876   std::string challenge_msg;
7877   std::string authenticate_msg;
7878   base::Base64Encode(
7879       base::StringPiece(
7880           reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
7881           base::size(ntlm::test::kExpectedNegotiateMsg)),
7882       &negotiate_msg);
7883   base::Base64Encode(
7884       base::StringPiece(
7885           reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
7886           base::size(ntlm::test::kChallengeMsgFromSpecV2)),
7887       &challenge_msg);
7888   base::Base64Encode(
7889       base::StringPiece(
7890           reinterpret_cast<const char*>(
7891               ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
7892           base::size(
7893               ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
7894       &authenticate_msg);
7895 
7896   MockWrite data_writes1[] = {
7897       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7898                 "Host: server\r\n"
7899                 "Connection: keep-alive\r\n\r\n"),
7900   };
7901 
7902   MockRead data_reads1[] = {
7903     MockRead("HTTP/1.1 401 Access Denied\r\n"),
7904     // Negotiate and NTLM are often requested together.  However, we only want
7905     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7906     // the header that requests Negotiate for this test.
7907     MockRead("WWW-Authenticate: NTLM\r\n"),
7908     MockRead("Connection: close\r\n"),
7909     MockRead("Content-Length: 42\r\n"),
7910     MockRead("Content-Type: text/html\r\n\r\n"),
7911     // Missing content -- won't matter, as connection will be reset.
7912   };
7913 
7914   MockWrite data_writes2[] = {
7915       // After restarting with a null identity, this is the
7916       // request we should be issuing -- the final header line contains a Type
7917       // 1 message.
7918       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7919                 "Host: server\r\n"
7920                 "Connection: keep-alive\r\n"
7921                 "Authorization: NTLM "),
7922       MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
7923 
7924       // After calling trans.RestartWithAuth(), we should send a Type 3 message
7925       // (using correct credentials).  The second request continues on the
7926       // same connection.
7927       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7928                 "Host: server\r\n"
7929                 "Connection: keep-alive\r\n"
7930                 "Authorization: NTLM "),
7931       MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
7932   };
7933 
7934   MockRead data_reads2[] = {
7935       // The origin server responds with a Type 2 message.
7936       MockRead("HTTP/1.1 401 Access Denied\r\n"),
7937       MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7938       MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
7939       MockRead("Content-Type: text/html\r\n\r\n"),
7940       MockRead("You are not authorized to view this page\r\n"),
7941 
7942       // Lastly we get the desired content.
7943       MockRead("HTTP/1.1 200 OK\r\n"),
7944       MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7945       MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
7946   };
7947 
7948   StaticSocketDataProvider data1(data_reads1, data_writes1);
7949   StaticSocketDataProvider data2(data_reads2, data_writes2);
7950   session_deps_.socket_factory->AddSocketDataProvider(&data1);
7951   session_deps_.socket_factory->AddSocketDataProvider(&data2);
7952 
7953   SSLSocketDataProvider ssl1(ASYNC, OK);
7954   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7955   SSLSocketDataProvider ssl2(ASYNC, OK);
7956   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7957 
7958   TestCompletionCallback callback1;
7959 
7960   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7961 
7962   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7963   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7964 
7965   rv = callback1.WaitForResult();
7966   EXPECT_THAT(rv, IsOk());
7967 
7968   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7969 
7970   const HttpResponseInfo* response = trans.GetResponseInfo();
7971   ASSERT_TRUE(response);
7972   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
7973 
7974   TestCompletionCallback callback2;
7975 
7976   rv = trans.RestartWithAuth(
7977       AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7978       callback2.callback());
7979   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7980 
7981   rv = callback2.WaitForResult();
7982   EXPECT_THAT(rv, IsOk());
7983 
7984   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7985 
7986   response = trans.GetResponseInfo();
7987   ASSERT_TRUE(response);
7988   EXPECT_FALSE(response->auth_challenge.has_value());
7989 
7990   TestCompletionCallback callback3;
7991 
7992   rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
7993   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7994 
7995   rv = callback3.WaitForResult();
7996   EXPECT_THAT(rv, IsOk());
7997 
7998   response = trans.GetResponseInfo();
7999   ASSERT_TRUE(response);
8000   EXPECT_FALSE(response->auth_challenge.has_value());
8001   EXPECT_EQ(14, response->headers->GetContentLength());
8002 
8003   std::string response_data;
8004   rv = ReadTransaction(&trans, &response_data);
8005   EXPECT_THAT(rv, IsOk());
8006   EXPECT_EQ("Please Login\r\n", response_data);
8007 
8008   EXPECT_TRUE(data1.AllReadDataConsumed());
8009   EXPECT_TRUE(data1.AllWriteDataConsumed());
8010   EXPECT_TRUE(data2.AllReadDataConsumed());
8011   EXPECT_TRUE(data2.AllWriteDataConsumed());
8012 }
8013 
8014 // Enter a wrong password, and then the correct one.
TEST_F(HttpNetworkTransactionTest,NTLMAuthV2WrongThenRightPassword)8015 TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
8016   HttpRequestInfo request;
8017   request.method = "GET";
8018   request.url = GURL("https://server/kids/login.aspx");
8019   request.traffic_annotation =
8020       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8021 
8022   HttpAuthNtlmMechanism::ScopedProcSetter proc_setter(
8023       MockGetMSTime, MockGenerateRandom, MockGetHostName);
8024   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8025 
8026   // Generate the NTLM messages based on known test data.
8027   std::string negotiate_msg;
8028   std::string challenge_msg;
8029   std::string authenticate_msg;
8030   base::Base64Encode(
8031       base::StringPiece(
8032           reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
8033           base::size(ntlm::test::kExpectedNegotiateMsg)),
8034       &negotiate_msg);
8035   base::Base64Encode(
8036       base::StringPiece(
8037           reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
8038           base::size(ntlm::test::kChallengeMsgFromSpecV2)),
8039       &challenge_msg);
8040   base::Base64Encode(
8041       base::StringPiece(
8042           reinterpret_cast<const char*>(
8043               ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
8044           base::size(
8045               ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
8046       &authenticate_msg);
8047 
8048   // The authenticate message when |kWrongPassword| is sent.
8049   std::string wrong_password_authenticate_msg(
8050       "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
8051       "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
8052       "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
8053       "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
8054       "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
8055       "QwBPAE0AUABVAFQARQBSAA==");
8056 
8057   // Sanity check that it's the same length as the correct authenticate message
8058   // and that it's different.
8059   ASSERT_EQ(authenticate_msg.length(),
8060             wrong_password_authenticate_msg.length());
8061   ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
8062 
8063   MockWrite data_writes1[] = {
8064       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
8065                 "Host: server\r\n"
8066                 "Connection: keep-alive\r\n\r\n"),
8067   };
8068 
8069   MockRead data_reads1[] = {
8070     MockRead("HTTP/1.1 401 Access Denied\r\n"),
8071     // Negotiate and NTLM are often requested together.  However, we only want
8072     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
8073     // the header that requests Negotiate for this test.
8074     MockRead("WWW-Authenticate: NTLM\r\n"),
8075     MockRead("Connection: close\r\n"),
8076     MockRead("Content-Length: 42\r\n"),
8077     MockRead("Content-Type: text/html\r\n\r\n"),
8078     // Missing content -- won't matter, as connection will be reset.
8079   };
8080 
8081   MockWrite data_writes2[] = {
8082       // After restarting with a null identity, this is the
8083       // request we should be issuing -- the final header line contains a Type
8084       // 1 message.
8085       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
8086                 "Host: server\r\n"
8087                 "Connection: keep-alive\r\n"
8088                 "Authorization: NTLM "),
8089       MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
8090 
8091       // After calling trans.RestartWithAuth(), we should send a Type 3 message
8092       // (using incorrect credentials).  The second request continues on the
8093       // same connection.
8094       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
8095                 "Host: server\r\n"
8096                 "Connection: keep-alive\r\n"
8097                 "Authorization: NTLM "),
8098       MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
8099   };
8100 
8101   MockRead data_reads2[] = {
8102       // The origin server responds with a Type 2 message.
8103       MockRead("HTTP/1.1 401 Access Denied\r\n"),
8104       MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
8105       MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
8106       MockRead("Content-Type: text/html\r\n\r\n"),
8107       MockRead("You are not authorized to view this page\r\n"),
8108 
8109       // Wrong password.
8110       MockRead("HTTP/1.1 401 Access Denied\r\n"),
8111       MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
8112       MockRead("Content-Length: 42\r\n"),
8113       MockRead("Content-Type: text/html\r\n\r\n"),
8114       // Missing content -- won't matter, as connection will be reset.
8115   };
8116 
8117   MockWrite data_writes3[] = {
8118       // After restarting with a null identity, this is the
8119       // request we should be issuing -- the final header line contains a Type
8120       // 1 message.
8121       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
8122                 "Host: server\r\n"
8123                 "Connection: keep-alive\r\n"
8124                 "Authorization: NTLM "),
8125       MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
8126 
8127       // After calling trans.RestartWithAuth(), we should send a Type 3 message
8128       // (the credentials for the origin server).  The second request continues
8129       // on the same connection.
8130       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
8131                 "Host: server\r\n"
8132                 "Connection: keep-alive\r\n"
8133                 "Authorization: NTLM "),
8134       MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
8135   };
8136 
8137   MockRead data_reads3[] = {
8138       // The origin server responds with a Type 2 message.
8139       MockRead("HTTP/1.1 401 Access Denied\r\n"),
8140       MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
8141       MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
8142       MockRead("Content-Type: text/html\r\n\r\n"),
8143       MockRead("You are not authorized to view this page\r\n"),
8144 
8145       // Lastly we get the desired content.
8146       MockRead("HTTP/1.1 200 OK\r\n"),
8147       MockRead("Content-Type: text/html; charset=utf-8\r\n"),
8148       MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
8149   };
8150 
8151   StaticSocketDataProvider data1(data_reads1, data_writes1);
8152   StaticSocketDataProvider data2(data_reads2, data_writes2);
8153   StaticSocketDataProvider data3(data_reads3, data_writes3);
8154   session_deps_.socket_factory->AddSocketDataProvider(&data1);
8155   session_deps_.socket_factory->AddSocketDataProvider(&data2);
8156   session_deps_.socket_factory->AddSocketDataProvider(&data3);
8157 
8158   SSLSocketDataProvider ssl1(ASYNC, OK);
8159   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
8160   SSLSocketDataProvider ssl2(ASYNC, OK);
8161   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
8162   SSLSocketDataProvider ssl3(ASYNC, OK);
8163   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
8164 
8165   TestCompletionCallback callback1;
8166 
8167   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8168 
8169   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
8170   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8171 
8172   rv = callback1.WaitForResult();
8173   EXPECT_THAT(rv, IsOk());
8174 
8175   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
8176 
8177   const HttpResponseInfo* response = trans.GetResponseInfo();
8178   ASSERT_TRUE(response);
8179   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
8180 
8181   TestCompletionCallback callback2;
8182 
8183   // Enter the wrong password.
8184   rv = trans.RestartWithAuth(
8185       AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
8186       callback2.callback());
8187   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8188 
8189   rv = callback2.WaitForResult();
8190   EXPECT_THAT(rv, IsOk());
8191 
8192   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
8193   TestCompletionCallback callback3;
8194   rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
8195   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8196   rv = callback3.WaitForResult();
8197   EXPECT_THAT(rv, IsOk());
8198   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
8199 
8200   response = trans.GetResponseInfo();
8201   ASSERT_TRUE(response);
8202   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
8203 
8204   TestCompletionCallback callback4;
8205 
8206   // Now enter the right password.
8207   rv = trans.RestartWithAuth(
8208       AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
8209       callback4.callback());
8210   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8211 
8212   rv = callback4.WaitForResult();
8213   EXPECT_THAT(rv, IsOk());
8214 
8215   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
8216 
8217   TestCompletionCallback callback5;
8218 
8219   // One more roundtrip
8220   rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
8221   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8222 
8223   rv = callback5.WaitForResult();
8224   EXPECT_THAT(rv, IsOk());
8225 
8226   response = trans.GetResponseInfo();
8227   EXPECT_FALSE(response->auth_challenge.has_value());
8228   EXPECT_EQ(14, response->headers->GetContentLength());
8229 
8230   std::string response_data;
8231   rv = ReadTransaction(&trans, &response_data);
8232   EXPECT_THAT(rv, IsOk());
8233   EXPECT_EQ("Please Login\r\n", response_data);
8234 
8235   EXPECT_TRUE(data1.AllReadDataConsumed());
8236   EXPECT_TRUE(data1.AllWriteDataConsumed());
8237   EXPECT_TRUE(data2.AllReadDataConsumed());
8238   EXPECT_TRUE(data2.AllWriteDataConsumed());
8239   EXPECT_TRUE(data3.AllReadDataConsumed());
8240   EXPECT_TRUE(data3.AllWriteDataConsumed());
8241 }
8242 
8243 // Server requests NTLM authentication, which is not supported over HTTP/2.
8244 // Subsequent request with authorization header should be sent over HTTP/1.1.
TEST_F(HttpNetworkTransactionTest,NTLMOverHttp2)8245 TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
8246   HttpAuthNtlmMechanism::ScopedProcSetter proc_setter(
8247       MockGetMSTime, MockGenerateRandom, MockGetHostName);
8248 
8249   const char* kUrl = "https://server/kids/login.aspx";
8250 
8251   HttpRequestInfo request;
8252   request.method = "GET";
8253   request.url = GURL(kUrl);
8254   request.traffic_annotation =
8255       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8256 
8257   // First request without credentials.
8258   spdy::SpdyHeaderBlock request_headers0(
8259       spdy_util_.ConstructGetHeaderBlock(kUrl));
8260   spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
8261       1, std::move(request_headers0), LOWEST, true));
8262 
8263   spdy::SpdyHeaderBlock response_headers0;
8264   response_headers0[spdy::kHttp2StatusHeader] = "401";
8265   response_headers0["www-authenticate"] = "NTLM";
8266   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
8267       1, std::move(response_headers0), true));
8268 
8269   // Stream 1 is closed.
8270   spdy_util_.UpdateWithStreamDestruction(1);
8271 
8272   // Generate the NTLM messages based on known test data.
8273   std::string negotiate_msg;
8274   std::string challenge_msg;
8275   std::string authenticate_msg;
8276   base::Base64Encode(
8277       base::StringPiece(
8278           reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
8279           base::size(ntlm::test::kExpectedNegotiateMsg)),
8280       &negotiate_msg);
8281   base::Base64Encode(
8282       base::StringPiece(
8283           reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
8284           base::size(ntlm::test::kChallengeMsgFromSpecV2)),
8285       &challenge_msg);
8286   base::Base64Encode(
8287       base::StringPiece(
8288           reinterpret_cast<const char*>(
8289               ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
8290           base::size(
8291               ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
8292       &authenticate_msg);
8293 
8294   MockWrite writes0[] = {CreateMockWrite(request0, 0)};
8295   MockRead reads0[] = {CreateMockRead(resp, 1),
8296                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2)};
8297 
8298   // Retry yet again using HTTP/1.1.
8299   MockWrite writes1[] = {
8300       // After restarting with a null identity, this is the
8301       // request we should be issuing -- the final header line contains a Type
8302       // 1 message.
8303       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
8304                 "Host: server\r\n"
8305                 "Connection: keep-alive\r\n"
8306                 "Authorization: NTLM "),
8307       MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
8308 
8309       // After calling trans.RestartWithAuth(), we should send a Type 3 message
8310       // (the credentials for the origin server).  The second request continues
8311       // on the same connection.
8312       MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
8313                 "Host: server\r\n"
8314                 "Connection: keep-alive\r\n"
8315                 "Authorization: NTLM "),
8316       MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
8317   };
8318 
8319   MockRead reads1[] = {
8320       // The origin server responds with a Type 2 message.
8321       MockRead("HTTP/1.1 401 Access Denied\r\n"),
8322       MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
8323       MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
8324       MockRead("Content-Type: text/html\r\n\r\n"),
8325       MockRead("You are not authorized to view this page\r\n"),
8326 
8327       // Lastly we get the desired content.
8328       MockRead("HTTP/1.1 200 OK\r\n"),
8329       MockRead("Content-Type: text/html; charset=utf-8\r\n"),
8330       MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
8331   };
8332   SequencedSocketData data0(reads0, writes0);
8333   StaticSocketDataProvider data1(reads1, writes1);
8334   session_deps_.socket_factory->AddSocketDataProvider(&data0);
8335   session_deps_.socket_factory->AddSocketDataProvider(&data1);
8336 
8337   SSLSocketDataProvider ssl0(ASYNC, OK);
8338   ssl0.next_proto = kProtoHTTP2;
8339   ssl0.next_protos_expected_in_ssl_config =
8340       NextProtoVector{kProtoHTTP2, kProtoHTTP11};
8341   SSLSocketDataProvider ssl1(ASYNC, OK);
8342   // When creating the second connection, only HTTP/1.1 should be allowed.
8343   ssl1.next_protos_expected_in_ssl_config = NextProtoVector{kProtoHTTP11};
8344   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
8345   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
8346 
8347   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8348   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8349 
8350   TestCompletionCallback callback1;
8351   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
8352   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8353 
8354   rv = callback1.WaitForResult();
8355   EXPECT_THAT(rv, IsOk());
8356 
8357   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
8358 
8359   const HttpResponseInfo* response = trans.GetResponseInfo();
8360   ASSERT_TRUE(response);
8361   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
8362 
8363   TestCompletionCallback callback2;
8364 
8365   rv = trans.RestartWithAuth(
8366       AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
8367       callback2.callback());
8368   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8369 
8370   rv = callback2.WaitForResult();
8371   EXPECT_THAT(rv, IsOk());
8372 
8373   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
8374 
8375   response = trans.GetResponseInfo();
8376   ASSERT_TRUE(response);
8377   EXPECT_FALSE(response->auth_challenge.has_value());
8378 
8379   TestCompletionCallback callback3;
8380 
8381   rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
8382   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8383 
8384   rv = callback3.WaitForResult();
8385   EXPECT_THAT(rv, IsOk());
8386 
8387   response = trans.GetResponseInfo();
8388   ASSERT_TRUE(response);
8389   EXPECT_FALSE(response->auth_challenge.has_value());
8390   EXPECT_EQ(14, response->headers->GetContentLength());
8391 
8392   std::string response_data;
8393   rv = ReadTransaction(&trans, &response_data);
8394   EXPECT_THAT(rv, IsOk());
8395   EXPECT_EQ("Please Login\r\n", response_data);
8396 
8397   EXPECT_TRUE(data0.AllReadDataConsumed());
8398   EXPECT_TRUE(data0.AllWriteDataConsumed());
8399   EXPECT_TRUE(data1.AllReadDataConsumed());
8400   EXPECT_TRUE(data1.AllWriteDataConsumed());
8401 }
8402 
8403 #if BUILDFLAG(ENABLE_WEBSOCKETS)
8404 
8405 // Variant of above test using WebSockets.
TEST_F(HttpNetworkTransactionTest,NTLMOverHttp2WithWebsockets)8406 TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2WithWebsockets) {
8407   const GURL kInitialUrl("https://server/");
8408   const GURL kWebSocketUrl("wss://server/");
8409   HttpAuthNtlmMechanism::ScopedProcSetter proc_setter(
8410       MockGetMSTime, MockGenerateRandom, MockGetHostName);
8411 
8412   // Initial request establishes an H2 connection, which will then be reused for
8413   // WebSockets. This is needed since WebSockets will reuse H2 connections, but
8414   // it won't create a new one.
8415   spdy::SpdyHeaderBlock initial_request_headers(
8416       spdy_util_.ConstructGetHeaderBlock(kInitialUrl.spec()));
8417   spdy::SpdySerializedFrame initial_request(spdy_util_.ConstructSpdyHeaders(
8418       1, std::move(initial_request_headers), DEFAULT_PRIORITY, true));
8419   spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
8420 
8421   // Settings frame, indicating WebSockets is supported.
8422   spdy::SettingsMap settings;
8423   settings[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
8424   spdy::SpdySerializedFrame settings_frame(
8425       spdy_util_.ConstructSpdySettings(settings));
8426 
8427   // Response headers for first request. Body is never received, but that
8428   // shouldn't matter for the purposes of this test.
8429   spdy::SpdySerializedFrame initial_response(
8430       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
8431 
8432   // First WebSocket request, which has no credentials.
8433   spdy::SpdyHeaderBlock websocket_request_headers;
8434   websocket_request_headers[spdy::kHttp2MethodHeader] = "CONNECT";
8435   websocket_request_headers[spdy::kHttp2AuthorityHeader] = "server";
8436   websocket_request_headers[spdy::kHttp2SchemeHeader] = "https";
8437   websocket_request_headers[spdy::kHttp2PathHeader] = "/";
8438   websocket_request_headers[spdy::kHttp2ProtocolHeader] = "websocket";
8439   websocket_request_headers["origin"] = "http://server";
8440   websocket_request_headers["sec-websocket-version"] = "13";
8441   websocket_request_headers["sec-websocket-extensions"] =
8442       "permessage-deflate; client_max_window_bits";
8443   spdy::SpdySerializedFrame websocket_request(spdy_util_.ConstructSpdyHeaders(
8444       3, std::move(websocket_request_headers), MEDIUM, false));
8445 
8446   // Auth challenge to WebSocket request.
8447   spdy::SpdyHeaderBlock auth_challenge_headers;
8448   auth_challenge_headers[spdy::kHttp2StatusHeader] = "401";
8449   auth_challenge_headers["www-authenticate"] = "NTLM";
8450   spdy::SpdySerializedFrame websocket_auth_challenge(
8451       spdy_util_.ConstructSpdyResponseHeaders(
8452           3, std::move(auth_challenge_headers), true));
8453 
8454   MockWrite writes0[] = {CreateMockWrite(initial_request, 0),
8455                          CreateMockWrite(settings_ack, 2),
8456                          CreateMockWrite(websocket_request, 4),
8457                          MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 7)};
8458   MockRead reads0[] = {CreateMockRead(settings_frame, 1),
8459                        CreateMockRead(initial_response, 3),
8460                        CreateMockRead(websocket_auth_challenge, 5),
8461                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6)};
8462 
8463   // Generate the NTLM messages based on known test data.
8464   std::string negotiate_msg;
8465   std::string challenge_msg;
8466   std::string authenticate_msg;
8467   base::Base64Encode(
8468       base::StringPiece(
8469           reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
8470           base::size(ntlm::test::kExpectedNegotiateMsg)),
8471       &negotiate_msg);
8472   base::Base64Encode(
8473       base::StringPiece(
8474           reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
8475           base::size(ntlm::test::kChallengeMsgFromSpecV2)),
8476       &challenge_msg);
8477   base::Base64Encode(
8478       base::StringPiece(
8479           reinterpret_cast<const char*>(
8480               ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
8481           base::size(
8482               ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
8483       &authenticate_msg);
8484 
8485   // Retry yet again using HTTP/1.1.
8486   MockWrite writes1[] = {
8487       // After restarting with a null identity, this is the
8488       // request we should be issuing -- the final header line contains a Type
8489       // 1 message.
8490       MockWrite("GET / HTTP/1.1\r\n"
8491                 "Host: server\r\n"
8492                 "Connection: Upgrade\r\n"
8493                 "Authorization: NTLM "),
8494       MockWrite(negotiate_msg.c_str()),
8495       MockWrite("\r\n"),
8496       MockWrite("Origin: http://server\r\n"
8497                 "Sec-WebSocket-Version: 13\r\n"
8498                 "Upgrade: websocket\r\n"
8499                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
8500                 "Sec-WebSocket-Extensions: permessage-deflate; "
8501                 "client_max_window_bits\r\n\r\n"),
8502 
8503       // After calling trans.RestartWithAuth(), we should send a Type 3 message
8504       // (the credentials for the origin server).  The second request continues
8505       // on the same connection.
8506       MockWrite("GET / HTTP/1.1\r\n"
8507                 "Host: server\r\n"
8508                 "Connection: Upgrade\r\n"
8509                 "Authorization: NTLM "),
8510       MockWrite(authenticate_msg.c_str()),
8511       MockWrite("\r\n"),
8512       MockWrite("Origin: http://server\r\n"
8513                 "Sec-WebSocket-Version: 13\r\n"
8514                 "Upgrade: websocket\r\n"
8515                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
8516                 "Sec-WebSocket-Extensions: permessage-deflate; "
8517                 "client_max_window_bits\r\n\r\n"),
8518   };
8519 
8520   MockRead reads1[] = {
8521       // The origin server responds with a Type 2 message.
8522       MockRead("HTTP/1.1 401 Access Denied\r\n"),
8523       MockRead("WWW-Authenticate: NTLM "),
8524       MockRead(challenge_msg.c_str()),
8525       MockRead("\r\n"),
8526       MockRead("Content-Length: 42\r\n"),
8527       MockRead("Content-Type: text/html\r\n\r\n"),
8528       MockRead("You are not authorized to view this page\r\n"),
8529 
8530       // Lastly we get the desired content.
8531       MockRead("HTTP/1.1 101 Switching Protocols\r\n"
8532                "Upgrade: websocket\r\n"
8533                "Connection: Upgrade\r\n"
8534                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
8535   };
8536   SequencedSocketData data0(reads0, writes0);
8537   session_deps_.socket_factory->AddSocketDataProvider(&data0);
8538   SSLSocketDataProvider ssl0(ASYNC, OK);
8539   ssl0.next_proto = kProtoHTTP2;
8540   ssl0.next_protos_expected_in_ssl_config =
8541       NextProtoVector{kProtoHTTP2, kProtoHTTP11};
8542   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
8543 
8544   StaticSocketDataProvider data1(reads1, writes1);
8545   session_deps_.socket_factory->AddSocketDataProvider(&data1);
8546   SSLSocketDataProvider ssl1(ASYNC, OK);
8547   // When creating the second connection, only HTTP/1.1 should be allowed.
8548   ssl1.next_protos_expected_in_ssl_config = NextProtoVector{};
8549   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
8550 
8551   session_deps_.enable_websocket_over_http2 = true;
8552   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8553 
8554   HttpRequestInfo initial_request_info;
8555   initial_request_info.method = "GET";
8556   initial_request_info.url = kInitialUrl;
8557   initial_request_info.traffic_annotation =
8558       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8559   HttpNetworkTransaction initial_trans(DEFAULT_PRIORITY, session.get());
8560   TestCompletionCallback initial_callback;
8561   int rv = initial_trans.Start(&initial_request_info,
8562                                initial_callback.callback(), NetLogWithSource());
8563   EXPECT_THAT(initial_callback.GetResult(rv), IsOk());
8564 
8565   EXPECT_FALSE(session->http_server_properties()->RequiresHTTP11(
8566       url::SchemeHostPort(kInitialUrl), NetworkIsolationKey()));
8567 
8568   HttpRequestInfo websocket_request_info;
8569   websocket_request_info.method = "GET";
8570   websocket_request_info.url = kWebSocketUrl;
8571   websocket_request_info.traffic_annotation =
8572       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8573   EXPECT_TRUE(HostPortPair::FromURL(initial_request_info.url)
8574                   .Equals(HostPortPair::FromURL(websocket_request_info.url)));
8575   websocket_request_info.extra_headers.SetHeader("Origin", "http://server");
8576   websocket_request_info.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
8577   // The following two headers must be removed by WebSocketHttp2HandshakeStream.
8578   websocket_request_info.extra_headers.SetHeader("Connection", "Upgrade");
8579   websocket_request_info.extra_headers.SetHeader("Upgrade", "websocket");
8580 
8581   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
8582 
8583   HttpNetworkTransaction websocket_trans(MEDIUM, session.get());
8584   websocket_trans.SetWebSocketHandshakeStreamCreateHelper(
8585       &websocket_stream_create_helper);
8586 
8587   TestCompletionCallback websocket_callback;
8588   rv = websocket_trans.Start(&websocket_request_info,
8589                              websocket_callback.callback(), NetLogWithSource());
8590   EXPECT_THAT(websocket_callback.GetResult(rv), IsOk());
8591 
8592   EXPECT_FALSE(websocket_trans.IsReadyToRestartForAuth());
8593 
8594   const HttpResponseInfo* response = websocket_trans.GetResponseInfo();
8595   ASSERT_TRUE(response);
8596   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
8597 
8598   rv = websocket_trans.RestartWithAuth(
8599       AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
8600       websocket_callback.callback());
8601   EXPECT_THAT(websocket_callback.GetResult(rv), IsOk());
8602 
8603   EXPECT_TRUE(websocket_trans.IsReadyToRestartForAuth());
8604 
8605   response = websocket_trans.GetResponseInfo();
8606   ASSERT_TRUE(response);
8607   EXPECT_FALSE(response->auth_challenge.has_value());
8608 
8609   rv = websocket_trans.RestartWithAuth(AuthCredentials(),
8610                                        websocket_callback.callback());
8611   EXPECT_THAT(websocket_callback.GetResult(rv), IsOk());
8612 
8613   // The server should have been marked as requiring HTTP/1.1. The important
8614   // part here is that the scheme that requires HTTP/1.1 should be HTTPS, not
8615   // WSS.
8616   EXPECT_TRUE(session->http_server_properties()->RequiresHTTP11(
8617       url::SchemeHostPort(kInitialUrl), NetworkIsolationKey()));
8618 }
8619 
8620 #endif  // BUILDFLAG(ENABLE_WEBSOCKETS)
8621 
8622 // Test that, if we have an NTLM proxy and the origin resets the connection, we
8623 // do no retry forever as a result of TLS retries. This is a regression test for
8624 // https://crbug.com/823387. The version interference probe has since been
8625 // removed, but we now have a legacy crypto fallback. (If that fallback is
8626 // removed, this test should be kept but with the expectations tweaked, in case
8627 // future fallbacks are added.)
TEST_F(HttpNetworkTransactionTest,NTLMProxyTLSHandshakeReset)8628 TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
8629   // The NTLM test data expects the proxy to be named 'server'. The origin is
8630   // https://origin/.
8631   session_deps_.proxy_resolution_service =
8632       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8633           "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
8634 
8635   SSLContextConfig config;
8636   session_deps_.ssl_config_service =
8637       std::make_unique<TestSSLConfigService>(config);
8638 
8639   HttpRequestInfo request;
8640   request.method = "GET";
8641   request.url = GURL("https://origin/");
8642   request.traffic_annotation =
8643       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8644 
8645   // Ensure load is not disrupted by flags which suppress behaviour specific
8646   // to other auth schemes.
8647   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
8648 
8649   HttpAuthNtlmMechanism::ScopedProcSetter proc_setter(
8650       MockGetMSTime, MockGenerateRandom, MockGetHostName);
8651   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8652 
8653   // Generate the NTLM messages based on known test data.
8654   std::string negotiate_msg;
8655   std::string challenge_msg;
8656   std::string authenticate_msg;
8657   base::Base64Encode(
8658       base::StringPiece(
8659           reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
8660           base::size(ntlm::test::kExpectedNegotiateMsg)),
8661       &negotiate_msg);
8662   base::Base64Encode(
8663       base::StringPiece(
8664           reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
8665           base::size(ntlm::test::kChallengeMsgFromSpecV2)),
8666       &challenge_msg);
8667   base::Base64Encode(
8668       base::StringPiece(
8669           reinterpret_cast<const char*>(
8670               ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
8671           base::size(
8672               ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
8673       &authenticate_msg);
8674 
8675   MockWrite data_writes[] = {
8676       // The initial CONNECT request.
8677       MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
8678                 "Host: origin:443\r\n"
8679                 "Proxy-Connection: keep-alive\r\n\r\n"),
8680 
8681       // After restarting with an identity.
8682       MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
8683                 "Host: origin:443\r\n"
8684                 "Proxy-Connection: keep-alive\r\n"
8685                 "Proxy-Authorization: NTLM "),
8686       MockWrite(negotiate_msg.c_str()),
8687       // End headers.
8688       MockWrite("\r\n\r\n"),
8689 
8690       // The second restart.
8691       MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
8692                 "Host: origin:443\r\n"
8693                 "Proxy-Connection: keep-alive\r\n"
8694                 "Proxy-Authorization: NTLM "),
8695       MockWrite(authenticate_msg.c_str()),
8696       // End headers.
8697       MockWrite("\r\n\r\n"),
8698   };
8699 
8700   MockRead data_reads[] = {
8701       // The initial NTLM response.
8702       MockRead("HTTP/1.1 407 Access Denied\r\n"
8703                "Content-Length: 0\r\n"
8704                "Proxy-Authenticate: NTLM\r\n\r\n"),
8705 
8706       // The NTLM challenge message.
8707       MockRead("HTTP/1.1 407 Access Denied\r\n"
8708                "Content-Length: 0\r\n"
8709                "Proxy-Authenticate: NTLM "),
8710       MockRead(challenge_msg.c_str()),
8711       // End headers.
8712       MockRead("\r\n\r\n"),
8713 
8714       // Finally the tunnel is established.
8715       MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
8716   };
8717 
8718   StaticSocketDataProvider data(data_reads, data_writes);
8719   SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
8720   session_deps_.socket_factory->AddSocketDataProvider(&data);
8721   session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
8722 
8723   StaticSocketDataProvider data2(data_reads, data_writes);
8724   SSLSocketDataProvider data2_ssl(ASYNC, ERR_CONNECTION_RESET);
8725   session_deps_.socket_factory->AddSocketDataProvider(&data2);
8726   session_deps_.socket_factory->AddSSLSocketDataProvider(&data2_ssl);
8727 
8728   // Start the transaction. The proxy responds with an NTLM authentication
8729   // request.
8730   TestCompletionCallback callback;
8731   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8732   int rv = callback.GetResult(
8733       trans.Start(&request, callback.callback(), NetLogWithSource()));
8734 
8735   EXPECT_THAT(rv, IsOk());
8736   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
8737   const HttpResponseInfo* response = trans.GetResponseInfo();
8738   ASSERT_TRUE(response);
8739   EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge));
8740 
8741   // Configure credentials and restart. The proxy responds with the challenge
8742   // message.
8743   rv = callback.GetResult(trans.RestartWithAuth(
8744       AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
8745       callback.callback()));
8746   EXPECT_THAT(rv, IsOk());
8747   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
8748   response = trans.GetResponseInfo();
8749   ASSERT_TRUE(response);
8750   EXPECT_FALSE(response->auth_challenge.has_value());
8751 
8752   // Restart once more. The tunnel will be established and the the SSL handshake
8753   // will reset. The fallback will then kick in and restart the process. The
8754   // proxy responds with another NTLM authentiation request, but we don't need
8755   // to provide credentials as the cached ones work.
8756   rv = callback.GetResult(
8757       trans.RestartWithAuth(AuthCredentials(), callback.callback()));
8758   EXPECT_THAT(rv, IsOk());
8759   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
8760   response = trans.GetResponseInfo();
8761   ASSERT_TRUE(response);
8762   EXPECT_FALSE(response->auth_challenge.has_value());
8763 
8764   // The proxy responds with the NTLM challenge message.
8765   rv = callback.GetResult(
8766       trans.RestartWithAuth(AuthCredentials(), callback.callback()));
8767   EXPECT_THAT(rv, IsOk());
8768   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
8769   response = trans.GetResponseInfo();
8770   ASSERT_TRUE(response);
8771   EXPECT_FALSE(response->auth_challenge.has_value());
8772 
8773   // Send the NTLM authenticate message. The tunnel is established and the
8774   // handshake resets again. We should not retry again.
8775   rv = callback.GetResult(
8776       trans.RestartWithAuth(AuthCredentials(), callback.callback()));
8777   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
8778 }
8779 
8780 #endif  // NTLM_PORTABLE
8781 
8782 // Test reading a server response which has only headers, and no body.
8783 // After some maximum number of bytes is consumed, the transaction should
8784 // fail with ERR_RESPONSE_HEADERS_TOO_BIG.
TEST_F(HttpNetworkTransactionTest,LargeHeadersNoBody)8785 TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
8786   HttpRequestInfo request;
8787   request.method = "GET";
8788   request.url = GURL("http://www.example.org/");
8789   request.traffic_annotation =
8790       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8791 
8792   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8793   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8794 
8795   // Respond with 300 kb of headers (we should fail after 256 kb).
8796   std::string large_headers_string;
8797   FillLargeHeadersString(&large_headers_string, 300 * 1024);
8798 
8799   MockRead data_reads[] = {
8800     MockRead("HTTP/1.0 200 OK\r\n"),
8801     MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
8802     MockRead("\r\nBODY"),
8803     MockRead(SYNCHRONOUS, OK),
8804   };
8805   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
8806   session_deps_.socket_factory->AddSocketDataProvider(&data);
8807 
8808   TestCompletionCallback callback;
8809 
8810   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8811   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8812 
8813   rv = callback.WaitForResult();
8814   EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
8815 }
8816 
8817 // Make sure that we don't try to reuse a TCPClientSocket when failing to
8818 // establish tunnel.
8819 // http://code.google.com/p/chromium/issues/detail?id=3772
TEST_F(HttpNetworkTransactionTest,DontRecycleTransportSocketForSSLTunnel)8820 TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
8821   HttpRequestInfo request;
8822   request.method = "GET";
8823   request.url = GURL("https://www.example.org/");
8824   request.traffic_annotation =
8825       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8826 
8827   // Configure against proxy server "myproxy:70".
8828   session_deps_.proxy_resolution_service =
8829       ConfiguredProxyResolutionService::CreateFixed(
8830           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8831 
8832   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8833 
8834   auto trans =
8835       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
8836 
8837   // Since we have proxy, should try to establish tunnel.
8838   MockWrite data_writes1[] = {
8839       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8840                 "Host: www.example.org:443\r\n"
8841                 "Proxy-Connection: keep-alive\r\n\r\n"),
8842   };
8843 
8844   // The proxy responds to the connect with a 404, using a persistent
8845   // connection. Usually a proxy would return 501 (not implemented),
8846   // or 200 (tunnel established).
8847   MockRead data_reads1[] = {
8848       MockRead("HTTP/1.1 404 Not Found\r\n"),
8849       MockRead("Content-Length: 10\r\n\r\n"),
8850       MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
8851   };
8852 
8853   StaticSocketDataProvider data1(data_reads1, data_writes1);
8854   session_deps_.socket_factory->AddSocketDataProvider(&data1);
8855 
8856   TestCompletionCallback callback1;
8857 
8858   int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
8859   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8860 
8861   rv = callback1.WaitForResult();
8862   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
8863 
8864   // Empty the current queue.  This is necessary because idle sockets are
8865   // added to the connection pool asynchronously with a PostTask.
8866   base::RunLoop().RunUntilIdle();
8867 
8868   // We now check to make sure the TCPClientSocket was not added back to
8869   // the pool.
8870   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8871   trans.reset();
8872   base::RunLoop().RunUntilIdle();
8873   // Make sure that the socket didn't get recycled after calling the destructor.
8874   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8875 }
8876 
8877 // Make sure that we recycle a socket after reading all of the response body.
TEST_F(HttpNetworkTransactionTest,RecycleSocket)8878 TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
8879   HttpRequestInfo request;
8880   request.method = "GET";
8881   request.url = GURL("http://www.example.org/");
8882   request.traffic_annotation =
8883       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8884 
8885   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8886 
8887   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8888 
8889   MockRead data_reads[] = {
8890     // A part of the response body is received with the response headers.
8891     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8892     // The rest of the response body is received in two parts.
8893     MockRead("lo"),
8894     MockRead(" world"),
8895     MockRead("junk"),  // Should not be read!!
8896     MockRead(SYNCHRONOUS, OK),
8897   };
8898 
8899   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
8900   session_deps_.socket_factory->AddSocketDataProvider(&data);
8901 
8902   TestCompletionCallback callback;
8903 
8904   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8905   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8906 
8907   rv = callback.WaitForResult();
8908   EXPECT_THAT(rv, IsOk());
8909 
8910   const HttpResponseInfo* response = trans.GetResponseInfo();
8911   ASSERT_TRUE(response);
8912 
8913   EXPECT_TRUE(response->headers);
8914   std::string status_line = response->headers->GetStatusLine();
8915   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8916 
8917   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8918 
8919   std::string response_data;
8920   rv = ReadTransaction(&trans, &response_data);
8921   EXPECT_THAT(rv, IsOk());
8922   EXPECT_EQ("hello world", response_data);
8923 
8924   // Empty the current queue.  This is necessary because idle sockets are
8925   // added to the connection pool asynchronously with a PostTask.
8926   base::RunLoop().RunUntilIdle();
8927 
8928   // We now check to make sure the socket was added back to the pool.
8929   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8930 }
8931 
8932 // Make sure that we recycle a SSL socket after reading all of the response
8933 // body.
TEST_F(HttpNetworkTransactionTest,RecycleSSLSocket)8934 TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
8935   HttpRequestInfo request;
8936   request.method = "GET";
8937   request.url = GURL("https://www.example.org/");
8938   request.traffic_annotation =
8939       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8940 
8941   MockWrite data_writes[] = {
8942       MockWrite(
8943           "GET / HTTP/1.1\r\n"
8944           "Host: www.example.org\r\n"
8945           "Connection: keep-alive\r\n\r\n"),
8946   };
8947 
8948   MockRead data_reads[] = {
8949     MockRead("HTTP/1.1 200 OK\r\n"),
8950     MockRead("Content-Length: 11\r\n\r\n"),
8951     MockRead("hello world"),
8952     MockRead(SYNCHRONOUS, OK),
8953   };
8954 
8955   SSLSocketDataProvider ssl(ASYNC, OK);
8956   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8957 
8958   StaticSocketDataProvider data(data_reads, data_writes);
8959   session_deps_.socket_factory->AddSocketDataProvider(&data);
8960 
8961   TestCompletionCallback callback;
8962 
8963   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8964   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8965 
8966   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8967 
8968   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8969   EXPECT_THAT(callback.WaitForResult(), IsOk());
8970 
8971   const HttpResponseInfo* response = trans.GetResponseInfo();
8972   ASSERT_TRUE(response);
8973   ASSERT_TRUE(response->headers);
8974   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8975 
8976   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8977 
8978   std::string response_data;
8979   rv = ReadTransaction(&trans, &response_data);
8980   EXPECT_THAT(rv, IsOk());
8981   EXPECT_EQ("hello world", response_data);
8982 
8983   // Empty the current queue.  This is necessary because idle sockets are
8984   // added to the connection pool asynchronously with a PostTask.
8985   base::RunLoop().RunUntilIdle();
8986 
8987   // We now check to make sure the socket was added back to the pool.
8988   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8989 }
8990 
8991 // Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
8992 // from the pool and make sure that we recover okay.
TEST_F(HttpNetworkTransactionTest,RecycleDeadSSLSocket)8993 TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
8994   HttpRequestInfo request;
8995   request.method = "GET";
8996   request.url = GURL("https://www.example.org/");
8997   request.traffic_annotation =
8998       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8999 
9000   MockWrite data_writes[] = {
9001       MockWrite(
9002           "GET / HTTP/1.1\r\n"
9003           "Host: www.example.org\r\n"
9004           "Connection: keep-alive\r\n\r\n"),
9005       MockWrite(
9006           "GET / HTTP/1.1\r\n"
9007           "Host: www.example.org\r\n"
9008           "Connection: keep-alive\r\n\r\n"),
9009   };
9010 
9011   MockRead data_reads[] = {
9012       MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
9013       MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
9014 
9015   SSLSocketDataProvider ssl(ASYNC, OK);
9016   SSLSocketDataProvider ssl2(ASYNC, OK);
9017   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9018   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
9019 
9020   StaticSocketDataProvider data(data_reads, data_writes);
9021   StaticSocketDataProvider data2(data_reads, data_writes);
9022   session_deps_.socket_factory->AddSocketDataProvider(&data);
9023   session_deps_.socket_factory->AddSocketDataProvider(&data2);
9024 
9025   TestCompletionCallback callback;
9026 
9027   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9028   auto trans =
9029       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
9030 
9031   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
9032 
9033   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9034   EXPECT_THAT(callback.WaitForResult(), IsOk());
9035 
9036   const HttpResponseInfo* response = trans->GetResponseInfo();
9037   ASSERT_TRUE(response);
9038   ASSERT_TRUE(response->headers);
9039   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9040 
9041   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
9042 
9043   std::string response_data;
9044   rv = ReadTransaction(trans.get(), &response_data);
9045   EXPECT_THAT(rv, IsOk());
9046   EXPECT_EQ("hello world", response_data);
9047 
9048   // Empty the current queue.  This is necessary because idle sockets are
9049   // added to the connection pool asynchronously with a PostTask.
9050   base::RunLoop().RunUntilIdle();
9051 
9052   // We now check to make sure the socket was added back to the pool.
9053   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
9054 
9055   // Now start the second transaction, which should reuse the previous socket.
9056 
9057   trans =
9058       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
9059 
9060   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
9061 
9062   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9063   EXPECT_THAT(callback.WaitForResult(), IsOk());
9064 
9065   response = trans->GetResponseInfo();
9066   ASSERT_TRUE(response);
9067   ASSERT_TRUE(response->headers);
9068   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9069 
9070   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
9071 
9072   rv = ReadTransaction(trans.get(), &response_data);
9073   EXPECT_THAT(rv, IsOk());
9074   EXPECT_EQ("hello world", response_data);
9075 
9076   // Empty the current queue.  This is necessary because idle sockets are
9077   // added to the connection pool asynchronously with a PostTask.
9078   base::RunLoop().RunUntilIdle();
9079 
9080   // We now check to make sure the socket was added back to the pool.
9081   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
9082 }
9083 
9084 // Grab a socket, use it, and put it back into the pool. Then, make
9085 // low memory notification and ensure the socket pool is flushed.
TEST_F(HttpNetworkTransactionTest,FlushSocketPoolOnLowMemoryNotifications)9086 TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
9087   HttpRequestInfo request;
9088   request.method = "GET";
9089   request.url = GURL("http://www.example.org/");
9090   request.load_flags = 0;
9091   request.traffic_annotation =
9092       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9093 
9094   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9095 
9096   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9097 
9098   MockRead data_reads[] = {
9099       // A part of the response body is received with the response headers.
9100       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
9101       // The rest of the response body is received in two parts.
9102       MockRead("lo"), MockRead(" world"),
9103       MockRead("junk"),  // Should not be read!!
9104       MockRead(SYNCHRONOUS, OK),
9105   };
9106 
9107   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
9108   session_deps_.socket_factory->AddSocketDataProvider(&data);
9109 
9110   TestCompletionCallback callback;
9111 
9112   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9113   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9114 
9115   EXPECT_THAT(callback.GetResult(rv), IsOk());
9116 
9117   const HttpResponseInfo* response = trans.GetResponseInfo();
9118   ASSERT_TRUE(response);
9119   EXPECT_TRUE(response->headers);
9120   std::string status_line = response->headers->GetStatusLine();
9121   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
9122 
9123   // Make memory critical notification and ensure the transaction still has been
9124   // operating right.
9125   base::MemoryPressureListener::NotifyMemoryPressure(
9126       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
9127   base::RunLoop().RunUntilIdle();
9128 
9129   // Socket should not be flushed as long as it is not idle.
9130   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
9131 
9132   std::string response_data;
9133   rv = ReadTransaction(&trans, &response_data);
9134   EXPECT_THAT(rv, IsOk());
9135   EXPECT_EQ("hello world", response_data);
9136 
9137   // Empty the current queue.  This is necessary because idle sockets are
9138   // added to the connection pool asynchronously with a PostTask.
9139   base::RunLoop().RunUntilIdle();
9140 
9141   // We now check to make sure the socket was added back to the pool.
9142   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
9143 
9144   // Idle sockets should be flushed now.
9145   base::MemoryPressureListener::NotifyMemoryPressure(
9146       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
9147   base::RunLoop().RunUntilIdle();
9148 
9149   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
9150 }
9151 
9152 // Disable idle socket closing on memory pressure.
9153 // Grab a socket, use it, and put it back into the pool. Then, make
9154 // low memory notification and ensure the socket pool is NOT flushed.
TEST_F(HttpNetworkTransactionTest,NoFlushSocketPoolOnLowMemoryNotifications)9155 TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
9156   HttpRequestInfo request;
9157   request.method = "GET";
9158   request.url = GURL("http://www.example.org/");
9159   request.load_flags = 0;
9160   request.traffic_annotation =
9161       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9162 
9163   // Disable idle socket closing on memory pressure.
9164   session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
9165   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9166 
9167   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9168 
9169   MockRead data_reads[] = {
9170       // A part of the response body is received with the response headers.
9171       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
9172       // The rest of the response body is received in two parts.
9173       MockRead("lo"), MockRead(" world"),
9174       MockRead("junk"),  // Should not be read!!
9175       MockRead(SYNCHRONOUS, OK),
9176   };
9177 
9178   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
9179   session_deps_.socket_factory->AddSocketDataProvider(&data);
9180 
9181   TestCompletionCallback callback;
9182 
9183   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9184   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9185 
9186   EXPECT_THAT(callback.GetResult(rv), IsOk());
9187 
9188   const HttpResponseInfo* response = trans.GetResponseInfo();
9189   ASSERT_TRUE(response);
9190   EXPECT_TRUE(response->headers);
9191   std::string status_line = response->headers->GetStatusLine();
9192   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
9193 
9194   // Make memory critical notification and ensure the transaction still has been
9195   // operating right.
9196   base::MemoryPressureListener::NotifyMemoryPressure(
9197       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
9198   base::RunLoop().RunUntilIdle();
9199 
9200   // Socket should not be flushed as long as it is not idle.
9201   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
9202 
9203   std::string response_data;
9204   rv = ReadTransaction(&trans, &response_data);
9205   EXPECT_THAT(rv, IsOk());
9206   EXPECT_EQ("hello world", response_data);
9207 
9208   // Empty the current queue.  This is necessary because idle sockets are
9209   // added to the connection pool asynchronously with a PostTask.
9210   base::RunLoop().RunUntilIdle();
9211 
9212   // We now check to make sure the socket was added back to the pool.
9213   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
9214 
9215   // Idle sockets should NOT be flushed on moderate memory pressure.
9216   base::MemoryPressureListener::NotifyMemoryPressure(
9217       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
9218   base::RunLoop().RunUntilIdle();
9219 
9220   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
9221 
9222   // Idle sockets should NOT be flushed on critical memory pressure.
9223   base::MemoryPressureListener::NotifyMemoryPressure(
9224       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
9225   base::RunLoop().RunUntilIdle();
9226 
9227   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
9228 }
9229 
9230 // Grab an SSL socket, use it, and put it back into the pool. Then, make
9231 // low memory notification and ensure the socket pool is flushed.
TEST_F(HttpNetworkTransactionTest,FlushSSLSocketPoolOnLowMemoryNotifications)9232 TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
9233   HttpRequestInfo request;
9234   request.method = "GET";
9235   request.url = GURL("https://www.example.org/");
9236   request.load_flags = 0;
9237   request.traffic_annotation =
9238       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9239 
9240   MockWrite data_writes[] = {
9241       MockWrite("GET / HTTP/1.1\r\n"
9242                 "Host: www.example.org\r\n"
9243                 "Connection: keep-alive\r\n\r\n"),
9244   };
9245 
9246   MockRead data_reads[] = {
9247       MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
9248       MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
9249 
9250   SSLSocketDataProvider ssl(ASYNC, OK);
9251   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9252 
9253   StaticSocketDataProvider data(data_reads, data_writes);
9254   session_deps_.socket_factory->AddSocketDataProvider(&data);
9255 
9256   TestCompletionCallback callback;
9257 
9258   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9259   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9260 
9261   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
9262   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9263 
9264   EXPECT_THAT(callback.GetResult(rv), IsOk());
9265 
9266   const HttpResponseInfo* response = trans.GetResponseInfo();
9267   ASSERT_TRUE(response);
9268   ASSERT_TRUE(response->headers);
9269   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9270 
9271   // Make memory critical notification and ensure the transaction still has been
9272   // operating right.
9273   base::MemoryPressureListener::NotifyMemoryPressure(
9274       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
9275   base::RunLoop().RunUntilIdle();
9276 
9277   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
9278 
9279   std::string response_data;
9280   rv = ReadTransaction(&trans, &response_data);
9281   EXPECT_THAT(rv, IsOk());
9282   EXPECT_EQ("hello world", response_data);
9283 
9284   // Empty the current queue.  This is necessary because idle sockets are
9285   // added to the connection pool asynchronously with a PostTask.
9286   base::RunLoop().RunUntilIdle();
9287 
9288   // We now check to make sure the socket was added back to the pool.
9289   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
9290 
9291   // Make memory notification once again and ensure idle socket is closed.
9292   base::MemoryPressureListener::NotifyMemoryPressure(
9293       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
9294   base::RunLoop().RunUntilIdle();
9295 
9296   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
9297 }
9298 
9299 // Make sure that we recycle a socket after a zero-length response.
9300 // http://crbug.com/9880
TEST_F(HttpNetworkTransactionTest,RecycleSocketAfterZeroContentLength)9301 TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
9302   HttpRequestInfo request;
9303   request.method = "GET";
9304   request.url = GURL(
9305       "http://www.example.org/csi?v=3&s=web&action=&"
9306       "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
9307       "e=17259,18167,19592,19773,19981,20133,20173,20233&"
9308       "rt=prt.2642,ol.2649,xjs.2951");
9309   request.traffic_annotation =
9310       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9311 
9312   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9313 
9314   MockRead data_reads[] = {
9315     MockRead("HTTP/1.1 204 No Content\r\n"
9316              "Content-Length: 0\r\n"
9317              "Content-Type: text/html\r\n\r\n"),
9318     MockRead("junk"),  // Should not be read!!
9319     MockRead(SYNCHRONOUS, OK),
9320   };
9321 
9322   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
9323   session_deps_.socket_factory->AddSocketDataProvider(&data);
9324 
9325   // Transaction must be created after the MockReads, so it's destroyed before
9326   // them.
9327   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9328 
9329   TestCompletionCallback callback;
9330 
9331   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9332   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9333 
9334   rv = callback.WaitForResult();
9335   EXPECT_THAT(rv, IsOk());
9336 
9337   const HttpResponseInfo* response = trans.GetResponseInfo();
9338   ASSERT_TRUE(response);
9339 
9340   EXPECT_TRUE(response->headers);
9341   std::string status_line = response->headers->GetStatusLine();
9342   EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
9343 
9344   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
9345 
9346   std::string response_data;
9347   rv = ReadTransaction(&trans, &response_data);
9348   EXPECT_THAT(rv, IsOk());
9349   EXPECT_EQ("", response_data);
9350 
9351   // Empty the current queue.  This is necessary because idle sockets are
9352   // added to the connection pool asynchronously with a PostTask.
9353   base::RunLoop().RunUntilIdle();
9354 
9355   // We now check to make sure the socket was added back to the pool.
9356   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
9357 }
9358 
TEST_F(HttpNetworkTransactionTest,ResendRequestOnWriteBodyError)9359 TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
9360   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9361   element_readers.push_back(
9362       std::make_unique<UploadBytesElementReader>("foo", 3));
9363   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
9364 
9365   HttpRequestInfo request[2];
9366   // Transaction 1: a GET request that succeeds.  The socket is recycled
9367   // after use.
9368   request[0].method = "GET";
9369   request[0].url = GURL("http://www.google.com/");
9370   request[0].load_flags = 0;
9371   request[0].traffic_annotation =
9372       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9373   // Transaction 2: a POST request.  Reuses the socket kept alive from
9374   // transaction 1.  The first attempts fails when writing the POST data.
9375   // This causes the transaction to retry with a new socket.  The second
9376   // attempt succeeds.
9377   request[1].method = "POST";
9378   request[1].url = GURL("http://www.google.com/login.cgi");
9379   request[1].upload_data_stream = &upload_data_stream;
9380   request[1].load_flags = 0;
9381   request[1].traffic_annotation =
9382       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9383 
9384   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9385 
9386   // The first socket is used for transaction 1 and the first attempt of
9387   // transaction 2.
9388 
9389   // The response of transaction 1.
9390   MockRead data_reads1[] = {
9391     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
9392     MockRead("hello world"),
9393     MockRead(SYNCHRONOUS, OK),
9394   };
9395   // The mock write results of transaction 1 and the first attempt of
9396   // transaction 2.
9397   MockWrite data_writes1[] = {
9398     MockWrite(SYNCHRONOUS, 64),  // GET
9399     MockWrite(SYNCHRONOUS, 93),  // POST
9400     MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
9401   };
9402   StaticSocketDataProvider data1(data_reads1, data_writes1);
9403 
9404   // The second socket is used for the second attempt of transaction 2.
9405 
9406   // The response of transaction 2.
9407   MockRead data_reads2[] = {
9408     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
9409     MockRead("welcome"),
9410     MockRead(SYNCHRONOUS, OK),
9411   };
9412   // The mock write results of the second attempt of transaction 2.
9413   MockWrite data_writes2[] = {
9414     MockWrite(SYNCHRONOUS, 93),  // POST
9415     MockWrite(SYNCHRONOUS, 3),  // POST data
9416   };
9417   StaticSocketDataProvider data2(data_reads2, data_writes2);
9418 
9419   session_deps_.socket_factory->AddSocketDataProvider(&data1);
9420   session_deps_.socket_factory->AddSocketDataProvider(&data2);
9421 
9422   const char* const kExpectedResponseData[] = {
9423     "hello world", "welcome"
9424   };
9425 
9426   for (int i = 0; i < 2; ++i) {
9427     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9428 
9429     TestCompletionCallback callback;
9430 
9431     int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
9432     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9433 
9434     rv = callback.WaitForResult();
9435     EXPECT_THAT(rv, IsOk());
9436 
9437     const HttpResponseInfo* response = trans.GetResponseInfo();
9438     ASSERT_TRUE(response);
9439 
9440     EXPECT_TRUE(response->headers);
9441     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9442 
9443     std::string response_data;
9444     rv = ReadTransaction(&trans, &response_data);
9445     EXPECT_THAT(rv, IsOk());
9446     EXPECT_EQ(kExpectedResponseData[i], response_data);
9447   }
9448 }
9449 
9450 // Test the request-challenge-retry sequence for basic auth when there is
9451 // an identity in the URL. The request should be sent as normal, but when
9452 // it fails the identity from the URL is used to answer the challenge.
TEST_F(HttpNetworkTransactionTest,AuthIdentityInURL)9453 TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
9454   HttpRequestInfo request;
9455   request.method = "GET";
9456   request.url = GURL("http://foo:b@r@www.example.org/");
9457   request.load_flags = LOAD_NORMAL;
9458   request.traffic_annotation =
9459       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9460 
9461   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9462   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9463 
9464   // The password contains an escaped character -- for this test to pass it
9465   // will need to be unescaped by HttpNetworkTransaction.
9466   EXPECT_EQ("b%40r", request.url.password());
9467 
9468   MockWrite data_writes1[] = {
9469       MockWrite(
9470           "GET / HTTP/1.1\r\n"
9471           "Host: www.example.org\r\n"
9472           "Connection: keep-alive\r\n\r\n"),
9473   };
9474 
9475   MockRead data_reads1[] = {
9476     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9477     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9478     MockRead("Content-Length: 10\r\n\r\n"),
9479     MockRead(SYNCHRONOUS, ERR_FAILED),
9480   };
9481 
9482   // After the challenge above, the transaction will be restarted using the
9483   // identity from the url (foo, b@r) to answer the challenge.
9484   MockWrite data_writes2[] = {
9485       MockWrite(
9486           "GET / HTTP/1.1\r\n"
9487           "Host: www.example.org\r\n"
9488           "Connection: keep-alive\r\n"
9489           "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
9490   };
9491 
9492   MockRead data_reads2[] = {
9493     MockRead("HTTP/1.0 200 OK\r\n"),
9494     MockRead("Content-Length: 100\r\n\r\n"),
9495     MockRead(SYNCHRONOUS, OK),
9496   };
9497 
9498   StaticSocketDataProvider data1(data_reads1, data_writes1);
9499   StaticSocketDataProvider data2(data_reads2, data_writes2);
9500   session_deps_.socket_factory->AddSocketDataProvider(&data1);
9501   session_deps_.socket_factory->AddSocketDataProvider(&data2);
9502 
9503   TestCompletionCallback callback1;
9504   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
9505   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9506   rv = callback1.WaitForResult();
9507   EXPECT_THAT(rv, IsOk());
9508   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
9509 
9510   TestCompletionCallback callback2;
9511   rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
9512   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9513   rv = callback2.WaitForResult();
9514   EXPECT_THAT(rv, IsOk());
9515   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
9516 
9517   const HttpResponseInfo* response = trans.GetResponseInfo();
9518   ASSERT_TRUE(response);
9519 
9520   // There is no challenge info, since the identity in URL worked.
9521   EXPECT_FALSE(response->auth_challenge.has_value());
9522 
9523   EXPECT_EQ(100, response->headers->GetContentLength());
9524 
9525   // Empty the current queue.
9526   base::RunLoop().RunUntilIdle();
9527 }
9528 
9529 // Test the request-challenge-retry sequence for basic auth when there is an
9530 // incorrect identity in the URL. The identity from the URL should be used only
9531 // once.
TEST_F(HttpNetworkTransactionTest,WrongAuthIdentityInURL)9532 TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
9533   HttpRequestInfo request;
9534   request.method = "GET";
9535   // Note: the URL has a username:password in it.  The password "baz" is
9536   // wrong (should be "bar").
9537   request.url = GURL("http://foo:baz@www.example.org/");
9538 
9539   request.load_flags = LOAD_NORMAL;
9540   request.traffic_annotation =
9541       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9542 
9543   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9544   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9545 
9546   MockWrite data_writes1[] = {
9547       MockWrite(
9548           "GET / HTTP/1.1\r\n"
9549           "Host: www.example.org\r\n"
9550           "Connection: keep-alive\r\n\r\n"),
9551   };
9552 
9553   MockRead data_reads1[] = {
9554     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9555     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9556     MockRead("Content-Length: 10\r\n\r\n"),
9557     MockRead(SYNCHRONOUS, ERR_FAILED),
9558   };
9559 
9560   // After the challenge above, the transaction will be restarted using the
9561   // identity from the url (foo, baz) to answer the challenge.
9562   MockWrite data_writes2[] = {
9563       MockWrite(
9564           "GET / HTTP/1.1\r\n"
9565           "Host: www.example.org\r\n"
9566           "Connection: keep-alive\r\n"
9567           "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
9568   };
9569 
9570   MockRead data_reads2[] = {
9571     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9572     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9573     MockRead("Content-Length: 10\r\n\r\n"),
9574     MockRead(SYNCHRONOUS, ERR_FAILED),
9575   };
9576 
9577   // After the challenge above, the transaction will be restarted using the
9578   // identity supplied by the user (foo, bar) to answer the challenge.
9579   MockWrite data_writes3[] = {
9580       MockWrite(
9581           "GET / HTTP/1.1\r\n"
9582           "Host: www.example.org\r\n"
9583           "Connection: keep-alive\r\n"
9584           "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
9585   };
9586 
9587   MockRead data_reads3[] = {
9588     MockRead("HTTP/1.0 200 OK\r\n"),
9589     MockRead("Content-Length: 100\r\n\r\n"),
9590     MockRead(SYNCHRONOUS, OK),
9591   };
9592 
9593   StaticSocketDataProvider data1(data_reads1, data_writes1);
9594   StaticSocketDataProvider data2(data_reads2, data_writes2);
9595   StaticSocketDataProvider data3(data_reads3, data_writes3);
9596   session_deps_.socket_factory->AddSocketDataProvider(&data1);
9597   session_deps_.socket_factory->AddSocketDataProvider(&data2);
9598   session_deps_.socket_factory->AddSocketDataProvider(&data3);
9599 
9600   TestCompletionCallback callback1;
9601 
9602   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
9603   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9604 
9605   rv = callback1.WaitForResult();
9606   EXPECT_THAT(rv, IsOk());
9607 
9608   EXPECT_TRUE(trans.IsReadyToRestartForAuth());
9609   TestCompletionCallback callback2;
9610   rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
9611   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9612   rv = callback2.WaitForResult();
9613   EXPECT_THAT(rv, IsOk());
9614   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
9615 
9616   const HttpResponseInfo* response = trans.GetResponseInfo();
9617   ASSERT_TRUE(response);
9618   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
9619 
9620   TestCompletionCallback callback3;
9621   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
9622   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9623   rv = callback3.WaitForResult();
9624   EXPECT_THAT(rv, IsOk());
9625   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
9626 
9627   response = trans.GetResponseInfo();
9628   ASSERT_TRUE(response);
9629 
9630   // There is no challenge info, since the identity worked.
9631   EXPECT_FALSE(response->auth_challenge.has_value());
9632 
9633   EXPECT_EQ(100, response->headers->GetContentLength());
9634 
9635   // Empty the current queue.
9636   base::RunLoop().RunUntilIdle();
9637 }
9638 
9639 
9640 // Test the request-challenge-retry sequence for basic auth when there is a
9641 // correct identity in the URL, but its use is being suppressed. The identity
9642 // from the URL should never be used.
TEST_F(HttpNetworkTransactionTest,AuthIdentityInURLSuppressed)9643 TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
9644   HttpRequestInfo request;
9645   request.method = "GET";
9646   request.url = GURL("http://foo:bar@www.example.org/");
9647   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
9648   request.traffic_annotation =
9649       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9650 
9651   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9652   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9653 
9654   MockWrite data_writes1[] = {
9655       MockWrite(
9656           "GET / HTTP/1.1\r\n"
9657           "Host: www.example.org\r\n"
9658           "Connection: keep-alive\r\n\r\n"),
9659   };
9660 
9661   MockRead data_reads1[] = {
9662     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9663     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9664     MockRead("Content-Length: 10\r\n\r\n"),
9665     MockRead(SYNCHRONOUS, ERR_FAILED),
9666   };
9667 
9668   // After the challenge above, the transaction will be restarted using the
9669   // identity supplied by the user, not the one in the URL, to answer the
9670   // challenge.
9671   MockWrite data_writes3[] = {
9672       MockWrite(
9673           "GET / HTTP/1.1\r\n"
9674           "Host: www.example.org\r\n"
9675           "Connection: keep-alive\r\n"
9676           "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
9677   };
9678 
9679   MockRead data_reads3[] = {
9680     MockRead("HTTP/1.0 200 OK\r\n"),
9681     MockRead("Content-Length: 100\r\n\r\n"),
9682     MockRead(SYNCHRONOUS, OK),
9683   };
9684 
9685   StaticSocketDataProvider data1(data_reads1, data_writes1);
9686   StaticSocketDataProvider data3(data_reads3, data_writes3);
9687   session_deps_.socket_factory->AddSocketDataProvider(&data1);
9688   session_deps_.socket_factory->AddSocketDataProvider(&data3);
9689 
9690   TestCompletionCallback callback1;
9691   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
9692   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9693   rv = callback1.WaitForResult();
9694   EXPECT_THAT(rv, IsOk());
9695   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
9696 
9697   const HttpResponseInfo* response = trans.GetResponseInfo();
9698   ASSERT_TRUE(response);
9699   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
9700 
9701   TestCompletionCallback callback3;
9702   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
9703   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9704   rv = callback3.WaitForResult();
9705   EXPECT_THAT(rv, IsOk());
9706   EXPECT_FALSE(trans.IsReadyToRestartForAuth());
9707 
9708   response = trans.GetResponseInfo();
9709   ASSERT_TRUE(response);
9710 
9711   // There is no challenge info, since the identity worked.
9712   EXPECT_FALSE(response->auth_challenge.has_value());
9713   EXPECT_EQ(100, response->headers->GetContentLength());
9714 
9715   // Empty the current queue.
9716   base::RunLoop().RunUntilIdle();
9717 }
9718 
9719 // Test that previously tried username/passwords for a realm get re-used.
TEST_F(HttpNetworkTransactionTest,BasicAuthCacheAndPreauth)9720 TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
9721   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9722 
9723   // Transaction 1: authenticate (foo, bar) on MyRealm1
9724   {
9725     HttpRequestInfo request;
9726     request.method = "GET";
9727     request.url = GURL("http://www.example.org/x/y/z");
9728     request.traffic_annotation =
9729         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9730 
9731     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9732 
9733     MockWrite data_writes1[] = {
9734         MockWrite(
9735             "GET /x/y/z HTTP/1.1\r\n"
9736             "Host: www.example.org\r\n"
9737             "Connection: keep-alive\r\n\r\n"),
9738     };
9739 
9740     MockRead data_reads1[] = {
9741       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9742       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9743       MockRead("Content-Length: 10000\r\n\r\n"),
9744       MockRead(SYNCHRONOUS, ERR_FAILED),
9745     };
9746 
9747     // Resend with authorization (username=foo, password=bar)
9748     MockWrite data_writes2[] = {
9749         MockWrite(
9750             "GET /x/y/z HTTP/1.1\r\n"
9751             "Host: www.example.org\r\n"
9752             "Connection: keep-alive\r\n"
9753             "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
9754     };
9755 
9756     // Sever accepts the authorization.
9757     MockRead data_reads2[] = {
9758       MockRead("HTTP/1.0 200 OK\r\n"),
9759       MockRead("Content-Length: 100\r\n\r\n"),
9760       MockRead(SYNCHRONOUS, OK),
9761     };
9762 
9763     StaticSocketDataProvider data1(data_reads1, data_writes1);
9764     StaticSocketDataProvider data2(data_reads2, data_writes2);
9765     session_deps_.socket_factory->AddSocketDataProvider(&data1);
9766     session_deps_.socket_factory->AddSocketDataProvider(&data2);
9767 
9768     TestCompletionCallback callback1;
9769 
9770     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
9771     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9772 
9773     rv = callback1.WaitForResult();
9774     EXPECT_THAT(rv, IsOk());
9775 
9776     const HttpResponseInfo* response = trans.GetResponseInfo();
9777     ASSERT_TRUE(response);
9778     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
9779 
9780     TestCompletionCallback callback2;
9781 
9782     rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
9783                                callback2.callback());
9784     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9785 
9786     rv = callback2.WaitForResult();
9787     EXPECT_THAT(rv, IsOk());
9788 
9789     response = trans.GetResponseInfo();
9790     ASSERT_TRUE(response);
9791     EXPECT_FALSE(response->auth_challenge.has_value());
9792     EXPECT_EQ(100, response->headers->GetContentLength());
9793   }
9794 
9795   // ------------------------------------------------------------------------
9796 
9797   // Transaction 2: authenticate (foo2, bar2) on MyRealm2
9798   {
9799     HttpRequestInfo request;
9800     request.method = "GET";
9801     // Note that Transaction 1 was at /x/y/z, so this is in the same
9802     // protection space as MyRealm1.
9803     request.url = GURL("http://www.example.org/x/y/a/b");
9804     request.traffic_annotation =
9805         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9806 
9807     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9808 
9809     MockWrite data_writes1[] = {
9810         MockWrite(
9811             "GET /x/y/a/b HTTP/1.1\r\n"
9812             "Host: www.example.org\r\n"
9813             "Connection: keep-alive\r\n"
9814             // Send preemptive authorization for MyRealm1
9815             "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
9816     };
9817 
9818     // The server didn't like the preemptive authorization, and
9819     // challenges us for a different realm (MyRealm2).
9820     MockRead data_reads1[] = {
9821       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9822       MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
9823       MockRead("Content-Length: 10000\r\n\r\n"),
9824       MockRead(SYNCHRONOUS, ERR_FAILED),
9825     };
9826 
9827     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
9828     MockWrite data_writes2[] = {
9829         MockWrite(
9830             "GET /x/y/a/b HTTP/1.1\r\n"
9831             "Host: www.example.org\r\n"
9832             "Connection: keep-alive\r\n"
9833             "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
9834     };
9835 
9836     // Sever accepts the authorization.
9837     MockRead data_reads2[] = {
9838       MockRead("HTTP/1.0 200 OK\r\n"),
9839       MockRead("Content-Length: 100\r\n\r\n"),
9840       MockRead(SYNCHRONOUS, OK),
9841     };
9842 
9843     StaticSocketDataProvider data1(data_reads1, data_writes1);
9844     StaticSocketDataProvider data2(data_reads2, data_writes2);
9845     session_deps_.socket_factory->AddSocketDataProvider(&data1);
9846     session_deps_.socket_factory->AddSocketDataProvider(&data2);
9847 
9848     TestCompletionCallback callback1;
9849 
9850     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
9851     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9852 
9853     rv = callback1.WaitForResult();
9854     EXPECT_THAT(rv, IsOk());
9855 
9856     const HttpResponseInfo* response = trans.GetResponseInfo();
9857     ASSERT_TRUE(response);
9858     ASSERT_TRUE(response->auth_challenge);
9859     EXPECT_FALSE(response->auth_challenge->is_proxy);
9860     EXPECT_EQ("http://www.example.org",
9861               response->auth_challenge->challenger.Serialize());
9862     EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
9863     EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
9864 
9865     TestCompletionCallback callback2;
9866 
9867     rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
9868                                callback2.callback());
9869     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9870 
9871     rv = callback2.WaitForResult();
9872     EXPECT_THAT(rv, IsOk());
9873 
9874     response = trans.GetResponseInfo();
9875     ASSERT_TRUE(response);
9876     EXPECT_FALSE(response->auth_challenge.has_value());
9877     EXPECT_EQ(100, response->headers->GetContentLength());
9878   }
9879 
9880   // ------------------------------------------------------------------------
9881 
9882   // Transaction 3: Resend a request in MyRealm's protection space --
9883   // succeed with preemptive authorization.
9884   {
9885     HttpRequestInfo request;
9886     request.method = "GET";
9887     request.url = GURL("http://www.example.org/x/y/z2");
9888     request.traffic_annotation =
9889         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9890 
9891     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9892 
9893     MockWrite data_writes1[] = {
9894         MockWrite(
9895             "GET /x/y/z2 HTTP/1.1\r\n"
9896             "Host: www.example.org\r\n"
9897             "Connection: keep-alive\r\n"
9898             // The authorization for MyRealm1 gets sent preemptively
9899             // (since the url is in the same protection space)
9900             "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
9901     };
9902 
9903     // Sever accepts the preemptive authorization
9904     MockRead data_reads1[] = {
9905       MockRead("HTTP/1.0 200 OK\r\n"),
9906       MockRead("Content-Length: 100\r\n\r\n"),
9907       MockRead(SYNCHRONOUS, OK),
9908     };
9909 
9910     StaticSocketDataProvider data1(data_reads1, data_writes1);
9911     session_deps_.socket_factory->AddSocketDataProvider(&data1);
9912 
9913     TestCompletionCallback callback1;
9914 
9915     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
9916     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9917 
9918     rv = callback1.WaitForResult();
9919     EXPECT_THAT(rv, IsOk());
9920 
9921     const HttpResponseInfo* response = trans.GetResponseInfo();
9922     ASSERT_TRUE(response);
9923 
9924     EXPECT_FALSE(response->auth_challenge.has_value());
9925     EXPECT_EQ(100, response->headers->GetContentLength());
9926   }
9927 
9928   // ------------------------------------------------------------------------
9929 
9930   // Transaction 4: request another URL in MyRealm (however the
9931   // url is not known to belong to the protection space, so no pre-auth).
9932   {
9933     HttpRequestInfo request;
9934     request.method = "GET";
9935     request.url = GURL("http://www.example.org/x/1");
9936     request.traffic_annotation =
9937         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9938 
9939     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9940 
9941     MockWrite data_writes1[] = {
9942         MockWrite(
9943             "GET /x/1 HTTP/1.1\r\n"
9944             "Host: www.example.org\r\n"
9945             "Connection: keep-alive\r\n\r\n"),
9946     };
9947 
9948     MockRead data_reads1[] = {
9949       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9950       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9951       MockRead("Content-Length: 10000\r\n\r\n"),
9952       MockRead(SYNCHRONOUS, ERR_FAILED),
9953     };
9954 
9955     // Resend with authorization from MyRealm's cache.
9956     MockWrite data_writes2[] = {
9957         MockWrite(
9958             "GET /x/1 HTTP/1.1\r\n"
9959             "Host: www.example.org\r\n"
9960             "Connection: keep-alive\r\n"
9961             "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
9962     };
9963 
9964     // Sever accepts the authorization.
9965     MockRead data_reads2[] = {
9966       MockRead("HTTP/1.0 200 OK\r\n"),
9967       MockRead("Content-Length: 100\r\n\r\n"),
9968       MockRead(SYNCHRONOUS, OK),
9969     };
9970 
9971     StaticSocketDataProvider data1(data_reads1, data_writes1);
9972     StaticSocketDataProvider data2(data_reads2, data_writes2);
9973     session_deps_.socket_factory->AddSocketDataProvider(&data1);
9974     session_deps_.socket_factory->AddSocketDataProvider(&data2);
9975 
9976     TestCompletionCallback callback1;
9977 
9978     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
9979     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9980 
9981     rv = callback1.WaitForResult();
9982     EXPECT_THAT(rv, IsOk());
9983 
9984     EXPECT_TRUE(trans.IsReadyToRestartForAuth());
9985     TestCompletionCallback callback2;
9986     rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
9987     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9988     rv = callback2.WaitForResult();
9989     EXPECT_THAT(rv, IsOk());
9990     EXPECT_FALSE(trans.IsReadyToRestartForAuth());
9991 
9992     const HttpResponseInfo* response = trans.GetResponseInfo();
9993     ASSERT_TRUE(response);
9994     EXPECT_FALSE(response->auth_challenge.has_value());
9995     EXPECT_EQ(100, response->headers->GetContentLength());
9996   }
9997 
9998   // ------------------------------------------------------------------------
9999 
10000   // Transaction 5: request a URL in MyRealm, but the server rejects the
10001   // cached identity. Should invalidate and re-prompt.
10002   {
10003     HttpRequestInfo request;
10004     request.method = "GET";
10005     request.url = GURL("http://www.example.org/p/q/t");
10006     request.traffic_annotation =
10007         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10008 
10009     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10010 
10011     MockWrite data_writes1[] = {
10012         MockWrite(
10013             "GET /p/q/t HTTP/1.1\r\n"
10014             "Host: www.example.org\r\n"
10015             "Connection: keep-alive\r\n\r\n"),
10016     };
10017 
10018     MockRead data_reads1[] = {
10019       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
10020       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10021       MockRead("Content-Length: 10000\r\n\r\n"),
10022       MockRead(SYNCHRONOUS, ERR_FAILED),
10023     };
10024 
10025     // Resend with authorization from cache for MyRealm.
10026     MockWrite data_writes2[] = {
10027         MockWrite(
10028             "GET /p/q/t HTTP/1.1\r\n"
10029             "Host: www.example.org\r\n"
10030             "Connection: keep-alive\r\n"
10031             "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
10032     };
10033 
10034     // Sever rejects the authorization.
10035     MockRead data_reads2[] = {
10036       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
10037       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10038       MockRead("Content-Length: 10000\r\n\r\n"),
10039       MockRead(SYNCHRONOUS, ERR_FAILED),
10040     };
10041 
10042     // At this point we should prompt for new credentials for MyRealm.
10043     // Restart with username=foo3, password=foo4.
10044     MockWrite data_writes3[] = {
10045         MockWrite(
10046             "GET /p/q/t HTTP/1.1\r\n"
10047             "Host: www.example.org\r\n"
10048             "Connection: keep-alive\r\n"
10049             "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
10050     };
10051 
10052     // Sever accepts the authorization.
10053     MockRead data_reads3[] = {
10054       MockRead("HTTP/1.0 200 OK\r\n"),
10055       MockRead("Content-Length: 100\r\n\r\n"),
10056       MockRead(SYNCHRONOUS, OK),
10057     };
10058 
10059     StaticSocketDataProvider data1(data_reads1, data_writes1);
10060     StaticSocketDataProvider data2(data_reads2, data_writes2);
10061     StaticSocketDataProvider data3(data_reads3, data_writes3);
10062     session_deps_.socket_factory->AddSocketDataProvider(&data1);
10063     session_deps_.socket_factory->AddSocketDataProvider(&data2);
10064     session_deps_.socket_factory->AddSocketDataProvider(&data3);
10065 
10066     TestCompletionCallback callback1;
10067 
10068     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
10069     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10070 
10071     rv = callback1.WaitForResult();
10072     EXPECT_THAT(rv, IsOk());
10073 
10074     EXPECT_TRUE(trans.IsReadyToRestartForAuth());
10075     TestCompletionCallback callback2;
10076     rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
10077     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10078     rv = callback2.WaitForResult();
10079     EXPECT_THAT(rv, IsOk());
10080     EXPECT_FALSE(trans.IsReadyToRestartForAuth());
10081 
10082     const HttpResponseInfo* response = trans.GetResponseInfo();
10083     ASSERT_TRUE(response);
10084     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
10085 
10086     TestCompletionCallback callback3;
10087 
10088     rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
10089                                callback3.callback());
10090     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10091 
10092     rv = callback3.WaitForResult();
10093     EXPECT_THAT(rv, IsOk());
10094 
10095     response = trans.GetResponseInfo();
10096     ASSERT_TRUE(response);
10097     EXPECT_FALSE(response->auth_challenge.has_value());
10098     EXPECT_EQ(100, response->headers->GetContentLength());
10099   }
10100 }
10101 
10102 // Tests that nonce count increments when multiple auth attempts
10103 // are started with the same nonce.
TEST_F(HttpNetworkTransactionTest,DigestPreAuthNonceCount)10104 TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
10105   HttpAuthHandlerDigest::Factory* digest_factory =
10106       new HttpAuthHandlerDigest::Factory();
10107   HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
10108       new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
10109   digest_factory->set_nonce_generator(nonce_generator);
10110   session_deps_.http_auth_handler_factory.reset(digest_factory);
10111   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10112 
10113   // Transaction 1: authenticate (foo, bar) on MyRealm1
10114   {
10115     HttpRequestInfo request;
10116     request.method = "GET";
10117     request.url = GURL("http://www.example.org/x/y/z");
10118     request.traffic_annotation =
10119         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10120 
10121     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10122 
10123     MockWrite data_writes1[] = {
10124         MockWrite(
10125             "GET /x/y/z HTTP/1.1\r\n"
10126             "Host: www.example.org\r\n"
10127             "Connection: keep-alive\r\n\r\n"),
10128     };
10129 
10130     MockRead data_reads1[] = {
10131       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
10132       MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
10133                "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
10134       MockRead(SYNCHRONOUS, OK),
10135     };
10136 
10137     // Resend with authorization (username=foo, password=bar)
10138     MockWrite data_writes2[] = {
10139         MockWrite(
10140             "GET /x/y/z HTTP/1.1\r\n"
10141             "Host: www.example.org\r\n"
10142             "Connection: keep-alive\r\n"
10143             "Authorization: Digest username=\"foo\", realm=\"digestive\", "
10144             "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
10145             "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
10146             "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
10147     };
10148 
10149     // Sever accepts the authorization.
10150     MockRead data_reads2[] = {
10151       MockRead("HTTP/1.0 200 OK\r\n"),
10152       MockRead(SYNCHRONOUS, OK),
10153     };
10154 
10155     StaticSocketDataProvider data1(data_reads1, data_writes1);
10156     StaticSocketDataProvider data2(data_reads2, data_writes2);
10157     session_deps_.socket_factory->AddSocketDataProvider(&data1);
10158     session_deps_.socket_factory->AddSocketDataProvider(&data2);
10159 
10160     TestCompletionCallback callback1;
10161 
10162     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
10163     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10164 
10165     rv = callback1.WaitForResult();
10166     EXPECT_THAT(rv, IsOk());
10167 
10168     const HttpResponseInfo* response = trans.GetResponseInfo();
10169     ASSERT_TRUE(response);
10170     EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge));
10171 
10172     TestCompletionCallback callback2;
10173 
10174     rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
10175                                callback2.callback());
10176     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10177 
10178     rv = callback2.WaitForResult();
10179     EXPECT_THAT(rv, IsOk());
10180 
10181     response = trans.GetResponseInfo();
10182     ASSERT_TRUE(response);
10183     EXPECT_FALSE(response->auth_challenge.has_value());
10184   }
10185 
10186   // ------------------------------------------------------------------------
10187 
10188   // Transaction 2: Request another resource in digestive's protection space.
10189   // This will preemptively add an Authorization header which should have an
10190   // "nc" value of 2 (as compared to 1 in the first use.
10191   {
10192     HttpRequestInfo request;
10193     request.method = "GET";
10194     // Note that Transaction 1 was at /x/y/z, so this is in the same
10195     // protection space as digest.
10196     request.url = GURL("http://www.example.org/x/y/a/b");
10197     request.traffic_annotation =
10198         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10199 
10200     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10201 
10202     MockWrite data_writes1[] = {
10203         MockWrite(
10204             "GET /x/y/a/b HTTP/1.1\r\n"
10205             "Host: www.example.org\r\n"
10206             "Connection: keep-alive\r\n"
10207             "Authorization: Digest username=\"foo\", realm=\"digestive\", "
10208             "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
10209             "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
10210             "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
10211     };
10212 
10213     // Sever accepts the authorization.
10214     MockRead data_reads1[] = {
10215       MockRead("HTTP/1.0 200 OK\r\n"),
10216       MockRead("Content-Length: 100\r\n\r\n"),
10217       MockRead(SYNCHRONOUS, OK),
10218     };
10219 
10220     StaticSocketDataProvider data1(data_reads1, data_writes1);
10221     session_deps_.socket_factory->AddSocketDataProvider(&data1);
10222 
10223     TestCompletionCallback callback1;
10224 
10225     int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
10226     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10227 
10228     rv = callback1.WaitForResult();
10229     EXPECT_THAT(rv, IsOk());
10230 
10231     const HttpResponseInfo* response = trans.GetResponseInfo();
10232     ASSERT_TRUE(response);
10233     EXPECT_FALSE(response->auth_challenge.has_value());
10234   }
10235 }
10236 
10237 // Test the ResetStateForRestart() private method.
TEST_F(HttpNetworkTransactionTest,ResetStateForRestart)10238 TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
10239   // Create a transaction (the dependencies aren't important).
10240   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10241   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10242 
10243   // Setup some state (which we expect ResetStateForRestart() will clear).
10244   trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
10245   trans.read_buf_len_ = 15;
10246   trans.request_headers_.SetHeader("Authorization", "NTLM");
10247 
10248   // Setup state in response_
10249   HttpResponseInfo* response = &trans.response_;
10250   response->auth_challenge = base::nullopt;
10251   response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
10252   response->response_time = base::Time::Now();
10253   response->was_cached = true;  // (Wouldn't ever actually be true...)
10254 
10255   { // Setup state for response_.vary_data
10256     HttpRequestInfo request;
10257     std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
10258     std::replace(temp.begin(), temp.end(), '\n', '\0');
10259     scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
10260     request.extra_headers.SetHeader("Foo", "1");
10261     request.extra_headers.SetHeader("bar", "23");
10262     EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
10263   }
10264 
10265   // Cause the above state to be reset.
10266   trans.ResetStateForRestart();
10267 
10268   // Verify that the state that needed to be reset, has been reset.
10269   EXPECT_FALSE(trans.read_buf_);
10270   EXPECT_EQ(0, trans.read_buf_len_);
10271   EXPECT_TRUE(trans.request_headers_.IsEmpty());
10272   EXPECT_FALSE(response->auth_challenge.has_value());
10273   EXPECT_FALSE(response->headers);
10274   EXPECT_FALSE(response->was_cached);
10275   EXPECT_EQ(0U, response->ssl_info.cert_status);
10276   EXPECT_FALSE(response->vary_data.is_valid());
10277 }
10278 
10279 // Test HTTPS connections to a site with a bad certificate
TEST_F(HttpNetworkTransactionTest,HTTPSBadCertificate)10280 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
10281   HttpRequestInfo request;
10282   request.method = "GET";
10283   request.url = GURL("https://www.example.org/");
10284   request.traffic_annotation =
10285       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10286 
10287   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10288   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10289 
10290   MockWrite data_writes[] = {
10291       MockWrite(
10292           "GET / HTTP/1.1\r\n"
10293           "Host: www.example.org\r\n"
10294           "Connection: keep-alive\r\n\r\n"),
10295   };
10296 
10297   MockRead data_reads[] = {
10298     MockRead("HTTP/1.0 200 OK\r\n"),
10299     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10300     MockRead("Content-Length: 100\r\n\r\n"),
10301     MockRead(SYNCHRONOUS, OK),
10302   };
10303 
10304   StaticSocketDataProvider ssl_bad_certificate;
10305   StaticSocketDataProvider data(data_reads, data_writes);
10306   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10307   SSLSocketDataProvider ssl(ASYNC, OK);
10308 
10309   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10310   session_deps_.socket_factory->AddSocketDataProvider(&data);
10311   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
10312   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10313 
10314   TestCompletionCallback callback;
10315 
10316   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10317   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10318 
10319   rv = callback.WaitForResult();
10320   EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
10321 
10322   rv = trans.RestartIgnoringLastError(callback.callback());
10323   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10324 
10325   rv = callback.WaitForResult();
10326   EXPECT_THAT(rv, IsOk());
10327 
10328   const HttpResponseInfo* response = trans.GetResponseInfo();
10329 
10330   ASSERT_TRUE(response);
10331   EXPECT_EQ(100, response->headers->GetContentLength());
10332 }
10333 
10334 // Test HTTPS connections to a site with a bad certificate, going through a
10335 // proxy
TEST_F(HttpNetworkTransactionTest,HTTPSBadCertificateViaProxy)10336 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
10337   session_deps_.proxy_resolution_service =
10338       ConfiguredProxyResolutionService::CreateFixed(
10339           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10340 
10341   HttpRequestInfo request;
10342   request.method = "GET";
10343   request.url = GURL("https://www.example.org/");
10344   request.traffic_annotation =
10345       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10346 
10347   MockWrite proxy_writes[] = {
10348       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10349                 "Host: www.example.org:443\r\n"
10350                 "Proxy-Connection: keep-alive\r\n\r\n"),
10351   };
10352 
10353   MockRead proxy_reads[] = {
10354     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10355     MockRead(SYNCHRONOUS, OK)
10356   };
10357 
10358   MockWrite data_writes[] = {
10359       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10360                 "Host: www.example.org:443\r\n"
10361                 "Proxy-Connection: keep-alive\r\n\r\n"),
10362       MockWrite("GET / HTTP/1.1\r\n"
10363                 "Host: www.example.org\r\n"
10364                 "Connection: keep-alive\r\n\r\n"),
10365   };
10366 
10367   MockRead data_reads[] = {
10368     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10369     MockRead("HTTP/1.0 200 OK\r\n"),
10370     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10371     MockRead("Content-Length: 100\r\n\r\n"),
10372     MockRead(SYNCHRONOUS, OK),
10373   };
10374 
10375   StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
10376   StaticSocketDataProvider data(data_reads, data_writes);
10377   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10378   SSLSocketDataProvider ssl(ASYNC, OK);
10379 
10380   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10381   session_deps_.socket_factory->AddSocketDataProvider(&data);
10382   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
10383   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10384 
10385   TestCompletionCallback callback;
10386 
10387   for (int i = 0; i < 2; i++) {
10388     session_deps_.socket_factory->ResetNextMockIndexes();
10389 
10390     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10391     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10392 
10393     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10394     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10395 
10396     rv = callback.WaitForResult();
10397     EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
10398 
10399     rv = trans.RestartIgnoringLastError(callback.callback());
10400     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10401 
10402     rv = callback.WaitForResult();
10403     EXPECT_THAT(rv, IsOk());
10404 
10405     const HttpResponseInfo* response = trans.GetResponseInfo();
10406 
10407     ASSERT_TRUE(response);
10408     EXPECT_EQ(100, response->headers->GetContentLength());
10409   }
10410 }
10411 
10412 
10413 // Test HTTPS connections to a site, going through an HTTPS proxy
TEST_F(HttpNetworkTransactionTest,HTTPSViaHttpsProxy)10414 TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
10415   session_deps_.proxy_resolution_service =
10416       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
10417           "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10418   RecordingTestNetLog net_log;
10419   session_deps_.net_log = &net_log;
10420 
10421   HttpRequestInfo request;
10422   request.method = "GET";
10423   request.url = GURL("https://www.example.org/");
10424   request.traffic_annotation =
10425       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10426 
10427   MockWrite data_writes[] = {
10428       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10429                 "Host: www.example.org:443\r\n"
10430                 "Proxy-Connection: keep-alive\r\n\r\n"),
10431       MockWrite("GET / HTTP/1.1\r\n"
10432                 "Host: www.example.org\r\n"
10433                 "Connection: keep-alive\r\n\r\n"),
10434   };
10435 
10436   MockRead data_reads[] = {
10437     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10438     MockRead("HTTP/1.1 200 OK\r\n"),
10439     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10440     MockRead("Content-Length: 100\r\n\r\n"),
10441     MockRead(SYNCHRONOUS, OK),
10442   };
10443 
10444   StaticSocketDataProvider data(data_reads, data_writes);
10445   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
10446   SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
10447 
10448   session_deps_.socket_factory->AddSocketDataProvider(&data);
10449   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
10450   session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
10451 
10452   TestCompletionCallback callback;
10453 
10454   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10455   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10456 
10457   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10458   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10459 
10460   rv = callback.WaitForResult();
10461   EXPECT_THAT(rv, IsOk());
10462   const HttpResponseInfo* response = trans.GetResponseInfo();
10463 
10464   ASSERT_TRUE(response);
10465 
10466   EXPECT_TRUE(response->proxy_server.is_https());
10467   EXPECT_TRUE(response->headers->IsKeepAlive());
10468   EXPECT_EQ(200, response->headers->response_code());
10469   EXPECT_EQ(100, response->headers->GetContentLength());
10470   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10471 
10472   LoadTimingInfo load_timing_info;
10473   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
10474   TestLoadTimingNotReusedWithPac(load_timing_info,
10475                                  CONNECT_TIMING_HAS_SSL_TIMES);
10476 }
10477 
10478 // Test that an HTTPS Proxy cannot redirect a CONNECT request for main frames.
TEST_F(HttpNetworkTransactionTest,RedirectOfHttpsConnectViaHttpsProxy)10479 TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
10480   session_deps_.proxy_resolution_service =
10481       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
10482           "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10483   RecordingTestNetLog net_log;
10484   session_deps_.net_log = &net_log;
10485 
10486   const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
10487   session_deps_.host_resolver->set_ondemand_mode(true);
10488 
10489   HttpRequestInfo request;
10490   request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
10491   request.method = "GET";
10492   request.url = GURL("https://www.example.org/");
10493   request.traffic_annotation =
10494       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10495 
10496   MockWrite data_writes[] = {
10497       MockWrite(ASYNC, 0,
10498                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10499                 "Host: www.example.org:443\r\n"
10500                 "Proxy-Connection: keep-alive\r\n\r\n"),
10501   };
10502 
10503   MockRead data_reads[] = {
10504       // Pause on first read.
10505       MockRead(ASYNC, ERR_IO_PENDING, 1),
10506       MockRead(ASYNC, 2, "HTTP/1.1 302 Redirect\r\n"),
10507       MockRead(ASYNC, 3, "Location: http://login.example.com/\r\n"),
10508       MockRead(ASYNC, 4, "Content-Length: 0\r\n\r\n"),
10509   };
10510 
10511   SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
10512   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
10513 
10514   session_deps_.socket_factory->AddSocketDataProvider(&data);
10515   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
10516 
10517   TestCompletionCallback callback;
10518 
10519   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10520   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10521 
10522   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10523   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10524   EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
10525 
10526   // Host resolution takes |kTimeIncrement|.
10527   FastForwardBy(kTimeIncrement);
10528   // Resolving the current request with |ResolveNow| will cause the pending
10529   // request to instantly complete, and the async connect will start as well.
10530   session_deps_.host_resolver->ResolveOnlyRequestNow();
10531 
10532   // Connecting takes |kTimeIncrement|.
10533   FastForwardBy(kTimeIncrement);
10534   data.RunUntilPaused();
10535 
10536   // The server takes |kTimeIncrement| to respond.
10537   FastForwardBy(kTimeIncrement);
10538   data.Resume();
10539 
10540   rv = callback.WaitForResult();
10541   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
10542 }
10543 
10544 // Test that an HTTPS Proxy cannot redirect a CONNECT request for subresources.
TEST_F(HttpNetworkTransactionTest,RedirectOfHttpsConnectSubresourceViaHttpsProxy)10545 TEST_F(HttpNetworkTransactionTest,
10546        RedirectOfHttpsConnectSubresourceViaHttpsProxy) {
10547   base::HistogramTester histograms;
10548   session_deps_.proxy_resolution_service =
10549       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
10550           "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10551   RecordingTestNetLog net_log;
10552   session_deps_.net_log = &net_log;
10553 
10554   HttpRequestInfo request;
10555   request.method = "GET";
10556   request.url = GURL("https://www.example.org/");
10557   request.traffic_annotation =
10558       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10559 
10560   MockWrite data_writes[] = {
10561       MockWrite(ASYNC, 0,
10562                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10563                 "Host: www.example.org:443\r\n"
10564                 "Proxy-Connection: keep-alive\r\n\r\n"),
10565   };
10566 
10567   MockRead data_reads[] = {
10568       MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
10569       MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
10570       MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
10571   };
10572 
10573   SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
10574   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
10575 
10576   session_deps_.socket_factory->AddSocketDataProvider(&data);
10577   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
10578 
10579   TestCompletionCallback callback;
10580 
10581   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10582   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10583 
10584   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10585   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10586 
10587   rv = callback.WaitForResult();
10588   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
10589 }
10590 
10591 // Test that an HTTPS Proxy which was auto-detected cannot redirect a CONNECT
10592 // request for main frames.
TEST_F(HttpNetworkTransactionTest,RedirectOfHttpsConnectViaAutoDetectedHttpsProxy)10593 TEST_F(HttpNetworkTransactionTest,
10594        RedirectOfHttpsConnectViaAutoDetectedHttpsProxy) {
10595   base::HistogramTester histograms;
10596   session_deps_.proxy_resolution_service =
10597       ConfiguredProxyResolutionService::CreateFixedFromAutoDetectedPacResult(
10598           "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10599   RecordingTestNetLog net_log;
10600   session_deps_.net_log = &net_log;
10601 
10602   HttpRequestInfo request;
10603   request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
10604   request.method = "GET";
10605   request.url = GURL("https://www.example.org/");
10606   request.traffic_annotation =
10607       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10608 
10609   MockWrite data_writes[] = {
10610       MockWrite(ASYNC, 0,
10611                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10612                 "Host: www.example.org:443\r\n"
10613                 "Proxy-Connection: keep-alive\r\n\r\n"),
10614   };
10615 
10616   MockRead data_reads[] = {
10617       MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
10618       MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
10619       MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
10620   };
10621 
10622   SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
10623   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
10624 
10625   session_deps_.socket_factory->AddSocketDataProvider(&data);
10626   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
10627 
10628   TestCompletionCallback callback;
10629 
10630   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10631   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10632 
10633   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10634   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10635 
10636   rv = callback.WaitForResult();
10637   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
10638 }
10639 
10640 // Tests that an HTTPS (SPDY) Proxy's cannot redirect a CONNECT request for main
10641 // frames.
TEST_F(HttpNetworkTransactionTest,RedirectOfHttpsConnectViaSpdyProxy)10642 TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
10643   base::HistogramTester histograms;
10644   session_deps_.proxy_resolution_service =
10645       ConfiguredProxyResolutionService::CreateFixed(
10646           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10647   RecordingTestNetLog net_log;
10648   session_deps_.net_log = &net_log;
10649 
10650   const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
10651   session_deps_.host_resolver->set_ondemand_mode(true);
10652 
10653   HttpRequestInfo request;
10654   request.method = "GET";
10655   request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
10656   request.url = GURL("https://www.example.org/");
10657   request.traffic_annotation =
10658       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10659 
10660   spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
10661       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
10662       HostPortPair("www.example.org", 443)));
10663   spdy::SpdySerializedFrame goaway(
10664       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
10665   MockWrite data_writes[] = {
10666       CreateMockWrite(conn, 0, SYNCHRONOUS),
10667       CreateMockWrite(goaway, 3, SYNCHRONOUS),
10668   };
10669 
10670   static const char* const kExtraHeaders[] = {
10671     "location",
10672     "http://login.example.com/",
10673   };
10674   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
10675       "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
10676   MockRead data_reads[] = {
10677       // Pause on first read.
10678       MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
10679       MockRead(ASYNC, 0, 4),  // EOF
10680   };
10681 
10682   SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
10683   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
10684   proxy_ssl.next_proto = kProtoHTTP2;
10685 
10686   session_deps_.socket_factory->AddSocketDataProvider(&data);
10687   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
10688 
10689   TestCompletionCallback callback;
10690 
10691   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10692   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10693 
10694   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10695   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10696   EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
10697 
10698   // Host resolution takes |kTimeIncrement|.
10699   FastForwardBy(kTimeIncrement);
10700   // Resolving the current request with |ResolveNow| will cause the pending
10701   // request to instantly complete, and the async connect will start as well.
10702   session_deps_.host_resolver->ResolveOnlyRequestNow();
10703 
10704   // Connecting takes |kTimeIncrement|.
10705   FastForwardBy(kTimeIncrement);
10706   data.RunUntilPaused();
10707 
10708   FastForwardBy(kTimeIncrement);
10709   data.Resume();
10710   rv = callback.WaitForResult();
10711   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
10712 }
10713 
10714 // Test that an HTTPS proxy's response to a CONNECT request is filtered.
TEST_F(HttpNetworkTransactionTest,ErrorResponseToHttpsConnectViaHttpsProxy)10715 TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
10716   session_deps_.proxy_resolution_service =
10717       ConfiguredProxyResolutionService::CreateFixed(
10718           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10719 
10720   HttpRequestInfo request;
10721   request.method = "GET";
10722   request.url = GURL("https://www.example.org/");
10723   request.traffic_annotation =
10724       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10725 
10726   MockWrite data_writes[] = {
10727       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10728                 "Host: www.example.org:443\r\n"
10729                 "Proxy-Connection: keep-alive\r\n\r\n"),
10730   };
10731 
10732   MockRead data_reads[] = {
10733     MockRead("HTTP/1.1 404 Not Found\r\n"),
10734     MockRead("Content-Length: 23\r\n\r\n"),
10735     MockRead("The host does not exist"),
10736     MockRead(SYNCHRONOUS, OK),
10737   };
10738 
10739   StaticSocketDataProvider data(data_reads, data_writes);
10740   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
10741 
10742   session_deps_.socket_factory->AddSocketDataProvider(&data);
10743   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
10744 
10745   TestCompletionCallback callback;
10746 
10747   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10748   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10749 
10750   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10751   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10752 
10753   rv = callback.WaitForResult();
10754   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
10755 
10756   // TODO(juliatuttle): Anything else to check here?
10757 }
10758 
10759 // Test that a SPDY proxy's response to a CONNECT request is filtered.
TEST_F(HttpNetworkTransactionTest,ErrorResponseToHttpsConnectViaSpdyProxy)10760 TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
10761   session_deps_.proxy_resolution_service =
10762       ConfiguredProxyResolutionService::CreateFixed(
10763           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10764 
10765   HttpRequestInfo request;
10766   request.method = "GET";
10767   request.url = GURL("https://www.example.org/");
10768   request.traffic_annotation =
10769       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10770 
10771   spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
10772       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
10773       HostPortPair("www.example.org", 443)));
10774   spdy::SpdySerializedFrame rst(
10775       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
10776   MockWrite data_writes[] = {
10777       CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
10778   };
10779 
10780   static const char* const kExtraHeaders[] = {
10781     "location",
10782     "http://login.example.com/",
10783   };
10784   spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
10785       "404", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
10786   spdy::SpdySerializedFrame body(
10787       spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
10788   MockRead data_reads[] = {
10789       CreateMockRead(resp, 1), CreateMockRead(body, 2),
10790       MockRead(ASYNC, 0, 4),  // EOF
10791   };
10792 
10793   SequencedSocketData data(data_reads, data_writes);
10794   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
10795   proxy_ssl.next_proto = kProtoHTTP2;
10796 
10797   session_deps_.socket_factory->AddSocketDataProvider(&data);
10798   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
10799 
10800   TestCompletionCallback callback;
10801 
10802   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10803   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10804 
10805   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10806   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10807 
10808   rv = callback.WaitForResult();
10809   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
10810 
10811   // TODO(juliatuttle): Anything else to check here?
10812 }
10813 
10814 // Test the request-challenge-retry sequence for basic auth, through
10815 // a SPDY proxy over a single SPDY session.
TEST_F(HttpNetworkTransactionTest,BasicAuthSpdyProxy)10816 TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
10817   HttpRequestInfo request;
10818   request.method = "GET";
10819   request.url = GURL("https://www.example.org/");
10820   // when the no authentication data flag is set.
10821   request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
10822   request.traffic_annotation =
10823       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10824 
10825   // Configure against https proxy server "myproxy:70".
10826   session_deps_.proxy_resolution_service =
10827       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
10828           "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
10829   RecordingBoundTestNetLog log;
10830   session_deps_.net_log = log.bound().net_log();
10831   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10832 
10833   // Since we have proxy, should try to establish tunnel.
10834   spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
10835       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
10836       HostPortPair("www.example.org", 443)));
10837   spdy::SpdySerializedFrame rst(
10838       spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
10839   spdy_util_.UpdateWithStreamDestruction(1);
10840 
10841   // After calling trans.RestartWithAuth(), this is the request we should
10842   // be issuing -- the final header line contains the credentials.
10843   const char* const kAuthCredentials[] = {
10844       "proxy-authorization", "Basic Zm9vOmJhcg==",
10845   };
10846   spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
10847       kAuthCredentials, base::size(kAuthCredentials) / 2, 3,
10848       HttpProxyConnectJob::kH2QuicTunnelPriority,
10849       HostPortPair("www.example.org", 443)));
10850   // fetch https://www.example.org/ via HTTP
10851   const char get[] =
10852       "GET / HTTP/1.1\r\n"
10853       "Host: www.example.org\r\n"
10854       "Connection: keep-alive\r\n\r\n";
10855   spdy::SpdySerializedFrame wrapped_get(
10856       spdy_util_.ConstructSpdyDataFrame(3, get, false));
10857 
10858   MockWrite spdy_writes[] = {
10859       CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
10860       CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
10861   };
10862 
10863   // The proxy responds to the connect with a 407, using a persistent
10864   // connection.
10865   const char kAuthStatus[] = "407";
10866   const char* const kAuthChallenge[] = {
10867     "proxy-authenticate", "Basic realm=\"MyRealm1\"",
10868   };
10869   spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
10870       kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1));
10871 
10872   spdy::SpdySerializedFrame conn_resp(
10873       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
10874   const char resp[] = "HTTP/1.1 200 OK\r\n"
10875       "Content-Length: 5\r\n\r\n";
10876 
10877   spdy::SpdySerializedFrame wrapped_get_resp(
10878       spdy_util_.ConstructSpdyDataFrame(3, resp, false));
10879   spdy::SpdySerializedFrame wrapped_body(
10880       spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
10881   MockRead spdy_reads[] = {
10882       CreateMockRead(conn_auth_resp, 1, ASYNC),
10883       CreateMockRead(conn_resp, 4, ASYNC),
10884       CreateMockRead(wrapped_get_resp, 6, ASYNC),
10885       CreateMockRead(wrapped_body, 7, ASYNC),
10886       MockRead(ASYNC, OK, 8),  // EOF.  May or may not be read.
10887   };
10888 
10889   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
10890   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10891   // Negotiate SPDY to the proxy
10892   SSLSocketDataProvider proxy(ASYNC, OK);
10893   proxy.next_proto = kProtoHTTP2;
10894   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
10895   // Vanilla SSL to the server
10896   SSLSocketDataProvider server(ASYNC, OK);
10897   session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
10898 
10899   TestCompletionCallback callback1;
10900 
10901   auto trans =
10902       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
10903 
10904   int rv = trans->Start(&request, callback1.callback(), log.bound());
10905   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10906 
10907   rv = callback1.WaitForResult();
10908   EXPECT_THAT(rv, IsOk());
10909   auto entries = log.GetEntries();
10910   size_t pos = ExpectLogContainsSomewhere(
10911       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10912       NetLogEventPhase::NONE);
10913   ExpectLogContainsSomewhere(
10914       entries, pos,
10915       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10916       NetLogEventPhase::NONE);
10917 
10918   const HttpResponseInfo* response = trans->GetResponseInfo();
10919   ASSERT_TRUE(response);
10920   ASSERT_TRUE(response->headers);
10921   EXPECT_EQ(407, response->headers->response_code());
10922   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10923   EXPECT_TRUE(response->auth_challenge.has_value());
10924   EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
10925 
10926   TestCompletionCallback callback2;
10927 
10928   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
10929                               callback2.callback());
10930   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10931 
10932   rv = callback2.WaitForResult();
10933   EXPECT_THAT(rv, IsOk());
10934 
10935   response = trans->GetResponseInfo();
10936   ASSERT_TRUE(response);
10937 
10938   EXPECT_TRUE(response->headers->IsKeepAlive());
10939   EXPECT_EQ(200, response->headers->response_code());
10940   EXPECT_EQ(5, response->headers->GetContentLength());
10941   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10942 
10943   // The password prompt info should not be set.
10944   EXPECT_FALSE(response->auth_challenge.has_value());
10945 
10946   LoadTimingInfo load_timing_info;
10947   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10948   TestLoadTimingNotReusedWithPac(load_timing_info,
10949                                  CONNECT_TIMING_HAS_SSL_TIMES);
10950 
10951   trans.reset();
10952   session->CloseAllConnections(ERR_FAILED, "Very good reason");
10953 }
10954 
10955 // Test that an explicitly trusted SPDY proxy can push a resource from an
10956 // origin that is different from that of its associated resource.
TEST_F(HttpNetworkTransactionTest,CrossOriginSPDYProxyPush)10957 TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
10958   // Configure the proxy delegate to allow cross-origin SPDY pushes.
10959   auto proxy_delegate = std::make_unique<TestProxyDelegate>();
10960   proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10961       "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
10962   HttpRequestInfo request;
10963   HttpRequestInfo push_request;
10964   request.traffic_annotation =
10965       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10966 
10967   request.method = "GET";
10968   request.url = GURL("http://www.example.org/");
10969   push_request.method = "GET";
10970   push_request.url = GURL("http://www.another-origin.com/foo.dat");
10971   push_request.traffic_annotation =
10972       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10973 
10974   // Configure against https proxy server "myproxy:443".
10975   session_deps_.proxy_resolution_service =
10976       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
10977           "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
10978   RecordingBoundTestNetLog log;
10979   session_deps_.net_log = log.bound().net_log();
10980 
10981   session_deps_.proxy_resolution_service->SetProxyDelegate(
10982       proxy_delegate.get());
10983 
10984   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10985 
10986   spdy::SpdySerializedFrame stream1_syn(
10987       spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
10988   spdy::SpdySerializedFrame stream2_priority(
10989       spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
10990 
10991   MockWrite spdy_writes[] = {
10992       CreateMockWrite(stream1_syn, 0, ASYNC),
10993       CreateMockWrite(stream2_priority, 3, ASYNC),
10994   };
10995 
10996   spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
10997       nullptr, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
10998 
10999   spdy::SpdySerializedFrame stream1_reply(
11000       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11001 
11002   spdy::SpdySerializedFrame stream1_body(
11003       spdy_util_.ConstructSpdyDataFrame(1, true));
11004 
11005   spdy::SpdySerializedFrame stream2_body(
11006       spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
11007 
11008   MockRead spdy_reads[] = {
11009       CreateMockRead(stream2_syn, 1, ASYNC),
11010       CreateMockRead(stream1_reply, 2, ASYNC),
11011       CreateMockRead(stream1_body, 4, ASYNC),
11012       CreateMockRead(stream2_body, 5, ASYNC),
11013       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),  // Force a hang
11014   };
11015 
11016   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
11017   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11018   // Negotiate SPDY to the proxy
11019   SSLSocketDataProvider proxy(ASYNC, OK);
11020   proxy.next_proto = kProtoHTTP2;
11021   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
11022 
11023   auto trans =
11024       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
11025   TestCompletionCallback callback;
11026   int rv = trans->Start(&request, callback.callback(), log.bound());
11027   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11028 
11029   rv = callback.WaitForResult();
11030   EXPECT_THAT(rv, IsOk());
11031   const HttpResponseInfo* response = trans->GetResponseInfo();
11032 
11033   auto push_trans =
11034       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
11035   rv = push_trans->Start(&push_request, callback.callback(), log.bound());
11036   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11037 
11038   rv = callback.WaitForResult();
11039   EXPECT_THAT(rv, IsOk());
11040   const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
11041 
11042   ASSERT_TRUE(response);
11043   EXPECT_TRUE(response->headers->IsKeepAlive());
11044 
11045   EXPECT_EQ(200, response->headers->response_code());
11046   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11047 
11048   std::string response_data;
11049   rv = ReadTransaction(trans.get(), &response_data);
11050   EXPECT_THAT(rv, IsOk());
11051   EXPECT_EQ("hello!", response_data);
11052 
11053   LoadTimingInfo load_timing_info;
11054   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11055   TestLoadTimingNotReusedWithPac(load_timing_info,
11056                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11057 
11058   // Verify the pushed stream.
11059   EXPECT_TRUE(push_response->headers);
11060   EXPECT_EQ(200, push_response->headers->response_code());
11061 
11062   rv = ReadTransaction(push_trans.get(), &response_data);
11063   EXPECT_THAT(rv, IsOk());
11064   EXPECT_EQ("pushed", response_data);
11065 
11066   LoadTimingInfo push_load_timing_info;
11067   EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
11068   TestLoadTimingReusedWithPac(push_load_timing_info);
11069   // The transactions should share a socket ID, despite being for different
11070   // origins.
11071   EXPECT_EQ(load_timing_info.socket_log_id,
11072             push_load_timing_info.socket_log_id);
11073 
11074   trans.reset();
11075   push_trans.reset();
11076   session->CloseAllConnections(ERR_FAILED, "Very good reason");
11077 }
11078 
11079 // Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
TEST_F(HttpNetworkTransactionTest,CrossOriginProxyPushCorrectness)11080 TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
11081   // Configure the proxy delegate to allow cross-origin SPDY pushes.
11082   auto proxy_delegate = std::make_unique<TestProxyDelegate>();
11083   proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
11084       "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
11085   HttpRequestInfo request;
11086 
11087   request.method = "GET";
11088   request.url = GURL("http://www.example.org/");
11089   request.traffic_annotation =
11090       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11091 
11092   session_deps_.proxy_resolution_service =
11093       ConfiguredProxyResolutionService::CreateFixed(
11094           "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
11095   RecordingBoundTestNetLog log;
11096   session_deps_.net_log = log.bound().net_log();
11097 
11098   // Enable cross-origin push.
11099   session_deps_.proxy_resolution_service->SetProxyDelegate(
11100       proxy_delegate.get());
11101 
11102   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11103 
11104   spdy::SpdySerializedFrame stream1_syn(
11105       spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
11106 
11107   spdy::SpdySerializedFrame push_rst(
11108       spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
11109 
11110   MockWrite spdy_writes[] = {
11111       CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
11112   };
11113 
11114   spdy::SpdySerializedFrame stream1_reply(
11115       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11116 
11117   spdy::SpdySerializedFrame stream1_body(
11118       spdy_util_.ConstructSpdyDataFrame(1, true));
11119 
11120   spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
11121       nullptr, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
11122 
11123   MockRead spdy_reads[] = {
11124       CreateMockRead(stream1_reply, 1, ASYNC),
11125       CreateMockRead(stream2_syn, 2, ASYNC),
11126       CreateMockRead(stream1_body, 4, ASYNC),
11127       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),  // Force a hang
11128   };
11129 
11130   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
11131   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11132   // Negotiate SPDY to the proxy
11133   SSLSocketDataProvider proxy(ASYNC, OK);
11134   proxy.next_proto = kProtoHTTP2;
11135   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
11136 
11137   auto trans =
11138       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
11139   TestCompletionCallback callback;
11140   int rv = trans->Start(&request, callback.callback(), log.bound());
11141   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11142 
11143   rv = callback.WaitForResult();
11144   EXPECT_THAT(rv, IsOk());
11145   const HttpResponseInfo* response = trans->GetResponseInfo();
11146 
11147   ASSERT_TRUE(response);
11148   EXPECT_TRUE(response->headers->IsKeepAlive());
11149 
11150   EXPECT_EQ(200, response->headers->response_code());
11151   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11152 
11153   std::string response_data;
11154   rv = ReadTransaction(trans.get(), &response_data);
11155   EXPECT_THAT(rv, IsOk());
11156   EXPECT_EQ("hello!", response_data);
11157 
11158   trans.reset();
11159   session->CloseAllConnections(ERR_FAILED, "Very good reason");
11160 }
11161 
11162 // Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
11163 // resources.
TEST_F(HttpNetworkTransactionTest,SameOriginProxyPushCorrectness)11164 TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
11165   // Configure the proxy delegate to allow cross-origin SPDY pushes.
11166   auto proxy_delegate = std::make_unique<TestProxyDelegate>();
11167   proxy_delegate->set_trusted_spdy_proxy(
11168       net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
11169 
11170   HttpRequestInfo request;
11171 
11172   request.method = "GET";
11173   request.url = GURL("http://www.example.org/");
11174   request.traffic_annotation =
11175       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11176 
11177   // Configure against https proxy server "myproxy:70".
11178   session_deps_.proxy_resolution_service =
11179       ConfiguredProxyResolutionService::CreateFixed(
11180           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
11181   RecordingBoundTestNetLog log;
11182   session_deps_.net_log = log.bound().net_log();
11183 
11184   // Enable cross-origin push.
11185   session_deps_.proxy_resolution_service->SetProxyDelegate(
11186       proxy_delegate.get());
11187 
11188   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11189 
11190   spdy::SpdySerializedFrame stream1_syn(
11191       spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
11192   spdy::SpdySerializedFrame stream2_priority(
11193       spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
11194 
11195   MockWrite spdy_writes[] = {
11196       CreateMockWrite(stream1_syn, 0, ASYNC),
11197       CreateMockWrite(stream2_priority, 3, ASYNC),
11198   };
11199 
11200   spdy::SpdySerializedFrame stream1_reply(
11201       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11202 
11203   spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
11204       nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
11205 
11206   spdy::SpdySerializedFrame stream1_body(
11207       spdy_util_.ConstructSpdyDataFrame(1, true));
11208 
11209   spdy::SpdySerializedFrame stream2_reply(
11210       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11211 
11212   spdy::SpdySerializedFrame stream2_body(
11213       spdy_util_.ConstructSpdyDataFrame(1, true));
11214 
11215   MockRead spdy_reads[] = {
11216       CreateMockRead(stream1_reply, 1, ASYNC),
11217       CreateMockRead(stream2_syn, 2, ASYNC),
11218       CreateMockRead(stream1_body, 4, ASYNC),
11219       CreateMockRead(stream2_body, 5, ASYNC),
11220       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),  // Force a hang
11221   };
11222 
11223   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
11224   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11225   // Negotiate SPDY to the proxy
11226   SSLSocketDataProvider proxy(ASYNC, OK);
11227   proxy.next_proto = kProtoHTTP2;
11228   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
11229 
11230   auto trans =
11231       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
11232   TestCompletionCallback callback;
11233   int rv = trans->Start(&request, callback.callback(), log.bound());
11234   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11235 
11236   rv = callback.WaitForResult();
11237   EXPECT_THAT(rv, IsOk());
11238   const HttpResponseInfo* response = trans->GetResponseInfo();
11239 
11240   ASSERT_TRUE(response);
11241   EXPECT_TRUE(response->headers->IsKeepAlive());
11242 
11243   EXPECT_EQ(200, response->headers->response_code());
11244   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11245 
11246   std::string response_data;
11247   rv = ReadTransaction(trans.get(), &response_data);
11248   EXPECT_THAT(rv, IsOk());
11249   EXPECT_EQ("hello!", response_data);
11250 
11251   trans.reset();
11252   session->CloseAllConnections(ERR_FAILED, "Very good reason");
11253 }
11254 
11255 // Test HTTPS connections to a site with a bad certificate, going through an
11256 // HTTPS proxy
TEST_F(HttpNetworkTransactionTest,HTTPSBadCertificateViaHttpsProxy)11257 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
11258   session_deps_.proxy_resolution_service =
11259       ConfiguredProxyResolutionService::CreateFixed(
11260           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
11261 
11262   HttpRequestInfo request;
11263   request.method = "GET";
11264   request.url = GURL("https://www.example.org/");
11265   request.traffic_annotation =
11266       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11267 
11268   // Attempt to fetch the URL from a server with a bad cert
11269   MockWrite bad_cert_writes[] = {
11270       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
11271                 "Host: www.example.org:443\r\n"
11272                 "Proxy-Connection: keep-alive\r\n\r\n"),
11273   };
11274 
11275   MockRead bad_cert_reads[] = {
11276     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
11277     MockRead(SYNCHRONOUS, OK)
11278   };
11279 
11280   // Attempt to fetch the URL with a good cert
11281   MockWrite good_data_writes[] = {
11282       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
11283                 "Host: www.example.org:443\r\n"
11284                 "Proxy-Connection: keep-alive\r\n\r\n"),
11285       MockWrite("GET / HTTP/1.1\r\n"
11286                 "Host: www.example.org\r\n"
11287                 "Connection: keep-alive\r\n\r\n"),
11288   };
11289 
11290   MockRead good_cert_reads[] = {
11291     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
11292     MockRead("HTTP/1.0 200 OK\r\n"),
11293     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11294     MockRead("Content-Length: 100\r\n\r\n"),
11295     MockRead(SYNCHRONOUS, OK),
11296   };
11297 
11298   StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
11299   StaticSocketDataProvider data(good_cert_reads, good_data_writes);
11300   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
11301   SSLSocketDataProvider ssl(ASYNC, OK);
11302 
11303   // SSL to the proxy, then CONNECT request, then SSL with bad certificate
11304   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11305   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
11306   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
11307 
11308   // SSL to the proxy, then CONNECT request, then valid SSL certificate
11309   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11310   session_deps_.socket_factory->AddSocketDataProvider(&data);
11311   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11312 
11313   TestCompletionCallback callback;
11314 
11315   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11316   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11317 
11318   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11319   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11320 
11321   rv = callback.WaitForResult();
11322   EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
11323 
11324   rv = trans.RestartIgnoringLastError(callback.callback());
11325   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11326 
11327   rv = callback.WaitForResult();
11328   EXPECT_THAT(rv, IsOk());
11329 
11330   const HttpResponseInfo* response = trans.GetResponseInfo();
11331 
11332   ASSERT_TRUE(response);
11333   EXPECT_EQ(100, response->headers->GetContentLength());
11334 }
11335 
TEST_F(HttpNetworkTransactionTest,BuildRequest_UserAgent)11336 TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
11337   HttpRequestInfo request;
11338   request.method = "GET";
11339   request.url = GURL("http://www.example.org/");
11340   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
11341                                   "Chromium Ultra Awesome X Edition");
11342   request.traffic_annotation =
11343       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11344 
11345   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11346   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11347 
11348   MockWrite data_writes[] = {
11349       MockWrite(
11350           "GET / HTTP/1.1\r\n"
11351           "Host: www.example.org\r\n"
11352           "Connection: keep-alive\r\n"
11353           "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
11354   };
11355 
11356   // Lastly, the server responds with the actual content.
11357   MockRead data_reads[] = {
11358     MockRead("HTTP/1.0 200 OK\r\n"),
11359     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11360     MockRead("Content-Length: 100\r\n\r\n"),
11361     MockRead(SYNCHRONOUS, OK),
11362   };
11363 
11364   StaticSocketDataProvider data(data_reads, data_writes);
11365   session_deps_.socket_factory->AddSocketDataProvider(&data);
11366 
11367   TestCompletionCallback callback;
11368 
11369   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11370   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11371 
11372   rv = callback.WaitForResult();
11373   EXPECT_THAT(rv, IsOk());
11374 }
11375 
TEST_F(HttpNetworkTransactionTest,BuildRequest_UserAgentOverTunnel)11376 TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
11377   // Test user agent values, used both for the request header of the original
11378   // request, and the value returned by the HttpUserAgentSettings. nullptr means
11379   // no request header / no HttpUserAgentSettings object.
11380   const char* kTestUserAgents[] = {nullptr, "", "Foopy"};
11381 
11382   for (const char* setting_user_agent : kTestUserAgents) {
11383     if (!setting_user_agent) {
11384       session_deps_.http_user_agent_settings.reset();
11385     } else {
11386       session_deps_.http_user_agent_settings =
11387           std::make_unique<StaticHttpUserAgentSettings>(
11388               std::string() /* accept-language */, setting_user_agent);
11389     }
11390     session_deps_.proxy_resolution_service =
11391         ConfiguredProxyResolutionService::CreateFixed(
11392             "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
11393     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11394     for (const char* request_user_agent : kTestUserAgents) {
11395       HttpRequestInfo request;
11396       request.method = "GET";
11397       request.url = GURL("https://www.example.org/");
11398       if (request_user_agent) {
11399         request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
11400                                         request_user_agent);
11401       }
11402       request.traffic_annotation =
11403           net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11404 
11405       HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11406 
11407       std::string expected_request;
11408       if (!setting_user_agent || strlen(setting_user_agent) == 0) {
11409         expected_request =
11410             "CONNECT www.example.org:443 HTTP/1.1\r\n"
11411             "Host: www.example.org:443\r\n"
11412             "Proxy-Connection: keep-alive\r\n\r\n";
11413       } else {
11414         expected_request = base::StringPrintf(
11415             "CONNECT www.example.org:443 HTTP/1.1\r\n"
11416             "Host: www.example.org:443\r\n"
11417             "Proxy-Connection: keep-alive\r\n"
11418             "User-Agent: %s\r\n\r\n",
11419             setting_user_agent);
11420       }
11421       MockWrite data_writes[] = {
11422           MockWrite(expected_request.c_str()),
11423       };
11424       MockRead data_reads[] = {
11425           // Return an error, so the transaction stops here (this test isn't
11426           // interested in the rest).
11427           MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
11428           MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11429           MockRead("Proxy-Connection: close\r\n\r\n"),
11430       };
11431 
11432       StaticSocketDataProvider data(data_reads, data_writes);
11433       session_deps_.socket_factory->AddSocketDataProvider(&data);
11434 
11435       TestCompletionCallback callback;
11436 
11437       int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11438       EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11439 
11440       rv = callback.WaitForResult();
11441       EXPECT_THAT(rv, IsOk());
11442     }
11443   }
11444 }
11445 
TEST_F(HttpNetworkTransactionTest,BuildRequest_Referer)11446 TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
11447   HttpRequestInfo request;
11448   request.method = "GET";
11449   request.url = GURL("http://www.example.org/");
11450   request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
11451                                   "http://the.previous.site.com/");
11452   request.traffic_annotation =
11453       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11454 
11455   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11456   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11457 
11458   MockWrite data_writes[] = {
11459       MockWrite(
11460           "GET / HTTP/1.1\r\n"
11461           "Host: www.example.org\r\n"
11462           "Connection: keep-alive\r\n"
11463           "Referer: http://the.previous.site.com/\r\n\r\n"),
11464   };
11465 
11466   // Lastly, the server responds with the actual content.
11467   MockRead data_reads[] = {
11468     MockRead("HTTP/1.0 200 OK\r\n"),
11469     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11470     MockRead("Content-Length: 100\r\n\r\n"),
11471     MockRead(SYNCHRONOUS, OK),
11472   };
11473 
11474   StaticSocketDataProvider data(data_reads, data_writes);
11475   session_deps_.socket_factory->AddSocketDataProvider(&data);
11476 
11477   TestCompletionCallback callback;
11478 
11479   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11480   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11481 
11482   rv = callback.WaitForResult();
11483   EXPECT_THAT(rv, IsOk());
11484 }
11485 
TEST_F(HttpNetworkTransactionTest,BuildRequest_PostContentLengthZero)11486 TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
11487   HttpRequestInfo request;
11488   request.method = "POST";
11489   request.url = GURL("http://www.example.org/");
11490   request.traffic_annotation =
11491       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11492 
11493   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11494   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11495 
11496   MockWrite data_writes[] = {
11497       MockWrite(
11498           "POST / HTTP/1.1\r\n"
11499           "Host: www.example.org\r\n"
11500           "Connection: keep-alive\r\n"
11501           "Content-Length: 0\r\n\r\n"),
11502   };
11503 
11504   // Lastly, the server responds with the actual content.
11505   MockRead data_reads[] = {
11506     MockRead("HTTP/1.0 200 OK\r\n"),
11507     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11508     MockRead("Content-Length: 100\r\n\r\n"),
11509     MockRead(SYNCHRONOUS, OK),
11510   };
11511 
11512   StaticSocketDataProvider data(data_reads, data_writes);
11513   session_deps_.socket_factory->AddSocketDataProvider(&data);
11514 
11515   TestCompletionCallback callback;
11516 
11517   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11518   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11519 
11520   rv = callback.WaitForResult();
11521   EXPECT_THAT(rv, IsOk());
11522 }
11523 
TEST_F(HttpNetworkTransactionTest,BuildRequest_PutContentLengthZero)11524 TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
11525   HttpRequestInfo request;
11526   request.method = "PUT";
11527   request.url = GURL("http://www.example.org/");
11528   request.traffic_annotation =
11529       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11530 
11531   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11532   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11533 
11534   MockWrite data_writes[] = {
11535       MockWrite(
11536           "PUT / HTTP/1.1\r\n"
11537           "Host: www.example.org\r\n"
11538           "Connection: keep-alive\r\n"
11539           "Content-Length: 0\r\n\r\n"),
11540   };
11541 
11542   // Lastly, the server responds with the actual content.
11543   MockRead data_reads[] = {
11544     MockRead("HTTP/1.0 200 OK\r\n"),
11545     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11546     MockRead("Content-Length: 100\r\n\r\n"),
11547     MockRead(SYNCHRONOUS, OK),
11548   };
11549 
11550   StaticSocketDataProvider data(data_reads, data_writes);
11551   session_deps_.socket_factory->AddSocketDataProvider(&data);
11552 
11553   TestCompletionCallback callback;
11554 
11555   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11556   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11557 
11558   rv = callback.WaitForResult();
11559   EXPECT_THAT(rv, IsOk());
11560 }
11561 
TEST_F(HttpNetworkTransactionTest,BuildRequest_HeadContentLengthZero)11562 TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
11563   HttpRequestInfo request;
11564   request.method = "HEAD";
11565   request.url = GURL("http://www.example.org/");
11566   request.traffic_annotation =
11567       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11568 
11569   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11570   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11571 
11572   MockWrite data_writes[] = {
11573       MockWrite("HEAD / HTTP/1.1\r\n"
11574                 "Host: www.example.org\r\n"
11575                 "Connection: keep-alive\r\n\r\n"),
11576   };
11577 
11578   // Lastly, the server responds with the actual content.
11579   MockRead data_reads[] = {
11580     MockRead("HTTP/1.0 200 OK\r\n"),
11581     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11582     MockRead("Content-Length: 100\r\n\r\n"),
11583     MockRead(SYNCHRONOUS, OK),
11584   };
11585 
11586   StaticSocketDataProvider data(data_reads, data_writes);
11587   session_deps_.socket_factory->AddSocketDataProvider(&data);
11588 
11589   TestCompletionCallback callback;
11590 
11591   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11592   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11593 
11594   rv = callback.WaitForResult();
11595   EXPECT_THAT(rv, IsOk());
11596 }
11597 
TEST_F(HttpNetworkTransactionTest,BuildRequest_CacheControlNoCache)11598 TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
11599   HttpRequestInfo request;
11600   request.method = "GET";
11601   request.url = GURL("http://www.example.org/");
11602   request.load_flags = LOAD_BYPASS_CACHE;
11603   request.traffic_annotation =
11604       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11605 
11606   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11607   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11608 
11609   MockWrite data_writes[] = {
11610       MockWrite(
11611           "GET / HTTP/1.1\r\n"
11612           "Host: www.example.org\r\n"
11613           "Connection: keep-alive\r\n"
11614           "Pragma: no-cache\r\n"
11615           "Cache-Control: no-cache\r\n\r\n"),
11616   };
11617 
11618   // Lastly, the server responds with the actual content.
11619   MockRead data_reads[] = {
11620     MockRead("HTTP/1.0 200 OK\r\n"),
11621     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11622     MockRead("Content-Length: 100\r\n\r\n"),
11623     MockRead(SYNCHRONOUS, OK),
11624   };
11625 
11626   StaticSocketDataProvider data(data_reads, data_writes);
11627   session_deps_.socket_factory->AddSocketDataProvider(&data);
11628 
11629   TestCompletionCallback callback;
11630 
11631   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11632   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11633 
11634   rv = callback.WaitForResult();
11635   EXPECT_THAT(rv, IsOk());
11636 }
11637 
TEST_F(HttpNetworkTransactionTest,BuildRequest_CacheControlValidateCache)11638 TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
11639   HttpRequestInfo request;
11640   request.method = "GET";
11641   request.url = GURL("http://www.example.org/");
11642   request.load_flags = LOAD_VALIDATE_CACHE;
11643   request.traffic_annotation =
11644       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11645 
11646   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11647   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11648 
11649   MockWrite data_writes[] = {
11650       MockWrite(
11651           "GET / HTTP/1.1\r\n"
11652           "Host: www.example.org\r\n"
11653           "Connection: keep-alive\r\n"
11654           "Cache-Control: max-age=0\r\n\r\n"),
11655   };
11656 
11657   // Lastly, the server responds with the actual content.
11658   MockRead data_reads[] = {
11659     MockRead("HTTP/1.0 200 OK\r\n"),
11660     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11661     MockRead("Content-Length: 100\r\n\r\n"),
11662     MockRead(SYNCHRONOUS, OK),
11663   };
11664 
11665   StaticSocketDataProvider data(data_reads, data_writes);
11666   session_deps_.socket_factory->AddSocketDataProvider(&data);
11667 
11668   TestCompletionCallback callback;
11669 
11670   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11671   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11672 
11673   rv = callback.WaitForResult();
11674   EXPECT_THAT(rv, IsOk());
11675 }
11676 
TEST_F(HttpNetworkTransactionTest,BuildRequest_ExtraHeaders)11677 TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
11678   HttpRequestInfo request;
11679   request.method = "GET";
11680   request.url = GURL("http://www.example.org/");
11681   request.extra_headers.SetHeader("FooHeader", "Bar");
11682   request.traffic_annotation =
11683       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11684 
11685   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11686   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11687 
11688   MockWrite data_writes[] = {
11689       MockWrite(
11690           "GET / HTTP/1.1\r\n"
11691           "Host: www.example.org\r\n"
11692           "Connection: keep-alive\r\n"
11693           "FooHeader: Bar\r\n\r\n"),
11694   };
11695 
11696   // Lastly, the server responds with the actual content.
11697   MockRead data_reads[] = {
11698     MockRead("HTTP/1.0 200 OK\r\n"),
11699     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11700     MockRead("Content-Length: 100\r\n\r\n"),
11701     MockRead(SYNCHRONOUS, OK),
11702   };
11703 
11704   StaticSocketDataProvider data(data_reads, data_writes);
11705   session_deps_.socket_factory->AddSocketDataProvider(&data);
11706 
11707   TestCompletionCallback callback;
11708 
11709   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11710   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11711 
11712   rv = callback.WaitForResult();
11713   EXPECT_THAT(rv, IsOk());
11714 }
11715 
TEST_F(HttpNetworkTransactionTest,BuildRequest_ExtraHeadersStripped)11716 TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
11717   HttpRequestInfo request;
11718   request.method = "GET";
11719   request.url = GURL("http://www.example.org/");
11720   request.extra_headers.SetHeader("referer", "www.foo.com");
11721   request.extra_headers.SetHeader("hEllo", "Kitty");
11722   request.extra_headers.SetHeader("FoO", "bar");
11723   request.traffic_annotation =
11724       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11725 
11726   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11727   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11728 
11729   MockWrite data_writes[] = {
11730       MockWrite(
11731           "GET / HTTP/1.1\r\n"
11732           "Host: www.example.org\r\n"
11733           "Connection: keep-alive\r\n"
11734           "referer: www.foo.com\r\n"
11735           "hEllo: Kitty\r\n"
11736           "FoO: bar\r\n\r\n"),
11737   };
11738 
11739   // Lastly, the server responds with the actual content.
11740   MockRead data_reads[] = {
11741     MockRead("HTTP/1.0 200 OK\r\n"),
11742     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11743     MockRead("Content-Length: 100\r\n\r\n"),
11744     MockRead(SYNCHRONOUS, OK),
11745   };
11746 
11747   StaticSocketDataProvider data(data_reads, data_writes);
11748   session_deps_.socket_factory->AddSocketDataProvider(&data);
11749 
11750   TestCompletionCallback callback;
11751 
11752   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11753   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11754 
11755   rv = callback.WaitForResult();
11756   EXPECT_THAT(rv, IsOk());
11757 }
11758 
TEST_F(HttpNetworkTransactionTest,SOCKS4_HTTP_GET)11759 TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
11760   HttpRequestInfo request;
11761   request.method = "GET";
11762   request.url = GURL("http://www.example.org/");
11763   request.traffic_annotation =
11764       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11765 
11766   session_deps_.proxy_resolution_service =
11767       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
11768           "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
11769   RecordingTestNetLog net_log;
11770   session_deps_.net_log = &net_log;
11771 
11772   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11773   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11774 
11775   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
11776   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
11777 
11778   MockWrite data_writes[] = {
11779       MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
11780       MockWrite("GET / HTTP/1.1\r\n"
11781                 "Host: www.example.org\r\n"
11782                 "Connection: keep-alive\r\n\r\n")};
11783 
11784   MockRead data_reads[] = {
11785       MockRead(ASYNC, read_buffer, base::size(read_buffer)),
11786       MockRead("HTTP/1.0 200 OK\r\n"),
11787       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11788       MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
11789 
11790   StaticSocketDataProvider data(data_reads, data_writes);
11791   session_deps_.socket_factory->AddSocketDataProvider(&data);
11792 
11793   TestCompletionCallback callback;
11794 
11795   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11796   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11797 
11798   rv = callback.WaitForResult();
11799   EXPECT_THAT(rv, IsOk());
11800 
11801   const HttpResponseInfo* response = trans.GetResponseInfo();
11802   ASSERT_TRUE(response);
11803 
11804   EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
11805   LoadTimingInfo load_timing_info;
11806   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
11807   TestLoadTimingNotReusedWithPac(load_timing_info,
11808                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11809 
11810   std::string response_text;
11811   rv = ReadTransaction(&trans, &response_text);
11812   EXPECT_THAT(rv, IsOk());
11813   EXPECT_EQ("Payload", response_text);
11814 }
11815 
TEST_F(HttpNetworkTransactionTest,SOCKS4_SSL_GET)11816 TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
11817   HttpRequestInfo request;
11818   request.method = "GET";
11819   request.url = GURL("https://www.example.org/");
11820   request.traffic_annotation =
11821       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11822 
11823   session_deps_.proxy_resolution_service =
11824       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
11825           "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
11826   RecordingTestNetLog net_log;
11827   session_deps_.net_log = &net_log;
11828 
11829   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11830   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11831 
11832   unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
11833   unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
11834 
11835   MockWrite data_writes[] = {
11836       MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
11837                 base::size(write_buffer)),
11838       MockWrite("GET / HTTP/1.1\r\n"
11839                 "Host: www.example.org\r\n"
11840                 "Connection: keep-alive\r\n\r\n")};
11841 
11842   MockRead data_reads[] = {
11843       MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
11844                base::size(read_buffer)),
11845       MockRead("HTTP/1.0 200 OK\r\n"),
11846       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11847       MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
11848 
11849   StaticSocketDataProvider data(data_reads, data_writes);
11850   session_deps_.socket_factory->AddSocketDataProvider(&data);
11851 
11852   SSLSocketDataProvider ssl(ASYNC, OK);
11853   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11854 
11855   TestCompletionCallback callback;
11856 
11857   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11858   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11859 
11860   rv = callback.WaitForResult();
11861   EXPECT_THAT(rv, IsOk());
11862 
11863   LoadTimingInfo load_timing_info;
11864   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
11865   TestLoadTimingNotReusedWithPac(load_timing_info,
11866                                  CONNECT_TIMING_HAS_SSL_TIMES);
11867 
11868   const HttpResponseInfo* response = trans.GetResponseInfo();
11869   ASSERT_TRUE(response);
11870   EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
11871 
11872   std::string response_text;
11873   rv = ReadTransaction(&trans, &response_text);
11874   EXPECT_THAT(rv, IsOk());
11875   EXPECT_EQ("Payload", response_text);
11876 }
11877 
TEST_F(HttpNetworkTransactionTest,SOCKS4_HTTP_GET_no_PAC)11878 TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
11879   HttpRequestInfo request;
11880   request.method = "GET";
11881   request.url = GURL("http://www.example.org/");
11882   request.traffic_annotation =
11883       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11884 
11885   session_deps_.proxy_resolution_service =
11886       ConfiguredProxyResolutionService::CreateFixed(
11887           "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
11888   RecordingTestNetLog net_log;
11889   session_deps_.net_log = &net_log;
11890 
11891   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11892   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11893 
11894   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
11895   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
11896 
11897   MockWrite data_writes[] = {
11898       MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
11899       MockWrite("GET / HTTP/1.1\r\n"
11900                 "Host: www.example.org\r\n"
11901                 "Connection: keep-alive\r\n\r\n")};
11902 
11903   MockRead data_reads[] = {
11904       MockRead(ASYNC, read_buffer, base::size(read_buffer)),
11905       MockRead("HTTP/1.0 200 OK\r\n"),
11906       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11907       MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
11908 
11909   StaticSocketDataProvider data(data_reads, data_writes);
11910   session_deps_.socket_factory->AddSocketDataProvider(&data);
11911 
11912   TestCompletionCallback callback;
11913 
11914   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11915   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11916 
11917   rv = callback.WaitForResult();
11918   EXPECT_THAT(rv, IsOk());
11919 
11920   const HttpResponseInfo* response = trans.GetResponseInfo();
11921   ASSERT_TRUE(response);
11922 
11923   LoadTimingInfo load_timing_info;
11924   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
11925   TestLoadTimingNotReused(load_timing_info,
11926                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11927 
11928   std::string response_text;
11929   rv = ReadTransaction(&trans, &response_text);
11930   EXPECT_THAT(rv, IsOk());
11931   EXPECT_EQ("Payload", response_text);
11932 }
11933 
TEST_F(HttpNetworkTransactionTest,SOCKS5_HTTP_GET)11934 TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
11935   HttpRequestInfo request;
11936   request.method = "GET";
11937   request.url = GURL("http://www.example.org/");
11938   request.traffic_annotation =
11939       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11940 
11941   session_deps_.proxy_resolution_service =
11942       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
11943           "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
11944   RecordingTestNetLog net_log;
11945   session_deps_.net_log = &net_log;
11946 
11947   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11948   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11949 
11950   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11951   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
11952   const char kSOCKS5OkRequest[] = {
11953       0x05,  // Version
11954       0x01,  // Command (CONNECT)
11955       0x00,  // Reserved.
11956       0x03,  // Address type (DOMAINNAME).
11957       0x0F,  // Length of domain (15)
11958       'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e',  // Domain string
11959       '.', 'o', 'r', 'g', 0x00, 0x50,  // 16-bit port (80)
11960   };
11961   const char kSOCKS5OkResponse[] =
11962       { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
11963 
11964   MockWrite data_writes[] = {
11965       MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
11966       MockWrite(ASYNC, kSOCKS5OkRequest, base::size(kSOCKS5OkRequest)),
11967       MockWrite("GET / HTTP/1.1\r\n"
11968                 "Host: www.example.org\r\n"
11969                 "Connection: keep-alive\r\n\r\n")};
11970 
11971   MockRead data_reads[] = {
11972       MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11973       MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11974       MockRead("HTTP/1.0 200 OK\r\n"),
11975       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11976       MockRead("Payload"),
11977       MockRead(SYNCHRONOUS, OK)};
11978 
11979   StaticSocketDataProvider data(data_reads, data_writes);
11980   session_deps_.socket_factory->AddSocketDataProvider(&data);
11981 
11982   TestCompletionCallback callback;
11983 
11984   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11985   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11986 
11987   rv = callback.WaitForResult();
11988   EXPECT_THAT(rv, IsOk());
11989 
11990   const HttpResponseInfo* response = trans.GetResponseInfo();
11991   ASSERT_TRUE(response);
11992   EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
11993 
11994   LoadTimingInfo load_timing_info;
11995   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
11996   TestLoadTimingNotReusedWithPac(load_timing_info,
11997                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11998 
11999   std::string response_text;
12000   rv = ReadTransaction(&trans, &response_text);
12001   EXPECT_THAT(rv, IsOk());
12002   EXPECT_EQ("Payload", response_text);
12003 }
12004 
TEST_F(HttpNetworkTransactionTest,SOCKS5_SSL_GET)12005 TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
12006   HttpRequestInfo request;
12007   request.method = "GET";
12008   request.url = GURL("https://www.example.org/");
12009   request.traffic_annotation =
12010       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12011 
12012   session_deps_.proxy_resolution_service =
12013       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
12014           "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
12015   RecordingTestNetLog net_log;
12016   session_deps_.net_log = &net_log;
12017 
12018   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12019   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12020 
12021   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
12022   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
12023   const unsigned char kSOCKS5OkRequest[] = {
12024       0x05,  // Version
12025       0x01,  // Command (CONNECT)
12026       0x00,  // Reserved.
12027       0x03,  // Address type (DOMAINNAME).
12028       0x0F,  // Length of domain (15)
12029       'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e',  // Domain string
12030       '.', 'o', 'r', 'g', 0x01, 0xBB,  // 16-bit port (443)
12031   };
12032 
12033   const char kSOCKS5OkResponse[] =
12034       { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
12035 
12036   MockWrite data_writes[] = {
12037       MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
12038       MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
12039                 base::size(kSOCKS5OkRequest)),
12040       MockWrite("GET / HTTP/1.1\r\n"
12041                 "Host: www.example.org\r\n"
12042                 "Connection: keep-alive\r\n\r\n")};
12043 
12044   MockRead data_reads[] = {
12045       MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
12046       MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
12047       MockRead("HTTP/1.0 200 OK\r\n"),
12048       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
12049       MockRead("Payload"),
12050       MockRead(SYNCHRONOUS, OK)};
12051 
12052   StaticSocketDataProvider data(data_reads, data_writes);
12053   session_deps_.socket_factory->AddSocketDataProvider(&data);
12054 
12055   SSLSocketDataProvider ssl(ASYNC, OK);
12056   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12057 
12058   TestCompletionCallback callback;
12059 
12060   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12061   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12062 
12063   rv = callback.WaitForResult();
12064   EXPECT_THAT(rv, IsOk());
12065 
12066   const HttpResponseInfo* response = trans.GetResponseInfo();
12067   ASSERT_TRUE(response);
12068   EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
12069 
12070   LoadTimingInfo load_timing_info;
12071   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
12072   TestLoadTimingNotReusedWithPac(load_timing_info,
12073                                  CONNECT_TIMING_HAS_SSL_TIMES);
12074 
12075   std::string response_text;
12076   rv = ReadTransaction(&trans, &response_text);
12077   EXPECT_THAT(rv, IsOk());
12078   EXPECT_EQ("Payload", response_text);
12079 }
12080 
12081 namespace {
12082 
12083 // Tests that for connection endpoints the group ids are correctly set.
12084 
12085 struct GroupIdTest {
12086   std::string proxy_server;
12087   std::string url;
12088   ClientSocketPool::GroupId expected_group_id;
12089   bool ssl;
12090 };
12091 
SetupSessionForGroupIdTests(SpdySessionDependencies * session_deps_)12092 std::unique_ptr<HttpNetworkSession> SetupSessionForGroupIdTests(
12093     SpdySessionDependencies* session_deps_) {
12094   std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
12095 
12096   HttpServerProperties* http_server_properties =
12097       session->http_server_properties();
12098   AlternativeService alternative_service(kProtoHTTP2, "", 444);
12099   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
12100   http_server_properties->SetHttp2AlternativeService(
12101       url::SchemeHostPort("https", "host.with.alternate", 443),
12102       NetworkIsolationKey(), alternative_service, expiration);
12103 
12104   return session;
12105 }
12106 
GroupIdTransactionHelper(const std::string & url,HttpNetworkSession * session)12107 int GroupIdTransactionHelper(const std::string& url,
12108                              HttpNetworkSession* session) {
12109   HttpRequestInfo request;
12110   request.method = "GET";
12111   request.url = GURL(url);
12112   request.traffic_annotation =
12113       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12114 
12115   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
12116 
12117   TestCompletionCallback callback;
12118 
12119   // We do not complete this request, the dtor will clean the transaction up.
12120   return trans.Start(&request, callback.callback(), NetLogWithSource());
12121 }
12122 
12123 }  // namespace
12124 
TEST_F(HttpNetworkTransactionTest,GroupIdForDirectConnections)12125 TEST_F(HttpNetworkTransactionTest, GroupIdForDirectConnections) {
12126   const GroupIdTest tests[] = {
12127       {
12128           "",  // unused
12129           "http://www.example.org/direct",
12130           ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
12131                                     ClientSocketPool::SocketType::kHttp,
12132                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12133                                     NetworkIsolationKey(),
12134                                     false /* disable_secure_dns */),
12135           false,
12136       },
12137       {
12138           "",  // unused
12139           "http://[2001:1418:13:1::25]/direct",
12140           ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 80),
12141                                     ClientSocketPool::SocketType::kHttp,
12142                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12143                                     NetworkIsolationKey(),
12144                                     false /* disable_secure_dns */),
12145           false,
12146       },
12147 
12148       // SSL Tests
12149       {
12150           "",  // unused
12151           "https://www.example.org/direct_ssl",
12152           ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
12153                                     ClientSocketPool::SocketType::kSsl,
12154                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12155                                     NetworkIsolationKey(),
12156                                     false /* disable_secure_dns */),
12157           true,
12158       },
12159       {
12160           "",  // unused
12161           "https://[2001:1418:13:1::25]/direct",
12162           ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 443),
12163                                     ClientSocketPool::SocketType::kSsl,
12164                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12165                                     NetworkIsolationKey(),
12166                                     false /* disable_secure_dns */),
12167           true,
12168       },
12169       {
12170           "",  // unused
12171           "https://host.with.alternate/direct",
12172           ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
12173                                     ClientSocketPool::SocketType::kSsl,
12174                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12175                                     NetworkIsolationKey(),
12176                                     false /* disable_secure_dns */),
12177           true,
12178       },
12179   };
12180 
12181   for (size_t i = 0; i < base::size(tests); ++i) {
12182     session_deps_.proxy_resolution_service =
12183         ConfiguredProxyResolutionService::CreateFixed(
12184             tests[i].proxy_server, TRAFFIC_ANNOTATION_FOR_TESTS);
12185     std::unique_ptr<HttpNetworkSession> session(
12186         SetupSessionForGroupIdTests(&session_deps_));
12187 
12188     HttpNetworkSessionPeer peer(session.get());
12189     CaptureGroupIdTransportSocketPool* transport_conn_pool =
12190         new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
12191     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
12192     mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
12193                                      base::WrapUnique(transport_conn_pool));
12194     peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
12195 
12196     EXPECT_EQ(ERR_IO_PENDING,
12197               GroupIdTransactionHelper(tests[i].url, session.get()));
12198     EXPECT_EQ(tests[i].expected_group_id,
12199               transport_conn_pool->last_group_id_received());
12200     EXPECT_TRUE(transport_conn_pool->socket_requested());
12201   }
12202 }
12203 
TEST_F(HttpNetworkTransactionTest,GroupIdForHTTPProxyConnections)12204 TEST_F(HttpNetworkTransactionTest, GroupIdForHTTPProxyConnections) {
12205   const GroupIdTest tests[] = {
12206       {
12207           "http_proxy",
12208           "http://www.example.org/http_proxy_normal",
12209           ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
12210                                     ClientSocketPool::SocketType::kHttp,
12211                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12212                                     NetworkIsolationKey(),
12213                                     false /* disable_secure_dns */),
12214           false,
12215       },
12216 
12217       // SSL Tests
12218       {
12219           "http_proxy",
12220           "https://www.example.org/http_connect_ssl",
12221           ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
12222                                     ClientSocketPool::SocketType::kSsl,
12223                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12224                                     NetworkIsolationKey(),
12225                                     false /* disable_secure_dns */),
12226           true,
12227       },
12228 
12229       {
12230           "http_proxy",
12231           "https://host.with.alternate/direct",
12232           ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
12233                                     ClientSocketPool::SocketType::kSsl,
12234                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12235                                     NetworkIsolationKey(),
12236                                     false /* disable_secure_dns */),
12237           true,
12238       },
12239   };
12240 
12241   for (size_t i = 0; i < base::size(tests); ++i) {
12242     session_deps_.proxy_resolution_service =
12243         ConfiguredProxyResolutionService::CreateFixed(
12244             tests[i].proxy_server, TRAFFIC_ANNOTATION_FOR_TESTS);
12245     std::unique_ptr<HttpNetworkSession> session(
12246         SetupSessionForGroupIdTests(&session_deps_));
12247 
12248     HttpNetworkSessionPeer peer(session.get());
12249 
12250     ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
12251                              HostPortPair("http_proxy", 80));
12252     CaptureGroupIdTransportSocketPool* http_proxy_pool =
12253         new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
12254     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
12255     mock_pool_manager->SetSocketPool(proxy_server,
12256                                      base::WrapUnique(http_proxy_pool));
12257     peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
12258 
12259     EXPECT_EQ(ERR_IO_PENDING,
12260               GroupIdTransactionHelper(tests[i].url, session.get()));
12261     EXPECT_EQ(tests[i].expected_group_id,
12262               http_proxy_pool->last_group_id_received());
12263   }
12264 }
12265 
TEST_F(HttpNetworkTransactionTest,GroupIdForSOCKSConnections)12266 TEST_F(HttpNetworkTransactionTest, GroupIdForSOCKSConnections) {
12267   const GroupIdTest tests[] = {
12268       {
12269           "socks4://socks_proxy:1080",
12270           "http://www.example.org/socks4_direct",
12271           ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
12272                                     ClientSocketPool::SocketType::kHttp,
12273                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12274                                     NetworkIsolationKey(),
12275                                     false /* disable_secure_dns */),
12276           false,
12277       },
12278       {
12279           "socks5://socks_proxy:1080",
12280           "http://www.example.org/socks5_direct",
12281           ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
12282                                     ClientSocketPool::SocketType::kHttp,
12283                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12284                                     NetworkIsolationKey(),
12285                                     false /* disable_secure_dns */),
12286           false,
12287       },
12288 
12289       // SSL Tests
12290       {
12291           "socks4://socks_proxy:1080",
12292           "https://www.example.org/socks4_ssl",
12293           ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
12294                                     ClientSocketPool::SocketType::kSsl,
12295                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12296                                     NetworkIsolationKey(),
12297                                     false /* disable_secure_dns */),
12298           true,
12299       },
12300       {
12301           "socks5://socks_proxy:1080",
12302           "https://www.example.org/socks5_ssl",
12303           ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
12304                                     ClientSocketPool::SocketType::kSsl,
12305                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12306                                     NetworkIsolationKey(),
12307                                     false /* disable_secure_dns */),
12308           true,
12309       },
12310 
12311       {
12312           "socks4://socks_proxy:1080",
12313           "https://host.with.alternate/direct",
12314           ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
12315                                     ClientSocketPool::SocketType::kSsl,
12316                                     PrivacyMode::PRIVACY_MODE_DISABLED,
12317                                     NetworkIsolationKey(),
12318                                     false /* disable_secure_dns */),
12319           true,
12320       },
12321   };
12322 
12323   for (size_t i = 0; i < base::size(tests); ++i) {
12324     session_deps_.proxy_resolution_service =
12325         ConfiguredProxyResolutionService::CreateFixed(
12326             tests[i].proxy_server, TRAFFIC_ANNOTATION_FOR_TESTS);
12327     std::unique_ptr<HttpNetworkSession> session(
12328         SetupSessionForGroupIdTests(&session_deps_));
12329 
12330     HttpNetworkSessionPeer peer(session.get());
12331 
12332     ProxyServer proxy_server(
12333         ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
12334     ASSERT_TRUE(proxy_server.is_valid());
12335     CaptureGroupIdTransportSocketPool* socks_conn_pool =
12336         new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
12337     auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
12338     mock_pool_manager->SetSocketPool(proxy_server,
12339                                      base::WrapUnique(socks_conn_pool));
12340     peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
12341 
12342     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12343 
12344     EXPECT_EQ(ERR_IO_PENDING,
12345               GroupIdTransactionHelper(tests[i].url, session.get()));
12346     EXPECT_EQ(tests[i].expected_group_id,
12347               socks_conn_pool->last_group_id_received());
12348   }
12349 }
12350 
TEST_F(HttpNetworkTransactionTest,ReconsiderProxyAfterFailedConnection)12351 TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
12352   HttpRequestInfo request;
12353   request.method = "GET";
12354   request.url = GURL("http://www.example.org/");
12355   request.traffic_annotation =
12356       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12357 
12358   session_deps_.proxy_resolution_service =
12359       ConfiguredProxyResolutionService::CreateFixed(
12360           "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
12361 
12362   // This simulates failure resolving all hostnames; that means we will fail
12363   // connecting to both proxies (myproxy:70 and foobar:80).
12364   session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
12365 
12366   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12367   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12368 
12369   TestCompletionCallback callback;
12370 
12371   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12372   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12373 
12374   rv = callback.WaitForResult();
12375   EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
12376 }
12377 
12378 // Make sure we can handle an error when writing the request.
TEST_F(HttpNetworkTransactionTest,RequestWriteError)12379 TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
12380   HttpRequestInfo request;
12381   request.method = "GET";
12382   request.url = GURL("http://www.foo.com/");
12383   request.traffic_annotation =
12384       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12385 
12386   MockWrite write_failure[] = {
12387     MockWrite(ASYNC, ERR_CONNECTION_RESET),
12388   };
12389   StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
12390   session_deps_.socket_factory->AddSocketDataProvider(&data);
12391   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12392 
12393   TestCompletionCallback callback;
12394 
12395   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12396 
12397   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12398   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12399 
12400   rv = callback.WaitForResult();
12401   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
12402 
12403   IPEndPoint endpoint;
12404   EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
12405   EXPECT_LT(0u, endpoint.address().size());
12406 }
12407 
12408 // Check that a connection closed after the start of the headers finishes ok.
TEST_F(HttpNetworkTransactionTest,ConnectionClosedAfterStartOfHeaders)12409 TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
12410   HttpRequestInfo request;
12411   request.method = "GET";
12412   request.url = GURL("http://www.foo.com/");
12413   request.traffic_annotation =
12414       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12415 
12416   MockRead data_reads[] = {
12417     MockRead("HTTP/1."),
12418     MockRead(SYNCHRONOUS, OK),
12419   };
12420 
12421   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
12422   session_deps_.socket_factory->AddSocketDataProvider(&data);
12423   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12424 
12425   TestCompletionCallback callback;
12426 
12427   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12428 
12429   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12430   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12431 
12432   rv = callback.WaitForResult();
12433   EXPECT_THAT(rv, IsOk());
12434 
12435   const HttpResponseInfo* response = trans.GetResponseInfo();
12436   ASSERT_TRUE(response);
12437 
12438   EXPECT_TRUE(response->headers);
12439   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
12440 
12441   std::string response_data;
12442   rv = ReadTransaction(&trans, &response_data);
12443   EXPECT_THAT(rv, IsOk());
12444   EXPECT_EQ("", response_data);
12445 
12446   IPEndPoint endpoint;
12447   EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
12448   EXPECT_LT(0u, endpoint.address().size());
12449 }
12450 
12451 // Make sure that a dropped connection while draining the body for auth
12452 // restart does the right thing.
TEST_F(HttpNetworkTransactionTest,DrainResetOK)12453 TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
12454   HttpRequestInfo request;
12455   request.method = "GET";
12456   request.url = GURL("http://www.example.org/");
12457   request.traffic_annotation =
12458       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12459 
12460   MockWrite data_writes1[] = {
12461       MockWrite(
12462           "GET / HTTP/1.1\r\n"
12463           "Host: www.example.org\r\n"
12464           "Connection: keep-alive\r\n\r\n"),
12465   };
12466 
12467   MockRead data_reads1[] = {
12468     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
12469     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
12470     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12471     MockRead("Content-Length: 14\r\n\r\n"),
12472     MockRead("Unauth"),
12473     MockRead(ASYNC, ERR_CONNECTION_RESET),
12474   };
12475 
12476   StaticSocketDataProvider data1(data_reads1, data_writes1);
12477   session_deps_.socket_factory->AddSocketDataProvider(&data1);
12478 
12479   // After calling trans.RestartWithAuth(), this is the request we should
12480   // be issuing -- the final header line contains the credentials.
12481   MockWrite data_writes2[] = {
12482       MockWrite(
12483           "GET / HTTP/1.1\r\n"
12484           "Host: www.example.org\r\n"
12485           "Connection: keep-alive\r\n"
12486           "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
12487   };
12488 
12489   // Lastly, the server responds with the actual content.
12490   MockRead data_reads2[] = {
12491     MockRead("HTTP/1.1 200 OK\r\n"),
12492     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12493     MockRead("Content-Length: 100\r\n\r\n"),
12494     MockRead(SYNCHRONOUS, OK),
12495   };
12496 
12497   StaticSocketDataProvider data2(data_reads2, data_writes2);
12498   session_deps_.socket_factory->AddSocketDataProvider(&data2);
12499   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12500 
12501   TestCompletionCallback callback1;
12502 
12503   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12504 
12505   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
12506   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12507 
12508   rv = callback1.WaitForResult();
12509   EXPECT_THAT(rv, IsOk());
12510 
12511   const HttpResponseInfo* response = trans.GetResponseInfo();
12512   ASSERT_TRUE(response);
12513   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
12514 
12515   TestCompletionCallback callback2;
12516 
12517   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
12518   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12519 
12520   rv = callback2.WaitForResult();
12521   EXPECT_THAT(rv, IsOk());
12522 
12523   response = trans.GetResponseInfo();
12524   ASSERT_TRUE(response);
12525   EXPECT_FALSE(response->auth_challenge.has_value());
12526   EXPECT_EQ(100, response->headers->GetContentLength());
12527 }
12528 
12529 // Test HTTPS connections going through a proxy that sends extra data.
TEST_F(HttpNetworkTransactionTest,HTTPSViaProxyWithExtraData)12530 TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
12531   session_deps_.proxy_resolution_service =
12532       ConfiguredProxyResolutionService::CreateFixed(
12533           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
12534 
12535   HttpRequestInfo request;
12536   request.method = "GET";
12537   request.url = GURL("https://www.example.org/");
12538   request.traffic_annotation =
12539       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12540 
12541   MockRead proxy_reads[] = {
12542     MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
12543     MockRead(SYNCHRONOUS, OK)
12544   };
12545 
12546   StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
12547   SSLSocketDataProvider ssl(ASYNC, OK);
12548 
12549   session_deps_.socket_factory->AddSocketDataProvider(&data);
12550   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12551 
12552   TestCompletionCallback callback;
12553 
12554   session_deps_.socket_factory->ResetNextMockIndexes();
12555 
12556   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12557   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12558 
12559   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12560   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12561 
12562   rv = callback.WaitForResult();
12563   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
12564 }
12565 
TEST_F(HttpNetworkTransactionTest,LargeContentLengthThenClose)12566 TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
12567   HttpRequestInfo request;
12568   request.method = "GET";
12569   request.url = GURL("http://www.example.org/");
12570   request.traffic_annotation =
12571       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12572 
12573   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12574   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12575 
12576   MockRead data_reads[] = {
12577     MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
12578     MockRead(SYNCHRONOUS, OK),
12579   };
12580 
12581   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
12582   session_deps_.socket_factory->AddSocketDataProvider(&data);
12583 
12584   TestCompletionCallback callback;
12585 
12586   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12587   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12588 
12589   EXPECT_THAT(callback.WaitForResult(), IsOk());
12590 
12591   const HttpResponseInfo* response = trans.GetResponseInfo();
12592   ASSERT_TRUE(response);
12593 
12594   EXPECT_TRUE(response->headers);
12595   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
12596 
12597   std::string response_data;
12598   rv = ReadTransaction(&trans, &response_data);
12599   EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
12600 }
12601 
TEST_F(HttpNetworkTransactionTest,UploadFileSmallerThanLength)12602 TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
12603   base::FilePath temp_file_path;
12604   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
12605   const uint64_t kFakeSize = 100000;  // file is actually blank
12606   UploadFileElementReader::ScopedOverridingContentLengthForTests
12607       overriding_content_length(kFakeSize);
12608 
12609   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
12610   element_readers.push_back(std::make_unique<UploadFileElementReader>(
12611       base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
12612       std::numeric_limits<uint64_t>::max(), base::Time()));
12613   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
12614 
12615   HttpRequestInfo request;
12616   request.method = "POST";
12617   request.url = GURL("http://www.example.org/upload");
12618   request.upload_data_stream = &upload_data_stream;
12619   request.traffic_annotation =
12620       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12621 
12622   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12623   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12624 
12625   MockRead data_reads[] = {
12626     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
12627     MockRead("hello world"),
12628     MockRead(SYNCHRONOUS, OK),
12629   };
12630   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
12631   session_deps_.socket_factory->AddSocketDataProvider(&data);
12632 
12633   TestCompletionCallback callback;
12634 
12635   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12636   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12637 
12638   rv = callback.WaitForResult();
12639   EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
12640 
12641   const HttpResponseInfo* response = trans.GetResponseInfo();
12642   ASSERT_TRUE(response);
12643 
12644   EXPECT_FALSE(response->headers);
12645 
12646   base::DeleteFile(temp_file_path, false);
12647 }
12648 
TEST_F(HttpNetworkTransactionTest,UploadUnreadableFile)12649 TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
12650   base::FilePath temp_file;
12651   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
12652   std::string temp_file_content("Unreadable file.");
12653   ASSERT_EQ(static_cast<int>(temp_file_content.length()),
12654             base::WriteFile(temp_file, temp_file_content.c_str(),
12655                             temp_file_content.length()));
12656   ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
12657 
12658   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
12659   element_readers.push_back(std::make_unique<UploadFileElementReader>(
12660       base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
12661       std::numeric_limits<uint64_t>::max(), base::Time()));
12662   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
12663 
12664   HttpRequestInfo request;
12665   request.method = "POST";
12666   request.url = GURL("http://www.example.org/upload");
12667   request.upload_data_stream = &upload_data_stream;
12668   request.traffic_annotation =
12669       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12670 
12671   // If we try to upload an unreadable file, the transaction should fail.
12672   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12673   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12674 
12675   StaticSocketDataProvider data;
12676   session_deps_.socket_factory->AddSocketDataProvider(&data);
12677 
12678   TestCompletionCallback callback;
12679 
12680   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12681   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12682 
12683   rv = callback.WaitForResult();
12684   EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
12685 
12686   base::DeleteFile(temp_file, false);
12687 }
12688 
TEST_F(HttpNetworkTransactionTest,CancelDuringInitRequestBody)12689 TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
12690   class FakeUploadElementReader : public UploadElementReader {
12691    public:
12692     FakeUploadElementReader() = default;
12693     ~FakeUploadElementReader() override = default;
12694 
12695     CompletionOnceCallback TakeCallback() { return std::move(callback_); }
12696 
12697     // UploadElementReader overrides:
12698     int Init(CompletionOnceCallback callback) override {
12699       callback_ = std::move(callback);
12700       return ERR_IO_PENDING;
12701     }
12702     uint64_t GetContentLength() const override { return 0; }
12703     uint64_t BytesRemaining() const override { return 0; }
12704     int Read(IOBuffer* buf,
12705              int buf_length,
12706              CompletionOnceCallback callback) override {
12707       return ERR_FAILED;
12708     }
12709 
12710    private:
12711     CompletionOnceCallback callback_;
12712   };
12713 
12714   FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
12715   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
12716   element_readers.push_back(base::WrapUnique(fake_reader));
12717   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
12718 
12719   HttpRequestInfo request;
12720   request.method = "POST";
12721   request.url = GURL("http://www.example.org/upload");
12722   request.upload_data_stream = &upload_data_stream;
12723   request.traffic_annotation =
12724       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12725 
12726   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12727   auto trans =
12728       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
12729 
12730   StaticSocketDataProvider data;
12731   session_deps_.socket_factory->AddSocketDataProvider(&data);
12732 
12733   TestCompletionCallback callback;
12734   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12735   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12736   base::RunLoop().RunUntilIdle();
12737 
12738   // Transaction is pending on request body initialization.
12739   CompletionOnceCallback init_callback = fake_reader->TakeCallback();
12740   ASSERT_FALSE(init_callback.is_null());
12741 
12742   // Return Init()'s result after the transaction gets destroyed.
12743   trans.reset();
12744   std::move(init_callback).Run(OK);  // Should not crash.
12745 }
12746 
12747 // Tests that changes to Auth realms are treated like auth rejections.
TEST_F(HttpNetworkTransactionTest,ChangeAuthRealms)12748 TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
12749   HttpRequestInfo request;
12750   request.method = "GET";
12751   request.url = GURL("http://www.example.org/");
12752   request.traffic_annotation =
12753       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12754 
12755   // First transaction will request a resource and receive a Basic challenge
12756   // with realm="first_realm".
12757   MockWrite data_writes1[] = {
12758       MockWrite(
12759           "GET / HTTP/1.1\r\n"
12760           "Host: www.example.org\r\n"
12761           "Connection: keep-alive\r\n"
12762           "\r\n"),
12763   };
12764   MockRead data_reads1[] = {
12765     MockRead("HTTP/1.1 401 Unauthorized\r\n"
12766              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
12767              "\r\n"),
12768   };
12769 
12770   // After calling trans.RestartWithAuth(), provide an Authentication header
12771   // for first_realm. The server will reject and provide a challenge with
12772   // second_realm.
12773   MockWrite data_writes2[] = {
12774       MockWrite(
12775           "GET / HTTP/1.1\r\n"
12776           "Host: www.example.org\r\n"
12777           "Connection: keep-alive\r\n"
12778           "Authorization: Basic Zmlyc3Q6YmF6\r\n"
12779           "\r\n"),
12780   };
12781   MockRead data_reads2[] = {
12782     MockRead("HTTP/1.1 401 Unauthorized\r\n"
12783              "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
12784              "\r\n"),
12785   };
12786 
12787   // This again fails, and goes back to first_realm. Make sure that the
12788   // entry is removed from cache.
12789   MockWrite data_writes3[] = {
12790       MockWrite(
12791           "GET / HTTP/1.1\r\n"
12792           "Host: www.example.org\r\n"
12793           "Connection: keep-alive\r\n"
12794           "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
12795           "\r\n"),
12796   };
12797   MockRead data_reads3[] = {
12798     MockRead("HTTP/1.1 401 Unauthorized\r\n"
12799              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
12800              "\r\n"),
12801   };
12802 
12803   // Try one last time (with the correct password) and get the resource.
12804   MockWrite data_writes4[] = {
12805       MockWrite(
12806           "GET / HTTP/1.1\r\n"
12807           "Host: www.example.org\r\n"
12808           "Connection: keep-alive\r\n"
12809           "Authorization: Basic Zmlyc3Q6YmFy\r\n"
12810           "\r\n"),
12811   };
12812   MockRead data_reads4[] = {
12813     MockRead("HTTP/1.1 200 OK\r\n"
12814              "Content-Type: text/html; charset=iso-8859-1\r\n"
12815              "Content-Length: 5\r\n"
12816              "\r\n"
12817              "hello"),
12818   };
12819 
12820   StaticSocketDataProvider data1(data_reads1, data_writes1);
12821   StaticSocketDataProvider data2(data_reads2, data_writes2);
12822   StaticSocketDataProvider data3(data_reads3, data_writes3);
12823   StaticSocketDataProvider data4(data_reads4, data_writes4);
12824   session_deps_.socket_factory->AddSocketDataProvider(&data1);
12825   session_deps_.socket_factory->AddSocketDataProvider(&data2);
12826   session_deps_.socket_factory->AddSocketDataProvider(&data3);
12827   session_deps_.socket_factory->AddSocketDataProvider(&data4);
12828 
12829   TestCompletionCallback callback1;
12830 
12831   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12832   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12833 
12834   // Issue the first request with Authorize headers. There should be a
12835   // password prompt for first_realm waiting to be filled in after the
12836   // transaction completes.
12837   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
12838   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12839   rv = callback1.WaitForResult();
12840   EXPECT_THAT(rv, IsOk());
12841   const HttpResponseInfo* response = trans.GetResponseInfo();
12842   ASSERT_TRUE(response);
12843   base::Optional<AuthChallengeInfo> challenge = response->auth_challenge;
12844   ASSERT_TRUE(challenge);
12845   EXPECT_FALSE(challenge->is_proxy);
12846   EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
12847   EXPECT_EQ("first_realm", challenge->realm);
12848   EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
12849 
12850   // Issue the second request with an incorrect password. There should be a
12851   // password prompt for second_realm waiting to be filled in after the
12852   // transaction completes.
12853   TestCompletionCallback callback2;
12854   rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
12855                              callback2.callback());
12856   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12857   rv = callback2.WaitForResult();
12858   EXPECT_THAT(rv, IsOk());
12859   response = trans.GetResponseInfo();
12860   ASSERT_TRUE(response);
12861   challenge = response->auth_challenge;
12862   ASSERT_TRUE(challenge);
12863   EXPECT_FALSE(challenge->is_proxy);
12864   EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
12865   EXPECT_EQ("second_realm", challenge->realm);
12866   EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
12867 
12868   // Issue the third request with another incorrect password. There should be
12869   // a password prompt for first_realm waiting to be filled in. If the password
12870   // prompt is not present, it indicates that the HttpAuthCacheEntry for
12871   // first_realm was not correctly removed.
12872   TestCompletionCallback callback3;
12873   rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
12874                              callback3.callback());
12875   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12876   rv = callback3.WaitForResult();
12877   EXPECT_THAT(rv, IsOk());
12878   response = trans.GetResponseInfo();
12879   ASSERT_TRUE(response);
12880   challenge = response->auth_challenge;
12881   ASSERT_TRUE(challenge);
12882   EXPECT_FALSE(challenge->is_proxy);
12883   EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
12884   EXPECT_EQ("first_realm", challenge->realm);
12885   EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
12886 
12887   // Issue the fourth request with the correct password and username.
12888   TestCompletionCallback callback4;
12889   rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
12890                              callback4.callback());
12891   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12892   rv = callback4.WaitForResult();
12893   EXPECT_THAT(rv, IsOk());
12894   response = trans.GetResponseInfo();
12895   ASSERT_TRUE(response);
12896   EXPECT_FALSE(response->auth_challenge.has_value());
12897 }
12898 
12899 // Regression test for https://crbug.com/754395.
TEST_F(HttpNetworkTransactionTest,IgnoreAltSvcWithInvalidCert)12900 TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
12901   MockRead data_reads[] = {
12902       MockRead("HTTP/1.1 200 OK\r\n"),
12903       MockRead(kAlternativeServiceHttpHeader),
12904       MockRead("\r\n"),
12905       MockRead("hello world"),
12906       MockRead(SYNCHRONOUS, OK),
12907   };
12908 
12909   HttpRequestInfo request;
12910   request.method = "GET";
12911   request.url = GURL("https://www.example.org/");
12912   request.traffic_annotation =
12913       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12914 
12915   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
12916   session_deps_.socket_factory->AddSocketDataProvider(&data);
12917 
12918   SSLSocketDataProvider ssl(ASYNC, OK);
12919   ssl.ssl_info.cert =
12920       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12921   ASSERT_TRUE(ssl.ssl_info.cert);
12922   ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
12923   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12924 
12925   TestCompletionCallback callback;
12926 
12927   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12928   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12929 
12930   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12931   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12932 
12933   url::SchemeHostPort test_server(request.url);
12934   HttpServerProperties* http_server_properties =
12935       session->http_server_properties();
12936   EXPECT_TRUE(
12937       http_server_properties
12938           ->GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
12939           .empty());
12940 
12941   EXPECT_THAT(callback.WaitForResult(), IsOk());
12942 
12943   const HttpResponseInfo* response = trans.GetResponseInfo();
12944   ASSERT_TRUE(response);
12945   ASSERT_TRUE(response->headers);
12946   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12947   EXPECT_FALSE(response->was_fetched_via_spdy);
12948   EXPECT_FALSE(response->was_alpn_negotiated);
12949 
12950   std::string response_data;
12951   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12952   EXPECT_EQ("hello world", response_data);
12953 
12954   EXPECT_TRUE(
12955       http_server_properties
12956           ->GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
12957           .empty());
12958 }
12959 
TEST_F(HttpNetworkTransactionTest,HonorAlternativeServiceHeader)12960 TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
12961   MockRead data_reads[] = {
12962       MockRead("HTTP/1.1 200 OK\r\n"),
12963       MockRead(kAlternativeServiceHttpHeader),
12964       MockRead("\r\n"),
12965       MockRead("hello world"),
12966       MockRead(SYNCHRONOUS, OK),
12967   };
12968 
12969   HttpRequestInfo request;
12970   request.method = "GET";
12971   request.url = GURL("https://www.example.org/");
12972   request.traffic_annotation =
12973       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12974 
12975   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
12976   session_deps_.socket_factory->AddSocketDataProvider(&data);
12977 
12978   SSLSocketDataProvider ssl(ASYNC, OK);
12979   ssl.ssl_info.cert =
12980       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12981   ASSERT_TRUE(ssl.ssl_info.cert);
12982   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12983 
12984   TestCompletionCallback callback;
12985 
12986   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12987   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12988 
12989   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12990   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12991 
12992   url::SchemeHostPort test_server(request.url);
12993   HttpServerProperties* http_server_properties =
12994       session->http_server_properties();
12995   EXPECT_TRUE(
12996       http_server_properties
12997           ->GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
12998           .empty());
12999 
13000   EXPECT_THAT(callback.WaitForResult(), IsOk());
13001 
13002   const HttpResponseInfo* response = trans.GetResponseInfo();
13003   ASSERT_TRUE(response);
13004   ASSERT_TRUE(response->headers);
13005   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13006   EXPECT_FALSE(response->was_fetched_via_spdy);
13007   EXPECT_FALSE(response->was_alpn_negotiated);
13008 
13009   std::string response_data;
13010   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13011   EXPECT_EQ("hello world", response_data);
13012 
13013   AlternativeServiceInfoVector alternative_service_info_vector =
13014       http_server_properties->GetAlternativeServiceInfos(test_server,
13015                                                          NetworkIsolationKey());
13016   ASSERT_EQ(1u, alternative_service_info_vector.size());
13017   AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
13018   EXPECT_EQ(alternative_service,
13019             alternative_service_info_vector[0].alternative_service());
13020 }
13021 
TEST_F(HttpNetworkTransactionTest,HonorAlternativeServiceHeaderWithNetworkIsolationKey)13022 TEST_F(HttpNetworkTransactionTest,
13023        HonorAlternativeServiceHeaderWithNetworkIsolationKey) {
13024   base::test::ScopedFeatureList feature_list;
13025   feature_list.InitWithFeatures(
13026       // enabled_features
13027       {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
13028        // Need to partition connections by NetworkIsolationKey for
13029        // SpdySessionKeys to include NetworkIsolationKeys.
13030        features::kPartitionConnectionsByNetworkIsolationKey},
13031       // disabled_features
13032       {});
13033   // Since HttpServerProperties caches the feature value, have to create a new
13034   // one.
13035   session_deps_.http_server_properties =
13036       std::make_unique<HttpServerProperties>();
13037 
13038   const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
13039   const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
13040   const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
13041   const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
13042 
13043   MockRead data_reads[] = {
13044       MockRead("HTTP/1.1 200 OK\r\n"),
13045       MockRead(kAlternativeServiceHttpHeader),
13046       MockRead("\r\n"),
13047       MockRead("hello world"),
13048       MockRead(SYNCHRONOUS, OK),
13049   };
13050 
13051   HttpRequestInfo request;
13052   request.method = "GET";
13053   request.url = GURL("https://www.example.org/");
13054   request.traffic_annotation =
13055       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13056   request.network_isolation_key = kNetworkIsolationKey1;
13057 
13058   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
13059   session_deps_.socket_factory->AddSocketDataProvider(&data);
13060 
13061   SSLSocketDataProvider ssl(ASYNC, OK);
13062   ssl.ssl_info.cert =
13063       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
13064   ASSERT_TRUE(ssl.ssl_info.cert);
13065   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13066 
13067   TestCompletionCallback callback;
13068 
13069   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13070   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13071 
13072   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
13073   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13074 
13075   url::SchemeHostPort test_server(request.url);
13076   HttpServerProperties* http_server_properties =
13077       session->http_server_properties();
13078   EXPECT_TRUE(
13079       http_server_properties
13080           ->GetAlternativeServiceInfos(test_server, kNetworkIsolationKey1)
13081           .empty());
13082 
13083   EXPECT_THAT(callback.WaitForResult(), IsOk());
13084 
13085   const HttpResponseInfo* response = trans.GetResponseInfo();
13086   ASSERT_TRUE(response);
13087   ASSERT_TRUE(response->headers);
13088   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13089   EXPECT_FALSE(response->was_fetched_via_spdy);
13090   EXPECT_FALSE(response->was_alpn_negotiated);
13091 
13092   std::string response_data;
13093   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13094   EXPECT_EQ("hello world", response_data);
13095 
13096   AlternativeServiceInfoVector alternative_service_info_vector =
13097       http_server_properties->GetAlternativeServiceInfos(test_server,
13098                                                          kNetworkIsolationKey1);
13099   ASSERT_EQ(1u, alternative_service_info_vector.size());
13100   AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
13101   EXPECT_EQ(alternative_service,
13102             alternative_service_info_vector[0].alternative_service());
13103 
13104   // Make sure the alternative service information is only associated with
13105   // kNetworkIsolationKey1.
13106   EXPECT_TRUE(
13107       http_server_properties
13108           ->GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
13109           .empty());
13110   EXPECT_TRUE(
13111       http_server_properties
13112           ->GetAlternativeServiceInfos(test_server, kNetworkIsolationKey2)
13113           .empty());
13114 }
13115 
13116 // Regression test for https://crbug.com/615497.
TEST_F(HttpNetworkTransactionTest,DoNotParseAlternativeServiceHeaderOnInsecureRequest)13117 TEST_F(HttpNetworkTransactionTest,
13118        DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
13119   MockRead data_reads[] = {
13120       MockRead("HTTP/1.1 200 OK\r\n"),
13121       MockRead(kAlternativeServiceHttpHeader),
13122       MockRead("\r\n"),
13123       MockRead("hello world"),
13124       MockRead(SYNCHRONOUS, OK),
13125   };
13126 
13127   HttpRequestInfo request;
13128   request.method = "GET";
13129   request.url = GURL("http://www.example.org/");
13130   request.load_flags = 0;
13131   request.traffic_annotation =
13132       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13133 
13134   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
13135   session_deps_.socket_factory->AddSocketDataProvider(&data);
13136 
13137   TestCompletionCallback callback;
13138 
13139   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13140   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13141 
13142   url::SchemeHostPort test_server(request.url);
13143   HttpServerProperties* http_server_properties =
13144       session->http_server_properties();
13145   EXPECT_TRUE(
13146       http_server_properties
13147           ->GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
13148           .empty());
13149 
13150   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
13151   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13152   EXPECT_THAT(callback.WaitForResult(), IsOk());
13153 
13154   const HttpResponseInfo* response = trans.GetResponseInfo();
13155   ASSERT_TRUE(response);
13156   ASSERT_TRUE(response->headers);
13157   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13158   EXPECT_FALSE(response->was_fetched_via_spdy);
13159   EXPECT_FALSE(response->was_alpn_negotiated);
13160 
13161   std::string response_data;
13162   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13163   EXPECT_EQ("hello world", response_data);
13164 
13165   EXPECT_TRUE(
13166       http_server_properties
13167           ->GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
13168           .empty());
13169 }
13170 
13171 // HTTP/2 Alternative Services should be disabled by default.
13172 // TODO(bnc): Remove when https://crbug.com/615413 is fixed.
TEST_F(HttpNetworkTransactionTest,DisableHTTP2AlternativeServicesWithDifferentHost)13173 TEST_F(HttpNetworkTransactionTest,
13174        DisableHTTP2AlternativeServicesWithDifferentHost) {
13175   session_deps_.enable_http2_alternative_service = false;
13176 
13177   HttpRequestInfo request;
13178   request.method = "GET";
13179   request.url = GURL("https://www.example.org/");
13180   request.load_flags = 0;
13181   request.traffic_annotation =
13182       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13183 
13184   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13185   StaticSocketDataProvider first_data;
13186   first_data.set_connect_data(mock_connect);
13187   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
13188   SSLSocketDataProvider ssl_http11(ASYNC, OK);
13189   ssl_http11.next_proto = kProtoHTTP11;
13190   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
13191 
13192   MockRead data_reads[] = {
13193       MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
13194       MockRead(ASYNC, OK),
13195   };
13196   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
13197   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
13198 
13199   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13200 
13201   HttpServerProperties* http_server_properties =
13202       session->http_server_properties();
13203   AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
13204                                          444);
13205   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
13206   http_server_properties->SetHttp2AlternativeService(
13207       url::SchemeHostPort(request.url), NetworkIsolationKey(),
13208       alternative_service, expiration);
13209 
13210   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13211   TestCompletionCallback callback;
13212 
13213   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
13214   // Alternative service is not used, request fails.
13215   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
13216 }
13217 
13218 // Regression test for https://crbug.com/615497:
13219 // Alternative Services should be disabled for http origin.
TEST_F(HttpNetworkTransactionTest,DisableAlternativeServicesForInsecureOrigin)13220 TEST_F(HttpNetworkTransactionTest,
13221        DisableAlternativeServicesForInsecureOrigin) {
13222   HttpRequestInfo request;
13223   request.method = "GET";
13224   request.url = GURL("http://www.example.org/");
13225   request.load_flags = 0;
13226   request.traffic_annotation =
13227       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13228 
13229   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13230   StaticSocketDataProvider first_data;
13231   first_data.set_connect_data(mock_connect);
13232   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
13233 
13234   MockRead data_reads[] = {
13235       MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
13236       MockRead(ASYNC, OK),
13237   };
13238   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
13239   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
13240 
13241   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13242 
13243   HttpServerProperties* http_server_properties =
13244       session->http_server_properties();
13245   AlternativeService alternative_service(kProtoHTTP2, "", 444);
13246   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
13247   http_server_properties->SetHttp2AlternativeService(
13248       url::SchemeHostPort(request.url), NetworkIsolationKey(),
13249       alternative_service, expiration);
13250 
13251   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13252   TestCompletionCallback callback;
13253 
13254   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
13255   // Alternative service is not used, request fails.
13256   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
13257 }
13258 
TEST_F(HttpNetworkTransactionTest,ClearAlternativeServices)13259 TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
13260   // Set an alternative service for origin.
13261   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13262   HttpServerProperties* http_server_properties =
13263       session->http_server_properties();
13264   url::SchemeHostPort test_server("https", "www.example.org", 443);
13265   AlternativeService alternative_service(kProtoQUIC, "", 80);
13266   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
13267   http_server_properties->SetQuicAlternativeService(
13268       test_server, NetworkIsolationKey(), alternative_service, expiration,
13269       session->context().quic_context->params()->supported_versions);
13270   EXPECT_EQ(1u,
13271             http_server_properties
13272                 ->GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
13273                 .size());
13274 
13275   // Send a clear header.
13276   MockRead data_reads[] = {
13277       MockRead("HTTP/1.1 200 OK\r\n"),
13278       MockRead("Alt-Svc: clear\r\n"),
13279       MockRead("\r\n"),
13280       MockRead("hello world"),
13281       MockRead(SYNCHRONOUS, OK),
13282   };
13283   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
13284   session_deps_.socket_factory->AddSocketDataProvider(&data);
13285 
13286   SSLSocketDataProvider ssl(ASYNC, OK);
13287   ssl.ssl_info.cert =
13288       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
13289   ASSERT_TRUE(ssl.ssl_info.cert);
13290   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13291 
13292   HttpRequestInfo request;
13293   request.method = "GET";
13294   request.url = GURL("https://www.example.org/");
13295   request.traffic_annotation =
13296       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13297 
13298   TestCompletionCallback callback;
13299 
13300   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13301 
13302   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
13303   EXPECT_THAT(callback.GetResult(rv), IsOk());
13304 
13305   const HttpResponseInfo* response = trans.GetResponseInfo();
13306   ASSERT_TRUE(response);
13307   ASSERT_TRUE(response->headers);
13308   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13309   EXPECT_FALSE(response->was_fetched_via_spdy);
13310   EXPECT_FALSE(response->was_alpn_negotiated);
13311 
13312   std::string response_data;
13313   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13314   EXPECT_EQ("hello world", response_data);
13315 
13316   EXPECT_TRUE(
13317       http_server_properties
13318           ->GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
13319           .empty());
13320 }
13321 
TEST_F(HttpNetworkTransactionTest,HonorMultipleAlternativeServiceHeaders)13322 TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
13323   MockRead data_reads[] = {
13324       MockRead("HTTP/1.1 200 OK\r\n"),
13325       MockRead("Alt-Svc: h2=\"www.example.com:443\","),
13326       MockRead("h2=\":1234\"\r\n\r\n"),
13327       MockRead("hello world"),
13328       MockRead(SYNCHRONOUS, OK),
13329   };
13330 
13331   HttpRequestInfo request;
13332   request.method = "GET";
13333   request.url = GURL("https://www.example.org/");
13334   request.traffic_annotation =
13335       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13336 
13337   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
13338   session_deps_.socket_factory->AddSocketDataProvider(&data);
13339 
13340   SSLSocketDataProvider ssl(ASYNC, OK);
13341   ssl.ssl_info.cert =
13342       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
13343   ASSERT_TRUE(ssl.ssl_info.cert);
13344   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13345 
13346   TestCompletionCallback callback;
13347 
13348   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13349   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13350 
13351   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
13352   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13353 
13354   url::SchemeHostPort test_server("https", "www.example.org", 443);
13355   HttpServerProperties* http_server_properties =
13356       session->http_server_properties();
13357   EXPECT_TRUE(
13358       http_server_properties
13359           ->GetAlternativeServiceInfos(test_server, NetworkIsolationKey())
13360           .empty());
13361 
13362   EXPECT_THAT(callback.WaitForResult(), IsOk());
13363 
13364   const HttpResponseInfo* response = trans.GetResponseInfo();
13365   ASSERT_TRUE(response);
13366   ASSERT_TRUE(response->headers);
13367   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13368   EXPECT_FALSE(response->was_fetched_via_spdy);
13369   EXPECT_FALSE(response->was_alpn_negotiated);
13370 
13371   std::string response_data;
13372   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13373   EXPECT_EQ("hello world", response_data);
13374 
13375   AlternativeServiceInfoVector alternative_service_info_vector =
13376       http_server_properties->GetAlternativeServiceInfos(test_server,
13377                                                          NetworkIsolationKey());
13378   ASSERT_EQ(2u, alternative_service_info_vector.size());
13379 
13380   AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
13381   EXPECT_EQ(alternative_service,
13382             alternative_service_info_vector[0].alternative_service());
13383   AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
13384                                            1234);
13385   EXPECT_EQ(alternative_service_2,
13386             alternative_service_info_vector[1].alternative_service());
13387 }
13388 
TEST_F(HttpNetworkTransactionTest,IdentifyQuicBroken)13389 TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
13390   url::SchemeHostPort server("https", "origin.example.org", 443);
13391   HostPortPair alternative("alternative.example.org", 443);
13392   std::string origin_url = "https://origin.example.org:443";
13393   std::string alternative_url = "https://alternative.example.org:443";
13394 
13395   // Negotiate HTTP/1.1 with alternative.example.org.
13396   SSLSocketDataProvider ssl(ASYNC, OK);
13397   ssl.next_proto = kProtoHTTP11;
13398   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13399 
13400   // HTTP/1.1 data for request.
13401   MockWrite http_writes[] = {
13402       MockWrite("GET / HTTP/1.1\r\n"
13403                 "Host: alternative.example.org\r\n"
13404                 "Connection: keep-alive\r\n\r\n"),
13405   };
13406 
13407   MockRead http_reads[] = {
13408       MockRead("HTTP/1.1 200 OK\r\n"
13409                "Content-Type: text/html; charset=iso-8859-1\r\n"
13410                "Content-Length: 40\r\n\r\n"
13411                "first HTTP/1.1 response from alternative"),
13412   };
13413   StaticSocketDataProvider http_data(http_reads, http_writes);
13414   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13415 
13416   StaticSocketDataProvider data_refused;
13417   data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13418   session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13419 
13420   // Set up a QUIC alternative service for server.
13421   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13422   HttpServerProperties* http_server_properties =
13423       session->http_server_properties();
13424   AlternativeService alternative_service(kProtoQUIC, alternative);
13425   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
13426   http_server_properties->SetQuicAlternativeService(
13427       server, NetworkIsolationKey(), alternative_service, expiration,
13428       DefaultSupportedQuicVersions());
13429   // Mark the QUIC alternative service as broken.
13430   http_server_properties->MarkAlternativeServiceBroken(alternative_service,
13431                                                        NetworkIsolationKey());
13432 
13433   HttpRequestInfo request;
13434   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13435   request.method = "GET";
13436   request.url = GURL(origin_url);
13437   request.traffic_annotation =
13438       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13439 
13440   TestCompletionCallback callback;
13441   NetErrorDetails details;
13442   EXPECT_FALSE(details.quic_broken);
13443 
13444   trans.Start(&request, callback.callback(), NetLogWithSource());
13445   trans.PopulateNetErrorDetails(&details);
13446   EXPECT_TRUE(details.quic_broken);
13447 }
13448 
TEST_F(HttpNetworkTransactionTest,IdentifyQuicNotBroken)13449 TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
13450   url::SchemeHostPort server("https", "origin.example.org", 443);
13451   HostPortPair alternative1("alternative1.example.org", 443);
13452   HostPortPair alternative2("alternative2.example.org", 443);
13453   std::string origin_url = "https://origin.example.org:443";
13454   std::string alternative_url1 = "https://alternative1.example.org:443";
13455   std::string alternative_url2 = "https://alternative2.example.org:443";
13456 
13457   // Negotiate HTTP/1.1 with alternative1.example.org.
13458   SSLSocketDataProvider ssl(ASYNC, OK);
13459   ssl.next_proto = kProtoHTTP11;
13460   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13461 
13462   // HTTP/1.1 data for request.
13463   MockWrite http_writes[] = {
13464       MockWrite("GET / HTTP/1.1\r\n"
13465                 "Host: alternative1.example.org\r\n"
13466                 "Connection: keep-alive\r\n\r\n"),
13467   };
13468 
13469   MockRead http_reads[] = {
13470       MockRead("HTTP/1.1 200 OK\r\n"
13471                "Content-Type: text/html; charset=iso-8859-1\r\n"
13472                "Content-Length: 40\r\n\r\n"
13473                "first HTTP/1.1 response from alternative1"),
13474   };
13475   StaticSocketDataProvider http_data(http_reads, http_writes);
13476   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13477 
13478   StaticSocketDataProvider data_refused;
13479   data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13480   session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13481 
13482   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13483   HttpServerProperties* http_server_properties =
13484       session->http_server_properties();
13485 
13486   // Set up two QUIC alternative services for server.
13487   AlternativeServiceInfoVector alternative_service_info_vector;
13488   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
13489 
13490   AlternativeService alternative_service1(kProtoQUIC, alternative1);
13491   alternative_service_info_vector.push_back(
13492       AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
13493           alternative_service1, expiration,
13494           session->context().quic_context->params()->supported_versions));
13495   AlternativeService alternative_service2(kProtoQUIC, alternative2);
13496   alternative_service_info_vector.push_back(
13497       AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
13498           alternative_service2, expiration,
13499           session->context().quic_context->params()->supported_versions));
13500 
13501   http_server_properties->SetAlternativeServices(
13502       server, NetworkIsolationKey(), alternative_service_info_vector);
13503 
13504   // Mark one of the QUIC alternative service as broken.
13505   http_server_properties->MarkAlternativeServiceBroken(alternative_service1,
13506                                                        NetworkIsolationKey());
13507   EXPECT_EQ(2u, http_server_properties
13508                     ->GetAlternativeServiceInfos(server, NetworkIsolationKey())
13509                     .size());
13510 
13511   HttpRequestInfo request;
13512   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13513   request.method = "GET";
13514   request.url = GURL(origin_url);
13515   request.traffic_annotation =
13516       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13517 
13518   TestCompletionCallback callback;
13519   NetErrorDetails details;
13520   EXPECT_FALSE(details.quic_broken);
13521 
13522   trans.Start(&request, callback.callback(), NetLogWithSource());
13523   trans.PopulateNetErrorDetails(&details);
13524   EXPECT_FALSE(details.quic_broken);
13525 }
13526 
TEST_F(HttpNetworkTransactionTest,MarkBrokenAlternateProtocolAndFallback)13527 TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
13528   HttpRequestInfo request;
13529   request.method = "GET";
13530   request.url = GURL("https://www.example.org/");
13531   request.traffic_annotation =
13532       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13533 
13534   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13535   StaticSocketDataProvider first_data;
13536   first_data.set_connect_data(mock_connect);
13537   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
13538   SSLSocketDataProvider ssl_http11(ASYNC, OK);
13539   ssl_http11.next_proto = kProtoHTTP11;
13540   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
13541 
13542   MockRead data_reads[] = {
13543     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
13544     MockRead("hello world"),
13545     MockRead(ASYNC, OK),
13546   };
13547   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
13548   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
13549 
13550   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13551 
13552   HttpServerProperties* http_server_properties =
13553       session->http_server_properties();
13554   const url::SchemeHostPort server(request.url);
13555   // Port must be < 1024, or the header will be ignored (since initial port was
13556   // port 80 (another restricted port).
13557   // Port is ignored by MockConnect anyway.
13558   const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
13559                                                666);
13560   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
13561   http_server_properties->SetHttp2AlternativeService(
13562       server, NetworkIsolationKey(), alternative_service, expiration);
13563 
13564   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13565   TestCompletionCallback callback;
13566 
13567   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
13568   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13569   EXPECT_THAT(callback.WaitForResult(), IsOk());
13570 
13571   const HttpResponseInfo* response = trans.GetResponseInfo();
13572   ASSERT_TRUE(response);
13573   ASSERT_TRUE(response->headers);
13574   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13575 
13576   std::string response_data;
13577   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13578   EXPECT_EQ("hello world", response_data);
13579 
13580   const AlternativeServiceInfoVector alternative_service_info_vector =
13581       http_server_properties->GetAlternativeServiceInfos(server,
13582                                                          NetworkIsolationKey());
13583   ASSERT_EQ(1u, alternative_service_info_vector.size());
13584   EXPECT_EQ(alternative_service,
13585             alternative_service_info_vector[0].alternative_service());
13586   EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
13587       alternative_service, NetworkIsolationKey()));
13588 }
13589 
13590 // Ensure that we are not allowed to redirect traffic via an alternate protocol
13591 // to an unrestricted (port >= 1024) when the original traffic was on a
13592 // restricted port (port < 1024).  Ensure that we can redirect in all other
13593 // cases.
TEST_F(HttpNetworkTransactionTest,AlternateProtocolPortRestrictedBlocked)13594 TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
13595   HttpRequestInfo restricted_port_request;
13596   restricted_port_request.method = "GET";
13597   restricted_port_request.url = GURL("https://www.example.org:1023/");
13598   restricted_port_request.load_flags = 0;
13599   restricted_port_request.traffic_annotation =
13600       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13601 
13602   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13603   StaticSocketDataProvider first_data;
13604   first_data.set_connect_data(mock_connect);
13605   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
13606 
13607   MockRead data_reads[] = {
13608     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
13609     MockRead("hello world"),
13610     MockRead(ASYNC, OK),
13611   };
13612   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
13613   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
13614   SSLSocketDataProvider ssl_http11(ASYNC, OK);
13615   ssl_http11.next_proto = kProtoHTTP11;
13616   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
13617 
13618   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13619 
13620   HttpServerProperties* http_server_properties =
13621       session->http_server_properties();
13622   const int kUnrestrictedAlternatePort = 1024;
13623   AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
13624                                          kUnrestrictedAlternatePort);
13625   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
13626   http_server_properties->SetHttp2AlternativeService(
13627       url::SchemeHostPort(restricted_port_request.url), NetworkIsolationKey(),
13628       alternative_service, expiration);
13629 
13630   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13631   TestCompletionCallback callback;
13632 
13633   int rv = trans.Start(&restricted_port_request, callback.callback(),
13634                        NetLogWithSource());
13635   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13636   // Invalid change to unrestricted port should fail.
13637   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
13638 }
13639 
13640 // Ensure that we are allowed to redirect traffic via an alternate protocol to
13641 // an unrestricted (port >= 1024) when the original traffic was on a restricted
13642 // port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
TEST_F(HttpNetworkTransactionTest,AlternateProtocolPortRestrictedPermitted)13643 TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
13644   session_deps_.enable_user_alternate_protocol_ports = true;
13645 
13646   HttpRequestInfo restricted_port_request;
13647   restricted_port_request.method = "GET";
13648   restricted_port_request.url = GURL("https://www.example.org:1023/");
13649   restricted_port_request.load_flags = 0;
13650   restricted_port_request.traffic_annotation =
13651       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13652 
13653   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13654   StaticSocketDataProvider first_data;
13655   first_data.set_connect_data(mock_connect);
13656   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
13657 
13658   MockRead data_reads[] = {
13659     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
13660     MockRead("hello world"),
13661     MockRead(ASYNC, OK),
13662   };
13663   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
13664   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
13665   SSLSocketDataProvider ssl_http11(ASYNC, OK);
13666   ssl_http11.next_proto = kProtoHTTP11;
13667   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
13668 
13669   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13670 
13671   HttpServerProperties* http_server_properties =
13672       session->http_server_properties();
13673   const int kUnrestrictedAlternatePort = 1024;
13674   AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
13675                                          kUnrestrictedAlternatePort);
13676   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
13677   http_server_properties->SetHttp2AlternativeService(
13678       url::SchemeHostPort(restricted_port_request.url), NetworkIsolationKey(),
13679       alternative_service, expiration);
13680 
13681   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13682   TestCompletionCallback callback;
13683 
13684   EXPECT_EQ(ERR_IO_PENDING,
13685             trans.Start(&restricted_port_request, callback.callback(),
13686                         NetLogWithSource()));
13687   // Change to unrestricted port should succeed.
13688   EXPECT_THAT(callback.WaitForResult(), IsOk());
13689 }
13690 
13691 // Ensure that we are not allowed to redirect traffic via an alternate protocol
13692 // to an unrestricted (port >= 1024) when the original traffic was on a
13693 // restricted port (port < 1024).  Ensure that we can redirect in all other
13694 // cases.
TEST_F(HttpNetworkTransactionTest,AlternateProtocolPortRestrictedAllowed)13695 TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
13696   HttpRequestInfo restricted_port_request;
13697   restricted_port_request.method = "GET";
13698   restricted_port_request.url = GURL("https://www.example.org:1023/");
13699   restricted_port_request.load_flags = 0;
13700   restricted_port_request.traffic_annotation =
13701       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13702 
13703   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13704   StaticSocketDataProvider first_data;
13705   first_data.set_connect_data(mock_connect);
13706   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
13707 
13708   MockRead data_reads[] = {
13709     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
13710     MockRead("hello world"),
13711     MockRead(ASYNC, OK),
13712   };
13713   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
13714   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
13715 
13716   SSLSocketDataProvider ssl(ASYNC, OK);
13717   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13718 
13719   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13720 
13721   HttpServerProperties* http_server_properties =
13722       session->http_server_properties();
13723   const int kRestrictedAlternatePort = 80;
13724   AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
13725                                          kRestrictedAlternatePort);
13726   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
13727   http_server_properties->SetHttp2AlternativeService(
13728       url::SchemeHostPort(restricted_port_request.url), NetworkIsolationKey(),
13729       alternative_service, expiration);
13730 
13731   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13732   TestCompletionCallback callback;
13733 
13734   int rv = trans.Start(&restricted_port_request, callback.callback(),
13735                        NetLogWithSource());
13736   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13737   // Valid change to restricted port should pass.
13738   EXPECT_THAT(callback.WaitForResult(), IsOk());
13739 }
13740 
13741 // Ensure that we are not allowed to redirect traffic via an alternate protocol
13742 // to an unrestricted (port >= 1024) when the original traffic was on a
13743 // restricted port (port < 1024).  Ensure that we can redirect in all other
13744 // cases.
TEST_F(HttpNetworkTransactionTest,AlternateProtocolPortUnrestrictedAllowed1)13745 TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
13746   HttpRequestInfo unrestricted_port_request;
13747   unrestricted_port_request.method = "GET";
13748   unrestricted_port_request.url = GURL("https://www.example.org:1024/");
13749   unrestricted_port_request.load_flags = 0;
13750   unrestricted_port_request.traffic_annotation =
13751       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13752 
13753   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13754   StaticSocketDataProvider first_data;
13755   first_data.set_connect_data(mock_connect);
13756   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
13757 
13758   MockRead data_reads[] = {
13759     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
13760     MockRead("hello world"),
13761     MockRead(ASYNC, OK),
13762   };
13763   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
13764   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
13765   SSLSocketDataProvider ssl_http11(ASYNC, OK);
13766   ssl_http11.next_proto = kProtoHTTP11;
13767   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
13768 
13769   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13770 
13771   HttpServerProperties* http_server_properties =
13772       session->http_server_properties();
13773   const int kRestrictedAlternatePort = 80;
13774   AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
13775                                          kRestrictedAlternatePort);
13776   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
13777   http_server_properties->SetHttp2AlternativeService(
13778       url::SchemeHostPort(unrestricted_port_request.url), NetworkIsolationKey(),
13779       alternative_service, expiration);
13780 
13781   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13782   TestCompletionCallback callback;
13783 
13784   int rv = trans.Start(&unrestricted_port_request, callback.callback(),
13785                        NetLogWithSource());
13786   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13787   // Valid change to restricted port should pass.
13788   EXPECT_THAT(callback.WaitForResult(), IsOk());
13789 }
13790 
13791 // Ensure that we are not allowed to redirect traffic via an alternate protocol
13792 // to an unrestricted (port >= 1024) when the original traffic was on a
13793 // restricted port (port < 1024).  Ensure that we can redirect in all other
13794 // cases.
TEST_F(HttpNetworkTransactionTest,AlternateProtocolPortUnrestrictedAllowed2)13795 TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
13796   HttpRequestInfo unrestricted_port_request;
13797   unrestricted_port_request.method = "GET";
13798   unrestricted_port_request.url = GURL("https://www.example.org:1024/");
13799   unrestricted_port_request.load_flags = 0;
13800   unrestricted_port_request.traffic_annotation =
13801       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13802 
13803   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13804   StaticSocketDataProvider first_data;
13805   first_data.set_connect_data(mock_connect);
13806   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
13807 
13808   MockRead data_reads[] = {
13809     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
13810     MockRead("hello world"),
13811     MockRead(ASYNC, OK),
13812   };
13813   StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
13814   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
13815 
13816   SSLSocketDataProvider ssl(ASYNC, OK);
13817   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13818 
13819   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13820 
13821   HttpServerProperties* http_server_properties =
13822       session->http_server_properties();
13823   const int kUnrestrictedAlternatePort = 1025;
13824   AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
13825                                          kUnrestrictedAlternatePort);
13826   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
13827   http_server_properties->SetHttp2AlternativeService(
13828       url::SchemeHostPort(unrestricted_port_request.url), NetworkIsolationKey(),
13829       alternative_service, expiration);
13830 
13831   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13832   TestCompletionCallback callback;
13833 
13834   int rv = trans.Start(&unrestricted_port_request, callback.callback(),
13835                        NetLogWithSource());
13836   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13837   // Valid change to an unrestricted port should pass.
13838   EXPECT_THAT(callback.WaitForResult(), IsOk());
13839 }
13840 
13841 // Ensure that we are not allowed to redirect traffic via an alternate protocol
13842 // to an unsafe port, and that we resume the second HttpStreamFactory::Job once
13843 // the alternate protocol request fails.
TEST_F(HttpNetworkTransactionTest,AlternateProtocolUnsafeBlocked)13844 TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
13845   HttpRequestInfo request;
13846   request.method = "GET";
13847   request.url = GURL("http://www.example.org/");
13848   request.traffic_annotation =
13849       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13850 
13851   // The alternate protocol request will error out before we attempt to connect,
13852   // so only the standard HTTP request will try to connect.
13853   MockRead data_reads[] = {
13854     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
13855     MockRead("hello world"),
13856     MockRead(ASYNC, OK),
13857   };
13858   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
13859   session_deps_.socket_factory->AddSocketDataProvider(&data);
13860 
13861   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13862 
13863   HttpServerProperties* http_server_properties =
13864       session->http_server_properties();
13865   const int kUnsafePort = 7;
13866   AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
13867                                          kUnsafePort);
13868   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
13869   http_server_properties->SetHttp2AlternativeService(
13870       url::SchemeHostPort(request.url), NetworkIsolationKey(),
13871       alternative_service, expiration);
13872 
13873   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13874   TestCompletionCallback callback;
13875 
13876   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
13877   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13878   // The HTTP request should succeed.
13879   EXPECT_THAT(callback.WaitForResult(), IsOk());
13880 
13881   const HttpResponseInfo* response = trans.GetResponseInfo();
13882   ASSERT_TRUE(response);
13883   ASSERT_TRUE(response->headers);
13884   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13885 
13886   std::string response_data;
13887   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13888   EXPECT_EQ("hello world", response_data);
13889 }
13890 
TEST_F(HttpNetworkTransactionTest,UseAlternateProtocolForNpnSpdy)13891 TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
13892   HttpRequestInfo request;
13893   request.method = "GET";
13894   request.url = GURL("https://www.example.org/");
13895   request.traffic_annotation =
13896       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13897 
13898   MockRead data_reads[] = {
13899       MockRead("HTTP/1.1 200 OK\r\n"),
13900       MockRead(kAlternativeServiceHttpHeader),
13901       MockRead("\r\n"),
13902       MockRead("hello world"),
13903       MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13904       MockRead(ASYNC, OK)};
13905 
13906   StaticSocketDataProvider first_transaction(data_reads,
13907                                              base::span<MockWrite>());
13908   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
13909   SSLSocketDataProvider ssl_http11(ASYNC, OK);
13910   ssl_http11.next_proto = kProtoHTTP11;
13911   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
13912 
13913   AddSSLSocketData();
13914 
13915   spdy::SpdySerializedFrame req(
13916       spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
13917   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
13918 
13919   spdy::SpdySerializedFrame resp(
13920       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13921   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
13922   MockRead spdy_reads[] = {
13923       CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
13924   };
13925 
13926   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
13927   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
13928 
13929   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
13930   StaticSocketDataProvider hanging_non_alternate_protocol_socket;
13931   hanging_non_alternate_protocol_socket.set_connect_data(
13932       never_finishing_connect);
13933   session_deps_.socket_factory->AddSocketDataProvider(
13934       &hanging_non_alternate_protocol_socket);
13935 
13936   TestCompletionCallback callback;
13937 
13938   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13939   auto trans =
13940       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
13941 
13942   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
13943   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13944   EXPECT_THAT(callback.WaitForResult(), IsOk());
13945 
13946   const HttpResponseInfo* response = trans->GetResponseInfo();
13947   ASSERT_TRUE(response);
13948   ASSERT_TRUE(response->headers);
13949   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13950 
13951   std::string response_data;
13952   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
13953   EXPECT_EQ("hello world", response_data);
13954 
13955   trans =
13956       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
13957 
13958   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
13959   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13960   EXPECT_THAT(callback.WaitForResult(), IsOk());
13961 
13962   response = trans->GetResponseInfo();
13963   ASSERT_TRUE(response);
13964   ASSERT_TRUE(response->headers);
13965   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13966   EXPECT_TRUE(response->was_fetched_via_spdy);
13967   EXPECT_TRUE(response->was_alpn_negotiated);
13968 
13969   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
13970   EXPECT_EQ("hello!", response_data);
13971 }
13972 
TEST_F(HttpNetworkTransactionTest,AlternateProtocolWithSpdyLateBinding)13973 TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
13974   HttpRequestInfo request;
13975   request.method = "GET";
13976   request.url = GURL("https://www.example.org/");
13977   request.traffic_annotation =
13978       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
13979 
13980   // First transaction receives Alt-Svc header over HTTP/1.1.
13981   MockRead data_reads[] = {
13982       MockRead("HTTP/1.1 200 OK\r\n"),
13983       MockRead(kAlternativeServiceHttpHeader),
13984       MockRead("\r\n"),
13985       MockRead("hello world"),
13986       MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13987       MockRead(ASYNC, OK),
13988   };
13989 
13990   StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
13991   session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
13992 
13993   SSLSocketDataProvider ssl_http11(ASYNC, OK);
13994   ssl_http11.ssl_info.cert =
13995       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
13996   ASSERT_TRUE(ssl_http11.ssl_info.cert);
13997   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
13998 
13999   // Second transaction starts an alternative and a non-alternative Job.
14000   // Both sockets hang.
14001   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
14002   StaticSocketDataProvider hanging_socket1;
14003   hanging_socket1.set_connect_data(never_finishing_connect);
14004   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
14005 
14006   StaticSocketDataProvider hanging_socket2;
14007   hanging_socket2.set_connect_data(never_finishing_connect);
14008   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
14009 
14010   // Third transaction starts an alternative and a non-alternative job.
14011   // The non-alternative job hangs, but the alternative one succeeds.
14012   // The second transaction, still pending, binds to this socket.
14013   spdy::SpdySerializedFrame req1(
14014       spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
14015   spdy::SpdySerializedFrame req2(
14016       spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
14017   MockWrite spdy_writes[] = {
14018       CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
14019   };
14020   spdy::SpdySerializedFrame resp1(
14021       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14022   spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
14023   spdy::SpdySerializedFrame resp2(
14024       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
14025   spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
14026   MockRead spdy_reads[] = {
14027       CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
14028       CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
14029       MockRead(ASYNC, 0, 6),
14030   };
14031 
14032   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
14033   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
14034 
14035   AddSSLSocketData();
14036 
14037   StaticSocketDataProvider hanging_socket3;
14038   hanging_socket3.set_connect_data(never_finishing_connect);
14039   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
14040 
14041   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14042   TestCompletionCallback callback1;
14043   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14044 
14045   int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
14046   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14047   EXPECT_THAT(callback1.WaitForResult(), IsOk());
14048 
14049   const HttpResponseInfo* response = trans1.GetResponseInfo();
14050   ASSERT_TRUE(response);
14051   ASSERT_TRUE(response->headers);
14052   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14053 
14054   std::string response_data;
14055   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14056   EXPECT_EQ("hello world", response_data);
14057 
14058   TestCompletionCallback callback2;
14059   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14060   rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
14061   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14062 
14063   TestCompletionCallback callback3;
14064   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
14065   rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
14066   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14067 
14068   EXPECT_THAT(callback2.WaitForResult(), IsOk());
14069   EXPECT_THAT(callback3.WaitForResult(), IsOk());
14070 
14071   response = trans2.GetResponseInfo();
14072   ASSERT_TRUE(response);
14073   ASSERT_TRUE(response->headers);
14074   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14075   EXPECT_TRUE(response->was_fetched_via_spdy);
14076   EXPECT_TRUE(response->was_alpn_negotiated);
14077   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14078   EXPECT_EQ("hello!", response_data);
14079 
14080   response = trans3.GetResponseInfo();
14081   ASSERT_TRUE(response);
14082   ASSERT_TRUE(response->headers);
14083   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14084   EXPECT_TRUE(response->was_fetched_via_spdy);
14085   EXPECT_TRUE(response->was_alpn_negotiated);
14086   ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
14087   EXPECT_EQ("hello!", response_data);
14088 }
14089 
TEST_F(HttpNetworkTransactionTest,StallAlternativeServiceForNpnSpdy)14090 TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
14091   session_deps_.host_resolver->set_synchronous_mode(true);
14092 
14093   HttpRequestInfo request;
14094   request.method = "GET";
14095   request.url = GURL("https://www.example.org/");
14096   request.traffic_annotation =
14097       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14098 
14099   MockRead data_reads[] = {
14100       MockRead("HTTP/1.1 200 OK\r\n"),
14101       MockRead(kAlternativeServiceHttpHeader),
14102       MockRead("\r\n"),
14103       MockRead("hello world"),
14104       MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
14105       MockRead(ASYNC, OK),
14106   };
14107 
14108   StaticSocketDataProvider first_transaction(data_reads,
14109                                              base::span<MockWrite>());
14110   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
14111 
14112   SSLSocketDataProvider ssl(ASYNC, OK);
14113   ssl.ssl_info.cert =
14114       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
14115   ASSERT_TRUE(ssl.ssl_info.cert);
14116   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14117 
14118   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
14119   StaticSocketDataProvider hanging_alternate_protocol_socket;
14120   hanging_alternate_protocol_socket.set_connect_data(
14121       never_finishing_connect);
14122   session_deps_.socket_factory->AddSocketDataProvider(
14123       &hanging_alternate_protocol_socket);
14124 
14125   // 2nd request is just a copy of the first one, over HTTP/1.1 again.
14126   StaticSocketDataProvider second_transaction(data_reads,
14127                                               base::span<MockWrite>());
14128   session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
14129   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14130 
14131   TestCompletionCallback callback;
14132 
14133   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14134   auto trans =
14135       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
14136 
14137   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
14138   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14139   EXPECT_THAT(callback.WaitForResult(), IsOk());
14140 
14141   const HttpResponseInfo* response = trans->GetResponseInfo();
14142   ASSERT_TRUE(response);
14143   ASSERT_TRUE(response->headers);
14144   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14145 
14146   std::string response_data;
14147   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
14148   EXPECT_EQ("hello world", response_data);
14149 
14150   trans =
14151       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
14152 
14153   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
14154   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14155   EXPECT_THAT(callback.WaitForResult(), IsOk());
14156 
14157   response = trans->GetResponseInfo();
14158   ASSERT_TRUE(response);
14159   ASSERT_TRUE(response->headers);
14160   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14161   EXPECT_FALSE(response->was_fetched_via_spdy);
14162   EXPECT_FALSE(response->was_alpn_negotiated);
14163 
14164   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
14165   EXPECT_EQ("hello world", response_data);
14166 }
14167 
14168 // Test that proxy is resolved using the origin url,
14169 // regardless of the alternative server.
TEST_F(HttpNetworkTransactionTest,UseOriginNotAlternativeForProxy)14170 TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
14171   // Configure proxy to bypass www.example.org, which is the origin URL.
14172   ProxyConfig proxy_config;
14173   proxy_config.proxy_rules().ParseFromString("myproxy:70");
14174   proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
14175   auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
14176       ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
14177 
14178   CapturingProxyResolver capturing_proxy_resolver;
14179   auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
14180       &capturing_proxy_resolver);
14181 
14182   RecordingTestNetLog net_log;
14183 
14184   session_deps_.proxy_resolution_service =
14185       std::make_unique<ConfiguredProxyResolutionService>(
14186           std::move(proxy_config_service), std::move(proxy_resolver_factory),
14187           &net_log);
14188 
14189   session_deps_.net_log = &net_log;
14190 
14191   // Configure alternative service with a hostname that is not bypassed by the
14192   // proxy.
14193   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14194   HttpServerProperties* http_server_properties =
14195       session->http_server_properties();
14196   url::SchemeHostPort server("https", "www.example.org", 443);
14197   HostPortPair alternative("www.example.com", 443);
14198   AlternativeService alternative_service(kProtoHTTP2, alternative);
14199   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
14200   http_server_properties->SetHttp2AlternativeService(
14201       server, NetworkIsolationKey(), alternative_service, expiration);
14202 
14203   // Non-alternative job should hang.
14204   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
14205   StaticSocketDataProvider hanging_alternate_protocol_socket;
14206   hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
14207   session_deps_.socket_factory->AddSocketDataProvider(
14208       &hanging_alternate_protocol_socket);
14209 
14210   AddSSLSocketData();
14211 
14212   HttpRequestInfo request;
14213   request.method = "GET";
14214   request.url = GURL("https://www.example.org/");
14215   request.load_flags = 0;
14216   request.traffic_annotation =
14217       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14218 
14219   spdy::SpdySerializedFrame req(
14220       spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
14221 
14222   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
14223 
14224   spdy::SpdySerializedFrame resp(
14225       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14226   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
14227   MockRead spdy_reads[] = {
14228       CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
14229   };
14230 
14231   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
14232   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
14233 
14234   TestCompletionCallback callback;
14235 
14236   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14237 
14238   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
14239   EXPECT_THAT(callback.GetResult(rv), IsOk());
14240 
14241   const HttpResponseInfo* response = trans.GetResponseInfo();
14242   ASSERT_TRUE(response);
14243   ASSERT_TRUE(response->headers);
14244   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14245   EXPECT_TRUE(response->was_fetched_via_spdy);
14246   EXPECT_TRUE(response->was_alpn_negotiated);
14247 
14248   std::string response_data;
14249   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
14250   EXPECT_EQ("hello!", response_data);
14251 
14252   // Origin host bypasses proxy, no resolution should have happened.
14253   ASSERT_TRUE(capturing_proxy_resolver.lookup_info().empty());
14254 }
14255 
TEST_F(HttpNetworkTransactionTest,UseAlternativeServiceForTunneledNpnSpdy)14256 TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
14257   ProxyConfig proxy_config;
14258   proxy_config.set_auto_detect(true);
14259   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
14260 
14261   CapturingProxyResolver capturing_proxy_resolver;
14262   session_deps_.proxy_resolution_service =
14263       std::make_unique<ConfiguredProxyResolutionService>(
14264           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
14265               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
14266           std::make_unique<CapturingProxyResolverFactory>(
14267               &capturing_proxy_resolver),
14268           nullptr);
14269   RecordingTestNetLog net_log;
14270   session_deps_.net_log = &net_log;
14271 
14272   HttpRequestInfo request;
14273   request.method = "GET";
14274   request.url = GURL("https://www.example.org/");
14275   request.traffic_annotation =
14276       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14277 
14278   MockRead data_reads[] = {
14279       MockRead("HTTP/1.1 200 OK\r\n"),
14280       MockRead(kAlternativeServiceHttpHeader),
14281       MockRead("\r\n"),
14282       MockRead("hello world"),
14283       MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
14284       MockRead(ASYNC, OK),
14285   };
14286 
14287   StaticSocketDataProvider first_transaction(data_reads,
14288                                              base::span<MockWrite>());
14289   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
14290   SSLSocketDataProvider ssl_http11(ASYNC, OK);
14291   ssl_http11.next_proto = kProtoHTTP11;
14292   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
14293 
14294   AddSSLSocketData();
14295 
14296   spdy::SpdySerializedFrame req(
14297       spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
14298   MockWrite spdy_writes[] = {
14299       MockWrite(ASYNC, 0,
14300                 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14301                 "Host: www.example.org:443\r\n"
14302                 "Proxy-Connection: keep-alive\r\n\r\n"),
14303       CreateMockWrite(req, 2),
14304   };
14305 
14306   const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
14307 
14308   spdy::SpdySerializedFrame resp(
14309       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14310   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
14311   MockRead spdy_reads[] = {
14312       MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
14313       CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
14314   };
14315 
14316   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
14317   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
14318 
14319   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
14320   StaticSocketDataProvider hanging_non_alternate_protocol_socket;
14321   hanging_non_alternate_protocol_socket.set_connect_data(
14322       never_finishing_connect);
14323   session_deps_.socket_factory->AddSocketDataProvider(
14324       &hanging_non_alternate_protocol_socket);
14325 
14326   TestCompletionCallback callback;
14327 
14328   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14329   auto trans =
14330       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
14331 
14332   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
14333   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14334   EXPECT_THAT(callback.WaitForResult(), IsOk());
14335 
14336   const HttpResponseInfo* response = trans->GetResponseInfo();
14337   ASSERT_TRUE(response);
14338   ASSERT_TRUE(response->headers);
14339   EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
14340   EXPECT_FALSE(response->was_fetched_via_spdy);
14341   EXPECT_TRUE(response->was_alpn_negotiated);
14342 
14343   std::string response_data;
14344   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
14345   EXPECT_EQ("hello world", response_data);
14346 
14347   trans =
14348       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
14349 
14350   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
14351   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14352   EXPECT_THAT(callback.WaitForResult(), IsOk());
14353 
14354   response = trans->GetResponseInfo();
14355   ASSERT_TRUE(response);
14356   ASSERT_TRUE(response->headers);
14357   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14358   EXPECT_TRUE(response->was_fetched_via_spdy);
14359   EXPECT_TRUE(response->was_alpn_negotiated);
14360 
14361   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
14362   EXPECT_EQ("hello!", response_data);
14363   ASSERT_EQ(2u, capturing_proxy_resolver.lookup_info().size());
14364   EXPECT_EQ("https://www.example.org/",
14365             capturing_proxy_resolver.lookup_info()[0].url.spec());
14366   EXPECT_EQ("https://www.example.org/",
14367             capturing_proxy_resolver.lookup_info()[1].url.spec());
14368 
14369   LoadTimingInfo load_timing_info;
14370   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
14371   TestLoadTimingNotReusedWithPac(load_timing_info,
14372                                  CONNECT_TIMING_HAS_SSL_TIMES);
14373 }
14374 
TEST_F(HttpNetworkTransactionTest,UseAlternativeServiceForNpnSpdyWithExistingSpdySession)14375 TEST_F(HttpNetworkTransactionTest,
14376        UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
14377   HttpRequestInfo request;
14378   request.method = "GET";
14379   request.url = GURL("https://www.example.org/");
14380   request.traffic_annotation =
14381       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
14382 
14383   MockRead data_reads[] = {
14384       MockRead("HTTP/1.1 200 OK\r\n"),
14385       MockRead(kAlternativeServiceHttpHeader),
14386       MockRead("\r\n"),
14387       MockRead("hello world"),
14388       MockRead(ASYNC, OK),
14389   };
14390 
14391   StaticSocketDataProvider first_transaction(data_reads,
14392                                              base::span<MockWrite>());
14393   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
14394   SSLSocketDataProvider ssl_http11(ASYNC, OK);
14395   ssl_http11.next_proto = kProtoHTTP11;
14396   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
14397 
14398   AddSSLSocketData();
14399 
14400   spdy::SpdySerializedFrame req(
14401       spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
14402   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
14403 
14404   spdy::SpdySerializedFrame resp(
14405       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14406   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
14407   MockRead spdy_reads[] = {
14408       CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
14409   };
14410 
14411   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
14412   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
14413 
14414   TestCompletionCallback callback;
14415 
14416   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14417 
14418   auto trans =
14419       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
14420 
14421   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
14422   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14423   EXPECT_THAT(callback.WaitForResult(), IsOk());
14424 
14425   const HttpResponseInfo* response = trans->GetResponseInfo();
14426   ASSERT_TRUE(response);
14427   ASSERT_TRUE(response->headers);
14428   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14429 
14430   std::string response_data;
14431   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
14432   EXPECT_EQ("hello world", response_data);
14433 
14434   // Set up an initial SpdySession in the pool to reuse.
14435   HostPortPair host_port_pair("www.example.org", 443);
14436   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
14437                      PRIVACY_MODE_DISABLED,
14438                      SpdySessionKey::IsProxySession::kFalse, SocketTag(),
14439                      NetworkIsolationKey(), false /* disable_secure_dns */);
14440   base::WeakPtr<SpdySession> spdy_session =
14441       CreateSpdySession(session.get(), key, NetLogWithSource());
14442 
14443   trans =
14444       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
14445 
14446   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
14447   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14448   EXPECT_THAT(callback.WaitForResult(), IsOk());
14449 
14450   response = trans->GetResponseInfo();
14451   ASSERT_TRUE(response);
14452   ASSERT_TRUE(response->headers);
14453   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14454   EXPECT_TRUE(response->was_fetched_via_spdy);
14455   EXPECT_TRUE(response->was_alpn_negotiated);
14456 
14457   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
14458   EXPECT_EQ("hello!", response_data);
14459 }
14460 
14461 // GenerateAuthToken is a mighty big test.
14462 // It tests all permutation of GenerateAuthToken behavior:
14463 //   - Synchronous and Asynchronous completion.
14464 //   - OK or error on completion.
14465 //   - Direct connection, non-authenticating proxy, and authenticating proxy.
14466 //   - HTTP or HTTPS backend (to include proxy tunneling).
14467 //   - Non-authenticating and authenticating backend.
14468 //
14469 // In all, there are 44 reasonable permuations (for example, if there are
14470 // problems generating an auth token for an authenticating proxy, we don't
14471 // need to test all permutations of the backend server).
14472 //
14473 // The test proceeds by going over each of the configuration cases, and
14474 // potentially running up to three rounds in each of the tests. The TestConfig
14475 // specifies both the configuration for the test as well as the expectations
14476 // for the results.
TEST_F(HttpNetworkTransactionTest,GenerateAuthToken)14477 TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
14478   static const char kServer[] = "http://www.example.com";
14479   static const char kSecureServer[] = "https://www.example.com";
14480   static const char kProxy[] = "myproxy:70";
14481 
14482   enum AuthTiming {
14483     AUTH_NONE,
14484     AUTH_SYNC,
14485     AUTH_ASYNC,
14486   };
14487 
14488   const MockWrite kGet(
14489       "GET / HTTP/1.1\r\n"
14490       "Host: www.example.com\r\n"
14491       "Connection: keep-alive\r\n\r\n");
14492   const MockWrite kGetProxy(
14493       "GET http://www.example.com/ HTTP/1.1\r\n"
14494       "Host: www.example.com\r\n"
14495       "Proxy-Connection: keep-alive\r\n\r\n");
14496   const MockWrite kGetAuth(
14497       "GET / HTTP/1.1\r\n"
14498       "Host: www.example.com\r\n"
14499       "Connection: keep-alive\r\n"
14500       "Authorization: auth_token\r\n\r\n");
14501   const MockWrite kGetProxyAuth(
14502       "GET http://www.example.com/ HTTP/1.1\r\n"
14503       "Host: www.example.com\r\n"
14504       "Proxy-Connection: keep-alive\r\n"
14505       "Proxy-Authorization: auth_token\r\n\r\n");
14506   const MockWrite kGetAuthThroughProxy(
14507       "GET http://www.example.com/ HTTP/1.1\r\n"
14508       "Host: www.example.com\r\n"
14509       "Proxy-Connection: keep-alive\r\n"
14510       "Authorization: auth_token\r\n\r\n");
14511   const MockWrite kGetAuthWithProxyAuth(
14512       "GET http://www.example.com/ HTTP/1.1\r\n"
14513       "Host: www.example.com\r\n"
14514       "Proxy-Connection: keep-alive\r\n"
14515       "Proxy-Authorization: auth_token\r\n"
14516       "Authorization: auth_token\r\n\r\n");
14517   const MockWrite kConnect(
14518       "CONNECT www.example.com:443 HTTP/1.1\r\n"
14519       "Host: www.example.com:443\r\n"
14520       "Proxy-Connection: keep-alive\r\n\r\n");
14521   const MockWrite kConnectProxyAuth(
14522       "CONNECT www.example.com:443 HTTP/1.1\r\n"
14523       "Host: www.example.com:443\r\n"
14524       "Proxy-Connection: keep-alive\r\n"
14525       "Proxy-Authorization: auth_token\r\n\r\n");
14526 
14527   const MockRead kSuccess(
14528       "HTTP/1.1 200 OK\r\n"
14529       "Content-Type: text/html; charset=iso-8859-1\r\n"
14530       "Content-Length: 3\r\n\r\n"
14531       "Yes");
14532   const MockRead kFailure(
14533       "Should not be called.");
14534   const MockRead kServerChallenge(
14535       "HTTP/1.1 401 Unauthorized\r\n"
14536       "WWW-Authenticate: Mock realm=server\r\n"
14537       "Content-Type: text/html; charset=iso-8859-1\r\n"
14538       "Content-Length: 14\r\n\r\n"
14539       "Unauthorized\r\n");
14540   const MockRead kProxyChallenge(
14541       "HTTP/1.1 407 Unauthorized\r\n"
14542       "Proxy-Authenticate: Mock realm=proxy\r\n"
14543       "Proxy-Connection: close\r\n"
14544       "Content-Type: text/html; charset=iso-8859-1\r\n"
14545       "Content-Length: 14\r\n\r\n"
14546       "Unauthorized\r\n");
14547   const MockRead kProxyConnected(
14548       "HTTP/1.1 200 Connection Established\r\n\r\n");
14549 
14550   // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
14551   // no constructors, but the C++ compiler on Windows warns about
14552   // unspecified data in compound literals. So, moved to using constructors,
14553   // and TestRound's created with the default constructor should not be used.
14554   struct TestRound {
14555     TestRound()
14556         : expected_rv(ERR_UNEXPECTED),
14557           extra_write(nullptr),
14558           extra_read(nullptr) {}
14559     TestRound(const MockWrite& write_arg,
14560               const MockRead& read_arg,
14561               int expected_rv_arg)
14562         : write(write_arg),
14563           read(read_arg),
14564           expected_rv(expected_rv_arg),
14565           extra_write(nullptr),
14566           extra_read(nullptr) {}
14567     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
14568               int expected_rv_arg, const MockWrite* extra_write_arg,
14569               const MockRead* extra_read_arg)
14570         : write(write_arg),
14571           read(read_arg),
14572           expected_rv(expected_rv_arg),
14573           extra_write(extra_write_arg),
14574           extra_read(extra_read_arg) {
14575     }
14576     MockWrite write;
14577     MockRead read;
14578     int expected_rv;
14579     const MockWrite* extra_write;
14580     const MockRead* extra_read;
14581   };
14582 
14583   static const int kNoSSL = 500;
14584 
14585   struct TestConfig {
14586     int line_number;
14587     const char* const proxy_url;
14588     AuthTiming proxy_auth_timing;
14589     int first_generate_proxy_token_rv;
14590     const char* const server_url;
14591     AuthTiming server_auth_timing;
14592     int first_generate_server_token_rv;
14593     int num_auth_rounds;
14594     int first_ssl_round;
14595     TestRound rounds[4];
14596   } test_configs[] = {
14597       // Non-authenticating HTTP server with a direct connection.
14598       {__LINE__,
14599        nullptr,
14600        AUTH_NONE,
14601        OK,
14602        kServer,
14603        AUTH_NONE,
14604        OK,
14605        1,
14606        kNoSSL,
14607        {TestRound(kGet, kSuccess, OK)}},
14608       // Authenticating HTTP server with a direct connection.
14609       {__LINE__,
14610        nullptr,
14611        AUTH_NONE,
14612        OK,
14613        kServer,
14614        AUTH_SYNC,
14615        OK,
14616        2,
14617        kNoSSL,
14618        {TestRound(kGet, kServerChallenge, OK),
14619         TestRound(kGetAuth, kSuccess, OK)}},
14620       {__LINE__,
14621        nullptr,
14622        AUTH_NONE,
14623        OK,
14624        kServer,
14625        AUTH_SYNC,
14626        ERR_INVALID_AUTH_CREDENTIALS,
14627        3,
14628        kNoSSL,
14629        {TestRound(kGet, kServerChallenge, OK),
14630         TestRound(kGet, kServerChallenge, OK),
14631         TestRound(kGetAuth, kSuccess, OK)}},
14632       {__LINE__,
14633        nullptr,
14634        AUTH_NONE,
14635        OK,
14636        kServer,
14637        AUTH_SYNC,
14638        ERR_UNSUPPORTED_AUTH_SCHEME,
14639        2,
14640        kNoSSL,
14641        {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
14642       {__LINE__,
14643        nullptr,
14644        AUTH_NONE,
14645        OK,
14646        kServer,
14647        AUTH_SYNC,
14648        ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
14649        2,
14650        kNoSSL,
14651        {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
14652       {__LINE__,
14653        kProxy,
14654        AUTH_SYNC,
14655        ERR_FAILED,
14656        kServer,
14657        AUTH_NONE,
14658        OK,
14659        2,
14660        kNoSSL,
14661        {TestRound(kGetProxy, kProxyChallenge, OK),
14662         TestRound(kGetProxy, kFailure, ERR_FAILED)}},
14663       {__LINE__,
14664        kProxy,
14665        AUTH_ASYNC,
14666        ERR_FAILED,
14667        kServer,
14668        AUTH_NONE,
14669        OK,
14670        2,
14671        kNoSSL,
14672        {TestRound(kGetProxy, kProxyChallenge, OK),
14673         TestRound(kGetProxy, kFailure, ERR_FAILED)}},
14674       {__LINE__,
14675        nullptr,
14676        AUTH_NONE,
14677        OK,
14678        kServer,
14679        AUTH_SYNC,
14680        ERR_FAILED,
14681        2,
14682        kNoSSL,
14683        {TestRound(kGet, kServerChallenge, OK),
14684         TestRound(kGet, kFailure, ERR_FAILED)}},
14685       {__LINE__,
14686        nullptr,
14687        AUTH_NONE,
14688        OK,
14689        kServer,
14690        AUTH_ASYNC,
14691        ERR_FAILED,
14692        2,
14693        kNoSSL,
14694        {TestRound(kGet, kServerChallenge, OK),
14695         TestRound(kGet, kFailure, ERR_FAILED)}},
14696       {__LINE__,
14697        nullptr,
14698        AUTH_NONE,
14699        OK,
14700        kServer,
14701        AUTH_ASYNC,
14702        OK,
14703        2,
14704        kNoSSL,
14705        {TestRound(kGet, kServerChallenge, OK),
14706         TestRound(kGetAuth, kSuccess, OK)}},
14707       {__LINE__,
14708        nullptr,
14709        AUTH_NONE,
14710        OK,
14711        kServer,
14712        AUTH_ASYNC,
14713        ERR_INVALID_AUTH_CREDENTIALS,
14714        3,
14715        kNoSSL,
14716        {TestRound(kGet, kServerChallenge, OK),
14717         // The second round uses a HttpAuthHandlerMock that always succeeds.
14718         TestRound(kGet, kServerChallenge, OK),
14719         TestRound(kGetAuth, kSuccess, OK)}},
14720       // Non-authenticating HTTP server through a non-authenticating proxy.
14721       {__LINE__,
14722        kProxy,
14723        AUTH_NONE,
14724        OK,
14725        kServer,
14726        AUTH_NONE,
14727        OK,
14728        1,
14729        kNoSSL,
14730        {TestRound(kGetProxy, kSuccess, OK)}},
14731       // Authenticating HTTP server through a non-authenticating proxy.
14732       {__LINE__,
14733        kProxy,
14734        AUTH_NONE,
14735        OK,
14736        kServer,
14737        AUTH_SYNC,
14738        OK,
14739        2,
14740        kNoSSL,
14741        {TestRound(kGetProxy, kServerChallenge, OK),
14742         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
14743       {__LINE__,
14744        kProxy,
14745        AUTH_NONE,
14746        OK,
14747        kServer,
14748        AUTH_SYNC,
14749        ERR_INVALID_AUTH_CREDENTIALS,
14750        3,
14751        kNoSSL,
14752        {TestRound(kGetProxy, kServerChallenge, OK),
14753         TestRound(kGetProxy, kServerChallenge, OK),
14754         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
14755       {__LINE__,
14756        kProxy,
14757        AUTH_NONE,
14758        OK,
14759        kServer,
14760        AUTH_ASYNC,
14761        OK,
14762        2,
14763        kNoSSL,
14764        {TestRound(kGetProxy, kServerChallenge, OK),
14765         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
14766       {__LINE__,
14767        kProxy,
14768        AUTH_NONE,
14769        OK,
14770        kServer,
14771        AUTH_ASYNC,
14772        ERR_INVALID_AUTH_CREDENTIALS,
14773        2,
14774        kNoSSL,
14775        {TestRound(kGetProxy, kServerChallenge, OK),
14776         TestRound(kGetProxy, kSuccess, OK)}},
14777       // Non-authenticating HTTP server through an authenticating proxy.
14778       {__LINE__,
14779        kProxy,
14780        AUTH_SYNC,
14781        OK,
14782        kServer,
14783        AUTH_NONE,
14784        OK,
14785        2,
14786        kNoSSL,
14787        {TestRound(kGetProxy, kProxyChallenge, OK),
14788         TestRound(kGetProxyAuth, kSuccess, OK)}},
14789       {__LINE__,
14790        kProxy,
14791        AUTH_SYNC,
14792        ERR_INVALID_AUTH_CREDENTIALS,
14793        kServer,
14794        AUTH_NONE,
14795        OK,
14796        2,
14797        kNoSSL,
14798        {TestRound(kGetProxy, kProxyChallenge, OK),
14799         TestRound(kGetProxy, kSuccess, OK)}},
14800       {__LINE__,
14801        kProxy,
14802        AUTH_ASYNC,
14803        OK,
14804        kServer,
14805        AUTH_NONE,
14806        OK,
14807        2,
14808        kNoSSL,
14809        {TestRound(kGetProxy, kProxyChallenge, OK),
14810         TestRound(kGetProxyAuth, kSuccess, OK)}},
14811       {__LINE__,
14812        kProxy,
14813        AUTH_ASYNC,
14814        ERR_INVALID_AUTH_CREDENTIALS,
14815        kServer,
14816        AUTH_NONE,
14817        OK,
14818        2,
14819        kNoSSL,
14820        {TestRound(kGetProxy, kProxyChallenge, OK),
14821         TestRound(kGetProxy, kSuccess, OK)}},
14822       {__LINE__,
14823        kProxy,
14824        AUTH_ASYNC,
14825        ERR_INVALID_AUTH_CREDENTIALS,
14826        kServer,
14827        AUTH_NONE,
14828        OK,
14829        3,
14830        kNoSSL,
14831        {TestRound(kGetProxy, kProxyChallenge, OK),
14832         TestRound(kGetProxy, kProxyChallenge, OK),
14833         TestRound(kGetProxyAuth, kSuccess, OK)}},
14834       // Authenticating HTTP server through an authenticating proxy.
14835       {__LINE__,
14836        kProxy,
14837        AUTH_SYNC,
14838        OK,
14839        kServer,
14840        AUTH_SYNC,
14841        OK,
14842        3,
14843        kNoSSL,
14844        {TestRound(kGetProxy, kProxyChallenge, OK),
14845         TestRound(kGetProxyAuth, kServerChallenge, OK),
14846         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
14847       {__LINE__,
14848        kProxy,
14849        AUTH_SYNC,
14850        OK,
14851        kServer,
14852        AUTH_SYNC,
14853        ERR_INVALID_AUTH_CREDENTIALS,
14854        3,
14855        kNoSSL,
14856        {TestRound(kGetProxy, kProxyChallenge, OK),
14857         TestRound(kGetProxyAuth, kServerChallenge, OK),
14858         TestRound(kGetProxyAuth, kSuccess, OK)}},
14859       {__LINE__,
14860        kProxy,
14861        AUTH_ASYNC,
14862        OK,
14863        kServer,
14864        AUTH_SYNC,
14865        OK,
14866        3,
14867        kNoSSL,
14868        {TestRound(kGetProxy, kProxyChallenge, OK),
14869         TestRound(kGetProxyAuth, kServerChallenge, OK),
14870         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
14871       {__LINE__,
14872        kProxy,
14873        AUTH_ASYNC,
14874        OK,
14875        kServer,
14876        AUTH_SYNC,
14877        ERR_INVALID_AUTH_CREDENTIALS,
14878        3,
14879        kNoSSL,
14880        {TestRound(kGetProxy, kProxyChallenge, OK),
14881         TestRound(kGetProxyAuth, kServerChallenge, OK),
14882         TestRound(kGetProxyAuth, kSuccess, OK)}},
14883       {__LINE__,
14884        kProxy,
14885        AUTH_SYNC,
14886        OK,
14887        kServer,
14888        AUTH_ASYNC,
14889        OK,
14890        3,
14891        kNoSSL,
14892        {TestRound(kGetProxy, kProxyChallenge, OK),
14893         TestRound(kGetProxyAuth, kServerChallenge, OK),
14894         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
14895       {__LINE__,
14896        kProxy,
14897        AUTH_SYNC,
14898        ERR_INVALID_AUTH_CREDENTIALS,
14899        kServer,
14900        AUTH_ASYNC,
14901        OK,
14902        4,
14903        kNoSSL,
14904        {TestRound(kGetProxy, kProxyChallenge, OK),
14905         TestRound(kGetProxy, kProxyChallenge, OK),
14906         TestRound(kGetProxyAuth, kServerChallenge, OK),
14907         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
14908       {__LINE__,
14909        kProxy,
14910        AUTH_SYNC,
14911        OK,
14912        kServer,
14913        AUTH_ASYNC,
14914        ERR_INVALID_AUTH_CREDENTIALS,
14915        3,
14916        kNoSSL,
14917        {TestRound(kGetProxy, kProxyChallenge, OK),
14918         TestRound(kGetProxyAuth, kServerChallenge, OK),
14919         TestRound(kGetProxyAuth, kSuccess, OK)}},
14920       {__LINE__,
14921        kProxy,
14922        AUTH_ASYNC,
14923        OK,
14924        kServer,
14925        AUTH_ASYNC,
14926        OK,
14927        3,
14928        kNoSSL,
14929        {TestRound(kGetProxy, kProxyChallenge, OK),
14930         TestRound(kGetProxyAuth, kServerChallenge, OK),
14931         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
14932       {__LINE__,
14933        kProxy,
14934        AUTH_ASYNC,
14935        OK,
14936        kServer,
14937        AUTH_ASYNC,
14938        ERR_INVALID_AUTH_CREDENTIALS,
14939        3,
14940        kNoSSL,
14941        {TestRound(kGetProxy, kProxyChallenge, OK),
14942         TestRound(kGetProxyAuth, kServerChallenge, OK),
14943         TestRound(kGetProxyAuth, kSuccess, OK)}},
14944       {__LINE__,
14945        kProxy,
14946        AUTH_ASYNC,
14947        ERR_INVALID_AUTH_CREDENTIALS,
14948        kServer,
14949        AUTH_ASYNC,
14950        ERR_INVALID_AUTH_CREDENTIALS,
14951        4,
14952        kNoSSL,
14953        {TestRound(kGetProxy, kProxyChallenge, OK),
14954         TestRound(kGetProxy, kProxyChallenge, OK),
14955         TestRound(kGetProxyAuth, kServerChallenge, OK),
14956         TestRound(kGetProxyAuth, kSuccess, OK)}},
14957       // Non-authenticating HTTPS server with a direct connection.
14958       {__LINE__,
14959        nullptr,
14960        AUTH_NONE,
14961        OK,
14962        kSecureServer,
14963        AUTH_NONE,
14964        OK,
14965        1,
14966        0,
14967        {TestRound(kGet, kSuccess, OK)}},
14968       // Authenticating HTTPS server with a direct connection.
14969       {__LINE__,
14970        nullptr,
14971        AUTH_NONE,
14972        OK,
14973        kSecureServer,
14974        AUTH_SYNC,
14975        OK,
14976        2,
14977        0,
14978        {TestRound(kGet, kServerChallenge, OK),
14979         TestRound(kGetAuth, kSuccess, OK)}},
14980       {__LINE__,
14981        nullptr,
14982        AUTH_NONE,
14983        OK,
14984        kSecureServer,
14985        AUTH_SYNC,
14986        ERR_INVALID_AUTH_CREDENTIALS,
14987        2,
14988        0,
14989        {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
14990       {__LINE__,
14991        nullptr,
14992        AUTH_NONE,
14993        OK,
14994        kSecureServer,
14995        AUTH_ASYNC,
14996        OK,
14997        2,
14998        0,
14999        {TestRound(kGet, kServerChallenge, OK),
15000         TestRound(kGetAuth, kSuccess, OK)}},
15001       {__LINE__,
15002        nullptr,
15003        AUTH_NONE,
15004        OK,
15005        kSecureServer,
15006        AUTH_ASYNC,
15007        ERR_INVALID_AUTH_CREDENTIALS,
15008        2,
15009        0,
15010        {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
15011       // Non-authenticating HTTPS server with a non-authenticating proxy.
15012       {__LINE__,
15013        kProxy,
15014        AUTH_NONE,
15015        OK,
15016        kSecureServer,
15017        AUTH_NONE,
15018        OK,
15019        1,
15020        0,
15021        {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
15022       // Authenticating HTTPS server through a non-authenticating proxy.
15023       {__LINE__,
15024        kProxy,
15025        AUTH_NONE,
15026        OK,
15027        kSecureServer,
15028        AUTH_SYNC,
15029        OK,
15030        2,
15031        0,
15032        {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
15033         TestRound(kGetAuth, kSuccess, OK)}},
15034       {__LINE__,
15035        kProxy,
15036        AUTH_NONE,
15037        OK,
15038        kSecureServer,
15039        AUTH_SYNC,
15040        ERR_INVALID_AUTH_CREDENTIALS,
15041        2,
15042        0,
15043        {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
15044         TestRound(kGet, kSuccess, OK)}},
15045       {__LINE__,
15046        kProxy,
15047        AUTH_NONE,
15048        OK,
15049        kSecureServer,
15050        AUTH_ASYNC,
15051        OK,
15052        2,
15053        0,
15054        {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
15055         TestRound(kGetAuth, kSuccess, OK)}},
15056       {__LINE__,
15057        kProxy,
15058        AUTH_NONE,
15059        OK,
15060        kSecureServer,
15061        AUTH_ASYNC,
15062        ERR_INVALID_AUTH_CREDENTIALS,
15063        2,
15064        0,
15065        {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
15066         TestRound(kGet, kSuccess, OK)}},
15067       // Non-Authenticating HTTPS server through an authenticating proxy.
15068       {__LINE__,
15069        kProxy,
15070        AUTH_SYNC,
15071        OK,
15072        kSecureServer,
15073        AUTH_NONE,
15074        OK,
15075        2,
15076        1,
15077        {TestRound(kConnect, kProxyChallenge, OK),
15078         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
15079       {__LINE__,
15080        kProxy,
15081        AUTH_SYNC,
15082        ERR_INVALID_AUTH_CREDENTIALS,
15083        kSecureServer,
15084        AUTH_NONE,
15085        OK,
15086        2,
15087        kNoSSL,
15088        {TestRound(kConnect, kProxyChallenge, OK),
15089         TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
15090       {__LINE__,
15091        kProxy,
15092        AUTH_SYNC,
15093        ERR_UNSUPPORTED_AUTH_SCHEME,
15094        kSecureServer,
15095        AUTH_NONE,
15096        OK,
15097        2,
15098        kNoSSL,
15099        {TestRound(kConnect, kProxyChallenge, OK),
15100         TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
15101       {__LINE__,
15102        kProxy,
15103        AUTH_SYNC,
15104        ERR_UNEXPECTED,
15105        kSecureServer,
15106        AUTH_NONE,
15107        OK,
15108        2,
15109        kNoSSL,
15110        {TestRound(kConnect, kProxyChallenge, OK),
15111         TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
15112       {__LINE__,
15113        kProxy,
15114        AUTH_ASYNC,
15115        OK,
15116        kSecureServer,
15117        AUTH_NONE,
15118        OK,
15119        2,
15120        1,
15121        {TestRound(kConnect, kProxyChallenge, OK),
15122         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
15123       {__LINE__,
15124        kProxy,
15125        AUTH_ASYNC,
15126        ERR_INVALID_AUTH_CREDENTIALS,
15127        kSecureServer,
15128        AUTH_NONE,
15129        OK,
15130        2,
15131        kNoSSL,
15132        {TestRound(kConnect, kProxyChallenge, OK),
15133         TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
15134       // Authenticating HTTPS server through an authenticating proxy.
15135       {__LINE__,
15136        kProxy,
15137        AUTH_SYNC,
15138        OK,
15139        kSecureServer,
15140        AUTH_SYNC,
15141        OK,
15142        3,
15143        1,
15144        {TestRound(kConnect, kProxyChallenge, OK),
15145         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
15146                   &kServerChallenge),
15147         TestRound(kGetAuth, kSuccess, OK)}},
15148       {__LINE__,
15149        kProxy,
15150        AUTH_SYNC,
15151        OK,
15152        kSecureServer,
15153        AUTH_SYNC,
15154        ERR_INVALID_AUTH_CREDENTIALS,
15155        3,
15156        1,
15157        {TestRound(kConnect, kProxyChallenge, OK),
15158         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
15159                   &kServerChallenge),
15160         TestRound(kGet, kSuccess, OK)}},
15161       {__LINE__,
15162        kProxy,
15163        AUTH_ASYNC,
15164        OK,
15165        kSecureServer,
15166        AUTH_SYNC,
15167        OK,
15168        3,
15169        1,
15170        {TestRound(kConnect, kProxyChallenge, OK),
15171         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
15172                   &kServerChallenge),
15173         TestRound(kGetAuth, kSuccess, OK)}},
15174       {__LINE__,
15175        kProxy,
15176        AUTH_ASYNC,
15177        OK,
15178        kSecureServer,
15179        AUTH_SYNC,
15180        ERR_INVALID_AUTH_CREDENTIALS,
15181        3,
15182        1,
15183        {TestRound(kConnect, kProxyChallenge, OK),
15184         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
15185                   &kServerChallenge),
15186         TestRound(kGet, kSuccess, OK)}},
15187       {__LINE__,
15188        kProxy,
15189        AUTH_SYNC,
15190        OK,
15191        kSecureServer,
15192        AUTH_ASYNC,
15193        OK,
15194        3,
15195        1,
15196        {TestRound(kConnect, kProxyChallenge, OK),
15197         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
15198                   &kServerChallenge),
15199         TestRound(kGetAuth, kSuccess, OK)}},
15200       {__LINE__,
15201        kProxy,
15202        AUTH_SYNC,
15203        OK,
15204        kSecureServer,
15205        AUTH_ASYNC,
15206        ERR_INVALID_AUTH_CREDENTIALS,
15207        3,
15208        1,
15209        {TestRound(kConnect, kProxyChallenge, OK),
15210         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
15211                   &kServerChallenge),
15212         TestRound(kGet, kSuccess, OK)}},
15213       {__LINE__,
15214        kProxy,
15215        AUTH_ASYNC,
15216        OK,
15217        kSecureServer,
15218        AUTH_ASYNC,
15219        OK,
15220        3,
15221        1,
15222        {TestRound(kConnect, kProxyChallenge, OK),
15223         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
15224                   &kServerChallenge),
15225         TestRound(kGetAuth, kSuccess, OK)}},
15226       {__LINE__,
15227        kProxy,
15228        AUTH_ASYNC,
15229        OK,
15230        kSecureServer,
15231        AUTH_ASYNC,
15232        ERR_INVALID_AUTH_CREDENTIALS,
15233        3,
15234        1,
15235        {TestRound(kConnect, kProxyChallenge, OK),
15236         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
15237                   &kServerChallenge),
15238         TestRound(kGet, kSuccess, OK)}},
15239       {__LINE__,
15240        kProxy,
15241        AUTH_ASYNC,
15242        ERR_INVALID_AUTH_CREDENTIALS,
15243        kSecureServer,
15244        AUTH_ASYNC,
15245        ERR_INVALID_AUTH_CREDENTIALS,
15246        4,
15247        2,
15248        {TestRound(kConnect, kProxyChallenge, OK),
15249         TestRound(kConnect, kProxyChallenge, OK),
15250         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
15251                   &kServerChallenge),
15252         TestRound(kGet, kSuccess, OK)}},
15253   };
15254 
15255   for (const auto& test_config : test_configs) {
15256     SCOPED_TRACE(::testing::Message() << "Test config at "
15257                                       << test_config.line_number);
15258     HttpAuthHandlerMock::Factory* auth_factory(
15259         new HttpAuthHandlerMock::Factory());
15260     session_deps_.http_auth_handler_factory.reset(auth_factory);
15261     SSLInfo empty_ssl_info;
15262 
15263     // Set up authentication handlers as necessary.
15264     if (test_config.proxy_auth_timing != AUTH_NONE) {
15265       for (int n = 0; n < 3; n++) {
15266         HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
15267         std::string auth_challenge = "Mock realm=proxy";
15268         GURL origin(test_config.proxy_url);
15269         HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
15270                                              auth_challenge.end());
15271         auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
15272                                         empty_ssl_info, origin,
15273                                         NetLogWithSource());
15274         auth_handler->SetGenerateExpectation(
15275             test_config.proxy_auth_timing == AUTH_ASYNC,
15276             n == 0 ? test_config.first_generate_proxy_token_rv : OK);
15277         auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
15278       }
15279     }
15280     if (test_config.server_auth_timing != AUTH_NONE) {
15281       HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
15282       std::string auth_challenge = "Mock realm=server";
15283       GURL origin(test_config.server_url);
15284       HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
15285                                            auth_challenge.end());
15286       auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
15287                                       empty_ssl_info, origin,
15288                                       NetLogWithSource());
15289       auth_handler->SetGenerateExpectation(
15290           test_config.server_auth_timing == AUTH_ASYNC,
15291           test_config.first_generate_server_token_rv);
15292       auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
15293 
15294       // The second handler always succeeds. It should only be used where there
15295       // are multiple auth sessions for server auth in the same network
15296       // transaction using the same auth scheme.
15297       std::unique_ptr<HttpAuthHandlerMock> second_handler =
15298           std::make_unique<HttpAuthHandlerMock>();
15299       second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
15300                                         empty_ssl_info, origin,
15301                                         NetLogWithSource());
15302       second_handler->SetGenerateExpectation(true, OK);
15303       auth_factory->AddMockHandler(second_handler.release(),
15304                                    HttpAuth::AUTH_SERVER);
15305     }
15306     if (test_config.proxy_url) {
15307       session_deps_.proxy_resolution_service =
15308           ConfiguredProxyResolutionService::CreateFixed(
15309               test_config.proxy_url, TRAFFIC_ANNOTATION_FOR_TESTS);
15310     } else {
15311       session_deps_.proxy_resolution_service =
15312           ConfiguredProxyResolutionService::CreateDirect();
15313     }
15314 
15315     HttpRequestInfo request;
15316     request.method = "GET";
15317     request.url = GURL(test_config.server_url);
15318     request.traffic_annotation =
15319         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15320 
15321     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15322 
15323     SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
15324 
15325     std::vector<std::vector<MockRead>> mock_reads(1);
15326     std::vector<std::vector<MockWrite>> mock_writes(1);
15327     for (int round = 0; round < test_config.num_auth_rounds; ++round) {
15328       SCOPED_TRACE(round);
15329       const TestRound& read_write_round = test_config.rounds[round];
15330 
15331       // Set up expected reads and writes.
15332       mock_reads.back().push_back(read_write_round.read);
15333       mock_writes.back().push_back(read_write_round.write);
15334 
15335       // kProxyChallenge uses Proxy-Connection: close which means that the
15336       // socket is closed and a new one will be created for the next request.
15337       if (read_write_round.read.data == kProxyChallenge.data) {
15338         mock_reads.push_back(std::vector<MockRead>());
15339         mock_writes.push_back(std::vector<MockWrite>());
15340       }
15341 
15342       if (read_write_round.extra_read) {
15343         mock_reads.back().push_back(*read_write_round.extra_read);
15344       }
15345       if (read_write_round.extra_write) {
15346         mock_writes.back().push_back(*read_write_round.extra_write);
15347       }
15348 
15349       // Add an SSL sequence if necessary.
15350       if (round >= test_config.first_ssl_round)
15351         session_deps_.socket_factory->AddSSLSocketDataProvider(
15352             &ssl_socket_data_provider);
15353     }
15354 
15355     std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
15356     for (size_t i = 0; i < mock_reads.size(); ++i) {
15357       data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
15358           mock_reads[i], mock_writes[i]));
15359       session_deps_.socket_factory->AddSocketDataProvider(
15360           data_providers.back().get());
15361     }
15362 
15363     // Transaction must be created after DataProviders, so it's destroyed before
15364     // they are as well.
15365     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15366 
15367     for (int round = 0; round < test_config.num_auth_rounds; ++round) {
15368       SCOPED_TRACE(round);
15369       const TestRound& read_write_round = test_config.rounds[round];
15370       // Start or restart the transaction.
15371       TestCompletionCallback callback;
15372       int rv;
15373       if (round == 0) {
15374         rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15375       } else {
15376         rv = trans.RestartWithAuth(
15377             AuthCredentials(kFoo, kBar), callback.callback());
15378       }
15379       if (rv == ERR_IO_PENDING)
15380         rv = callback.WaitForResult();
15381 
15382       // Compare results with expected data.
15383       EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
15384       const HttpResponseInfo* response = trans.GetResponseInfo();
15385       if (read_write_round.expected_rv != OK) {
15386         EXPECT_EQ(round + 1, test_config.num_auth_rounds);
15387         continue;
15388       }
15389       if (round + 1 < test_config.num_auth_rounds) {
15390         EXPECT_TRUE(response->auth_challenge.has_value());
15391       } else {
15392         EXPECT_FALSE(response->auth_challenge.has_value());
15393         EXPECT_FALSE(trans.IsReadyToRestartForAuth());
15394       }
15395     }
15396   }
15397 }
15398 
TEST_F(HttpNetworkTransactionTest,MultiRoundAuth)15399 TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
15400   // Do multi-round authentication and make sure it works correctly.
15401   HttpAuthHandlerMock::Factory* auth_factory(
15402       new HttpAuthHandlerMock::Factory());
15403   session_deps_.http_auth_handler_factory.reset(auth_factory);
15404   session_deps_.proxy_resolution_service =
15405       ConfiguredProxyResolutionService::CreateDirect();
15406   session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
15407 
15408   HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
15409   auth_handler->set_connection_based(true);
15410   std::string auth_challenge = "Mock realm=server";
15411   GURL origin("http://www.example.com");
15412   HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
15413                                        auth_challenge.end());
15414   SSLInfo empty_ssl_info;
15415   auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
15416                                   empty_ssl_info, origin, NetLogWithSource());
15417   auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
15418 
15419   int rv = OK;
15420   const HttpResponseInfo* response = nullptr;
15421   HttpRequestInfo request;
15422   request.method = "GET";
15423   request.url = origin;
15424   request.traffic_annotation =
15425       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15426 
15427   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15428 
15429   // Use a TCP Socket Pool with only one connection per group. This is used
15430   // to validate that the TCP socket is not released to the pool between
15431   // each round of multi-round authentication.
15432   HttpNetworkSessionPeer session_peer(session.get());
15433   CommonConnectJobParams common_connect_job_params(
15434       session->CreateCommonConnectJobParams());
15435   TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
15436       50,                                // Max sockets for pool
15437       1,                                 // Max sockets per group
15438       base::TimeDelta::FromSeconds(10),  // unused_idle_socket_timeout
15439       ProxyServer::Direct(), false,      // is_for_websockets
15440       &common_connect_job_params);
15441   auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
15442   mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
15443                                    base::WrapUnique(transport_pool));
15444   session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
15445 
15446   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15447   TestCompletionCallback callback;
15448 
15449   const MockWrite kGet(
15450       "GET / HTTP/1.1\r\n"
15451       "Host: www.example.com\r\n"
15452       "Connection: keep-alive\r\n\r\n");
15453   const MockWrite kGetAuth(
15454       "GET / HTTP/1.1\r\n"
15455       "Host: www.example.com\r\n"
15456       "Connection: keep-alive\r\n"
15457       "Authorization: auth_token\r\n\r\n");
15458 
15459   const MockRead kServerChallenge(
15460       "HTTP/1.1 401 Unauthorized\r\n"
15461       "WWW-Authenticate: Mock realm=server\r\n"
15462       "Content-Type: text/html; charset=iso-8859-1\r\n"
15463       "Content-Length: 14\r\n\r\n"
15464       "Unauthorized\r\n");
15465   const MockRead kSuccess(
15466       "HTTP/1.1 200 OK\r\n"
15467       "Content-Type: text/html; charset=iso-8859-1\r\n"
15468       "Content-Length: 3\r\n\r\n"
15469       "Yes");
15470 
15471   MockWrite writes[] = {
15472     // First round
15473     kGet,
15474     // Second round
15475     kGetAuth,
15476     // Third round
15477     kGetAuth,
15478     // Fourth round
15479     kGetAuth,
15480     // Competing request
15481     kGet,
15482   };
15483   MockRead reads[] = {
15484     // First round
15485     kServerChallenge,
15486     // Second round
15487     kServerChallenge,
15488     // Third round
15489     kServerChallenge,
15490     // Fourth round
15491     kSuccess,
15492     // Competing response
15493     kSuccess,
15494   };
15495   StaticSocketDataProvider data_provider(reads, writes);
15496   session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
15497 
15498   const ClientSocketPool::GroupId kSocketGroup(
15499       HostPortPair("www.example.com", 80), ClientSocketPool::SocketType::kHttp,
15500       PrivacyMode::PRIVACY_MODE_DISABLED, NetworkIsolationKey(),
15501       false /* disable_secure_dns */);
15502 
15503   // First round of authentication.
15504   auth_handler->SetGenerateExpectation(false, OK);
15505   rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15506   if (rv == ERR_IO_PENDING)
15507     rv = callback.WaitForResult();
15508   EXPECT_THAT(rv, IsOk());
15509   response = trans.GetResponseInfo();
15510   ASSERT_TRUE(response);
15511   EXPECT_TRUE(response->auth_challenge.has_value());
15512   EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
15513   EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
15514             auth_handler->state());
15515 
15516   // In between rounds, another request comes in for the same domain.
15517   // It should not be able to grab the TCP socket that trans has already
15518   // claimed.
15519   HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
15520   TestCompletionCallback callback_compete;
15521   rv = trans_compete.Start(&request, callback_compete.callback(),
15522                            NetLogWithSource());
15523   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15524   // callback_compete.WaitForResult at this point would stall forever,
15525   // since the HttpNetworkTransaction does not release the request back to
15526   // the pool until after authentication completes.
15527 
15528   // Second round of authentication.
15529   auth_handler->SetGenerateExpectation(false, OK);
15530   rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
15531   if (rv == ERR_IO_PENDING)
15532     rv = callback.WaitForResult();
15533   EXPECT_THAT(rv, IsOk());
15534   response = trans.GetResponseInfo();
15535   ASSERT_TRUE(response);
15536   EXPECT_FALSE(response->auth_challenge.has_value());
15537   EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
15538   EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
15539             auth_handler->state());
15540 
15541   // Third round of authentication.
15542   auth_handler->SetGenerateExpectation(false, OK);
15543   rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
15544   if (rv == ERR_IO_PENDING)
15545     rv = callback.WaitForResult();
15546   EXPECT_THAT(rv, IsOk());
15547   response = trans.GetResponseInfo();
15548   ASSERT_TRUE(response);
15549   EXPECT_FALSE(response->auth_challenge.has_value());
15550   EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
15551   EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
15552             auth_handler->state());
15553 
15554   // Fourth round of authentication, which completes successfully.
15555   auth_handler->SetGenerateExpectation(false, OK);
15556   rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
15557   if (rv == ERR_IO_PENDING)
15558     rv = callback.WaitForResult();
15559   EXPECT_THAT(rv, IsOk());
15560   response = trans.GetResponseInfo();
15561   ASSERT_TRUE(response);
15562   EXPECT_FALSE(response->auth_challenge.has_value());
15563   EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
15564 
15565   // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
15566   // auth handler should transition to a DONE state in concert with the remote
15567   // server. But that's not something we can test here with a mock handler.
15568   EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
15569             auth_handler->state());
15570 
15571   // Read the body since the fourth round was successful. This will also
15572   // release the socket back to the pool.
15573   scoped_refptr<IOBufferWithSize> io_buf =
15574       base::MakeRefCounted<IOBufferWithSize>(50);
15575   rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
15576   if (rv == ERR_IO_PENDING)
15577     rv = callback.WaitForResult();
15578   EXPECT_EQ(3, rv);
15579   rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
15580   EXPECT_EQ(0, rv);
15581   // There are still 0 idle sockets, since the trans_compete transaction
15582   // will be handed it immediately after trans releases it to the group.
15583   EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
15584 
15585   // The competing request can now finish. Wait for the headers and then
15586   // read the body.
15587   rv = callback_compete.WaitForResult();
15588   EXPECT_THAT(rv, IsOk());
15589   rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
15590   if (rv == ERR_IO_PENDING)
15591     rv = callback.WaitForResult();
15592   EXPECT_EQ(3, rv);
15593   rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
15594   EXPECT_EQ(0, rv);
15595 
15596   // Finally, the socket is released to the group.
15597   EXPECT_EQ(1u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
15598 }
15599 
15600 // This tests the case that a request is issued via http instead of spdy after
15601 // npn is negotiated.
TEST_F(HttpNetworkTransactionTest,NpnWithHttpOverSSL)15602 TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
15603   HttpRequestInfo request;
15604   request.method = "GET";
15605   request.url = GURL("https://www.example.org/");
15606   request.traffic_annotation =
15607       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15608 
15609   MockWrite data_writes[] = {
15610       MockWrite(
15611           "GET / HTTP/1.1\r\n"
15612           "Host: www.example.org\r\n"
15613           "Connection: keep-alive\r\n\r\n"),
15614   };
15615 
15616   MockRead data_reads[] = {
15617       MockRead("HTTP/1.1 200 OK\r\n"),
15618       MockRead(kAlternativeServiceHttpHeader),
15619       MockRead("\r\n"),
15620       MockRead("hello world"),
15621       MockRead(SYNCHRONOUS, OK),
15622   };
15623 
15624   SSLSocketDataProvider ssl(ASYNC, OK);
15625   ssl.next_proto = kProtoHTTP11;
15626 
15627   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15628 
15629   StaticSocketDataProvider data(data_reads, data_writes);
15630   session_deps_.socket_factory->AddSocketDataProvider(&data);
15631 
15632   TestCompletionCallback callback;
15633 
15634   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15635   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15636 
15637   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15638 
15639   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15640   EXPECT_THAT(callback.WaitForResult(), IsOk());
15641 
15642   const HttpResponseInfo* response = trans.GetResponseInfo();
15643   ASSERT_TRUE(response);
15644   ASSERT_TRUE(response->headers);
15645   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15646 
15647   std::string response_data;
15648   ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
15649   EXPECT_EQ("hello world", response_data);
15650 
15651   EXPECT_FALSE(response->was_fetched_via_spdy);
15652   EXPECT_TRUE(response->was_alpn_negotiated);
15653 }
15654 
15655 // Simulate the SSL handshake completing with an NPN negotiation followed by an
15656 // immediate server closing of the socket.
15657 // Regression test for https://crbug.com/46369.
TEST_F(HttpNetworkTransactionTest,SpdyPostNPNServerHangup)15658 TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
15659   HttpRequestInfo request;
15660   request.method = "GET";
15661   request.url = GURL("https://www.example.org/");
15662   request.traffic_annotation =
15663       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15664 
15665   SSLSocketDataProvider ssl(ASYNC, OK);
15666   ssl.next_proto = kProtoHTTP2;
15667   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15668 
15669   spdy::SpdySerializedFrame req(
15670       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
15671   MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
15672 
15673   MockRead spdy_reads[] = {
15674     MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
15675   };
15676 
15677   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
15678   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
15679 
15680   TestCompletionCallback callback;
15681 
15682   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15683   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15684 
15685   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15686   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15687   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
15688 }
15689 
15690 // A subclass of HttpAuthHandlerMock that records the request URL when
15691 // it gets it. This is needed since the auth handler may get destroyed
15692 // before we get a chance to query it.
15693 class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
15694  public:
UrlRecordingHttpAuthHandlerMock(GURL * url)15695   explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
15696 
15697   ~UrlRecordingHttpAuthHandlerMock() override = default;
15698 
15699  protected:
GenerateAuthTokenImpl(const AuthCredentials * credentials,const HttpRequestInfo * request,CompletionOnceCallback callback,std::string * auth_token)15700   int GenerateAuthTokenImpl(const AuthCredentials* credentials,
15701                             const HttpRequestInfo* request,
15702                             CompletionOnceCallback callback,
15703                             std::string* auth_token) override {
15704     *url_ = request->url;
15705     return HttpAuthHandlerMock::GenerateAuthTokenImpl(
15706         credentials, request, std::move(callback), auth_token);
15707   }
15708 
15709  private:
15710   GURL* url_;
15711 };
15712 
15713 // Test that if we cancel the transaction as the connection is completing, that
15714 // everything tears down correctly.
TEST_F(HttpNetworkTransactionTest,SimpleCancel)15715 TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
15716   // Setup everything about the connection to complete synchronously, so that
15717   // after calling HttpNetworkTransaction::Start, the only thing we're waiting
15718   // for is the callback from the HttpStreamRequest.
15719   // Then cancel the transaction.
15720   // Verify that we don't crash.
15721   MockConnect mock_connect(SYNCHRONOUS, OK);
15722   MockRead data_reads[] = {
15723     MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
15724     MockRead(SYNCHRONOUS, "hello world"),
15725     MockRead(SYNCHRONOUS, OK),
15726   };
15727 
15728   HttpRequestInfo request;
15729   request.method = "GET";
15730   request.url = GURL("http://www.example.org/");
15731   request.traffic_annotation =
15732       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15733 
15734   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15735   auto trans =
15736       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
15737 
15738   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
15739   data.set_connect_data(mock_connect);
15740   session_deps_.socket_factory->AddSocketDataProvider(&data);
15741 
15742   TestCompletionCallback callback;
15743 
15744   RecordingBoundTestNetLog log;
15745   int rv = trans->Start(&request, callback.callback(), log.bound());
15746   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15747   trans.reset();  // Cancel the transaction here.
15748 
15749   base::RunLoop().RunUntilIdle();
15750 }
15751 
15752 // Test that if a transaction is cancelled after receiving the headers, the
15753 // stream is drained properly and added back to the socket pool.  The main
15754 // purpose of this test is to make sure that an HttpStreamParser can be read
15755 // from after the HttpNetworkTransaction and the objects it owns have been
15756 // deleted.
15757 // See http://crbug.com/368418
TEST_F(HttpNetworkTransactionTest,CancelAfterHeaders)15758 TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
15759   MockRead data_reads[] = {
15760     MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
15761     MockRead(ASYNC, "Content-Length: 2\r\n"),
15762     MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
15763     MockRead(ASYNC, "1"),
15764     // 2 async reads are necessary to trigger a ReadResponseBody call after the
15765     // HttpNetworkTransaction has been deleted.
15766     MockRead(ASYNC, "2"),
15767     MockRead(SYNCHRONOUS, ERR_IO_PENDING),  // Should never read this.
15768   };
15769   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
15770   session_deps_.socket_factory->AddSocketDataProvider(&data);
15771 
15772   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15773 
15774   {
15775     HttpRequestInfo request;
15776     request.method = "GET";
15777     request.url = GURL("http://www.example.org/");
15778     request.traffic_annotation =
15779         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15780 
15781     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15782     TestCompletionCallback callback;
15783 
15784     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15785     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15786     callback.WaitForResult();
15787 
15788     const HttpResponseInfo* response = trans.GetResponseInfo();
15789     ASSERT_TRUE(response);
15790     EXPECT_TRUE(response->headers);
15791     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15792 
15793     // The transaction and HttpRequestInfo are deleted.
15794   }
15795 
15796   // Let the HttpResponseBodyDrainer drain the socket.
15797   base::RunLoop().RunUntilIdle();
15798 
15799   // Socket should now be idle, waiting to be reused.
15800   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
15801 }
15802 
15803 // Test a basic GET request through a proxy.
TEST_F(HttpNetworkTransactionTest,ProxyGet)15804 TEST_F(HttpNetworkTransactionTest, ProxyGet) {
15805   session_deps_.proxy_resolution_service =
15806       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
15807           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
15808   RecordingBoundTestNetLog log;
15809   session_deps_.net_log = log.bound().net_log();
15810   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15811 
15812   HttpRequestInfo request;
15813   request.method = "GET";
15814   request.url = GURL("http://www.example.org/");
15815   request.traffic_annotation =
15816       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15817 
15818   MockWrite data_writes1[] = {
15819       MockWrite(
15820           "GET http://www.example.org/ HTTP/1.1\r\n"
15821           "Host: www.example.org\r\n"
15822           "Proxy-Connection: keep-alive\r\n\r\n"),
15823   };
15824 
15825   MockRead data_reads1[] = {
15826     MockRead("HTTP/1.1 200 OK\r\n"),
15827     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15828     MockRead("Content-Length: 100\r\n\r\n"),
15829     MockRead(SYNCHRONOUS, OK),
15830   };
15831 
15832   StaticSocketDataProvider data1(data_reads1, data_writes1);
15833   session_deps_.socket_factory->AddSocketDataProvider(&data1);
15834 
15835   TestCompletionCallback callback1;
15836 
15837   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15838 
15839   int rv = trans.Start(&request, callback1.callback(), log.bound());
15840   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15841 
15842   rv = callback1.WaitForResult();
15843   EXPECT_THAT(rv, IsOk());
15844 
15845   const HttpResponseInfo* response = trans.GetResponseInfo();
15846   ASSERT_TRUE(response);
15847 
15848   EXPECT_TRUE(response->headers->IsKeepAlive());
15849   EXPECT_EQ(200, response->headers->response_code());
15850   EXPECT_EQ(100, response->headers->GetContentLength());
15851   EXPECT_TRUE(response->was_fetched_via_proxy);
15852   EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
15853                         HostPortPair::FromString("myproxy:70")),
15854             response->proxy_server);
15855   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
15856 
15857   LoadTimingInfo load_timing_info;
15858   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
15859   TestLoadTimingNotReusedWithPac(load_timing_info,
15860                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
15861 }
15862 
15863 // Test a basic HTTPS GET request through a proxy.
TEST_F(HttpNetworkTransactionTest,ProxyTunnelGet)15864 TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
15865   session_deps_.proxy_resolution_service =
15866       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
15867           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
15868   RecordingBoundTestNetLog log;
15869   session_deps_.net_log = log.bound().net_log();
15870   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15871 
15872   HttpRequestInfo request;
15873   request.method = "GET";
15874   request.url = GURL("https://www.example.org/");
15875   request.traffic_annotation =
15876       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15877 
15878   // Since we have proxy, should try to establish tunnel.
15879   MockWrite data_writes1[] = {
15880       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15881                 "Host: www.example.org:443\r\n"
15882                 "Proxy-Connection: keep-alive\r\n\r\n"),
15883 
15884       MockWrite("GET / HTTP/1.1\r\n"
15885                 "Host: www.example.org\r\n"
15886                 "Connection: keep-alive\r\n\r\n"),
15887   };
15888 
15889   MockRead data_reads1[] = {
15890     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15891 
15892     MockRead("HTTP/1.1 200 OK\r\n"),
15893     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15894     MockRead("Content-Length: 100\r\n\r\n"),
15895     MockRead(SYNCHRONOUS, OK),
15896   };
15897 
15898   StaticSocketDataProvider data1(data_reads1, data_writes1);
15899   session_deps_.socket_factory->AddSocketDataProvider(&data1);
15900   SSLSocketDataProvider ssl(ASYNC, OK);
15901   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15902 
15903   TestCompletionCallback callback1;
15904 
15905   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15906 
15907   int rv = trans.Start(&request, callback1.callback(), log.bound());
15908   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15909 
15910   rv = callback1.WaitForResult();
15911   EXPECT_THAT(rv, IsOk());
15912   auto entries = log.GetEntries();
15913   size_t pos = ExpectLogContainsSomewhere(
15914       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
15915       NetLogEventPhase::NONE);
15916   ExpectLogContainsSomewhere(
15917       entries, pos,
15918       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
15919       NetLogEventPhase::NONE);
15920 
15921   const HttpResponseInfo* response = trans.GetResponseInfo();
15922   ASSERT_TRUE(response);
15923 
15924   EXPECT_TRUE(response->headers->IsKeepAlive());
15925   EXPECT_EQ(200, response->headers->response_code());
15926   EXPECT_EQ(100, response->headers->GetContentLength());
15927   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
15928   EXPECT_TRUE(response->was_fetched_via_proxy);
15929   EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
15930                         HostPortPair::FromString("myproxy:70")),
15931             response->proxy_server);
15932 
15933   LoadTimingInfo load_timing_info;
15934   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
15935   TestLoadTimingNotReusedWithPac(load_timing_info,
15936                                  CONNECT_TIMING_HAS_SSL_TIMES);
15937 }
15938 
15939 // Test a basic HTTPS GET request through a proxy, connecting to an IPv6
15940 // literal host.
TEST_F(HttpNetworkTransactionTest,ProxyTunnelGetIPv6)15941 TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
15942   session_deps_.proxy_resolution_service =
15943       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
15944           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
15945   RecordingBoundTestNetLog log;
15946   session_deps_.net_log = log.bound().net_log();
15947   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15948 
15949   HttpRequestInfo request;
15950   request.method = "GET";
15951   request.url = GURL("https://[::2]:443/");
15952   request.traffic_annotation =
15953       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
15954 
15955   // Since we have proxy, should try to establish tunnel.
15956   MockWrite data_writes1[] = {
15957       MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
15958                 "Host: [::2]:443\r\n"
15959                 "Proxy-Connection: keep-alive\r\n\r\n"),
15960 
15961       MockWrite("GET / HTTP/1.1\r\n"
15962                 "Host: [::2]\r\n"
15963                 "Connection: keep-alive\r\n\r\n"),
15964   };
15965 
15966   MockRead data_reads1[] = {
15967       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15968 
15969       MockRead("HTTP/1.1 200 OK\r\n"),
15970       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15971       MockRead("Content-Length: 100\r\n\r\n"),
15972       MockRead(SYNCHRONOUS, OK),
15973   };
15974 
15975   StaticSocketDataProvider data1(data_reads1, data_writes1);
15976   session_deps_.socket_factory->AddSocketDataProvider(&data1);
15977   SSLSocketDataProvider ssl(ASYNC, OK);
15978   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15979 
15980   TestCompletionCallback callback1;
15981 
15982   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15983 
15984   int rv = trans.Start(&request, callback1.callback(), log.bound());
15985   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15986 
15987   rv = callback1.WaitForResult();
15988   EXPECT_THAT(rv, IsOk());
15989   auto entries = log.GetEntries();
15990   size_t pos = ExpectLogContainsSomewhere(
15991       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
15992       NetLogEventPhase::NONE);
15993   ExpectLogContainsSomewhere(
15994       entries, pos,
15995       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
15996       NetLogEventPhase::NONE);
15997 
15998   const HttpResponseInfo* response = trans.GetResponseInfo();
15999   ASSERT_TRUE(response);
16000 
16001   EXPECT_TRUE(response->headers->IsKeepAlive());
16002   EXPECT_EQ(200, response->headers->response_code());
16003   EXPECT_EQ(100, response->headers->GetContentLength());
16004   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
16005   EXPECT_TRUE(response->was_fetched_via_proxy);
16006   EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
16007                         HostPortPair::FromString("myproxy:70")),
16008             response->proxy_server);
16009 
16010   LoadTimingInfo load_timing_info;
16011   EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
16012   TestLoadTimingNotReusedWithPac(load_timing_info,
16013                                  CONNECT_TIMING_HAS_SSL_TIMES);
16014 }
16015 
16016 // Test a basic HTTPS GET request through a proxy, but the server hangs up
16017 // while establishing the tunnel.
TEST_F(HttpNetworkTransactionTest,ProxyTunnelGetHangup)16018 TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
16019   session_deps_.proxy_resolution_service =
16020       ConfiguredProxyResolutionService::CreateFixed(
16021           "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
16022   RecordingBoundTestNetLog log;
16023   session_deps_.net_log = log.bound().net_log();
16024   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16025 
16026   HttpRequestInfo request;
16027   request.method = "GET";
16028   request.url = GURL("https://www.example.org/");
16029   request.traffic_annotation =
16030       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16031 
16032   // Since we have proxy, should try to establish tunnel.
16033   MockWrite data_writes1[] = {
16034       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16035                 "Host: www.example.org:443\r\n"
16036                 "Proxy-Connection: keep-alive\r\n\r\n"),
16037 
16038       MockWrite("GET / HTTP/1.1\r\n"
16039                 "Host: www.example.org\r\n"
16040                 "Connection: keep-alive\r\n\r\n"),
16041   };
16042 
16043   MockRead data_reads1[] = {
16044     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16045     MockRead(ASYNC, 0, 0),  // EOF
16046   };
16047 
16048   StaticSocketDataProvider data1(data_reads1, data_writes1);
16049   session_deps_.socket_factory->AddSocketDataProvider(&data1);
16050   SSLSocketDataProvider ssl(ASYNC, OK);
16051   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16052 
16053   TestCompletionCallback callback1;
16054 
16055   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16056 
16057   int rv = trans.Start(&request, callback1.callback(), log.bound());
16058   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16059 
16060   rv = callback1.WaitForResult();
16061   EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
16062   auto entries = log.GetEntries();
16063   size_t pos = ExpectLogContainsSomewhere(
16064       entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
16065       NetLogEventPhase::NONE);
16066   ExpectLogContainsSomewhere(
16067       entries, pos,
16068       NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
16069       NetLogEventPhase::NONE);
16070 }
16071 
16072 // Test for crbug.com/55424.
TEST_F(HttpNetworkTransactionTest,PreconnectWithExistingSpdySession)16073 TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
16074   spdy::SpdySerializedFrame req(
16075       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
16076   MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
16077 
16078   spdy::SpdySerializedFrame resp(
16079       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
16080   spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
16081   MockRead spdy_reads[] = {
16082       CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
16083   };
16084 
16085   SequencedSocketData spdy_data(spdy_reads, spdy_writes);
16086   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
16087 
16088   SSLSocketDataProvider ssl(ASYNC, OK);
16089   ssl.next_proto = kProtoHTTP2;
16090   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16091 
16092   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16093 
16094   // Set up an initial SpdySession in the pool to reuse.
16095   HostPortPair host_port_pair("www.example.org", 443);
16096   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
16097                      PRIVACY_MODE_DISABLED,
16098                      SpdySessionKey::IsProxySession::kFalse, SocketTag(),
16099                      NetworkIsolationKey(), false /* disable_secure_dns */);
16100   base::WeakPtr<SpdySession> spdy_session =
16101       CreateSpdySession(session.get(), key, NetLogWithSource());
16102 
16103   HttpRequestInfo request;
16104   request.method = "GET";
16105   request.url = GURL("https://www.example.org/");
16106   request.traffic_annotation =
16107       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16108 
16109   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16110 
16111   TestCompletionCallback callback;
16112   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16113   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16114   EXPECT_THAT(callback.WaitForResult(), IsOk());
16115 }
16116 
16117 // Given a net error, cause that error to be returned from the first Write()
16118 // call and verify that the HttpNetworkTransaction fails with that error.
CheckErrorIsPassedBack(int error,IoMode mode)16119 void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
16120     int error, IoMode mode) {
16121   HttpRequestInfo request_info;
16122   request_info.url = GURL("https://www.example.com/");
16123   request_info.method = "GET";
16124   request_info.load_flags = LOAD_NORMAL;
16125   request_info.traffic_annotation =
16126       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16127 
16128   SSLSocketDataProvider ssl_data(mode, OK);
16129   MockWrite data_writes[] = {
16130       MockWrite(mode, error),
16131   };
16132   StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
16133   session_deps_.socket_factory->AddSocketDataProvider(&data);
16134   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
16135 
16136   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16137   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16138 
16139   TestCompletionCallback callback;
16140   int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
16141   if (rv == ERR_IO_PENDING)
16142     rv = callback.WaitForResult();
16143   ASSERT_EQ(error, rv);
16144 }
16145 
TEST_F(HttpNetworkTransactionTest,SSLWriteCertError)16146 TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
16147   // Just check a grab bag of cert errors.
16148   static const int kErrors[] = {
16149     ERR_CERT_COMMON_NAME_INVALID,
16150     ERR_CERT_AUTHORITY_INVALID,
16151     ERR_CERT_DATE_INVALID,
16152   };
16153   for (size_t i = 0; i < base::size(kErrors); i++) {
16154     CheckErrorIsPassedBack(kErrors[i], ASYNC);
16155     CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
16156   }
16157 }
16158 
16159 // Ensure that a client certificate is removed from the SSL client auth
16160 // cache when:
16161 //  1) No proxy is involved.
16162 //  2) TLS False Start is disabled.
16163 //  3) The initial TLS handshake requests a client certificate.
16164 //  4) The client supplies an invalid/unacceptable certificate.
TEST_F(HttpNetworkTransactionTest,ClientAuthCertCache_Direct_NoFalseStart)16165 TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
16166   HttpRequestInfo request_info;
16167   request_info.url = GURL("https://www.example.com/");
16168   request_info.method = "GET";
16169   request_info.load_flags = LOAD_NORMAL;
16170   request_info.traffic_annotation =
16171       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16172 
16173   auto cert_request = base::MakeRefCounted<SSLCertRequestInfo>();
16174   cert_request->host_and_port = HostPortPair("www.example.com", 443);
16175 
16176   // [ssl_]data1 contains the data for the first SSL handshake. When a
16177   // CertificateRequest is received for the first time, the handshake will
16178   // be aborted to allow the caller to provide a certificate.
16179   SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
16180   ssl_data1.cert_request_info = cert_request.get();
16181   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
16182   StaticSocketDataProvider data1;
16183   session_deps_.socket_factory->AddSocketDataProvider(&data1);
16184 
16185   // [ssl_]data2 contains the data for the second SSL handshake. When TLS
16186   // False Start is not being used, the result of the SSL handshake will be
16187   // returned as part of the SSLClientSocket::Connect() call. This test
16188   // matches the result of a server sending a handshake_failure alert,
16189   // rather than a Finished message, because it requires a client
16190   // certificate and none was supplied.
16191   SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
16192   ssl_data2.cert_request_info = cert_request.get();
16193   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
16194   StaticSocketDataProvider data2;
16195   session_deps_.socket_factory->AddSocketDataProvider(&data2);
16196 
16197   // [ssl_]data3 contains the data for the third SSL handshake. When a
16198   // connection to a server fails during an SSL handshake,
16199   // HttpNetworkTransaction will attempt to fallback with legacy cryptography
16200   // enabled on some errors. This is transparent to the caller
16201   // of the HttpNetworkTransaction. Because this test failure is due to
16202   // requiring a client certificate, this fallback handshake should also
16203   // fail.
16204   SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
16205   ssl_data3.expected_disable_legacy_crypto = false;
16206   ssl_data3.cert_request_info = cert_request.get();
16207   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
16208   StaticSocketDataProvider data3;
16209   session_deps_.socket_factory->AddSocketDataProvider(&data3);
16210 
16211   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16212   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16213 
16214   // Begin the SSL handshake with the peer. This consumes ssl_data1.
16215   TestCompletionCallback callback;
16216   int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
16217   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
16218 
16219   // Complete the SSL handshake, which should abort due to requiring a
16220   // client certificate.
16221   rv = callback.WaitForResult();
16222   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
16223 
16224   // Indicate that no certificate should be supplied. From the perspective
16225   // of SSLClientCertCache, NULL is just as meaningful as a real
16226   // certificate, so this is the same as supply a
16227   // legitimate-but-unacceptable certificate.
16228   rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
16229   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
16230 
16231   // Ensure the certificate was added to the client auth cache before
16232   // allowing the connection to continue restarting.
16233   scoped_refptr<X509Certificate> client_cert;
16234   scoped_refptr<SSLPrivateKey> client_private_key;
16235   ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate(
16236       HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
16237   ASSERT_FALSE(client_cert);
16238 
16239   // Restart the handshake. This will consume ssl_data2, which fails, and
16240   // then consume ssl_data3 and ssl_data4, both of which should also fail.
16241   // The result code is checked against what ssl_data4 should return.
16242   rv = callback.WaitForResult();
16243   ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
16244 
16245   // Ensure that the client certificate is removed from the cache on a
16246   // handshake failure.
16247   ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate(
16248       HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
16249 }
16250 
16251 // Ensure that a client certificate is removed from the SSL client auth
16252 // cache when:
16253 //  1) No proxy is involved.
16254 //  2) TLS False Start is enabled.
16255 //  3) The initial TLS handshake requests a client certificate.
16256 //  4) The client supplies an invalid/unacceptable certificate.
TEST_F(HttpNetworkTransactionTest,ClientAuthCertCache_Direct_FalseStart)16257 TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
16258   HttpRequestInfo request_info;
16259   request_info.url = GURL("https://www.example.com/");
16260   request_info.method = "GET";
16261   request_info.load_flags = LOAD_NORMAL;
16262   request_info.traffic_annotation =
16263       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16264 
16265   auto cert_request = base::MakeRefCounted<SSLCertRequestInfo>();
16266   cert_request->host_and_port = HostPortPair("www.example.com", 443);
16267 
16268   // When TLS False Start is used, SSLClientSocket::Connect() calls will
16269   // return successfully after reading up to the peer's Certificate message.
16270   // This is to allow the caller to call SSLClientSocket::Write(), which can
16271   // enqueue application data to be sent in the same packet as the
16272   // ChangeCipherSpec and Finished messages.
16273   // The actual handshake will be finished when SSLClientSocket::Read() is
16274   // called, which expects to process the peer's ChangeCipherSpec and
16275   // Finished messages. If there was an error negotiating with the peer,
16276   // such as due to the peer requiring a client certificate when none was
16277   // supplied, the alert sent by the peer won't be processed until Read() is
16278   // called.
16279 
16280   // Like the non-False Start case, when a client certificate is requested by
16281   // the peer, the handshake is aborted during the Connect() call.
16282   // [ssl_]data1 represents the initial SSL handshake with the peer.
16283   SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
16284   ssl_data1.cert_request_info = cert_request.get();
16285   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
16286   StaticSocketDataProvider data1;
16287   session_deps_.socket_factory->AddSocketDataProvider(&data1);
16288 
16289   // When a client certificate is supplied, Connect() will not be aborted
16290   // when the peer requests the certificate. Instead, the handshake will
16291   // artificially succeed, allowing the caller to write the HTTP request to
16292   // the socket. The handshake messages are not processed until Read() is
16293   // called, which then detects that the handshake was aborted, due to the
16294   // peer sending a handshake_failure because it requires a client
16295   // certificate.
16296   SSLSocketDataProvider ssl_data2(ASYNC, OK);
16297   ssl_data2.cert_request_info = cert_request.get();
16298   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
16299   MockRead data2_reads[] = {
16300       MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
16301   };
16302   StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
16303   session_deps_.socket_factory->AddSocketDataProvider(&data2);
16304 
16305   // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
16306   // the data for the SSL handshake once the TLSv1.1 connection falls back to
16307   // TLSv1. It has the same behaviour as [ssl_]data2.
16308   SSLSocketDataProvider ssl_data3(ASYNC, OK);
16309   ssl_data3.cert_request_info = cert_request.get();
16310   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
16311   StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
16312   session_deps_.socket_factory->AddSocketDataProvider(&data3);
16313 
16314   // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
16315   // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
16316   SSLSocketDataProvider ssl_data4(ASYNC, OK);
16317   ssl_data4.cert_request_info = cert_request.get();
16318   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
16319   StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
16320   session_deps_.socket_factory->AddSocketDataProvider(&data4);
16321 
16322   // Need one more if TLSv1.2 is enabled.
16323   SSLSocketDataProvider ssl_data5(ASYNC, OK);
16324   ssl_data5.cert_request_info = cert_request.get();
16325   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
16326   StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
16327   session_deps_.socket_factory->AddSocketDataProvider(&data5);
16328 
16329   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16330   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16331 
16332   // Begin the initial SSL handshake.
16333   TestCompletionCallback callback;
16334   int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
16335   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
16336 
16337   // Complete the SSL handshake, which should abort due to requiring a
16338   // client certificate.
16339   rv = callback.WaitForResult();
16340   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
16341 
16342   // Indicate that no certificate should be supplied. From the perspective
16343   // of SSLClientCertCache, NULL is just as meaningful as a real
16344   // certificate, so this is the same as supply a
16345   // legitimate-but-unacceptable certificate.
16346   rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
16347   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
16348 
16349   // Ensure the certificate was added to the client auth cache before
16350   // allowing the connection to continue restarting.
16351   scoped_refptr<X509Certificate> client_cert;
16352   scoped_refptr<SSLPrivateKey> client_private_key;
16353   ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate(
16354       HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
16355   ASSERT_FALSE(client_cert);
16356 
16357   // Restart the handshake. This will consume ssl_data2, which fails, and
16358   // then consume ssl_data3 and ssl_data4, both of which should also fail.
16359   // The result code is checked against what ssl_data4 should return.
16360   rv = callback.WaitForResult();
16361   ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
16362 
16363   // Ensure that the client certificate is removed from the cache on a
16364   // handshake failure.
16365   ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate(
16366       HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
16367 }
16368 
16369 // Ensure that a client certificate is removed from the SSL client auth
16370 // cache when:
16371 //  1) An HTTPS proxy is involved.
16372 //  3) The HTTPS proxy requests a client certificate.
16373 //  4) The client supplies an invalid/unacceptable certificate for the
16374 //     proxy.
TEST_F(HttpNetworkTransactionTest,ClientAuthCertCache_Proxy_Fail)16375 TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
16376   session_deps_.proxy_resolution_service =
16377       ConfiguredProxyResolutionService::CreateFixed(
16378           "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
16379   RecordingBoundTestNetLog log;
16380   session_deps_.net_log = log.bound().net_log();
16381 
16382   auto cert_request = base::MakeRefCounted<SSLCertRequestInfo>();
16383   cert_request->host_and_port = HostPortPair("proxy", 70);
16384 
16385   // Repeat the test for connecting to an HTTPS endpoint, then for connecting to
16386   // an HTTP endpoint.
16387   HttpRequestInfo requests[2];
16388   requests[0].url = GURL("https://www.example.com/");
16389   requests[0].method = "GET";
16390   requests[0].load_flags = LOAD_NORMAL;
16391   requests[0].traffic_annotation =
16392       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16393 
16394   // HTTPS requests are tunneled.
16395   MockWrite https_writes[] = {
16396       MockWrite("CONNECT www.example.com:443 HTTP/1.1\r\n"
16397                 "Host: www.example.com:443\r\n"
16398                 "Proxy-Connection: keep-alive\r\n\r\n"),
16399   };
16400 
16401   requests[1].url = GURL("http://www.example.com/");
16402   requests[1].method = "GET";
16403   requests[1].load_flags = LOAD_NORMAL;
16404   requests[1].traffic_annotation =
16405       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16406 
16407   // HTTP requests are not.
16408   MockWrite http_writes[] = {
16409       MockWrite("GET http://www.example.com/ HTTP/1.1\r\n"
16410                 "Host: www.example.com\r\n"
16411                 "Proxy-Connection: keep-alive\r\n\r\n"),
16412   };
16413 
16414   // When the server rejects the client certificate, it will close the
16415   // connection. In TLS 1.2, this is signaled out of Connect(). In TLS 1.3 (or
16416   // TLS 1.2 with False Start), the error is returned out of the first Read().
16417   for (bool reject_in_connect : {true, false}) {
16418     SCOPED_TRACE(reject_in_connect);
16419     // Client certificate errors are typically signaled with
16420     // ERR_BAD_SSL_CLIENT_AUTH_CERT, but sometimes the server gives an arbitrary
16421     // protocol error.
16422     for (Error reject_error :
16423          {ERR_SSL_PROTOCOL_ERROR, ERR_BAD_SSL_CLIENT_AUTH_CERT}) {
16424       SCOPED_TRACE(reject_error);
16425       // Tunneled and non-tunneled requests are handled differently. Test both.
16426       for (const HttpRequestInfo& request : requests) {
16427         SCOPED_TRACE(request.url);
16428 
16429         session_deps_.socket_factory =
16430             std::make_unique<MockClientSocketFactory>();
16431 
16432         // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
16433         // [ssl_]data[1-3].
16434         SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
16435         ssl_data1.cert_request_info = cert_request.get();
16436         session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
16437         StaticSocketDataProvider data1;
16438         session_deps_.socket_factory->AddSocketDataProvider(&data1);
16439 
16440         base::Optional<SSLSocketDataProvider> ssl_data2;
16441         base::Optional<StaticSocketDataProvider> data2;
16442         MockRead error_in_read[] = {MockRead(ASYNC, reject_error)};
16443         if (reject_in_connect) {
16444           ssl_data2.emplace(ASYNC, reject_error);
16445           // There are no reads or writes.
16446           data2.emplace();
16447         } else {
16448           ssl_data2.emplace(ASYNC, OK);
16449           // We will get one Write() in before observing the error in Read().
16450           if (request.url.SchemeIsCryptographic()) {
16451             data2.emplace(error_in_read, https_writes);
16452           } else {
16453             data2.emplace(error_in_read, http_writes);
16454           }
16455         }
16456         ssl_data2->cert_request_info = cert_request.get();
16457         session_deps_.socket_factory->AddSSLSocketDataProvider(
16458             &ssl_data2.value());
16459         session_deps_.socket_factory->AddSocketDataProvider(&data2.value());
16460 
16461         // If the handshake returns ERR_SSL_PROTOCOL_ERROR, we attempt to
16462         // connect twice.
16463         base::Optional<SSLSocketDataProvider> ssl_data3;
16464         base::Optional<StaticSocketDataProvider> data3;
16465         if (reject_in_connect && reject_error == ERR_SSL_PROTOCOL_ERROR) {
16466           ssl_data3.emplace(ASYNC, reject_error);
16467           data3.emplace();  // There are no reads or writes.
16468           ssl_data3->cert_request_info = cert_request.get();
16469           session_deps_.socket_factory->AddSSLSocketDataProvider(
16470               &ssl_data3.value());
16471           session_deps_.socket_factory->AddSocketDataProvider(&data3.value());
16472         }
16473 
16474         std::unique_ptr<HttpNetworkSession> session =
16475             CreateSession(&session_deps_);
16476         HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16477 
16478         // Begin the SSL handshake with the proxy.
16479         TestCompletionCallback callback;
16480         int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16481         ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
16482 
16483         // Complete the SSL handshake, which should abort due to requiring a
16484         // client certificate.
16485         rv = callback.WaitForResult();
16486         ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
16487 
16488         // Indicate that no certificate should be supplied. From the
16489         // perspective of SSLClientCertCache, NULL is just as meaningful as a
16490         // real certificate, so this is the same as supply a
16491         // legitimate-but-unacceptable certificate.
16492         rv =
16493             trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
16494         ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
16495 
16496         // Ensure the certificate was added to the client auth cache before
16497         // allowing the connection to continue restarting.
16498         scoped_refptr<X509Certificate> client_cert;
16499         scoped_refptr<SSLPrivateKey> client_private_key;
16500         ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate(
16501             HostPortPair("proxy", 70), &client_cert, &client_private_key));
16502         ASSERT_FALSE(client_cert);
16503         // Ensure the certificate was NOT cached for the endpoint. This only
16504         // applies to HTTPS requests, but is fine to check for HTTP requests.
16505         ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate(
16506             HostPortPair("www.example.com", 443), &client_cert,
16507             &client_private_key));
16508 
16509         // Restart the handshake. This will consume ssl_data2. The result code
16510         // is checked against what ssl_data2 should return.
16511         rv = callback.WaitForResult();
16512         ASSERT_THAT(rv, AnyOf(IsError(ERR_PROXY_CONNECTION_FAILED),
16513                               IsError(reject_error)));
16514 
16515         // Now that the new handshake has failed, ensure that the client
16516         // certificate was removed from the client auth cache.
16517         ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate(
16518             HostPortPair("proxy", 70), &client_cert, &client_private_key));
16519         ASSERT_FALSE(session->ssl_client_context()->GetClientCertificate(
16520             HostPortPair("www.example.com", 443), &client_cert,
16521             &client_private_key));
16522       }
16523     }
16524   }
16525 }
16526 
16527 // Test that HttpNetworkTransaction correctly handles (mocked) certificate
16528 // requests during a TLS renegotiation.
TEST_F(HttpNetworkTransactionTest,CertificateRequestInRenego)16529 TEST_F(HttpNetworkTransactionTest, CertificateRequestInRenego) {
16530   HttpRequestInfo request_info;
16531   request_info.url = GURL("https://www.example.com/");
16532   request_info.method = "GET";
16533   request_info.load_flags = LOAD_NORMAL;
16534   request_info.traffic_annotation =
16535       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16536 
16537   auto cert_request = base::MakeRefCounted<SSLCertRequestInfo>();
16538   cert_request->host_and_port = HostPortPair("www.example.com", 443);
16539 
16540   std::unique_ptr<FakeClientCertIdentity> identity =
16541       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
16542           GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
16543   ASSERT_TRUE(identity);
16544 
16545   // The first connection's handshake succeeds, but we get
16546   // ERR_SSL_CLIENT_AUTH_CERT_NEEDED instead of an HTTP response.
16547   SSLSocketDataProvider ssl_data1(ASYNC, OK);
16548   ssl_data1.cert_request_info = cert_request.get();
16549   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
16550   MockWrite data1_writes[] = {
16551       MockWrite("GET / HTTP/1.1\r\n"
16552                 "Host: www.example.com\r\n"
16553                 "Connection: keep-alive\r\n\r\n"),
16554   };
16555   MockRead data1_reads[] = {
16556       MockRead(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED),
16557   };
16558   StaticSocketDataProvider data1(data1_reads, data1_writes);
16559   session_deps_.socket_factory->AddSocketDataProvider(&data1);
16560 
16561   // After supplying with certificate, we restart the request from the top,
16562   // which succeeds this time.
16563   SSLSocketDataProvider ssl_data2(ASYNC, OK);
16564   ssl_data2.expected_send_client_cert = true;
16565   ssl_data2.expected_client_cert = identity->certificate();
16566   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
16567   MockWrite data2_writes[] = {
16568       MockWrite("GET / HTTP/1.1\r\n"
16569                 "Host: www.example.com\r\n"
16570                 "Connection: keep-alive\r\n\r\n"),
16571   };
16572   MockRead data2_reads[] = {
16573       MockRead("HTTP/1.1 200 OK\r\n"
16574                "Content-Length: 0\r\n\r\n"),
16575   };
16576   StaticSocketDataProvider data2(data2_reads, data2_writes);
16577   session_deps_.socket_factory->AddSocketDataProvider(&data2);
16578 
16579   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
16580   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16581 
16582   TestCompletionCallback callback;
16583   int rv = callback.GetResult(
16584       trans.Start(&request_info, callback.callback(), NetLogWithSource()));
16585   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
16586 
16587   rv = trans.RestartWithCertificate(identity->certificate(),
16588                                     identity->ssl_private_key(),
16589                                     callback.callback());
16590   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
16591 
16592   // Ensure the certificate was added to the client auth cache
16593   // allowing the connection to continue restarting.
16594   scoped_refptr<X509Certificate> client_cert;
16595   scoped_refptr<SSLPrivateKey> client_private_key;
16596   ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate(
16597       HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
16598   EXPECT_TRUE(client_cert->EqualsIncludingChain(identity->certificate()));
16599 
16600   // Complete the handshake. The request now succeeds.
16601   rv = callback.WaitForResult();
16602   ASSERT_THAT(rv, IsError(OK));
16603   EXPECT_EQ(200, trans.GetResponseInfo()->headers->response_code());
16604 
16605   // The client certificate remains in the cache.
16606   ASSERT_TRUE(session->ssl_client_context()->GetClientCertificate(
16607       HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
16608   EXPECT_TRUE(client_cert->EqualsIncludingChain(identity->certificate()));
16609 }
16610 
TEST_F(HttpNetworkTransactionTest,UseIPConnectionPooling)16611 TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
16612   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
16613   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
16614   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16615 
16616   AddSSLSocketData();
16617 
16618   spdy::SpdySerializedFrame host1_req(
16619       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
16620   spdy_util_.UpdateWithStreamDestruction(1);
16621   spdy::SpdySerializedFrame host2_req(
16622       spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
16623   MockWrite spdy_writes[] = {
16624       CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
16625   };
16626   spdy::SpdySerializedFrame host1_resp(
16627       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
16628   spdy::SpdySerializedFrame host1_resp_body(
16629       spdy_util_.ConstructSpdyDataFrame(1, true));
16630   spdy::SpdySerializedFrame host2_resp(
16631       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
16632   spdy::SpdySerializedFrame host2_resp_body(
16633       spdy_util_.ConstructSpdyDataFrame(3, true));
16634   MockRead spdy_reads[] = {
16635       CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
16636       CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
16637       MockRead(ASYNC, 0, 6),
16638   };
16639 
16640   IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
16641   MockConnect connect(ASYNC, OK, peer_addr);
16642   SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
16643   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
16644 
16645   TestCompletionCallback callback;
16646   HttpRequestInfo request1;
16647   request1.method = "GET";
16648   request1.url = GURL("https://www.example.org/");
16649   request1.load_flags = 0;
16650   request1.traffic_annotation =
16651       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16652   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16653 
16654   int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
16655   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16656   EXPECT_THAT(callback.WaitForResult(), IsOk());
16657 
16658   const HttpResponseInfo* response = trans1.GetResponseInfo();
16659   ASSERT_TRUE(response);
16660   ASSERT_TRUE(response->headers);
16661   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
16662 
16663   std::string response_data;
16664   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
16665   EXPECT_EQ("hello!", response_data);
16666 
16667   // Preload mail.example.com into HostCache.
16668   rv = session_deps_.host_resolver->LoadIntoCache(
16669       HostPortPair("mail.example.com", 443), NetworkIsolationKey(),
16670       base::nullopt);
16671   EXPECT_THAT(rv, IsOk());
16672 
16673   HttpRequestInfo request2;
16674   request2.method = "GET";
16675   request2.url = GURL("https://mail.example.com/");
16676   request2.load_flags = 0;
16677   request2.traffic_annotation =
16678       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16679   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16680 
16681   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
16682   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16683   EXPECT_THAT(callback.WaitForResult(), IsOk());
16684 
16685   response = trans2.GetResponseInfo();
16686   ASSERT_TRUE(response);
16687   ASSERT_TRUE(response->headers);
16688   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
16689   EXPECT_TRUE(response->was_fetched_via_spdy);
16690   EXPECT_TRUE(response->was_alpn_negotiated);
16691   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
16692   EXPECT_EQ("hello!", response_data);
16693 }
16694 
TEST_F(HttpNetworkTransactionTest,UseIPConnectionPoolingAfterResolution)16695 TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
16696   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
16697   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
16698   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16699 
16700   AddSSLSocketData();
16701 
16702   spdy::SpdySerializedFrame host1_req(
16703       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
16704   spdy_util_.UpdateWithStreamDestruction(1);
16705   spdy::SpdySerializedFrame host2_req(
16706       spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
16707   MockWrite spdy_writes[] = {
16708       CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
16709   };
16710   spdy::SpdySerializedFrame host1_resp(
16711       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
16712   spdy::SpdySerializedFrame host1_resp_body(
16713       spdy_util_.ConstructSpdyDataFrame(1, true));
16714   spdy::SpdySerializedFrame host2_resp(
16715       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
16716   spdy::SpdySerializedFrame host2_resp_body(
16717       spdy_util_.ConstructSpdyDataFrame(3, true));
16718   MockRead spdy_reads[] = {
16719       CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
16720       CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
16721       MockRead(ASYNC, 0, 6),
16722   };
16723 
16724   IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
16725   MockConnect connect(ASYNC, OK, peer_addr);
16726   SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
16727   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
16728 
16729   TestCompletionCallback callback;
16730   HttpRequestInfo request1;
16731   request1.method = "GET";
16732   request1.url = GURL("https://www.example.org/");
16733   request1.load_flags = 0;
16734   request1.traffic_annotation =
16735       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16736   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16737 
16738   int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
16739   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16740   EXPECT_THAT(callback.WaitForResult(), IsOk());
16741 
16742   const HttpResponseInfo* response = trans1.GetResponseInfo();
16743   ASSERT_TRUE(response);
16744   ASSERT_TRUE(response->headers);
16745   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
16746 
16747   std::string response_data;
16748   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
16749   EXPECT_EQ("hello!", response_data);
16750 
16751   HttpRequestInfo request2;
16752   request2.method = "GET";
16753   request2.url = GURL("https://mail.example.com/");
16754   request2.load_flags = 0;
16755   request2.traffic_annotation =
16756       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16757   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16758 
16759   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
16760   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16761   EXPECT_THAT(callback.WaitForResult(), IsOk());
16762 
16763   response = trans2.GetResponseInfo();
16764   ASSERT_TRUE(response);
16765   ASSERT_TRUE(response->headers);
16766   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
16767   EXPECT_TRUE(response->was_fetched_via_spdy);
16768   EXPECT_TRUE(response->was_alpn_negotiated);
16769   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
16770   EXPECT_EQ("hello!", response_data);
16771 }
16772 
16773 // Regression test for https://crbug.com/546991.
16774 // The server might not be able to serve an IP pooled request, and might send a
16775 // 421 Misdirected Request response status to indicate this.
16776 // HttpNetworkTransaction should reset the request and retry without IP pooling.
TEST_F(HttpNetworkTransactionTest,RetryWithoutConnectionPooling)16777 TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
16778   // Two hosts resolve to the same IP address.
16779   const std::string ip_addr = "1.2.3.4";
16780   IPAddress ip;
16781   ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
16782   IPEndPoint peer_addr = IPEndPoint(ip, 443);
16783 
16784   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
16785   session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
16786   session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
16787 
16788   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16789 
16790   // Two requests on the first connection.
16791   spdy::SpdySerializedFrame req1(
16792       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
16793   spdy_util_.UpdateWithStreamDestruction(1);
16794   spdy::SpdySerializedFrame req2(
16795       spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
16796   spdy::SpdySerializedFrame rst(
16797       spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
16798   MockWrite writes1[] = {
16799       CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
16800       CreateMockWrite(rst, 6),
16801   };
16802 
16803   // The first one succeeds, the second gets error 421 Misdirected Request.
16804   spdy::SpdySerializedFrame resp1(
16805       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
16806   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
16807   spdy::SpdyHeaderBlock response_headers;
16808   response_headers[spdy::kHttp2StatusHeader] = "421";
16809   spdy::SpdySerializedFrame resp2(
16810       spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
16811   MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
16812                        CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
16813 
16814   MockConnect connect1(ASYNC, OK, peer_addr);
16815   SequencedSocketData data1(connect1, reads1, writes1);
16816   session_deps_.socket_factory->AddSocketDataProvider(&data1);
16817 
16818   AddSSLSocketData();
16819 
16820   // Retry the second request on a second connection.
16821   SpdyTestUtil spdy_util2;
16822   spdy::SpdySerializedFrame req3(
16823       spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
16824   MockWrite writes2[] = {
16825       CreateMockWrite(req3, 0),
16826   };
16827 
16828   spdy::SpdySerializedFrame resp3(
16829       spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
16830   spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
16831   MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
16832                        MockRead(ASYNC, 0, 3)};
16833 
16834   MockConnect connect2(ASYNC, OK, peer_addr);
16835   SequencedSocketData data2(connect2, reads2, writes2);
16836   session_deps_.socket_factory->AddSocketDataProvider(&data2);
16837 
16838   AddSSLSocketData();
16839 
16840   // Preload mail.example.org into HostCache.
16841   int rv = session_deps_.host_resolver->LoadIntoCache(
16842       HostPortPair("mail.example.com", 443), NetworkIsolationKey(),
16843       base::nullopt);
16844   EXPECT_THAT(rv, IsOk());
16845 
16846   HttpRequestInfo request1;
16847   request1.method = "GET";
16848   request1.url = GURL("https://www.example.org/");
16849   request1.load_flags = 0;
16850   request1.traffic_annotation =
16851       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16852   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16853 
16854   TestCompletionCallback callback;
16855   rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
16856   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16857   rv = callback.WaitForResult();
16858   EXPECT_THAT(rv, IsOk());
16859 
16860   const HttpResponseInfo* response = trans1.GetResponseInfo();
16861   ASSERT_TRUE(response);
16862   ASSERT_TRUE(response->headers);
16863   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
16864   EXPECT_TRUE(response->was_fetched_via_spdy);
16865   EXPECT_TRUE(response->was_alpn_negotiated);
16866   std::string response_data;
16867   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
16868   EXPECT_EQ("hello!", response_data);
16869 
16870   HttpRequestInfo request2;
16871   request2.method = "GET";
16872   request2.url = GURL("https://mail.example.org/");
16873   request2.load_flags = 0;
16874   request2.traffic_annotation =
16875       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16876   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16877 
16878   RecordingBoundTestNetLog log;
16879   rv = trans2.Start(&request2, callback.callback(), log.bound());
16880   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16881   rv = callback.WaitForResult();
16882   EXPECT_THAT(rv, IsOk());
16883 
16884   response = trans2.GetResponseInfo();
16885   ASSERT_TRUE(response);
16886   ASSERT_TRUE(response->headers);
16887   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
16888   EXPECT_TRUE(response->was_fetched_via_spdy);
16889   EXPECT_TRUE(response->was_alpn_negotiated);
16890   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
16891   EXPECT_EQ("hello!", response_data);
16892 
16893   auto entries = log.GetEntries();
16894   ExpectLogContainsSomewhere(
16895       entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
16896       NetLogEventPhase::NONE);
16897 }
16898 
16899 // Test that HTTP 421 responses are properly returned to the caller if received
16900 // on the retry as well. HttpNetworkTransaction should not infinite loop or lose
16901 // portions of the response.
TEST_F(HttpNetworkTransactionTest,ReturnHTTP421OnRetry)16902 TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
16903   // Two hosts resolve to the same IP address.
16904   const std::string ip_addr = "1.2.3.4";
16905   IPAddress ip;
16906   ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
16907   IPEndPoint peer_addr = IPEndPoint(ip, 443);
16908 
16909   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
16910   session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
16911   session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
16912 
16913   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16914 
16915   // Two requests on the first connection.
16916   spdy::SpdySerializedFrame req1(
16917       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
16918   spdy_util_.UpdateWithStreamDestruction(1);
16919   spdy::SpdySerializedFrame req2(
16920       spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
16921   spdy::SpdySerializedFrame rst(
16922       spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
16923   MockWrite writes1[] = {
16924       CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
16925       CreateMockWrite(rst, 6),
16926   };
16927 
16928   // The first one succeeds, the second gets error 421 Misdirected Request.
16929   spdy::SpdySerializedFrame resp1(
16930       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
16931   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
16932   spdy::SpdyHeaderBlock response_headers;
16933   response_headers[spdy::kHttp2StatusHeader] = "421";
16934   spdy::SpdySerializedFrame resp2(
16935       spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
16936   MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
16937                        CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
16938 
16939   MockConnect connect1(ASYNC, OK, peer_addr);
16940   SequencedSocketData data1(connect1, reads1, writes1);
16941   session_deps_.socket_factory->AddSocketDataProvider(&data1);
16942 
16943   AddSSLSocketData();
16944 
16945   // Retry the second request on a second connection. It returns 421 Misdirected
16946   // Retry again.
16947   SpdyTestUtil spdy_util2;
16948   spdy::SpdySerializedFrame req3(
16949       spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
16950   MockWrite writes2[] = {
16951       CreateMockWrite(req3, 0),
16952   };
16953 
16954   spdy::SpdySerializedFrame resp3(
16955       spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
16956   spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
16957   MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
16958                        MockRead(ASYNC, 0, 3)};
16959 
16960   MockConnect connect2(ASYNC, OK, peer_addr);
16961   SequencedSocketData data2(connect2, reads2, writes2);
16962   session_deps_.socket_factory->AddSocketDataProvider(&data2);
16963 
16964   AddSSLSocketData();
16965 
16966   // Preload mail.example.org into HostCache.
16967   int rv = session_deps_.host_resolver->LoadIntoCache(
16968       HostPortPair("mail.example.com", 443), NetworkIsolationKey(),
16969       base::nullopt);
16970   EXPECT_THAT(rv, IsOk());
16971 
16972   HttpRequestInfo request1;
16973   request1.method = "GET";
16974   request1.url = GURL("https://www.example.org/");
16975   request1.load_flags = 0;
16976   request1.traffic_annotation =
16977       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16978   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16979 
16980   TestCompletionCallback callback;
16981   rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
16982   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16983   rv = callback.WaitForResult();
16984   EXPECT_THAT(rv, IsOk());
16985 
16986   const HttpResponseInfo* response = trans1.GetResponseInfo();
16987   ASSERT_TRUE(response);
16988   ASSERT_TRUE(response->headers);
16989   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
16990   EXPECT_TRUE(response->was_fetched_via_spdy);
16991   EXPECT_TRUE(response->was_alpn_negotiated);
16992   std::string response_data;
16993   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
16994   EXPECT_EQ("hello!", response_data);
16995 
16996   HttpRequestInfo request2;
16997   request2.method = "GET";
16998   request2.url = GURL("https://mail.example.org/");
16999   request2.load_flags = 0;
17000   request2.traffic_annotation =
17001       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17002   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
17003 
17004   RecordingBoundTestNetLog log;
17005   rv = trans2.Start(&request2, callback.callback(), log.bound());
17006   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17007   rv = callback.WaitForResult();
17008   EXPECT_THAT(rv, IsOk());
17009 
17010   // After a retry, the 421 Misdirected Request is reported back up to the
17011   // caller.
17012   response = trans2.GetResponseInfo();
17013   ASSERT_TRUE(response);
17014   ASSERT_TRUE(response->headers);
17015   EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
17016   EXPECT_TRUE(response->was_fetched_via_spdy);
17017   EXPECT_TRUE(response->was_alpn_negotiated);
17018   EXPECT_TRUE(response->ssl_info.cert);
17019   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
17020   EXPECT_EQ("hello!", response_data);
17021 }
17022 
TEST_F(HttpNetworkTransactionTest,UseIPConnectionPoolingWithHostCacheExpiration)17023 TEST_F(HttpNetworkTransactionTest,
17024        UseIPConnectionPoolingWithHostCacheExpiration) {
17025   // Set up HostResolver to invalidate cached entries after 1 cached resolve.
17026   session_deps_.host_resolver =
17027       std::make_unique<MockCachingHostResolver>(1 /* cache_invalidation_num */);
17028   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17029 
17030   AddSSLSocketData();
17031 
17032   spdy::SpdySerializedFrame host1_req(
17033       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
17034   spdy_util_.UpdateWithStreamDestruction(1);
17035   spdy::SpdySerializedFrame host2_req(
17036       spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
17037   MockWrite spdy_writes[] = {
17038       CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
17039   };
17040   spdy::SpdySerializedFrame host1_resp(
17041       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17042   spdy::SpdySerializedFrame host1_resp_body(
17043       spdy_util_.ConstructSpdyDataFrame(1, true));
17044   spdy::SpdySerializedFrame host2_resp(
17045       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
17046   spdy::SpdySerializedFrame host2_resp_body(
17047       spdy_util_.ConstructSpdyDataFrame(3, true));
17048   MockRead spdy_reads[] = {
17049       CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
17050       CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
17051       MockRead(ASYNC, 0, 6),
17052   };
17053 
17054   IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
17055   MockConnect connect(ASYNC, OK, peer_addr);
17056   SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
17057   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
17058 
17059   TestCompletionCallback callback;
17060   HttpRequestInfo request1;
17061   request1.method = "GET";
17062   request1.url = GURL("https://www.example.org/");
17063   request1.load_flags = 0;
17064   request1.traffic_annotation =
17065       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17066   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
17067 
17068   int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
17069   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17070   EXPECT_THAT(callback.WaitForResult(), IsOk());
17071 
17072   const HttpResponseInfo* response = trans1.GetResponseInfo();
17073   ASSERT_TRUE(response);
17074   ASSERT_TRUE(response->headers);
17075   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
17076 
17077   std::string response_data;
17078   ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
17079   EXPECT_EQ("hello!", response_data);
17080 
17081   // Preload cache entries into HostCache.
17082   rv = session_deps_.host_resolver->LoadIntoCache(
17083       HostPortPair("mail.example.com", 443), NetworkIsolationKey(),
17084       base::nullopt);
17085   EXPECT_THAT(rv, IsOk());
17086 
17087   HttpRequestInfo request2;
17088   request2.method = "GET";
17089   request2.url = GURL("https://mail.example.com/");
17090   request2.load_flags = 0;
17091   request2.traffic_annotation =
17092       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17093   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
17094 
17095   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
17096   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17097   EXPECT_THAT(callback.WaitForResult(), IsOk());
17098 
17099   response = trans2.GetResponseInfo();
17100   ASSERT_TRUE(response);
17101   ASSERT_TRUE(response->headers);
17102   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
17103   EXPECT_TRUE(response->was_fetched_via_spdy);
17104   EXPECT_TRUE(response->was_alpn_negotiated);
17105   ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
17106   EXPECT_EQ("hello!", response_data);
17107 }
17108 
TEST_F(HttpNetworkTransactionTest,DoNotUseSpdySessionForHttp)17109 TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
17110   const std::string https_url = "https://www.example.org:8080/";
17111   const std::string http_url = "http://www.example.org:8080/";
17112 
17113   // SPDY GET for HTTPS URL
17114   spdy::SpdySerializedFrame req1(
17115       spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
17116 
17117   MockWrite writes1[] = {
17118       CreateMockWrite(req1, 0),
17119   };
17120 
17121   spdy::SpdySerializedFrame resp1(
17122       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17123   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
17124   MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
17125                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
17126 
17127   SequencedSocketData data1(reads1, writes1);
17128   MockConnect connect_data1(ASYNC, OK);
17129   data1.set_connect_data(connect_data1);
17130 
17131   // HTTP GET for the HTTP URL
17132   MockWrite writes2[] = {
17133       MockWrite(ASYNC, 0,
17134                 "GET / HTTP/1.1\r\n"
17135                 "Host: www.example.org:8080\r\n"
17136                 "Connection: keep-alive\r\n\r\n"),
17137   };
17138 
17139   MockRead reads2[] = {
17140       MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
17141       MockRead(ASYNC, 2, "hello"),
17142       MockRead(ASYNC, OK, 3),
17143   };
17144 
17145   SequencedSocketData data2(reads2, writes2);
17146 
17147   SSLSocketDataProvider ssl(ASYNC, OK);
17148   ssl.next_proto = kProtoHTTP2;
17149   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17150   session_deps_.socket_factory->AddSocketDataProvider(&data1);
17151   session_deps_.socket_factory->AddSocketDataProvider(&data2);
17152 
17153   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17154 
17155   // Start the first transaction to set up the SpdySession
17156   HttpRequestInfo request1;
17157   request1.method = "GET";
17158   request1.url = GURL(https_url);
17159   request1.load_flags = 0;
17160   request1.traffic_annotation =
17161       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17162   HttpNetworkTransaction trans1(LOWEST, session.get());
17163   TestCompletionCallback callback1;
17164   EXPECT_EQ(ERR_IO_PENDING,
17165             trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
17166   base::RunLoop().RunUntilIdle();
17167 
17168   EXPECT_THAT(callback1.WaitForResult(), IsOk());
17169   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
17170 
17171   // Now, start the HTTP request
17172   HttpRequestInfo request2;
17173   request2.method = "GET";
17174   request2.url = GURL(http_url);
17175   request2.load_flags = 0;
17176   request2.traffic_annotation =
17177       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17178   HttpNetworkTransaction trans2(MEDIUM, session.get());
17179   TestCompletionCallback callback2;
17180   EXPECT_EQ(ERR_IO_PENDING,
17181             trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
17182   base::RunLoop().RunUntilIdle();
17183 
17184   EXPECT_THAT(callback2.WaitForResult(), IsOk());
17185   EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
17186 }
17187 
17188 // Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
17189 // with the alternative server.  That connection should not be used.
TEST_F(HttpNetworkTransactionTest,AlternativeServiceNotOnHttp11)17190 TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
17191   url::SchemeHostPort server("https", "www.example.org", 443);
17192   HostPortPair alternative("www.example.org", 444);
17193 
17194   // Negotiate HTTP/1.1 with alternative.
17195   SSLSocketDataProvider ssl(ASYNC, OK);
17196   ssl.next_proto = kProtoHTTP11;
17197   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17198 
17199   // No data should be read from the alternative, because HTTP/1.1 is
17200   // negotiated.
17201   StaticSocketDataProvider data;
17202   session_deps_.socket_factory->AddSocketDataProvider(&data);
17203 
17204   // This test documents that an alternate Job should not be used if HTTP/1.1 is
17205   // negotiated.  In order to test this, a failed connection to the server is
17206   // mocked.  This way the request relies on the alternate Job.
17207   StaticSocketDataProvider data_refused;
17208   data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
17209   session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
17210 
17211   // Set up alternative service for server.
17212   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17213   HttpServerProperties* http_server_properties =
17214       session->http_server_properties();
17215   AlternativeService alternative_service(kProtoHTTP2, alternative);
17216   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
17217   http_server_properties->SetHttp2AlternativeService(
17218       server, NetworkIsolationKey(), alternative_service, expiration);
17219 
17220   HttpRequestInfo request;
17221   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17222   request.method = "GET";
17223   request.url = GURL("https://www.example.org:443");
17224   request.traffic_annotation =
17225       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17226   TestCompletionCallback callback;
17227 
17228   // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
17229   // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
17230   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17231   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
17232 }
17233 
17234 // A request to a server with an alternative service fires two Jobs: one to the
17235 // server, and an alternate one to the alternative server.  If the former
17236 // succeeds, the request should succeed,  even if the latter fails because
17237 // HTTP/1.1 is negotiated which is insufficient for alternative service.
TEST_F(HttpNetworkTransactionTest,FailedAlternativeServiceIsNotUserVisible)17238 TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
17239   url::SchemeHostPort server("https", "www.example.org", 443);
17240   HostPortPair alternative("www.example.org", 444);
17241 
17242   // Negotiate HTTP/1.1 with alternative.
17243   SSLSocketDataProvider alternative_ssl(ASYNC, OK);
17244   alternative_ssl.next_proto = kProtoHTTP11;
17245   session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
17246 
17247   // No data should be read from the alternative, because HTTP/1.1 is
17248   // negotiated.
17249   StaticSocketDataProvider data;
17250   session_deps_.socket_factory->AddSocketDataProvider(&data);
17251 
17252   // Negotiate HTTP/1.1 with server.
17253   SSLSocketDataProvider origin_ssl(ASYNC, OK);
17254   origin_ssl.next_proto = kProtoHTTP11;
17255   session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
17256 
17257   MockWrite http_writes[] = {
17258       MockWrite("GET / HTTP/1.1\r\n"
17259                 "Host: www.example.org\r\n"
17260                 "Connection: keep-alive\r\n\r\n"),
17261       MockWrite("GET /second HTTP/1.1\r\n"
17262                 "Host: www.example.org\r\n"
17263                 "Connection: keep-alive\r\n\r\n"),
17264   };
17265 
17266   MockRead http_reads[] = {
17267       MockRead("HTTP/1.1 200 OK\r\n"),
17268       MockRead("Content-Type: text/html\r\n"),
17269       MockRead("Content-Length: 6\r\n\r\n"),
17270       MockRead("foobar"),
17271       MockRead("HTTP/1.1 200 OK\r\n"),
17272       MockRead("Content-Type: text/html\r\n"),
17273       MockRead("Content-Length: 7\r\n\r\n"),
17274       MockRead("another"),
17275   };
17276   StaticSocketDataProvider http_data(http_reads, http_writes);
17277   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17278 
17279   // Set up alternative service for server.
17280   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17281   HttpServerProperties* http_server_properties =
17282       session->http_server_properties();
17283   AlternativeService alternative_service(kProtoHTTP2, alternative);
17284   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
17285   http_server_properties->SetHttp2AlternativeService(
17286       server, NetworkIsolationKey(), alternative_service, expiration);
17287 
17288   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
17289   HttpRequestInfo request1;
17290   request1.method = "GET";
17291   request1.url = GURL("https://www.example.org:443");
17292   request1.load_flags = 0;
17293   request1.traffic_annotation =
17294       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17295   TestCompletionCallback callback1;
17296 
17297   int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
17298   rv = callback1.GetResult(rv);
17299   EXPECT_THAT(rv, IsOk());
17300 
17301   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
17302   ASSERT_TRUE(response1);
17303   ASSERT_TRUE(response1->headers);
17304   EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
17305 
17306   std::string response_data1;
17307   ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
17308   EXPECT_EQ("foobar", response_data1);
17309 
17310   // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
17311   // for alternative service.
17312   EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
17313       alternative_service, NetworkIsolationKey()));
17314 
17315   // Since |alternative_service| is broken, a second transaction to server
17316   // should not start an alternate Job.  It should pool to existing connection
17317   // to server.
17318   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
17319   HttpRequestInfo request2;
17320   request2.method = "GET";
17321   request2.url = GURL("https://www.example.org:443/second");
17322   request2.load_flags = 0;
17323   request2.traffic_annotation =
17324       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17325   TestCompletionCallback callback2;
17326 
17327   rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
17328   rv = callback2.GetResult(rv);
17329   EXPECT_THAT(rv, IsOk());
17330 
17331   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
17332   ASSERT_TRUE(response2);
17333   ASSERT_TRUE(response2->headers);
17334   EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
17335 
17336   std::string response_data2;
17337   ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
17338   EXPECT_EQ("another", response_data2);
17339 }
17340 
17341 // Alternative service requires HTTP/2 (or SPDY), but there is already a
17342 // HTTP/1.1 socket open to the alternative server.  That socket should not be
17343 // used.
TEST_F(HttpNetworkTransactionTest,AlternativeServiceShouldNotPoolToHttp11)17344 TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
17345   url::SchemeHostPort server("https", "origin.example.org", 443);
17346   HostPortPair alternative("alternative.example.org", 443);
17347   std::string origin_url = "https://origin.example.org:443";
17348   std::string alternative_url = "https://alternative.example.org:443";
17349 
17350   // Negotiate HTTP/1.1 with alternative.example.org.
17351   SSLSocketDataProvider ssl(ASYNC, OK);
17352   ssl.next_proto = kProtoHTTP11;
17353   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17354 
17355   // HTTP/1.1 data for |request1| and |request2|.
17356   MockWrite http_writes[] = {
17357       MockWrite(
17358           "GET / HTTP/1.1\r\n"
17359           "Host: alternative.example.org\r\n"
17360           "Connection: keep-alive\r\n\r\n"),
17361       MockWrite(
17362           "GET / HTTP/1.1\r\n"
17363           "Host: alternative.example.org\r\n"
17364           "Connection: keep-alive\r\n\r\n"),
17365   };
17366 
17367   MockRead http_reads[] = {
17368       MockRead(
17369           "HTTP/1.1 200 OK\r\n"
17370           "Content-Type: text/html; charset=iso-8859-1\r\n"
17371           "Content-Length: 40\r\n\r\n"
17372           "first HTTP/1.1 response from alternative"),
17373       MockRead(
17374           "HTTP/1.1 200 OK\r\n"
17375           "Content-Type: text/html; charset=iso-8859-1\r\n"
17376           "Content-Length: 41\r\n\r\n"
17377           "second HTTP/1.1 response from alternative"),
17378   };
17379   StaticSocketDataProvider http_data(http_reads, http_writes);
17380   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17381 
17382   // This test documents that an alternate Job should not pool to an already
17383   // existing HTTP/1.1 connection.  In order to test this, a failed connection
17384   // to the server is mocked.  This way |request2| relies on the alternate Job.
17385   StaticSocketDataProvider data_refused;
17386   data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
17387   session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
17388 
17389   // Set up alternative service for server.
17390   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17391   HttpServerProperties* http_server_properties =
17392       session->http_server_properties();
17393   AlternativeService alternative_service(kProtoHTTP2, alternative);
17394   base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
17395   http_server_properties->SetHttp2AlternativeService(
17396       server, NetworkIsolationKey(), alternative_service, expiration);
17397 
17398   // First transaction to alternative to open an HTTP/1.1 socket.
17399   HttpRequestInfo request1;
17400   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
17401   request1.method = "GET";
17402   request1.url = GURL(alternative_url);
17403   request1.load_flags = 0;
17404   request1.traffic_annotation =
17405       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17406   TestCompletionCallback callback1;
17407 
17408   int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
17409   EXPECT_THAT(callback1.GetResult(rv), IsOk());
17410   const HttpResponseInfo* response1 = trans1.GetResponseInfo();
17411   ASSERT_TRUE(response1);
17412   ASSERT_TRUE(response1->headers);
17413   EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
17414   EXPECT_TRUE(response1->was_alpn_negotiated);
17415   EXPECT_FALSE(response1->was_fetched_via_spdy);
17416   std::string response_data1;
17417   ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
17418   EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
17419 
17420   // Request for origin.example.org, which has an alternative service.  This
17421   // will start two Jobs: the alternative looks for connections to pool to,
17422   // finds one which is HTTP/1.1, and should ignore it, and should not try to
17423   // open other connections to alternative server.  The Job to server fails, so
17424   // this request fails.
17425   HttpRequestInfo request2;
17426   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
17427   request2.method = "GET";
17428   request2.url = GURL(origin_url);
17429   request2.load_flags = 0;
17430   request2.traffic_annotation =
17431       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17432   TestCompletionCallback callback2;
17433 
17434   rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
17435   EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
17436 
17437   // Another transaction to alternative.  This is to test that the HTTP/1.1
17438   // socket is still open and in the pool.
17439   HttpRequestInfo request3;
17440   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
17441   request3.method = "GET";
17442   request3.url = GURL(alternative_url);
17443   request3.load_flags = 0;
17444   request3.traffic_annotation =
17445       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17446   TestCompletionCallback callback3;
17447 
17448   rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
17449   EXPECT_THAT(callback3.GetResult(rv), IsOk());
17450   const HttpResponseInfo* response3 = trans3.GetResponseInfo();
17451   ASSERT_TRUE(response3);
17452   ASSERT_TRUE(response3->headers);
17453   EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
17454   EXPECT_TRUE(response3->was_alpn_negotiated);
17455   EXPECT_FALSE(response3->was_fetched_via_spdy);
17456   std::string response_data3;
17457   ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
17458   EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
17459 }
17460 
TEST_F(HttpNetworkTransactionTest,DoNotUseSpdySessionForHttpOverTunnel)17461 TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
17462   const std::string https_url = "https://www.example.org:8080/";
17463   const std::string http_url = "http://www.example.org:8080/";
17464 
17465   // Separate SPDY util instance for naked and wrapped requests.
17466   SpdyTestUtil spdy_util_wrapped;
17467 
17468   // SPDY GET for HTTPS URL (through CONNECT tunnel)
17469   const HostPortPair host_port_pair("www.example.org", 8080);
17470   spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
17471       nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
17472       host_port_pair));
17473   spdy::SpdySerializedFrame req1(
17474       spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
17475   spdy::SpdySerializedFrame wrapped_req1(
17476       spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
17477 
17478   // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
17479   spdy::SpdyHeaderBlock req2_block;
17480   req2_block[spdy::kHttp2MethodHeader] = "GET";
17481   req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
17482   req2_block[spdy::kHttp2SchemeHeader] = "http";
17483   req2_block[spdy::kHttp2PathHeader] = "/";
17484   spdy::SpdySerializedFrame req2(
17485       spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
17486 
17487   MockWrite writes1[] = {
17488       CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
17489       CreateMockWrite(req2, 6),
17490   };
17491 
17492   spdy::SpdySerializedFrame conn_resp(
17493       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17494   spdy::SpdySerializedFrame resp1(
17495       spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
17496   spdy::SpdySerializedFrame body1(
17497       spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
17498   spdy::SpdySerializedFrame wrapped_resp1(
17499       spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
17500   spdy::SpdySerializedFrame wrapped_body1(
17501       spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
17502   spdy::SpdySerializedFrame resp2(
17503       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
17504   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
17505   MockRead reads1[] = {
17506       CreateMockRead(conn_resp, 1),
17507       MockRead(ASYNC, ERR_IO_PENDING, 3),
17508       CreateMockRead(wrapped_resp1, 4),
17509       CreateMockRead(wrapped_body1, 5),
17510       MockRead(ASYNC, ERR_IO_PENDING, 7),
17511       CreateMockRead(resp2, 8),
17512       CreateMockRead(body2, 9),
17513       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
17514   };
17515 
17516   SequencedSocketData data1(reads1, writes1);
17517   MockConnect connect_data1(ASYNC, OK);
17518   data1.set_connect_data(connect_data1);
17519 
17520   session_deps_.proxy_resolution_service =
17521       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
17522           "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
17523   RecordingTestNetLog log;
17524   session_deps_.net_log = &log;
17525   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
17526   ssl1.next_proto = kProtoHTTP2;
17527   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
17528   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
17529   ssl2.next_proto = kProtoHTTP2;
17530   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
17531   session_deps_.socket_factory->AddSocketDataProvider(&data1);
17532 
17533   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
17534 
17535   // Start the first transaction to set up the SpdySession
17536   HttpRequestInfo request1;
17537   request1.method = "GET";
17538   request1.url = GURL(https_url);
17539   request1.load_flags = 0;
17540   request1.traffic_annotation =
17541       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17542   HttpNetworkTransaction trans1(LOWEST, session.get());
17543   TestCompletionCallback callback1;
17544   int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
17545 
17546   // This pause is a hack to avoid running into https://crbug.com/497228.
17547   data1.RunUntilPaused();
17548   base::RunLoop().RunUntilIdle();
17549   data1.Resume();
17550   EXPECT_THAT(callback1.GetResult(rv), IsOk());
17551   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
17552 
17553   LoadTimingInfo load_timing_info1;
17554   EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
17555   TestLoadTimingNotReusedWithPac(load_timing_info1,
17556                                  CONNECT_TIMING_HAS_SSL_TIMES);
17557 
17558   // Now, start the HTTP request.
17559   HttpRequestInfo request2;
17560   request2.method = "GET";
17561   request2.url = GURL(http_url);
17562   request2.load_flags = 0;
17563   request2.traffic_annotation =
17564       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17565   HttpNetworkTransaction trans2(MEDIUM, session.get());
17566   TestCompletionCallback callback2;
17567   rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
17568 
17569   // This pause is a hack to avoid running into https://crbug.com/497228.
17570   data1.RunUntilPaused();
17571   base::RunLoop().RunUntilIdle();
17572   data1.Resume();
17573   EXPECT_THAT(callback2.GetResult(rv), IsOk());
17574 
17575   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
17576 
17577   LoadTimingInfo load_timing_info2;
17578   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
17579   // The established SPDY sessions is considered reused by the HTTP request.
17580   TestLoadTimingReusedWithPac(load_timing_info2);
17581   // HTTP requests over a SPDY session should have a different connection
17582   // socket_log_id than requests over a tunnel.
17583   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
17584 }
17585 
17586 // Test that in the case where we have a SPDY session to a SPDY proxy
17587 // that we do not pool other origins that resolve to the same IP when
17588 // the certificate does not match the new origin.
17589 // http://crbug.com/134690
TEST_F(HttpNetworkTransactionTest,DoNotUseSpdySessionIfCertDoesNotMatch)17590 TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
17591   const std::string url1 = "http://www.example.org/";
17592   const std::string url2 = "https://news.example.org/";
17593   const std::string ip_addr = "1.2.3.4";
17594 
17595   // Second SpdyTestUtil instance for the second socket.
17596   SpdyTestUtil spdy_util_secure;
17597 
17598   // SPDY GET for HTTP URL (through SPDY proxy)
17599   spdy::SpdyHeaderBlock headers(
17600       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
17601   spdy::SpdySerializedFrame req1(
17602       spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
17603 
17604   MockWrite writes1[] = {
17605       CreateMockWrite(req1, 0),
17606   };
17607 
17608   spdy::SpdySerializedFrame resp1(
17609       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17610   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
17611   MockRead reads1[] = {
17612       MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
17613       CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4),  // EOF
17614   };
17615 
17616   SequencedSocketData data1(reads1, writes1);
17617   IPAddress ip;
17618   ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
17619   IPEndPoint peer_addr = IPEndPoint(ip, 443);
17620   MockConnect connect_data1(ASYNC, OK, peer_addr);
17621   data1.set_connect_data(connect_data1);
17622 
17623   // SPDY GET for HTTPS URL (direct)
17624   spdy::SpdySerializedFrame req2(
17625       spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
17626 
17627   MockWrite writes2[] = {
17628       CreateMockWrite(req2, 0),
17629   };
17630 
17631   spdy::SpdySerializedFrame resp2(
17632       spdy_util_secure.ConstructSpdyGetReply(nullptr, 0, 1));
17633   spdy::SpdySerializedFrame body2(
17634       spdy_util_secure.ConstructSpdyDataFrame(1, true));
17635   MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
17636                        MockRead(ASYNC, OK, 3)};
17637 
17638   SequencedSocketData data2(reads2, writes2);
17639   MockConnect connect_data2(ASYNC, OK);
17640   data2.set_connect_data(connect_data2);
17641 
17642   // Set up a proxy config that sends HTTP requests to a proxy, and
17643   // all others direct.
17644   ProxyConfig proxy_config;
17645   proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
17646   session_deps_.proxy_resolution_service =
17647       std::make_unique<ConfiguredProxyResolutionService>(
17648           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17649               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
17650           nullptr, nullptr);
17651 
17652   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
17653   ssl1.next_proto = kProtoHTTP2;
17654   // Load a valid cert.  Note, that this does not need to
17655   // be valid for proxy because the MockSSLClientSocket does
17656   // not actually verify it.  But SpdySession will use this
17657   // to see if it is valid for the new origin
17658   ssl1.ssl_info.cert =
17659       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
17660   ASSERT_TRUE(ssl1.ssl_info.cert);
17661   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
17662   session_deps_.socket_factory->AddSocketDataProvider(&data1);
17663 
17664   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
17665   ssl2.next_proto = kProtoHTTP2;
17666   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
17667   session_deps_.socket_factory->AddSocketDataProvider(&data2);
17668 
17669   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
17670   session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
17671   session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
17672 
17673   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
17674 
17675   // Start the first transaction to set up the SpdySession
17676   HttpRequestInfo request1;
17677   request1.method = "GET";
17678   request1.url = GURL(url1);
17679   request1.load_flags = 0;
17680   request1.traffic_annotation =
17681       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17682   HttpNetworkTransaction trans1(LOWEST, session.get());
17683   TestCompletionCallback callback1;
17684   ASSERT_EQ(ERR_IO_PENDING,
17685             trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
17686   // This pause is a hack to avoid running into https://crbug.com/497228.
17687   data1.RunUntilPaused();
17688   base::RunLoop().RunUntilIdle();
17689   data1.Resume();
17690 
17691   EXPECT_THAT(callback1.WaitForResult(), IsOk());
17692   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
17693 
17694   // Now, start the HTTP request
17695   HttpRequestInfo request2;
17696   request2.method = "GET";
17697   request2.url = GURL(url2);
17698   request2.load_flags = 0;
17699   request2.traffic_annotation =
17700       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17701   HttpNetworkTransaction trans2(MEDIUM, session.get());
17702   TestCompletionCallback callback2;
17703   EXPECT_EQ(ERR_IO_PENDING,
17704             trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
17705   base::RunLoop().RunUntilIdle();
17706 
17707   ASSERT_TRUE(callback2.have_result());
17708   EXPECT_THAT(callback2.WaitForResult(), IsOk());
17709   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
17710 }
17711 
17712 // Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
17713 // error) in SPDY session, removes the socket from pool and closes the SPDY
17714 // session. Verify that new url's from the same HttpNetworkSession (and a new
17715 // SpdySession) do work. http://crbug.com/224701
TEST_F(HttpNetworkTransactionTest,ErrorSocketNotConnected)17716 TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
17717   const std::string https_url = "https://www.example.org/";
17718 
17719   MockRead reads1[] = {
17720     MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
17721   };
17722 
17723   SequencedSocketData data1(reads1, base::span<MockWrite>());
17724 
17725   spdy::SpdySerializedFrame req2(
17726       spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
17727   MockWrite writes2[] = {
17728       CreateMockWrite(req2, 0),
17729   };
17730 
17731   spdy::SpdySerializedFrame resp2(
17732       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17733   spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
17734   MockRead reads2[] = {
17735       CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
17736       MockRead(ASYNC, OK, 3)  // EOF
17737   };
17738 
17739   SequencedSocketData data2(reads2, writes2);
17740 
17741   SSLSocketDataProvider ssl1(ASYNC, OK);
17742   ssl1.next_proto = kProtoHTTP2;
17743   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
17744   session_deps_.socket_factory->AddSocketDataProvider(&data1);
17745 
17746   SSLSocketDataProvider ssl2(ASYNC, OK);
17747   ssl2.next_proto = kProtoHTTP2;
17748   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
17749   session_deps_.socket_factory->AddSocketDataProvider(&data2);
17750 
17751   std::unique_ptr<HttpNetworkSession> session(
17752       SpdySessionDependencies::SpdyCreateSession(&session_deps_));
17753 
17754   // Start the first transaction to set up the SpdySession and verify that
17755   // connection was closed.
17756   HttpRequestInfo request1;
17757   request1.method = "GET";
17758   request1.url = GURL(https_url);
17759   request1.load_flags = 0;
17760   request1.traffic_annotation =
17761       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17762   HttpNetworkTransaction trans1(MEDIUM, session.get());
17763   TestCompletionCallback callback1;
17764   EXPECT_EQ(ERR_IO_PENDING,
17765             trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
17766   EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
17767 
17768   // Now, start the second request and make sure it succeeds.
17769   HttpRequestInfo request2;
17770   request2.method = "GET";
17771   request2.url = GURL(https_url);
17772   request2.load_flags = 0;
17773   request2.traffic_annotation =
17774       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17775   HttpNetworkTransaction trans2(MEDIUM, session.get());
17776   TestCompletionCallback callback2;
17777   EXPECT_EQ(ERR_IO_PENDING,
17778             trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
17779 
17780   ASSERT_THAT(callback2.WaitForResult(), IsOk());
17781   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
17782 }
17783 
TEST_F(HttpNetworkTransactionTest,CloseIdleSpdySessionToOpenNewOne)17784 TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
17785   ClientSocketPoolManager::set_max_sockets_per_group(
17786       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17787   ClientSocketPoolManager::set_max_sockets_per_pool(
17788       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17789 
17790   // Use two different hosts with different IPs so they don't get pooled.
17791   session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
17792   session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
17793   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17794 
17795   SSLSocketDataProvider ssl1(ASYNC, OK);
17796   ssl1.next_proto = kProtoHTTP2;
17797   SSLSocketDataProvider ssl2(ASYNC, OK);
17798   ssl2.next_proto = kProtoHTTP2;
17799   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
17800   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
17801 
17802   spdy::SpdySerializedFrame host1_req(
17803       spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
17804   MockWrite spdy1_writes[] = {
17805       CreateMockWrite(host1_req, 0),
17806   };
17807   spdy::SpdySerializedFrame host1_resp(
17808       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17809   spdy::SpdySerializedFrame host1_resp_body(
17810       spdy_util_.ConstructSpdyDataFrame(1, true));
17811   MockRead spdy1_reads[] = {
17812       CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
17813       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
17814   };
17815 
17816   // Use a separate test instance for the separate SpdySession that will be
17817   // created.
17818   SpdyTestUtil spdy_util_2;
17819   SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
17820   session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
17821 
17822   spdy::SpdySerializedFrame host2_req(
17823       spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
17824   MockWrite spdy2_writes[] = {
17825       CreateMockWrite(host2_req, 0),
17826   };
17827   spdy::SpdySerializedFrame host2_resp(
17828       spdy_util_2.ConstructSpdyGetReply(nullptr, 0, 1));
17829   spdy::SpdySerializedFrame host2_resp_body(
17830       spdy_util_2.ConstructSpdyDataFrame(1, true));
17831   MockRead spdy2_reads[] = {
17832       CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
17833       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
17834   };
17835 
17836   SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
17837   session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
17838 
17839   MockWrite http_write[] = {
17840     MockWrite("GET / HTTP/1.1\r\n"
17841               "Host: www.a.com\r\n"
17842               "Connection: keep-alive\r\n\r\n"),
17843   };
17844 
17845   MockRead http_read[] = {
17846     MockRead("HTTP/1.1 200 OK\r\n"),
17847     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
17848     MockRead("Content-Length: 6\r\n\r\n"),
17849     MockRead("hello!"),
17850   };
17851   StaticSocketDataProvider http_data(http_read, http_write);
17852   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17853 
17854   HostPortPair host_port_pair_a("www.a.com", 443);
17855   SpdySessionKey spdy_session_key_a(
17856       host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
17857       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
17858       NetworkIsolationKey(), false /* disable_secure_dns */);
17859   EXPECT_FALSE(
17860       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
17861 
17862   TestCompletionCallback callback;
17863   HttpRequestInfo request1;
17864   request1.method = "GET";
17865   request1.url = GURL("https://www.a.com/");
17866   request1.load_flags = 0;
17867   request1.traffic_annotation =
17868       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17869   auto trans =
17870       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
17871 
17872   int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
17873   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17874   EXPECT_THAT(callback.WaitForResult(), IsOk());
17875 
17876   const HttpResponseInfo* response = trans->GetResponseInfo();
17877   ASSERT_TRUE(response);
17878   ASSERT_TRUE(response->headers);
17879   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
17880   EXPECT_TRUE(response->was_fetched_via_spdy);
17881   EXPECT_TRUE(response->was_alpn_negotiated);
17882 
17883   std::string response_data;
17884   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
17885   EXPECT_EQ("hello!", response_data);
17886   trans.reset();
17887   EXPECT_TRUE(
17888       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
17889 
17890   HostPortPair host_port_pair_b("www.b.com", 443);
17891   SpdySessionKey spdy_session_key_b(
17892       host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
17893       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
17894       NetworkIsolationKey(), false /* disable_secure_dns */);
17895   EXPECT_FALSE(
17896       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
17897   HttpRequestInfo request2;
17898   request2.method = "GET";
17899   request2.url = GURL("https://www.b.com/");
17900   request2.load_flags = 0;
17901   request2.traffic_annotation =
17902       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17903   trans =
17904       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
17905 
17906   rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
17907   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17908   EXPECT_THAT(callback.WaitForResult(), IsOk());
17909 
17910   response = trans->GetResponseInfo();
17911   ASSERT_TRUE(response);
17912   ASSERT_TRUE(response->headers);
17913   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
17914   EXPECT_TRUE(response->was_fetched_via_spdy);
17915   EXPECT_TRUE(response->was_alpn_negotiated);
17916   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
17917   EXPECT_EQ("hello!", response_data);
17918   EXPECT_FALSE(
17919       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
17920   EXPECT_TRUE(
17921       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
17922 
17923   HostPortPair host_port_pair_a1("www.a.com", 80);
17924   SpdySessionKey spdy_session_key_a1(
17925       host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
17926       SpdySessionKey::IsProxySession::kFalse, SocketTag(),
17927       NetworkIsolationKey(), false /* disable_secure_dns */);
17928   EXPECT_FALSE(
17929       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
17930   HttpRequestInfo request3;
17931   request3.method = "GET";
17932   request3.url = GURL("http://www.a.com/");
17933   request3.load_flags = 0;
17934   request3.traffic_annotation =
17935       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17936   trans =
17937       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
17938 
17939   rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
17940   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17941   EXPECT_THAT(callback.WaitForResult(), IsOk());
17942 
17943   response = trans->GetResponseInfo();
17944   ASSERT_TRUE(response);
17945   ASSERT_TRUE(response->headers);
17946   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
17947   EXPECT_FALSE(response->was_fetched_via_spdy);
17948   EXPECT_FALSE(response->was_alpn_negotiated);
17949   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
17950   EXPECT_EQ("hello!", response_data);
17951   EXPECT_FALSE(
17952       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
17953   EXPECT_FALSE(
17954       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
17955 }
17956 
TEST_F(HttpNetworkTransactionTest,HttpSyncConnectError)17957 TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
17958   HttpRequestInfo request;
17959   request.method = "GET";
17960   request.url = GURL("http://www.example.org/");
17961   request.traffic_annotation =
17962       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17963 
17964   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17965   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17966 
17967   MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
17968   StaticSocketDataProvider data;
17969   data.set_connect_data(mock_connect);
17970   session_deps_.socket_factory->AddSocketDataProvider(&data);
17971 
17972   TestCompletionCallback callback;
17973 
17974   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17975   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17976 
17977   rv = callback.WaitForResult();
17978   EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
17979 
17980   ConnectionAttempts attempts;
17981   trans.GetConnectionAttempts(&attempts);
17982   ASSERT_EQ(1u, attempts.size());
17983   EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
17984 
17985   IPEndPoint endpoint;
17986   EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
17987   EXPECT_TRUE(endpoint.address().empty());
17988 }
17989 
TEST_F(HttpNetworkTransactionTest,HttpAsyncConnectError)17990 TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
17991   HttpRequestInfo request;
17992   request.method = "GET";
17993   request.url = GURL("http://www.example.org/");
17994   request.traffic_annotation =
17995       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17996 
17997   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17998   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17999 
18000   MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
18001   StaticSocketDataProvider data;
18002   data.set_connect_data(mock_connect);
18003   session_deps_.socket_factory->AddSocketDataProvider(&data);
18004 
18005   TestCompletionCallback callback;
18006 
18007   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18008   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18009 
18010   rv = callback.WaitForResult();
18011   EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
18012 
18013   ConnectionAttempts attempts;
18014   trans.GetConnectionAttempts(&attempts);
18015   ASSERT_EQ(1u, attempts.size());
18016   EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
18017 
18018   IPEndPoint endpoint;
18019   EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
18020   EXPECT_TRUE(endpoint.address().empty());
18021 }
18022 
TEST_F(HttpNetworkTransactionTest,HttpSyncWriteError)18023 TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
18024   HttpRequestInfo request;
18025   request.method = "GET";
18026   request.url = GURL("http://www.example.org/");
18027   request.traffic_annotation =
18028       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18029 
18030   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18031   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18032 
18033   MockWrite data_writes[] = {
18034     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
18035   };
18036   MockRead data_reads[] = {
18037     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
18038   };
18039 
18040   StaticSocketDataProvider data(data_reads, data_writes);
18041   session_deps_.socket_factory->AddSocketDataProvider(&data);
18042 
18043   TestCompletionCallback callback;
18044 
18045   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18046   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18047 
18048   rv = callback.WaitForResult();
18049   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
18050 }
18051 
TEST_F(HttpNetworkTransactionTest,HttpAsyncWriteError)18052 TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
18053   HttpRequestInfo request;
18054   request.method = "GET";
18055   request.url = GURL("http://www.example.org/");
18056   request.traffic_annotation =
18057       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18058 
18059   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18060   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18061 
18062   MockWrite data_writes[] = {
18063     MockWrite(ASYNC, ERR_CONNECTION_RESET),
18064   };
18065   MockRead data_reads[] = {
18066     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
18067   };
18068 
18069   StaticSocketDataProvider data(data_reads, data_writes);
18070   session_deps_.socket_factory->AddSocketDataProvider(&data);
18071 
18072   TestCompletionCallback callback;
18073 
18074   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18075   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18076 
18077   rv = callback.WaitForResult();
18078   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
18079 }
18080 
TEST_F(HttpNetworkTransactionTest,HttpSyncReadError)18081 TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
18082   HttpRequestInfo request;
18083   request.method = "GET";
18084   request.url = GURL("http://www.example.org/");
18085   request.traffic_annotation =
18086       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18087 
18088   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18089   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18090 
18091   MockWrite data_writes[] = {
18092       MockWrite(
18093           "GET / HTTP/1.1\r\n"
18094           "Host: www.example.org\r\n"
18095           "Connection: keep-alive\r\n\r\n"),
18096   };
18097   MockRead data_reads[] = {
18098     MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
18099   };
18100 
18101   StaticSocketDataProvider data(data_reads, data_writes);
18102   session_deps_.socket_factory->AddSocketDataProvider(&data);
18103 
18104   TestCompletionCallback callback;
18105 
18106   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18107   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18108 
18109   rv = callback.WaitForResult();
18110   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
18111 }
18112 
TEST_F(HttpNetworkTransactionTest,HttpAsyncReadError)18113 TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
18114   HttpRequestInfo request;
18115   request.method = "GET";
18116   request.url = GURL("http://www.example.org/");
18117   request.traffic_annotation =
18118       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18119 
18120   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18121   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18122 
18123   MockWrite data_writes[] = {
18124       MockWrite(
18125           "GET / HTTP/1.1\r\n"
18126           "Host: www.example.org\r\n"
18127           "Connection: keep-alive\r\n\r\n"),
18128   };
18129   MockRead data_reads[] = {
18130     MockRead(ASYNC, ERR_CONNECTION_RESET),
18131   };
18132 
18133   StaticSocketDataProvider data(data_reads, data_writes);
18134   session_deps_.socket_factory->AddSocketDataProvider(&data);
18135 
18136   TestCompletionCallback callback;
18137 
18138   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18139   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18140 
18141   rv = callback.WaitForResult();
18142   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
18143 }
18144 
18145 // Tests that when a used socket is returned to the SSL socket pool, it's closed
18146 // if the transport socket pool is stalled on the global socket limit.
TEST_F(HttpNetworkTransactionTest,CloseSSLSocketOnIdleForHttpRequest)18147 TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
18148   ClientSocketPoolManager::set_max_sockets_per_group(
18149       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
18150   ClientSocketPoolManager::set_max_sockets_per_pool(
18151       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
18152 
18153   // Set up SSL request.
18154 
18155   HttpRequestInfo ssl_request;
18156   ssl_request.method = "GET";
18157   ssl_request.url = GURL("https://www.example.org/");
18158   ssl_request.traffic_annotation =
18159       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18160 
18161   MockWrite ssl_writes[] = {
18162       MockWrite(
18163           "GET / HTTP/1.1\r\n"
18164           "Host: www.example.org\r\n"
18165           "Connection: keep-alive\r\n\r\n"),
18166   };
18167   MockRead ssl_reads[] = {
18168     MockRead("HTTP/1.1 200 OK\r\n"),
18169     MockRead("Content-Length: 11\r\n\r\n"),
18170     MockRead("hello world"),
18171     MockRead(SYNCHRONOUS, OK),
18172   };
18173   StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
18174   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
18175 
18176   SSLSocketDataProvider ssl(ASYNC, OK);
18177   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18178 
18179   // Set up HTTP request.
18180 
18181   HttpRequestInfo http_request;
18182   http_request.method = "GET";
18183   http_request.url = GURL("http://www.example.org/");
18184   http_request.traffic_annotation =
18185       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18186 
18187   MockWrite http_writes[] = {
18188       MockWrite(
18189           "GET / HTTP/1.1\r\n"
18190           "Host: www.example.org\r\n"
18191           "Connection: keep-alive\r\n\r\n"),
18192   };
18193   MockRead http_reads[] = {
18194     MockRead("HTTP/1.1 200 OK\r\n"),
18195     MockRead("Content-Length: 7\r\n\r\n"),
18196     MockRead("falafel"),
18197     MockRead(SYNCHRONOUS, OK),
18198   };
18199   StaticSocketDataProvider http_data(http_reads, http_writes);
18200   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
18201 
18202   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18203 
18204   // Start the SSL request.
18205   TestCompletionCallback ssl_callback;
18206   HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
18207   ASSERT_EQ(ERR_IO_PENDING,
18208             ssl_trans.Start(&ssl_request, ssl_callback.callback(),
18209                             NetLogWithSource()));
18210 
18211   // Start the HTTP request.  Pool should stall.
18212   TestCompletionCallback http_callback;
18213   HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
18214   ASSERT_EQ(ERR_IO_PENDING,
18215             http_trans.Start(&http_request, http_callback.callback(),
18216                              NetLogWithSource()));
18217   EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
18218 
18219   // Wait for response from SSL request.
18220   ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
18221   std::string response_data;
18222   ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
18223   EXPECT_EQ("hello world", response_data);
18224 
18225   // The SSL socket should automatically be closed, so the HTTP request can
18226   // start.
18227   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
18228   ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
18229 
18230   // The HTTP request can now complete.
18231   ASSERT_THAT(http_callback.WaitForResult(), IsOk());
18232   ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
18233   EXPECT_EQ("falafel", response_data);
18234 
18235   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
18236 }
18237 
18238 // Tests that when a SSL connection is established but there's no corresponding
18239 // request that needs it, the new socket is closed if the transport socket pool
18240 // is stalled on the global socket limit.
TEST_F(HttpNetworkTransactionTest,CloseSSLSocketOnIdleForHttpRequest2)18241 TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
18242   ClientSocketPoolManager::set_max_sockets_per_group(
18243       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
18244   ClientSocketPoolManager::set_max_sockets_per_pool(
18245       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
18246 
18247   // Set up an ssl request.
18248 
18249   HttpRequestInfo ssl_request;
18250   ssl_request.method = "GET";
18251   ssl_request.url = GURL("https://www.foopy.com/");
18252   ssl_request.traffic_annotation =
18253       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18254 
18255   // No data will be sent on the SSL socket.
18256   StaticSocketDataProvider ssl_data;
18257   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
18258 
18259   SSLSocketDataProvider ssl(ASYNC, OK);
18260   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18261 
18262   // Set up HTTP request.
18263 
18264   HttpRequestInfo http_request;
18265   http_request.method = "GET";
18266   http_request.url = GURL("http://www.example.org/");
18267   http_request.traffic_annotation =
18268       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18269 
18270   MockWrite http_writes[] = {
18271       MockWrite(
18272           "GET / HTTP/1.1\r\n"
18273           "Host: www.example.org\r\n"
18274           "Connection: keep-alive\r\n\r\n"),
18275   };
18276   MockRead http_reads[] = {
18277     MockRead("HTTP/1.1 200 OK\r\n"),
18278     MockRead("Content-Length: 7\r\n\r\n"),
18279     MockRead("falafel"),
18280     MockRead(SYNCHRONOUS, OK),
18281   };
18282   StaticSocketDataProvider http_data(http_reads, http_writes);
18283   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
18284 
18285   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18286 
18287   // Preconnect an SSL socket.  A preconnect is needed because connect jobs are
18288   // cancelled when a normal transaction is cancelled.
18289   HttpStreamFactory* http_stream_factory = session->http_stream_factory();
18290   http_stream_factory->PreconnectStreams(1, ssl_request);
18291   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
18292 
18293   // Start the HTTP request.  Pool should stall.
18294   TestCompletionCallback http_callback;
18295   HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
18296   ASSERT_EQ(ERR_IO_PENDING,
18297             http_trans.Start(&http_request, http_callback.callback(),
18298                              NetLogWithSource()));
18299   EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
18300 
18301   // The SSL connection will automatically be closed once the connection is
18302   // established, to let the HTTP request start.
18303   ASSERT_THAT(http_callback.WaitForResult(), IsOk());
18304   std::string response_data;
18305   ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
18306   EXPECT_EQ("falafel", response_data);
18307 
18308   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
18309 }
18310 
TEST_F(HttpNetworkTransactionTest,PostReadsErrorResponseAfterReset)18311 TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
18312   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
18313   element_readers.push_back(
18314       std::make_unique<UploadBytesElementReader>("foo", 3));
18315   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
18316 
18317   HttpRequestInfo request;
18318   request.method = "POST";
18319   request.url = GURL("http://www.foo.com/");
18320   request.upload_data_stream = &upload_data_stream;
18321   request.traffic_annotation =
18322       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18323 
18324   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18325   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18326   // Send headers successfully, but get an error while sending the body.
18327   MockWrite data_writes[] = {
18328     MockWrite("POST / HTTP/1.1\r\n"
18329               "Host: www.foo.com\r\n"
18330               "Connection: keep-alive\r\n"
18331               "Content-Length: 3\r\n\r\n"),
18332     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
18333   };
18334 
18335   MockRead data_reads[] = {
18336     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
18337     MockRead("hello world"),
18338     MockRead(SYNCHRONOUS, OK),
18339   };
18340   StaticSocketDataProvider data(data_reads, data_writes);
18341   session_deps_.socket_factory->AddSocketDataProvider(&data);
18342 
18343   TestCompletionCallback callback;
18344 
18345   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18346   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18347 
18348   rv = callback.WaitForResult();
18349   EXPECT_THAT(rv, IsOk());
18350 
18351   const HttpResponseInfo* response = trans.GetResponseInfo();
18352   ASSERT_TRUE(response);
18353 
18354   EXPECT_TRUE(response->headers);
18355   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
18356 
18357   std::string response_data;
18358   rv = ReadTransaction(&trans, &response_data);
18359   EXPECT_THAT(rv, IsOk());
18360   EXPECT_EQ("hello world", response_data);
18361 }
18362 
18363 // This test makes sure the retry logic doesn't trigger when reading an error
18364 // response from a server that rejected a POST with a CONNECTION_RESET.
TEST_F(HttpNetworkTransactionTest,PostReadsErrorResponseAfterResetOnReusedSocket)18365 TEST_F(HttpNetworkTransactionTest,
18366        PostReadsErrorResponseAfterResetOnReusedSocket) {
18367   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18368   MockWrite data_writes[] = {
18369     MockWrite("GET / HTTP/1.1\r\n"
18370               "Host: www.foo.com\r\n"
18371               "Connection: keep-alive\r\n\r\n"),
18372     MockWrite("POST / HTTP/1.1\r\n"
18373               "Host: www.foo.com\r\n"
18374               "Connection: keep-alive\r\n"
18375               "Content-Length: 3\r\n\r\n"),
18376     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
18377   };
18378 
18379   MockRead data_reads[] = {
18380     MockRead("HTTP/1.1 200 Peachy\r\n"
18381              "Content-Length: 14\r\n\r\n"),
18382     MockRead("first response"),
18383     MockRead("HTTP/1.1 400 Not OK\r\n"
18384              "Content-Length: 15\r\n\r\n"),
18385     MockRead("second response"),
18386     MockRead(SYNCHRONOUS, OK),
18387   };
18388   StaticSocketDataProvider data(data_reads, data_writes);
18389   session_deps_.socket_factory->AddSocketDataProvider(&data);
18390 
18391   TestCompletionCallback callback;
18392   HttpRequestInfo request1;
18393   request1.method = "GET";
18394   request1.url = GURL("http://www.foo.com/");
18395   request1.load_flags = 0;
18396   request1.traffic_annotation =
18397       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18398 
18399   auto trans1 =
18400       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18401   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
18402   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18403 
18404   rv = callback.WaitForResult();
18405   EXPECT_THAT(rv, IsOk());
18406 
18407   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
18408   ASSERT_TRUE(response1);
18409 
18410   EXPECT_TRUE(response1->headers);
18411   EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
18412 
18413   std::string response_data1;
18414   rv = ReadTransaction(trans1.get(), &response_data1);
18415   EXPECT_THAT(rv, IsOk());
18416   EXPECT_EQ("first response", response_data1);
18417   // Delete the transaction to release the socket back into the socket pool.
18418   trans1.reset();
18419 
18420   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
18421   element_readers.push_back(
18422       std::make_unique<UploadBytesElementReader>("foo", 3));
18423   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
18424 
18425   HttpRequestInfo request2;
18426   request2.method = "POST";
18427   request2.url = GURL("http://www.foo.com/");
18428   request2.upload_data_stream = &upload_data_stream;
18429   request2.load_flags = 0;
18430   request2.traffic_annotation =
18431       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18432 
18433   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
18434   rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
18435   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18436 
18437   rv = callback.WaitForResult();
18438   EXPECT_THAT(rv, IsOk());
18439 
18440   const HttpResponseInfo* response2 = trans2.GetResponseInfo();
18441   ASSERT_TRUE(response2);
18442 
18443   EXPECT_TRUE(response2->headers);
18444   EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
18445 
18446   std::string response_data2;
18447   rv = ReadTransaction(&trans2, &response_data2);
18448   EXPECT_THAT(rv, IsOk());
18449   EXPECT_EQ("second response", response_data2);
18450 }
18451 
TEST_F(HttpNetworkTransactionTest,PostReadsErrorResponseAfterResetPartialBodySent)18452 TEST_F(HttpNetworkTransactionTest,
18453        PostReadsErrorResponseAfterResetPartialBodySent) {
18454   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
18455   element_readers.push_back(
18456       std::make_unique<UploadBytesElementReader>("foo", 3));
18457   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
18458 
18459   HttpRequestInfo request;
18460   request.method = "POST";
18461   request.url = GURL("http://www.foo.com/");
18462   request.upload_data_stream = &upload_data_stream;
18463   request.traffic_annotation =
18464       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18465 
18466   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18467   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18468   // Send headers successfully, but get an error while sending the body.
18469   MockWrite data_writes[] = {
18470     MockWrite("POST / HTTP/1.1\r\n"
18471               "Host: www.foo.com\r\n"
18472               "Connection: keep-alive\r\n"
18473               "Content-Length: 3\r\n\r\n"
18474               "fo"),
18475     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
18476   };
18477 
18478   MockRead data_reads[] = {
18479     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
18480     MockRead("hello world"),
18481     MockRead(SYNCHRONOUS, OK),
18482   };
18483   StaticSocketDataProvider data(data_reads, data_writes);
18484   session_deps_.socket_factory->AddSocketDataProvider(&data);
18485 
18486   TestCompletionCallback callback;
18487 
18488   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18489   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18490 
18491   rv = callback.WaitForResult();
18492   EXPECT_THAT(rv, IsOk());
18493 
18494   const HttpResponseInfo* response = trans.GetResponseInfo();
18495   ASSERT_TRUE(response);
18496 
18497   EXPECT_TRUE(response->headers);
18498   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
18499 
18500   std::string response_data;
18501   rv = ReadTransaction(&trans, &response_data);
18502   EXPECT_THAT(rv, IsOk());
18503   EXPECT_EQ("hello world", response_data);
18504 }
18505 
18506 // This tests the more common case than the previous test, where headers and
18507 // body are not merged into a single request.
TEST_F(HttpNetworkTransactionTest,ChunkedPostReadsErrorResponseAfterReset)18508 TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
18509   ChunkedUploadDataStream upload_data_stream(0);
18510 
18511   HttpRequestInfo request;
18512   request.method = "POST";
18513   request.url = GURL("http://www.foo.com/");
18514   request.upload_data_stream = &upload_data_stream;
18515   request.traffic_annotation =
18516       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18517 
18518   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18519   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18520   // Send headers successfully, but get an error while sending the body.
18521   MockWrite data_writes[] = {
18522     MockWrite("POST / HTTP/1.1\r\n"
18523               "Host: www.foo.com\r\n"
18524               "Connection: keep-alive\r\n"
18525               "Transfer-Encoding: chunked\r\n\r\n"),
18526     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
18527   };
18528 
18529   MockRead data_reads[] = {
18530     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
18531     MockRead("hello world"),
18532     MockRead(SYNCHRONOUS, OK),
18533   };
18534   StaticSocketDataProvider data(data_reads, data_writes);
18535   session_deps_.socket_factory->AddSocketDataProvider(&data);
18536 
18537   TestCompletionCallback callback;
18538 
18539   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18540   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18541   // Make sure the headers are sent before adding a chunk.  This ensures that
18542   // they can't be merged with the body in a single send.  Not currently
18543   // necessary since a chunked body is never merged with headers, but this makes
18544   // the test more future proof.
18545   base::RunLoop().RunUntilIdle();
18546 
18547   upload_data_stream.AppendData("last chunk", 10, true);
18548 
18549   rv = callback.WaitForResult();
18550   EXPECT_THAT(rv, IsOk());
18551 
18552   const HttpResponseInfo* response = trans.GetResponseInfo();
18553   ASSERT_TRUE(response);
18554 
18555   EXPECT_TRUE(response->headers);
18556   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
18557 
18558   std::string response_data;
18559   rv = ReadTransaction(&trans, &response_data);
18560   EXPECT_THAT(rv, IsOk());
18561   EXPECT_EQ("hello world", response_data);
18562 }
18563 
TEST_F(HttpNetworkTransactionTest,PostReadsErrorResponseAfterResetAnd100)18564 TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
18565   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
18566   element_readers.push_back(
18567       std::make_unique<UploadBytesElementReader>("foo", 3));
18568   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
18569 
18570   HttpRequestInfo request;
18571   request.method = "POST";
18572   request.url = GURL("http://www.foo.com/");
18573   request.upload_data_stream = &upload_data_stream;
18574   request.traffic_annotation =
18575       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18576 
18577   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18578   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18579 
18580   MockWrite data_writes[] = {
18581     MockWrite("POST / HTTP/1.1\r\n"
18582               "Host: www.foo.com\r\n"
18583               "Connection: keep-alive\r\n"
18584               "Content-Length: 3\r\n\r\n"),
18585     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
18586   };
18587 
18588   MockRead data_reads[] = {
18589     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
18590     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
18591     MockRead("hello world"),
18592     MockRead(SYNCHRONOUS, OK),
18593   };
18594   StaticSocketDataProvider data(data_reads, data_writes);
18595   session_deps_.socket_factory->AddSocketDataProvider(&data);
18596 
18597   TestCompletionCallback callback;
18598 
18599   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18600   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18601 
18602   rv = callback.WaitForResult();
18603   EXPECT_THAT(rv, IsOk());
18604 
18605   const HttpResponseInfo* response = trans.GetResponseInfo();
18606   ASSERT_TRUE(response);
18607 
18608   EXPECT_TRUE(response->headers);
18609   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
18610 
18611   std::string response_data;
18612   rv = ReadTransaction(&trans, &response_data);
18613   EXPECT_THAT(rv, IsOk());
18614   EXPECT_EQ("hello world", response_data);
18615 }
18616 
TEST_F(HttpNetworkTransactionTest,PostIgnoresNonErrorResponseAfterReset)18617 TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
18618   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
18619   element_readers.push_back(
18620       std::make_unique<UploadBytesElementReader>("foo", 3));
18621   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
18622 
18623   HttpRequestInfo request;
18624   request.method = "POST";
18625   request.url = GURL("http://www.foo.com/");
18626   request.upload_data_stream = &upload_data_stream;
18627   request.traffic_annotation =
18628       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18629 
18630   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18631   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18632   // Send headers successfully, but get an error while sending the body.
18633   MockWrite data_writes[] = {
18634     MockWrite("POST / HTTP/1.1\r\n"
18635               "Host: www.foo.com\r\n"
18636               "Connection: keep-alive\r\n"
18637               "Content-Length: 3\r\n\r\n"),
18638     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
18639   };
18640 
18641   MockRead data_reads[] = {
18642     MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
18643     MockRead("hello world"),
18644     MockRead(SYNCHRONOUS, OK),
18645   };
18646   StaticSocketDataProvider data(data_reads, data_writes);
18647   session_deps_.socket_factory->AddSocketDataProvider(&data);
18648 
18649   TestCompletionCallback callback;
18650 
18651   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18652   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18653 
18654   rv = callback.WaitForResult();
18655   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
18656 }
18657 
TEST_F(HttpNetworkTransactionTest,PostIgnoresNonErrorResponseAfterResetAnd100)18658 TEST_F(HttpNetworkTransactionTest,
18659        PostIgnoresNonErrorResponseAfterResetAnd100) {
18660   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
18661   element_readers.push_back(
18662       std::make_unique<UploadBytesElementReader>("foo", 3));
18663   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
18664 
18665   HttpRequestInfo request;
18666   request.method = "POST";
18667   request.url = GURL("http://www.foo.com/");
18668   request.upload_data_stream = &upload_data_stream;
18669   request.traffic_annotation =
18670       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18671 
18672   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18673   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18674   // Send headers successfully, but get an error while sending the body.
18675   MockWrite data_writes[] = {
18676     MockWrite("POST / HTTP/1.1\r\n"
18677               "Host: www.foo.com\r\n"
18678               "Connection: keep-alive\r\n"
18679               "Content-Length: 3\r\n\r\n"),
18680     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
18681   };
18682 
18683   MockRead data_reads[] = {
18684     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
18685     MockRead("HTTP/1.0 302 Redirect\r\n"),
18686     MockRead("Location: http://somewhere-else.com/\r\n"),
18687     MockRead("Content-Length: 0\r\n\r\n"),
18688     MockRead(SYNCHRONOUS, OK),
18689   };
18690   StaticSocketDataProvider data(data_reads, data_writes);
18691   session_deps_.socket_factory->AddSocketDataProvider(&data);
18692 
18693   TestCompletionCallback callback;
18694 
18695   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18696   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18697 
18698   rv = callback.WaitForResult();
18699   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
18700 }
18701 
TEST_F(HttpNetworkTransactionTest,PostIgnoresHttp09ResponseAfterReset)18702 TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
18703   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
18704   element_readers.push_back(
18705       std::make_unique<UploadBytesElementReader>("foo", 3));
18706   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
18707 
18708   HttpRequestInfo request;
18709   request.method = "POST";
18710   request.url = GURL("http://www.foo.com/");
18711   request.upload_data_stream = &upload_data_stream;
18712   request.traffic_annotation =
18713       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18714 
18715   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18716   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18717   // Send headers successfully, but get an error while sending the body.
18718   MockWrite data_writes[] = {
18719     MockWrite("POST / HTTP/1.1\r\n"
18720               "Host: www.foo.com\r\n"
18721               "Connection: keep-alive\r\n"
18722               "Content-Length: 3\r\n\r\n"),
18723     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
18724   };
18725 
18726   MockRead data_reads[] = {
18727     MockRead("HTTP 0.9 rocks!"),
18728     MockRead(SYNCHRONOUS, OK),
18729   };
18730   StaticSocketDataProvider data(data_reads, data_writes);
18731   session_deps_.socket_factory->AddSocketDataProvider(&data);
18732 
18733   TestCompletionCallback callback;
18734 
18735   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18736   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18737 
18738   rv = callback.WaitForResult();
18739   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
18740 }
18741 
TEST_F(HttpNetworkTransactionTest,PostIgnoresPartial400HeadersAfterReset)18742 TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
18743   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
18744   element_readers.push_back(
18745       std::make_unique<UploadBytesElementReader>("foo", 3));
18746   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
18747 
18748   HttpRequestInfo request;
18749   request.method = "POST";
18750   request.url = GURL("http://www.foo.com/");
18751   request.upload_data_stream = &upload_data_stream;
18752   request.traffic_annotation =
18753       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18754 
18755   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18756   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18757   // Send headers successfully, but get an error while sending the body.
18758   MockWrite data_writes[] = {
18759     MockWrite("POST / HTTP/1.1\r\n"
18760               "Host: www.foo.com\r\n"
18761               "Connection: keep-alive\r\n"
18762               "Content-Length: 3\r\n\r\n"),
18763     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
18764   };
18765 
18766   MockRead data_reads[] = {
18767     MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
18768     MockRead(SYNCHRONOUS, OK),
18769   };
18770   StaticSocketDataProvider data(data_reads, data_writes);
18771   session_deps_.socket_factory->AddSocketDataProvider(&data);
18772 
18773   TestCompletionCallback callback;
18774 
18775   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18776   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18777 
18778   rv = callback.WaitForResult();
18779   EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
18780 }
18781 
18782 #if BUILDFLAG(ENABLE_WEBSOCKETS)
18783 
18784 namespace {
18785 
AddWebSocketHeaders(HttpRequestHeaders * headers)18786 void AddWebSocketHeaders(HttpRequestHeaders* headers) {
18787   headers->SetHeader("Connection", "Upgrade");
18788   headers->SetHeader("Upgrade", "websocket");
18789   headers->SetHeader("Origin", "http://www.example.org");
18790   headers->SetHeader("Sec-WebSocket-Version", "13");
18791 }
18792 
18793 }  // namespace
18794 
TEST_F(HttpNetworkTransactionTest,CreateWebSocketHandshakeStream)18795 TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
18796   for (bool secure : {true, false}) {
18797     MockWrite data_writes[] = {
18798         MockWrite("GET / HTTP/1.1\r\n"
18799                   "Host: www.example.org\r\n"
18800                   "Connection: Upgrade\r\n"
18801                   "Upgrade: websocket\r\n"
18802                   "Origin: http://www.example.org\r\n"
18803                   "Sec-WebSocket-Version: 13\r\n"
18804                   "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
18805                   "Sec-WebSocket-Extensions: permessage-deflate; "
18806                   "client_max_window_bits\r\n\r\n")};
18807 
18808     MockRead data_reads[] = {
18809         MockRead("HTTP/1.1 101 Switching Protocols\r\n"
18810                  "Upgrade: websocket\r\n"
18811                  "Connection: Upgrade\r\n"
18812                  "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
18813 
18814     StaticSocketDataProvider data(data_reads, data_writes);
18815     session_deps_.socket_factory->AddSocketDataProvider(&data);
18816     SSLSocketDataProvider ssl(ASYNC, OK);
18817     if (secure)
18818       session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18819 
18820     HttpRequestInfo request;
18821     request.method = "GET";
18822     request.url =
18823         GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
18824     AddWebSocketHeaders(&request.extra_headers);
18825     request.traffic_annotation =
18826         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18827 
18828     TestWebSocketHandshakeStreamCreateHelper
18829         websocket_handshake_stream_create_helper;
18830 
18831     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18832     HttpNetworkTransaction trans(LOW, session.get());
18833     trans.SetWebSocketHandshakeStreamCreateHelper(
18834         &websocket_handshake_stream_create_helper);
18835 
18836     TestCompletionCallback callback;
18837     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18838     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18839 
18840     const HttpStreamRequest* stream_request = trans.stream_request_.get();
18841     ASSERT_TRUE(stream_request);
18842     EXPECT_EQ(&websocket_handshake_stream_create_helper,
18843               stream_request->websocket_handshake_stream_create_helper());
18844 
18845     rv = callback.WaitForResult();
18846     EXPECT_THAT(rv, IsOk());
18847 
18848     EXPECT_TRUE(data.AllReadDataConsumed());
18849     EXPECT_TRUE(data.AllWriteDataConsumed());
18850   }
18851 }
18852 
18853 // Verify that proxy headers are not sent to the destination server when
18854 // establishing a tunnel for a secure WebSocket connection.
TEST_F(HttpNetworkTransactionTest,ProxyHeadersNotSentOverWssTunnel)18855 TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
18856   HttpRequestInfo request;
18857   request.method = "GET";
18858   request.url = GURL("wss://www.example.org/");
18859   request.traffic_annotation =
18860       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18861   AddWebSocketHeaders(&request.extra_headers);
18862 
18863   // Configure against proxy server "myproxy:70".
18864   session_deps_.proxy_resolution_service =
18865       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
18866           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
18867 
18868   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18869 
18870   // Since a proxy is configured, try to establish a tunnel.
18871   MockWrite data_writes[] = {
18872       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
18873                 "Host: www.example.org:443\r\n"
18874                 "Proxy-Connection: keep-alive\r\n\r\n"),
18875 
18876       // After calling trans->RestartWithAuth(), this is the request we should
18877       // be issuing -- the final header line contains the credentials.
18878       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
18879                 "Host: www.example.org:443\r\n"
18880                 "Proxy-Connection: keep-alive\r\n"
18881                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
18882 
18883       MockWrite("GET / HTTP/1.1\r\n"
18884                 "Host: www.example.org\r\n"
18885                 "Connection: Upgrade\r\n"
18886                 "Upgrade: websocket\r\n"
18887                 "Origin: http://www.example.org\r\n"
18888                 "Sec-WebSocket-Version: 13\r\n"
18889                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
18890                 "Sec-WebSocket-Extensions: permessage-deflate; "
18891                 "client_max_window_bits\r\n\r\n")};
18892 
18893   // The proxy responds to the connect with a 407, using a persistent
18894   // connection.
18895   MockRead data_reads[] = {
18896       // No credentials.
18897       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
18898                "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
18899                "Content-Length: 0\r\n"
18900                "Proxy-Connection: keep-alive\r\n\r\n"),
18901 
18902       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
18903 
18904       MockRead("HTTP/1.1 101 Switching Protocols\r\n"
18905                "Upgrade: websocket\r\n"
18906                "Connection: Upgrade\r\n"
18907                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
18908 
18909   StaticSocketDataProvider data(data_reads, data_writes);
18910   session_deps_.socket_factory->AddSocketDataProvider(&data);
18911   SSLSocketDataProvider ssl(ASYNC, OK);
18912   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18913 
18914   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
18915 
18916   auto trans =
18917       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18918   trans->SetWebSocketHandshakeStreamCreateHelper(
18919       &websocket_stream_create_helper);
18920 
18921   {
18922     TestCompletionCallback callback;
18923 
18924     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
18925     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18926 
18927     rv = callback.WaitForResult();
18928     EXPECT_THAT(rv, IsOk());
18929   }
18930 
18931   const HttpResponseInfo* response = trans->GetResponseInfo();
18932   ASSERT_TRUE(response);
18933   ASSERT_TRUE(response->headers);
18934   EXPECT_EQ(407, response->headers->response_code());
18935 
18936   {
18937     TestCompletionCallback callback;
18938 
18939     int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
18940                                     callback.callback());
18941     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18942 
18943     rv = callback.WaitForResult();
18944     EXPECT_THAT(rv, IsOk());
18945   }
18946 
18947   response = trans->GetResponseInfo();
18948   ASSERT_TRUE(response);
18949   ASSERT_TRUE(response->headers);
18950 
18951   EXPECT_EQ(101, response->headers->response_code());
18952 
18953   trans.reset();
18954   session->CloseAllConnections(ERR_FAILED, "Very good reason");
18955 }
18956 
18957 // Verify that proxy headers are not sent to the destination server when
18958 // establishing a tunnel for an insecure WebSocket connection.
18959 // This requires the authentication info to be injected into the auth cache
18960 // due to crbug.com/395064
18961 // TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
TEST_F(HttpNetworkTransactionTest,ProxyHeadersNotSentOverWsTunnel)18962 TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
18963   HttpRequestInfo request;
18964   request.method = "GET";
18965   request.url = GURL("ws://www.example.org/");
18966   request.traffic_annotation =
18967       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18968   AddWebSocketHeaders(&request.extra_headers);
18969 
18970   // Configure against proxy server "myproxy:70".
18971   session_deps_.proxy_resolution_service =
18972       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
18973           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
18974 
18975   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18976 
18977   MockWrite data_writes[] = {
18978       // Try to establish a tunnel for the WebSocket connection, with
18979       // credentials. Because WebSockets have a separate set of socket pools,
18980       // they cannot and will not use the same TCP/IP connection as the
18981       // preflight HTTP request.
18982       MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
18983                 "Host: www.example.org:80\r\n"
18984                 "Proxy-Connection: keep-alive\r\n"
18985                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
18986 
18987       MockWrite("GET / HTTP/1.1\r\n"
18988                 "Host: www.example.org\r\n"
18989                 "Connection: Upgrade\r\n"
18990                 "Upgrade: websocket\r\n"
18991                 "Origin: http://www.example.org\r\n"
18992                 "Sec-WebSocket-Version: 13\r\n"
18993                 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
18994                 "Sec-WebSocket-Extensions: permessage-deflate; "
18995                 "client_max_window_bits\r\n\r\n")};
18996 
18997   MockRead data_reads[] = {
18998       // HTTP CONNECT with credentials.
18999       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19000 
19001       // WebSocket connection established inside tunnel.
19002       MockRead("HTTP/1.1 101 Switching Protocols\r\n"
19003                "Upgrade: websocket\r\n"
19004                "Connection: Upgrade\r\n"
19005                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
19006 
19007   StaticSocketDataProvider data(data_reads, data_writes);
19008   session_deps_.socket_factory->AddSocketDataProvider(&data);
19009 
19010   session->http_auth_cache()->Add(
19011       GURL("http://myproxy:70/"), HttpAuth::AUTH_PROXY, "MyRealm1",
19012       HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
19013       "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
19014 
19015   TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
19016 
19017   auto trans =
19018       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19019   trans->SetWebSocketHandshakeStreamCreateHelper(
19020       &websocket_stream_create_helper);
19021 
19022   TestCompletionCallback callback;
19023 
19024   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19025   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19026 
19027   rv = callback.WaitForResult();
19028   EXPECT_THAT(rv, IsOk());
19029 
19030   const HttpResponseInfo* response = trans->GetResponseInfo();
19031   ASSERT_TRUE(response);
19032   ASSERT_TRUE(response->headers);
19033 
19034   EXPECT_EQ(101, response->headers->response_code());
19035 
19036   trans.reset();
19037   session->CloseAllConnections(ERR_FAILED, "Very good reason");
19038 }
19039 
19040 // WebSockets over QUIC is not supported, including over QUIC proxies.
TEST_F(HttpNetworkTransactionTest,WebSocketNotSentOverQuicProxy)19041 TEST_F(HttpNetworkTransactionTest, WebSocketNotSentOverQuicProxy) {
19042   for (bool secure : {true, false}) {
19043     SCOPED_TRACE(secure);
19044     session_deps_.proxy_resolution_service =
19045         ConfiguredProxyResolutionService::CreateFixedFromPacResult(
19046             "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
19047     session_deps_.enable_quic = true;
19048 
19049     HttpRequestInfo request;
19050     request.url =
19051         GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
19052     AddWebSocketHeaders(&request.extra_headers);
19053     request.traffic_annotation =
19054         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19055 
19056     TestWebSocketHandshakeStreamCreateHelper
19057         websocket_handshake_stream_create_helper;
19058 
19059     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19060     HttpNetworkTransaction trans(LOW, session.get());
19061     trans.SetWebSocketHandshakeStreamCreateHelper(
19062         &websocket_handshake_stream_create_helper);
19063 
19064     TestCompletionCallback callback;
19065     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
19066     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19067 
19068     rv = callback.WaitForResult();
19069     EXPECT_THAT(rv, IsError(ERR_NO_SUPPORTED_PROXIES));
19070   }
19071 }
19072 
19073 #endif  // BUILDFLAG(ENABLE_WEBSOCKETS)
19074 
TEST_F(HttpNetworkTransactionTest,TotalNetworkBytesPost)19075 TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
19076   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
19077   element_readers.push_back(
19078       std::make_unique<UploadBytesElementReader>("foo", 3));
19079   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
19080 
19081   HttpRequestInfo request;
19082   request.method = "POST";
19083   request.url = GURL("http://www.foo.com/");
19084   request.upload_data_stream = &upload_data_stream;
19085   request.traffic_annotation =
19086       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19087 
19088   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19089   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19090   MockWrite data_writes[] = {
19091       MockWrite("POST / HTTP/1.1\r\n"
19092                 "Host: www.foo.com\r\n"
19093                 "Connection: keep-alive\r\n"
19094                 "Content-Length: 3\r\n\r\n"),
19095       MockWrite("foo"),
19096   };
19097 
19098   MockRead data_reads[] = {
19099       MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
19100       MockRead(SYNCHRONOUS, OK),
19101   };
19102   StaticSocketDataProvider data(data_reads, data_writes);
19103   session_deps_.socket_factory->AddSocketDataProvider(&data);
19104 
19105   TestCompletionCallback callback;
19106 
19107   EXPECT_EQ(ERR_IO_PENDING,
19108             trans.Start(&request, callback.callback(), NetLogWithSource()));
19109   EXPECT_THAT(callback.WaitForResult(), IsOk());
19110 
19111   std::string response_data;
19112   EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
19113 
19114   EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
19115   EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
19116 }
19117 
TEST_F(HttpNetworkTransactionTest,TotalNetworkBytesPost100Continue)19118 TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
19119   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
19120   element_readers.push_back(
19121       std::make_unique<UploadBytesElementReader>("foo", 3));
19122   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
19123 
19124   HttpRequestInfo request;
19125   request.method = "POST";
19126   request.url = GURL("http://www.foo.com/");
19127   request.upload_data_stream = &upload_data_stream;
19128   request.traffic_annotation =
19129       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19130 
19131   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19132   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19133   MockWrite data_writes[] = {
19134       MockWrite("POST / HTTP/1.1\r\n"
19135                 "Host: www.foo.com\r\n"
19136                 "Connection: keep-alive\r\n"
19137                 "Content-Length: 3\r\n\r\n"),
19138       MockWrite("foo"),
19139   };
19140 
19141   MockRead data_reads[] = {
19142       MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
19143       MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
19144       MockRead(SYNCHRONOUS, OK),
19145   };
19146   StaticSocketDataProvider data(data_reads, data_writes);
19147   session_deps_.socket_factory->AddSocketDataProvider(&data);
19148 
19149   TestCompletionCallback callback;
19150 
19151   EXPECT_EQ(ERR_IO_PENDING,
19152             trans.Start(&request, callback.callback(), NetLogWithSource()));
19153   EXPECT_THAT(callback.WaitForResult(), IsOk());
19154 
19155   std::string response_data;
19156   EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
19157 
19158   EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
19159   EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
19160 }
19161 
TEST_F(HttpNetworkTransactionTest,TotalNetworkBytesChunkedPost)19162 TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
19163   ChunkedUploadDataStream upload_data_stream(0);
19164 
19165   HttpRequestInfo request;
19166   request.method = "POST";
19167   request.url = GURL("http://www.foo.com/");
19168   request.upload_data_stream = &upload_data_stream;
19169   request.traffic_annotation =
19170       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19171 
19172   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19173   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19174   // Send headers successfully, but get an error while sending the body.
19175   MockWrite data_writes[] = {
19176       MockWrite("POST / HTTP/1.1\r\n"
19177                 "Host: www.foo.com\r\n"
19178                 "Connection: keep-alive\r\n"
19179                 "Transfer-Encoding: chunked\r\n\r\n"),
19180       MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
19181   };
19182 
19183   MockRead data_reads[] = {
19184       MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
19185       MockRead(SYNCHRONOUS, OK),
19186   };
19187   StaticSocketDataProvider data(data_reads, data_writes);
19188   session_deps_.socket_factory->AddSocketDataProvider(&data);
19189 
19190   TestCompletionCallback callback;
19191 
19192   EXPECT_EQ(ERR_IO_PENDING,
19193             trans.Start(&request, callback.callback(), NetLogWithSource()));
19194 
19195   base::RunLoop().RunUntilIdle();
19196   upload_data_stream.AppendData("f", 1, false);
19197 
19198   base::RunLoop().RunUntilIdle();
19199   upload_data_stream.AppendData("oo", 2, true);
19200 
19201   EXPECT_THAT(callback.WaitForResult(), IsOk());
19202 
19203   std::string response_data;
19204   EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
19205 
19206   EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
19207   EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
19208 }
19209 
CheckContentEncodingMatching(SpdySessionDependencies * session_deps,const std::string & accept_encoding,const std::string & content_encoding,const std::string & location,bool should_match)19210 void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
19211                                   const std::string& accept_encoding,
19212                                   const std::string& content_encoding,
19213                                   const std::string& location,
19214                                   bool should_match) {
19215   HttpRequestInfo request;
19216   request.method = "GET";
19217   request.url = GURL("http://www.foo.com/");
19218   request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
19219                                   accept_encoding);
19220   request.traffic_annotation =
19221       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19222 
19223   std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
19224   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19225   // Send headers successfully, but get an error while sending the body.
19226   MockWrite data_writes[] = {
19227       MockWrite("GET / HTTP/1.1\r\n"
19228                 "Host: www.foo.com\r\n"
19229                 "Connection: keep-alive\r\n"
19230                 "Accept-Encoding: "),
19231       MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
19232   };
19233 
19234   std::string response_code = "200 OK";
19235   std::string extra;
19236   if (!location.empty()) {
19237     response_code = "301 Redirect\r\nLocation: ";
19238     response_code.append(location);
19239   }
19240 
19241   MockRead data_reads[] = {
19242       MockRead("HTTP/1.0 "),
19243       MockRead(response_code.data()),
19244       MockRead("\r\nContent-Encoding: "),
19245       MockRead(content_encoding.data()),
19246       MockRead("\r\n\r\n"),
19247       MockRead(SYNCHRONOUS, OK),
19248   };
19249   StaticSocketDataProvider data(data_reads, data_writes);
19250   session_deps->socket_factory->AddSocketDataProvider(&data);
19251 
19252   TestCompletionCallback callback;
19253 
19254   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
19255   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19256 
19257   rv = callback.WaitForResult();
19258   if (should_match) {
19259     EXPECT_THAT(rv, IsOk());
19260   } else {
19261     EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
19262   }
19263 }
19264 
TEST_F(HttpNetworkTransactionTest,MatchContentEncoding1)19265 TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
19266   CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
19267 }
19268 
TEST_F(HttpNetworkTransactionTest,MatchContentEncoding2)19269 TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
19270   CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
19271                                true);
19272 }
19273 
TEST_F(HttpNetworkTransactionTest,MatchContentEncoding3)19274 TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
19275   CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
19276                                "", false);
19277 }
19278 
TEST_F(HttpNetworkTransactionTest,MatchContentEncoding4)19279 TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
19280   CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
19281                                "www.foo.com/other", true);
19282 }
19283 
TEST_F(HttpNetworkTransactionTest,ProxyResolutionFailsSync)19284 TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
19285   ProxyConfig proxy_config;
19286   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
19287   proxy_config.set_pac_mandatory(true);
19288   MockAsyncProxyResolver resolver;
19289   session_deps_.proxy_resolution_service.reset(
19290       new ConfiguredProxyResolutionService(
19291           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
19292               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
19293           std::make_unique<FailingProxyResolverFactory>(), nullptr));
19294 
19295   HttpRequestInfo request;
19296   request.method = "GET";
19297   request.url = GURL("http://www.example.org/");
19298   request.traffic_annotation =
19299       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19300 
19301   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19302   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19303 
19304   TestCompletionCallback callback;
19305 
19306   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
19307   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19308   EXPECT_THAT(callback.WaitForResult(),
19309               IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
19310 }
19311 
TEST_F(HttpNetworkTransactionTest,ProxyResolutionFailsAsync)19312 TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
19313   ProxyConfig proxy_config;
19314   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
19315   proxy_config.set_pac_mandatory(true);
19316   MockAsyncProxyResolverFactory* proxy_resolver_factory =
19317       new MockAsyncProxyResolverFactory(false);
19318   MockAsyncProxyResolver resolver;
19319   session_deps_.proxy_resolution_service.reset(
19320       new ConfiguredProxyResolutionService(
19321           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
19322               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
19323           base::WrapUnique(proxy_resolver_factory), nullptr));
19324   HttpRequestInfo request;
19325   request.method = "GET";
19326   request.url = GURL("http://www.example.org/");
19327   request.traffic_annotation =
19328       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19329 
19330   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19331   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19332 
19333   TestCompletionCallback callback;
19334   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
19335   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19336 
19337   proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
19338       ERR_FAILED, &resolver);
19339   EXPECT_THAT(callback.WaitForResult(),
19340               IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
19341 }
19342 
TEST_F(HttpNetworkTransactionTest,NoSupportedProxies)19343 TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
19344   session_deps_.proxy_resolution_service =
19345       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
19346           "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
19347   session_deps_.enable_quic = false;
19348   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19349 
19350   HttpRequestInfo request;
19351   request.method = "GET";
19352   request.url = GURL("http://www.example.org/");
19353   request.traffic_annotation =
19354       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19355 
19356   TestCompletionCallback callback;
19357   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19358   int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
19359   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19360 
19361   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
19362 }
19363 
19364 //-----------------------------------------------------------------------------
19365 // Reporting tests
19366 
19367 #if BUILDFLAG(ENABLE_REPORTING)
19368 class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
19369  protected:
SetUp()19370   void SetUp() override {
19371     HttpNetworkTransactionTest::SetUp();
19372     auto test_reporting_context = std::make_unique<TestReportingContext>(
19373         &clock_, &tick_clock_, ReportingPolicy());
19374     test_reporting_context_ = test_reporting_context.get();
19375     session_deps_.reporting_service =
19376         ReportingService::CreateForTesting(std::move(test_reporting_context));
19377   }
19378 
reporting_context() const19379   TestReportingContext* reporting_context() const {
19380     return test_reporting_context_;
19381   }
19382 
clear_reporting_service()19383   void clear_reporting_service() {
19384     session_deps_.reporting_service.reset();
19385     test_reporting_context_ = nullptr;
19386   }
19387 
19388   // Makes an HTTPS request that should install a valid Reporting policy.
RequestPolicy(CertStatus cert_status=0)19389   void RequestPolicy(CertStatus cert_status = 0) {
19390     HttpRequestInfo request;
19391     request.method = "GET";
19392     request.url = GURL(url_);
19393     request.traffic_annotation =
19394         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19395 
19396     MockWrite data_writes[] = {
19397         MockWrite("GET / HTTP/1.1\r\n"
19398                   "Host: www.example.org\r\n"
19399                   "Connection: keep-alive\r\n\r\n"),
19400     };
19401     MockRead data_reads[] = {
19402         MockRead("HTTP/1.0 200 OK\r\n"),
19403         MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
19404                  "\"endpoints\": [{\"url\": "
19405                  "\"https://www.example.org/upload/\"}]}\r\n"),
19406         MockRead("\r\n"),
19407         MockRead("hello world"),
19408         MockRead(SYNCHRONOUS, OK),
19409     };
19410 
19411     StaticSocketDataProvider reads(data_reads, data_writes);
19412     session_deps_.socket_factory->AddSocketDataProvider(&reads);
19413 
19414     SSLSocketDataProvider ssl(ASYNC, OK);
19415     if (request.url.SchemeIsCryptographic()) {
19416       ssl.ssl_info.cert =
19417           ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
19418       ASSERT_TRUE(ssl.ssl_info.cert);
19419       ssl.ssl_info.cert_status = cert_status;
19420       session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19421     }
19422 
19423     TestCompletionCallback callback;
19424     auto session = CreateSession(&session_deps_);
19425     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19426     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
19427     EXPECT_THAT(callback.GetResult(rv), IsOk());
19428   }
19429 
19430  protected:
19431   std::string url_ = "https://www.example.org/";
19432 
19433  private:
19434   TestReportingContext* test_reporting_context_;
19435 };
19436 
TEST_F(HttpNetworkTransactionReportingTest,DontProcessReportToHeaderNoService)19437 TEST_F(HttpNetworkTransactionReportingTest,
19438        DontProcessReportToHeaderNoService) {
19439   base::HistogramTester histograms;
19440   clear_reporting_service();
19441   RequestPolicy();
19442   histograms.ExpectBucketCount(
19443       ReportingHeaderParser::kHeaderOutcomeHistogram,
19444       ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
19445 }
19446 
TEST_F(HttpNetworkTransactionReportingTest,DontProcessReportToHeaderHttp)19447 TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
19448   base::HistogramTester histograms;
19449   url_ = "http://www.example.org/";
19450   RequestPolicy();
19451   histograms.ExpectBucketCount(
19452       ReportingHeaderParser::kHeaderOutcomeHistogram,
19453       ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
19454 }
19455 
TEST_F(HttpNetworkTransactionReportingTest,ProcessReportToHeaderHttps)19456 TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
19457   RequestPolicy();
19458   ASSERT_EQ(1u, reporting_context()->cache()->GetEndpointCount());
19459   const ReportingEndpoint endpoint =
19460       reporting_context()->cache()->GetEndpointForTesting(
19461           ReportingEndpointGroupKey(
19462               NetworkIsolationKey(),
19463               url::Origin::Create(GURL("https://www.example.org/")), "nel"),
19464           GURL("https://www.example.org/upload/"));
19465   EXPECT_TRUE(endpoint);
19466 }
19467 
TEST_F(HttpNetworkTransactionReportingTest,DontProcessReportToHeaderInvalidHttps)19468 TEST_F(HttpNetworkTransactionReportingTest,
19469        DontProcessReportToHeaderInvalidHttps) {
19470   base::HistogramTester histograms;
19471   CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
19472   RequestPolicy(cert_status);
19473   histograms.ExpectBucketCount(
19474       ReportingHeaderParser::kHeaderOutcomeHistogram,
19475       ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
19476 }
19477 #endif  // BUILDFLAG(ENABLE_REPORTING)
19478 
19479 //-----------------------------------------------------------------------------
19480 // Network Error Logging tests
19481 
19482 #if BUILDFLAG(ENABLE_REPORTING)
19483 namespace {
19484 
19485 const char kUserAgent[] = "Mozilla/1.0";
19486 const char kReferrer[] = "https://www.referrer.org/";
19487 
19488 }  // namespace
19489 
19490 class HttpNetworkTransactionNetworkErrorLoggingTest
19491     : public HttpNetworkTransactionTest {
19492  protected:
SetUp()19493   void SetUp() override {
19494     HttpNetworkTransactionTest::SetUp();
19495     auto network_error_logging_service =
19496         std::make_unique<TestNetworkErrorLoggingService>();
19497     test_network_error_logging_service_ = network_error_logging_service.get();
19498     session_deps_.network_error_logging_service =
19499         std::move(network_error_logging_service);
19500 
19501     extra_headers_.SetHeader("User-Agent", kUserAgent);
19502     extra_headers_.SetHeader("Referer", kReferrer);
19503 
19504     request_.method = "GET";
19505     request_.url = GURL(url_);
19506     request_.extra_headers = extra_headers_;
19507     request_.reporting_upload_depth = reporting_upload_depth_;
19508     request_.traffic_annotation =
19509         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19510   }
19511 
network_error_logging_service() const19512   TestNetworkErrorLoggingService* network_error_logging_service() const {
19513     return test_network_error_logging_service_;
19514   }
19515 
clear_network_error_logging_service()19516   void clear_network_error_logging_service() {
19517     session_deps_.network_error_logging_service.reset();
19518     test_network_error_logging_service_ = nullptr;
19519   }
19520 
19521   // Makes an HTTPS request that should install a valid NEL policy.
RequestPolicy(CertStatus cert_status=0)19522   void RequestPolicy(CertStatus cert_status = 0) {
19523     std::string extra_header_string = extra_headers_.ToString();
19524     MockWrite data_writes[] = {
19525         MockWrite("GET / HTTP/1.1\r\n"
19526                   "Host: www.example.org\r\n"
19527                   "Connection: keep-alive\r\n"),
19528         MockWrite(ASYNC, extra_header_string.data(),
19529                   extra_header_string.size()),
19530     };
19531     MockRead data_reads[] = {
19532         MockRead("HTTP/1.0 200 OK\r\n"),
19533         MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
19534         MockRead("\r\n"),
19535         MockRead("hello world"),
19536         MockRead(SYNCHRONOUS, OK),
19537     };
19538 
19539     StaticSocketDataProvider reads(data_reads, data_writes);
19540     session_deps_.socket_factory->AddSocketDataProvider(&reads);
19541 
19542     SSLSocketDataProvider ssl(ASYNC, OK);
19543     if (request_.url.SchemeIsCryptographic()) {
19544       ssl.ssl_info.cert =
19545           ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
19546       ASSERT_TRUE(ssl.ssl_info.cert);
19547       ssl.ssl_info.cert_status = cert_status;
19548       session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19549     }
19550 
19551     TestCompletionCallback callback;
19552     auto session = CreateSession(&session_deps_);
19553     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19554     int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
19555     EXPECT_THAT(callback.GetResult(rv), IsOk());
19556 
19557     std::string response_data;
19558     ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
19559     EXPECT_EQ("hello world", response_data);
19560   }
19561 
CheckReport(size_t index,int status_code,int error_type,IPAddress server_ip=IPAddress::IPv4Localhost ())19562   void CheckReport(size_t index,
19563                    int status_code,
19564                    int error_type,
19565                    IPAddress server_ip = IPAddress::IPv4Localhost()) {
19566     ASSERT_LT(index, network_error_logging_service()->errors().size());
19567 
19568     const NetworkErrorLoggingService::RequestDetails& error =
19569         network_error_logging_service()->errors()[index];
19570     EXPECT_EQ(url_, error.uri);
19571     EXPECT_EQ(kReferrer, error.referrer);
19572     EXPECT_EQ(kUserAgent, error.user_agent);
19573     EXPECT_EQ(server_ip, error.server_ip);
19574     EXPECT_EQ("http/1.1", error.protocol);
19575     EXPECT_EQ("GET", error.method);
19576     EXPECT_EQ(status_code, error.status_code);
19577     EXPECT_EQ(error_type, error.type);
19578     EXPECT_EQ(0, error.reporting_upload_depth);
19579   }
19580 
19581  protected:
19582   std::string url_ = "https://www.example.org/";
19583   CertStatus cert_status_ = 0;
19584   HttpRequestInfo request_;
19585   HttpRequestHeaders extra_headers_;
19586   int reporting_upload_depth_ = 0;
19587 
19588  private:
19589   TestNetworkErrorLoggingService* test_network_error_logging_service_;
19590 };
19591 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,DontProcessNelHeaderNoService)19592 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19593        DontProcessNelHeaderNoService) {
19594   base::HistogramTester histograms;
19595   clear_network_error_logging_service();
19596   RequestPolicy();
19597   histograms.ExpectBucketCount(
19598       NetworkErrorLoggingService::kHeaderOutcomeHistogram,
19599       NetworkErrorLoggingService::HeaderOutcome::
19600           DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
19601       1);
19602 }
19603 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,DontProcessNelHeaderHttp)19604 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19605        DontProcessNelHeaderHttp) {
19606   base::HistogramTester histograms;
19607   url_ = "http://www.example.org/";
19608   request_.url = GURL(url_);
19609   RequestPolicy();
19610   histograms.ExpectBucketCount(
19611       NetworkErrorLoggingService::kHeaderOutcomeHistogram,
19612       NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
19613 }
19614 
19615 // Don't set NEL policies received on a proxied connection.
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,DontProcessNelHeaderProxy)19616 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19617        DontProcessNelHeaderProxy) {
19618   session_deps_.proxy_resolution_service =
19619       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
19620           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19621   RecordingBoundTestNetLog log;
19622   session_deps_.net_log = log.bound().net_log();
19623   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19624 
19625   HttpRequestInfo request;
19626   request.method = "GET";
19627   request.url = GURL("https://www.example.org/");
19628   request.traffic_annotation =
19629       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19630 
19631   // Since we have proxy, should try to establish tunnel.
19632   MockWrite data_writes1[] = {
19633       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19634                 "Host: www.example.org:443\r\n"
19635                 "Proxy-Connection: keep-alive\r\n\r\n"),
19636 
19637       MockWrite("GET / HTTP/1.1\r\n"
19638                 "Host: www.example.org\r\n"
19639                 "Connection: keep-alive\r\n\r\n"),
19640   };
19641 
19642   MockRead data_reads1[] = {
19643       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19644 
19645       MockRead("HTTP/1.1 200 OK\r\n"),
19646       MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
19647       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19648       MockRead("Content-Length: 100\r\n\r\n"),
19649       MockRead(SYNCHRONOUS, OK),
19650   };
19651 
19652   StaticSocketDataProvider data1(data_reads1, data_writes1);
19653   session_deps_.socket_factory->AddSocketDataProvider(&data1);
19654   SSLSocketDataProvider ssl(ASYNC, OK);
19655   ssl.ssl_info.cert =
19656       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
19657   ASSERT_TRUE(ssl.ssl_info.cert);
19658   ssl.ssl_info.cert_status = 0;
19659   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19660 
19661   TestCompletionCallback callback1;
19662   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19663 
19664   int rv = trans.Start(&request, callback1.callback(), log.bound());
19665   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19666 
19667   rv = callback1.WaitForResult();
19668   EXPECT_THAT(rv, IsOk());
19669 
19670   const HttpResponseInfo* response = trans.GetResponseInfo();
19671   ASSERT_TRUE(response);
19672   EXPECT_EQ(200, response->headers->response_code());
19673   EXPECT_TRUE(response->was_fetched_via_proxy);
19674 
19675   // No NEL header was set.
19676   EXPECT_EQ(0u, network_error_logging_service()->headers().size());
19677 }
19678 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,ProcessNelHeaderHttps)19679 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
19680   RequestPolicy();
19681   ASSERT_EQ(1u, network_error_logging_service()->headers().size());
19682   const auto& header = network_error_logging_service()->headers()[0];
19683   EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
19684             header.origin);
19685   EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
19686   EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
19687 }
19688 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,DontProcessNelHeaderInvalidHttps)19689 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19690        DontProcessNelHeaderInvalidHttps) {
19691   base::HistogramTester histograms;
19692   CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
19693   RequestPolicy(cert_status);
19694   histograms.ExpectBucketCount(
19695       NetworkErrorLoggingService::kHeaderOutcomeHistogram,
19696       NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
19697       1);
19698 }
19699 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportSuccess)19700 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
19701   RequestPolicy();
19702   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19703   CheckReport(0 /* index */, 200 /* status_code */, OK);
19704 }
19705 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportErrorAfterStart)19706 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19707        CreateReportErrorAfterStart) {
19708   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19709   auto trans =
19710       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19711 
19712   MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
19713   StaticSocketDataProvider data;
19714   data.set_connect_data(mock_connect);
19715   session_deps_.socket_factory->AddSocketDataProvider(&data);
19716 
19717   TestCompletionCallback callback;
19718 
19719   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19720   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
19721 
19722   trans.reset();
19723 
19724   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19725   CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
19726               IPAddress() /* server_ip */);
19727 }
19728 
19729 // Same as above except the error is ASYNC
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportErrorAfterStartAsync)19730 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19731        CreateReportErrorAfterStartAsync) {
19732   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19733   auto trans =
19734       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19735 
19736   MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
19737   StaticSocketDataProvider data;
19738   data.set_connect_data(mock_connect);
19739   session_deps_.socket_factory->AddSocketDataProvider(&data);
19740 
19741   TestCompletionCallback callback;
19742 
19743   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19744   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
19745 
19746   trans.reset();
19747 
19748   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19749   CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
19750               IPAddress() /* server_ip */);
19751 }
19752 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportReadBodyError)19753 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19754        CreateReportReadBodyError) {
19755   std::string extra_header_string = extra_headers_.ToString();
19756   MockWrite data_writes[] = {
19757       MockWrite("GET / HTTP/1.1\r\n"
19758                 "Host: www.example.org\r\n"
19759                 "Connection: keep-alive\r\n"),
19760       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19761   };
19762   MockRead data_reads[] = {
19763       MockRead("HTTP/1.0 200 OK\r\n"),
19764       MockRead("Content-Length: 100\r\n\r\n"),  // wrong content length
19765       MockRead("hello world"),
19766       MockRead(SYNCHRONOUS, OK),
19767   };
19768 
19769   StaticSocketDataProvider reads(data_reads, data_writes);
19770   session_deps_.socket_factory->AddSocketDataProvider(&reads);
19771 
19772   SSLSocketDataProvider ssl(ASYNC, OK);
19773   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19774 
19775   // Log start time
19776   base::TimeTicks start_time = base::TimeTicks::Now();
19777 
19778   TestCompletionCallback callback;
19779   auto session = CreateSession(&session_deps_);
19780   auto trans =
19781       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19782   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19783   EXPECT_THAT(callback.GetResult(rv), IsOk());
19784 
19785   const HttpResponseInfo* response = trans->GetResponseInfo();
19786   ASSERT_TRUE(response);
19787 
19788   EXPECT_TRUE(response->headers);
19789   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
19790 
19791   std::string response_data;
19792   rv = ReadTransaction(trans.get(), &response_data);
19793   EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
19794 
19795   trans.reset();
19796 
19797   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19798 
19799   CheckReport(0 /* index */, 200 /* status_code */,
19800               ERR_CONTENT_LENGTH_MISMATCH);
19801   const NetworkErrorLoggingService::RequestDetails& error =
19802       network_error_logging_service()->errors()[0];
19803   EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
19804 }
19805 
19806 // Same as above except the final read is ASYNC.
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportReadBodyErrorAsync)19807 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19808        CreateReportReadBodyErrorAsync) {
19809   std::string extra_header_string = extra_headers_.ToString();
19810   MockWrite data_writes[] = {
19811       MockWrite("GET / HTTP/1.1\r\n"
19812                 "Host: www.example.org\r\n"
19813                 "Connection: keep-alive\r\n"),
19814       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19815   };
19816   MockRead data_reads[] = {
19817       MockRead("HTTP/1.0 200 OK\r\n"),
19818       MockRead("Content-Length: 100\r\n\r\n"),  // wrong content length
19819       MockRead("hello world"),
19820       MockRead(ASYNC, OK),
19821   };
19822 
19823   StaticSocketDataProvider reads(data_reads, data_writes);
19824   session_deps_.socket_factory->AddSocketDataProvider(&reads);
19825 
19826   SSLSocketDataProvider ssl(ASYNC, OK);
19827   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19828 
19829   // Log start time
19830   base::TimeTicks start_time = base::TimeTicks::Now();
19831 
19832   TestCompletionCallback callback;
19833   auto session = CreateSession(&session_deps_);
19834   auto trans =
19835       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19836   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19837   EXPECT_THAT(callback.GetResult(rv), IsOk());
19838 
19839   const HttpResponseInfo* response = trans->GetResponseInfo();
19840   ASSERT_TRUE(response);
19841 
19842   EXPECT_TRUE(response->headers);
19843   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
19844 
19845   std::string response_data;
19846   rv = ReadTransaction(trans.get(), &response_data);
19847   EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
19848 
19849   trans.reset();
19850 
19851   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19852 
19853   CheckReport(0 /* index */, 200 /* status_code */,
19854               ERR_CONTENT_LENGTH_MISMATCH);
19855   const NetworkErrorLoggingService::RequestDetails& error =
19856       network_error_logging_service()->errors()[0];
19857   EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
19858 }
19859 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportRestartWithAuth)19860 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19861        CreateReportRestartWithAuth) {
19862   std::string extra_header_string = extra_headers_.ToString();
19863   static const base::TimeDelta kSleepDuration =
19864       base::TimeDelta::FromMilliseconds(10);
19865 
19866   MockWrite data_writes1[] = {
19867       MockWrite("GET / HTTP/1.1\r\n"
19868                 "Host: www.example.org\r\n"
19869                 "Connection: keep-alive\r\n"),
19870       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19871   };
19872 
19873   MockRead data_reads1[] = {
19874       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
19875       // Give a couple authenticate options (only the middle one is actually
19876       // supported).
19877       MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
19878       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19879       MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
19880       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19881       // Large content-length -- won't matter, as connection will be reset.
19882       MockRead("Content-Length: 10000\r\n\r\n"),
19883       MockRead(SYNCHRONOUS, ERR_FAILED),
19884   };
19885 
19886   // After calling trans->RestartWithAuth(), this is the request we should
19887   // be issuing -- the final header line contains the credentials.
19888   MockWrite data_writes2[] = {
19889       MockWrite("GET / HTTP/1.1\r\n"
19890                 "Host: www.example.org\r\n"
19891                 "Connection: keep-alive\r\n"
19892                 "Authorization: Basic Zm9vOmJhcg==\r\n"),
19893       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19894   };
19895 
19896   // Lastly, the server responds with the actual content.
19897   MockRead data_reads2[] = {
19898       MockRead("HTTP/1.0 200 OK\r\n\r\n"),
19899       MockRead("hello world"),
19900       MockRead(SYNCHRONOUS, OK),
19901   };
19902 
19903   StaticSocketDataProvider data1(data_reads1, data_writes1);
19904   StaticSocketDataProvider data2(data_reads2, data_writes2);
19905   session_deps_.socket_factory->AddSocketDataProvider(&data1);
19906   session_deps_.socket_factory->AddSocketDataProvider(&data2);
19907 
19908   SSLSocketDataProvider ssl1(ASYNC, OK);
19909   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
19910   SSLSocketDataProvider ssl2(ASYNC, OK);
19911   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
19912 
19913   base::TimeTicks start_time = base::TimeTicks::Now();
19914   base::TimeTicks restart_time;
19915 
19916   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19917   auto trans =
19918       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19919 
19920   TestCompletionCallback callback1;
19921 
19922   int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
19923   EXPECT_THAT(callback1.GetResult(rv), IsOk());
19924 
19925   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19926 
19927   TestCompletionCallback callback2;
19928 
19929   // Wait 10 ms then restart with auth
19930   FastForwardBy(kSleepDuration);
19931   restart_time = base::TimeTicks::Now();
19932   rv =
19933       trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
19934   EXPECT_THAT(callback2.GetResult(rv), IsOk());
19935 
19936   std::string response_data;
19937   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19938   EXPECT_EQ("hello world", response_data);
19939 
19940   trans.reset();
19941 
19942   // One 401 report for the auth challenge, then a 200 report for the successful
19943   // retry. Note that we don't report the error draining the body, as the first
19944   // request already generated a report for the auth challenge.
19945   ASSERT_EQ(2u, network_error_logging_service()->errors().size());
19946 
19947   // Check error report contents
19948   CheckReport(0 /* index */, 401 /* status_code */, OK);
19949   CheckReport(1 /* index */, 200 /* status_code */, OK);
19950 
19951   const NetworkErrorLoggingService::RequestDetails& error1 =
19952       network_error_logging_service()->errors()[0];
19953   const NetworkErrorLoggingService::RequestDetails& error2 =
19954       network_error_logging_service()->errors()[1];
19955 
19956   // Sanity-check elapsed time values
19957   EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
19958   // Check that the start time is refreshed when restarting with auth.
19959   EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
19960 }
19961 
19962 // Same as above, except draining the body before restarting fails
19963 // asynchronously.
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportRestartWithAuthAsync)19964 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19965        CreateReportRestartWithAuthAsync) {
19966   std::string extra_header_string = extra_headers_.ToString();
19967   static const base::TimeDelta kSleepDuration =
19968       base::TimeDelta::FromMilliseconds(10);
19969 
19970   MockWrite data_writes1[] = {
19971       MockWrite("GET / HTTP/1.1\r\n"
19972                 "Host: www.example.org\r\n"
19973                 "Connection: keep-alive\r\n"),
19974       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19975   };
19976 
19977   MockRead data_reads1[] = {
19978       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
19979       // Give a couple authenticate options (only the middle one is actually
19980       // supported).
19981       MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
19982       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19983       MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
19984       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19985       // Large content-length -- won't matter, as connection will be reset.
19986       MockRead("Content-Length: 10000\r\n\r\n"),
19987       MockRead(ASYNC, ERR_FAILED),
19988   };
19989 
19990   // After calling trans->RestartWithAuth(), this is the request we should
19991   // be issuing -- the final header line contains the credentials.
19992   MockWrite data_writes2[] = {
19993       MockWrite("GET / HTTP/1.1\r\n"
19994                 "Host: www.example.org\r\n"
19995                 "Connection: keep-alive\r\n"
19996                 "Authorization: Basic Zm9vOmJhcg==\r\n"),
19997       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19998   };
19999 
20000   // Lastly, the server responds with the actual content.
20001   MockRead data_reads2[] = {
20002       MockRead("HTTP/1.0 200 OK\r\n\r\n"),
20003       MockRead("hello world"),
20004       MockRead(SYNCHRONOUS, OK),
20005   };
20006 
20007   StaticSocketDataProvider data1(data_reads1, data_writes1);
20008   StaticSocketDataProvider data2(data_reads2, data_writes2);
20009   session_deps_.socket_factory->AddSocketDataProvider(&data1);
20010   session_deps_.socket_factory->AddSocketDataProvider(&data2);
20011 
20012   SSLSocketDataProvider ssl1(ASYNC, OK);
20013   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
20014   SSLSocketDataProvider ssl2(ASYNC, OK);
20015   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
20016 
20017   base::TimeTicks start_time = base::TimeTicks::Now();
20018   base::TimeTicks restart_time;
20019 
20020   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20021   auto trans =
20022       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20023 
20024   TestCompletionCallback callback1;
20025 
20026   int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
20027   EXPECT_THAT(callback1.GetResult(rv), IsOk());
20028 
20029   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
20030 
20031   TestCompletionCallback callback2;
20032 
20033   // Wait 10 ms then restart with auth
20034   FastForwardBy(kSleepDuration);
20035   restart_time = base::TimeTicks::Now();
20036   rv =
20037       trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
20038   EXPECT_THAT(callback2.GetResult(rv), IsOk());
20039 
20040   std::string response_data;
20041   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
20042   EXPECT_EQ("hello world", response_data);
20043 
20044   trans.reset();
20045 
20046   // One 401 report for the auth challenge, then a 200 report for the successful
20047   // retry. Note that we don't report the error draining the body, as the first
20048   // request already generated a report for the auth challenge.
20049   ASSERT_EQ(2u, network_error_logging_service()->errors().size());
20050 
20051   // Check error report contents
20052   CheckReport(0 /* index */, 401 /* status_code */, OK);
20053   CheckReport(1 /* index */, 200 /* status_code */, OK);
20054 
20055   const NetworkErrorLoggingService::RequestDetails& error1 =
20056       network_error_logging_service()->errors()[0];
20057   const NetworkErrorLoggingService::RequestDetails& error2 =
20058       network_error_logging_service()->errors()[1];
20059 
20060   // Sanity-check elapsed time values
20061   EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
20062   // Check that the start time is refreshed when restarting with auth.
20063   EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
20064 }
20065 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportRetryKeepAliveConnectionReset)20066 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
20067        CreateReportRetryKeepAliveConnectionReset) {
20068   std::string extra_header_string = extra_headers_.ToString();
20069   MockWrite data_writes1[] = {
20070       MockWrite("GET / HTTP/1.1\r\n"
20071                 "Host: www.example.org\r\n"
20072                 "Connection: keep-alive\r\n"),
20073       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
20074       MockWrite("GET / HTTP/1.1\r\n"
20075                 "Host: www.example.org\r\n"
20076                 "Connection: keep-alive\r\n"),
20077       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
20078   };
20079 
20080   MockRead data_reads1[] = {
20081       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
20082       MockRead("hello"),
20083       // Connection is reset
20084       MockRead(ASYNC, ERR_CONNECTION_RESET),
20085   };
20086 
20087   // Successful retry
20088   MockRead data_reads2[] = {
20089       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
20090       MockRead("world"),
20091       MockRead(ASYNC, OK),
20092   };
20093 
20094   StaticSocketDataProvider data1(data_reads1, data_writes1);
20095   StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
20096   session_deps_.socket_factory->AddSocketDataProvider(&data1);
20097   session_deps_.socket_factory->AddSocketDataProvider(&data2);
20098 
20099   SSLSocketDataProvider ssl1(ASYNC, OK);
20100   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
20101   SSLSocketDataProvider ssl2(ASYNC, OK);
20102   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
20103 
20104   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20105   auto trans1 =
20106       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20107 
20108   TestCompletionCallback callback1;
20109 
20110   int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
20111   EXPECT_THAT(callback1.GetResult(rv), IsOk());
20112 
20113   std::string response_data;
20114   ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
20115   EXPECT_EQ("hello", response_data);
20116 
20117   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
20118 
20119   auto trans2 =
20120       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20121 
20122   TestCompletionCallback callback2;
20123 
20124   rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
20125   EXPECT_THAT(callback2.GetResult(rv), IsOk());
20126 
20127   ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
20128   EXPECT_EQ("world", response_data);
20129 
20130   trans1.reset();
20131   trans2.reset();
20132 
20133   // One OK report from first request, then a ERR_CONNECTION_RESET report from
20134   // the second request, then an OK report from the successful retry.
20135   ASSERT_EQ(3u, network_error_logging_service()->errors().size());
20136 
20137   // Check error report contents
20138   CheckReport(0 /* index */, 200 /* status_code */, OK);
20139   CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
20140   CheckReport(2 /* index */, 200 /* status_code */, OK);
20141 }
20142 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportRetryKeepAlive408)20143 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
20144        CreateReportRetryKeepAlive408) {
20145   std::string extra_header_string = extra_headers_.ToString();
20146   MockWrite data_writes1[] = {
20147       MockWrite("GET / HTTP/1.1\r\n"
20148                 "Host: www.example.org\r\n"
20149                 "Connection: keep-alive\r\n"),
20150       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
20151       MockWrite("GET / HTTP/1.1\r\n"
20152                 "Host: www.example.org\r\n"
20153                 "Connection: keep-alive\r\n"),
20154       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
20155   };
20156 
20157   MockRead data_reads1[] = {
20158       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
20159       MockRead("hello"),
20160       // 408 Request Timeout
20161       MockRead(SYNCHRONOUS,
20162                "HTTP/1.1 408 Request Timeout\r\n"
20163                "Connection: Keep-Alive\r\n"
20164                "Content-Length: 6\r\n\r\n"
20165                "Pickle"),
20166   };
20167 
20168   // Successful retry
20169   MockRead data_reads2[] = {
20170       MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
20171       MockRead("world"),
20172       MockRead(ASYNC, OK),
20173   };
20174 
20175   StaticSocketDataProvider data1(data_reads1, data_writes1);
20176   StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
20177   session_deps_.socket_factory->AddSocketDataProvider(&data1);
20178   session_deps_.socket_factory->AddSocketDataProvider(&data2);
20179 
20180   SSLSocketDataProvider ssl1(ASYNC, OK);
20181   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
20182   SSLSocketDataProvider ssl2(ASYNC, OK);
20183   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
20184 
20185   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20186   auto trans1 =
20187       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20188 
20189   TestCompletionCallback callback1;
20190 
20191   int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
20192   EXPECT_THAT(callback1.GetResult(rv), IsOk());
20193 
20194   std::string response_data;
20195   ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
20196   EXPECT_EQ("hello", response_data);
20197 
20198   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
20199 
20200   auto trans2 =
20201       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20202 
20203   TestCompletionCallback callback2;
20204 
20205   rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
20206   EXPECT_THAT(callback2.GetResult(rv), IsOk());
20207 
20208   ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
20209   EXPECT_EQ("world", response_data);
20210 
20211   trans1.reset();
20212   trans2.reset();
20213 
20214   // One 200 report from first request, then a 408 report from
20215   // the second request, then a 200 report from the successful retry.
20216   ASSERT_EQ(3u, network_error_logging_service()->errors().size());
20217 
20218   // Check error report contents
20219   CheckReport(0 /* index */, 200 /* status_code */, OK);
20220   CheckReport(1 /* index */, 408 /* status_code */, OK);
20221   CheckReport(2 /* index */, 200 /* status_code */, OK);
20222 }
20223 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportRetry421WithoutConnectionPooling)20224 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
20225        CreateReportRetry421WithoutConnectionPooling) {
20226   // Two hosts resolve to the same IP address.
20227   const std::string ip_addr = "1.2.3.4";
20228   IPAddress ip;
20229   ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
20230   IPEndPoint peer_addr = IPEndPoint(ip, 443);
20231 
20232   session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
20233   session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
20234   session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
20235 
20236   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20237 
20238   // Two requests on the first connection.
20239   spdy::SpdySerializedFrame req1(
20240       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
20241   spdy_util_.UpdateWithStreamDestruction(1);
20242   spdy::SpdySerializedFrame req2(
20243       spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
20244   spdy::SpdySerializedFrame rst(
20245       spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
20246   MockWrite writes1[] = {
20247       CreateMockWrite(req1, 0),
20248       CreateMockWrite(req2, 3),
20249       CreateMockWrite(rst, 6),
20250   };
20251 
20252   // The first one succeeds, the second gets error 421 Misdirected Request.
20253   spdy::SpdySerializedFrame resp1(
20254       spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
20255   spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
20256   spdy::SpdyHeaderBlock response_headers;
20257   response_headers[spdy::kHttp2StatusHeader] = "421";
20258   spdy::SpdySerializedFrame resp2(
20259       spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
20260   MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
20261                        CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
20262 
20263   MockConnect connect1(ASYNC, OK, peer_addr);
20264   SequencedSocketData data1(connect1, reads1, writes1);
20265   session_deps_.socket_factory->AddSocketDataProvider(&data1);
20266 
20267   AddSSLSocketData();
20268 
20269   // Retry the second request on a second connection.
20270   SpdyTestUtil spdy_util2;
20271   spdy::SpdySerializedFrame req3(
20272       spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
20273   MockWrite writes2[] = {
20274       CreateMockWrite(req3, 0),
20275   };
20276 
20277   spdy::SpdySerializedFrame resp3(
20278       spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
20279   spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
20280   MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
20281                        MockRead(ASYNC, 0, 3)};
20282 
20283   MockConnect connect2(ASYNC, OK, peer_addr);
20284   SequencedSocketData data2(connect2, reads2, writes2);
20285   session_deps_.socket_factory->AddSocketDataProvider(&data2);
20286 
20287   AddSSLSocketData();
20288 
20289   // Preload mail.example.org into HostCache.
20290   int rv = session_deps_.host_resolver->LoadIntoCache(
20291       HostPortPair("mail.example.com", 443), NetworkIsolationKey(),
20292       base::nullopt);
20293   EXPECT_THAT(rv, IsOk());
20294 
20295   HttpRequestInfo request1;
20296   request1.method = "GET";
20297   request1.url = GURL("https://www.example.org/");
20298   request1.load_flags = 0;
20299   request1.traffic_annotation =
20300       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20301   auto trans1 =
20302       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20303 
20304   TestCompletionCallback callback;
20305   rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
20306   EXPECT_THAT(callback.GetResult(rv), IsOk());
20307 
20308   const HttpResponseInfo* response = trans1->GetResponseInfo();
20309   ASSERT_TRUE(response);
20310   ASSERT_TRUE(response->headers);
20311   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20312   EXPECT_TRUE(response->was_fetched_via_spdy);
20313   EXPECT_TRUE(response->was_alpn_negotiated);
20314   std::string response_data;
20315   ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
20316   EXPECT_EQ("hello!", response_data);
20317 
20318   trans1.reset();
20319 
20320   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
20321 
20322   HttpRequestInfo request2;
20323   request2.method = "GET";
20324   request2.url = GURL("https://mail.example.org/");
20325   request2.load_flags = 0;
20326   request2.traffic_annotation =
20327       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20328   auto trans2 =
20329       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20330 
20331   RecordingBoundTestNetLog log;
20332   rv = trans2->Start(&request2, callback.callback(), log.bound());
20333   EXPECT_THAT(callback.GetResult(rv), IsOk());
20334 
20335   response = trans2->GetResponseInfo();
20336   ASSERT_TRUE(response);
20337   ASSERT_TRUE(response->headers);
20338   EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
20339   EXPECT_TRUE(response->was_fetched_via_spdy);
20340   EXPECT_TRUE(response->was_alpn_negotiated);
20341   ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
20342   EXPECT_EQ("hello!", response_data);
20343 
20344   trans2.reset();
20345 
20346   // One 200 report from the first request, then a 421 report from the
20347   // second request, then a 200 report from the successful retry.
20348   ASSERT_EQ(3u, network_error_logging_service()->errors().size());
20349 
20350   // Check error report contents
20351   const NetworkErrorLoggingService::RequestDetails& error1 =
20352       network_error_logging_service()->errors()[0];
20353   EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
20354   EXPECT_TRUE(error1.referrer.is_empty());
20355   EXPECT_EQ("", error1.user_agent);
20356   EXPECT_EQ(ip, error1.server_ip);
20357   EXPECT_EQ("h2", error1.protocol);
20358   EXPECT_EQ("GET", error1.method);
20359   EXPECT_EQ(200, error1.status_code);
20360   EXPECT_EQ(OK, error1.type);
20361   EXPECT_EQ(0, error1.reporting_upload_depth);
20362 
20363   const NetworkErrorLoggingService::RequestDetails& error2 =
20364       network_error_logging_service()->errors()[1];
20365   EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
20366   EXPECT_TRUE(error2.referrer.is_empty());
20367   EXPECT_EQ("", error2.user_agent);
20368   EXPECT_EQ(ip, error2.server_ip);
20369   EXPECT_EQ("h2", error2.protocol);
20370   EXPECT_EQ("GET", error2.method);
20371   EXPECT_EQ(421, error2.status_code);
20372   EXPECT_EQ(OK, error2.type);
20373   EXPECT_EQ(0, error2.reporting_upload_depth);
20374 
20375   const NetworkErrorLoggingService::RequestDetails& error3 =
20376       network_error_logging_service()->errors()[2];
20377   EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
20378   EXPECT_TRUE(error3.referrer.is_empty());
20379   EXPECT_EQ("", error3.user_agent);
20380   EXPECT_EQ(ip, error3.server_ip);
20381   EXPECT_EQ("h2", error3.protocol);
20382   EXPECT_EQ("GET", error3.method);
20383   EXPECT_EQ(200, error3.status_code);
20384   EXPECT_EQ(OK, error3.type);
20385   EXPECT_EQ(0, error3.reporting_upload_depth);
20386 }
20387 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportCancelAfterStart)20388 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
20389        CreateReportCancelAfterStart) {
20390   StaticSocketDataProvider data;
20391   data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
20392   session_deps_.socket_factory->AddSocketDataProvider(&data);
20393 
20394   TestCompletionCallback callback;
20395   auto session = CreateSession(&session_deps_);
20396   auto trans =
20397       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20398   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
20399   EXPECT_EQ(rv, ERR_IO_PENDING);
20400 
20401   // Cancel after start.
20402   trans.reset();
20403 
20404   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
20405   CheckReport(0 /* index */, 0 /* status_code */, ERR_ABORTED,
20406               IPAddress() /* server_ip */);
20407 }
20408 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,CreateReportCancelBeforeReadingBody)20409 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
20410        CreateReportCancelBeforeReadingBody) {
20411   std::string extra_header_string = extra_headers_.ToString();
20412   MockWrite data_writes[] = {
20413       MockWrite("GET / HTTP/1.1\r\n"
20414                 "Host: www.example.org\r\n"
20415                 "Connection: keep-alive\r\n"),
20416       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
20417   };
20418   MockRead data_reads[] = {
20419       MockRead("HTTP/1.0 200 OK\r\n"),
20420       MockRead("Content-Length: 100\r\n\r\n"),  // Body is never read.
20421   };
20422 
20423   StaticSocketDataProvider data(data_reads, data_writes);
20424   session_deps_.socket_factory->AddSocketDataProvider(&data);
20425 
20426   SSLSocketDataProvider ssl(ASYNC, OK);
20427   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
20428 
20429   TestCompletionCallback callback;
20430   auto session = CreateSession(&session_deps_);
20431   auto trans =
20432       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20433   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
20434   EXPECT_THAT(callback.GetResult(rv), IsOk());
20435 
20436   const HttpResponseInfo* response = trans->GetResponseInfo();
20437   ASSERT_TRUE(response);
20438 
20439   EXPECT_TRUE(response->headers);
20440   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
20441 
20442   // Cancel before reading the body.
20443   trans.reset();
20444 
20445   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
20446   CheckReport(0 /* index */, 200 /* status_code */, ERR_ABORTED);
20447 }
20448 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,DontCreateReportHttp)20449 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
20450   RequestPolicy();
20451   EXPECT_EQ(1u, network_error_logging_service()->headers().size());
20452   EXPECT_EQ(1u, network_error_logging_service()->errors().size());
20453 
20454   // Make HTTP request
20455   std::string extra_header_string = extra_headers_.ToString();
20456   MockRead data_reads[] = {
20457       MockRead("HTTP/1.0 200 OK\r\n\r\n"),
20458       MockRead("hello world"),
20459       MockRead(SYNCHRONOUS, OK),
20460   };
20461   MockWrite data_writes[] = {
20462       MockWrite("GET / HTTP/1.1\r\n"
20463                 "Host: www.example.org\r\n"
20464                 "Connection: keep-alive\r\n"),
20465       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
20466   };
20467 
20468   StaticSocketDataProvider data(data_reads, data_writes);
20469   session_deps_.socket_factory->AddSocketDataProvider(&data);
20470 
20471   // Insecure url
20472   url_ = "http://www.example.org/";
20473   request_.url = GURL(url_);
20474 
20475   TestCompletionCallback callback;
20476   auto session = CreateSession(&session_deps_);
20477   auto trans =
20478       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20479   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
20480   EXPECT_THAT(callback.GetResult(rv), IsOk());
20481 
20482   std::string response_data;
20483   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
20484   EXPECT_EQ("hello world", response_data);
20485 
20486   // Insecure request does not generate a report
20487   EXPECT_EQ(1u, network_error_logging_service()->errors().size());
20488 }
20489 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,DontCreateReportHttpError)20490 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
20491        DontCreateReportHttpError) {
20492   RequestPolicy();
20493   EXPECT_EQ(1u, network_error_logging_service()->headers().size());
20494   EXPECT_EQ(1u, network_error_logging_service()->errors().size());
20495 
20496   // Make HTTP request that fails
20497   MockRead data_reads[] = {
20498       MockRead("hello world"),
20499       MockRead(SYNCHRONOUS, OK),
20500   };
20501 
20502   StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
20503   session_deps_.socket_factory->AddSocketDataProvider(&data);
20504 
20505   url_ = "http://www.originwithoutpolicy.com:2000/";
20506   request_.url = GURL(url_);
20507 
20508   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20509 
20510   auto trans =
20511       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20512   TestCompletionCallback callback;
20513   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
20514   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
20515 
20516   // Insecure request does not generate a report, regardless of existence of a
20517   // policy for the origin.
20518   EXPECT_EQ(1u, network_error_logging_service()->errors().size());
20519 }
20520 
20521 // Don't report on proxy auth challenges, don't report if connecting through a
20522 // proxy.
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,DontCreateReportProxy)20523 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) {
20524   HttpRequestInfo request;
20525   request.method = "GET";
20526   request.url = GURL("https://www.example.org/");
20527   request.traffic_annotation =
20528       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20529 
20530   // Configure against proxy server "myproxy:70".
20531   session_deps_.proxy_resolution_service =
20532       ConfiguredProxyResolutionService::CreateFixedFromPacResult(
20533           "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
20534   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20535 
20536   // Since we have proxy, should try to establish tunnel.
20537   MockWrite data_writes1[] = {
20538       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
20539                 "Host: www.example.org:443\r\n"
20540                 "Proxy-Connection: keep-alive\r\n\r\n"),
20541   };
20542 
20543   // The proxy responds to the connect with a 407, using a non-persistent
20544   // connection.
20545   MockRead data_reads1[] = {
20546       // No credentials.
20547       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
20548       MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
20549       MockRead("Proxy-Connection: close\r\n\r\n"),
20550   };
20551 
20552   MockWrite data_writes2[] = {
20553       // After calling trans->RestartWithAuth(), this is the request we should
20554       // be issuing -- the final header line contains the credentials.
20555       MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
20556                 "Host: www.example.org:443\r\n"
20557                 "Proxy-Connection: keep-alive\r\n"
20558                 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
20559 
20560       MockWrite("GET / HTTP/1.1\r\n"
20561                 "Host: www.example.org\r\n"
20562                 "Connection: keep-alive\r\n\r\n"),
20563   };
20564 
20565   MockRead data_reads2[] = {
20566       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
20567 
20568       MockRead("HTTP/1.1 200 OK\r\n"),
20569       MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
20570       MockRead("Content-Length: 5\r\n\r\n"),
20571       MockRead(SYNCHRONOUS, "hello"),
20572   };
20573 
20574   StaticSocketDataProvider data1(data_reads1, data_writes1);
20575   session_deps_.socket_factory->AddSocketDataProvider(&data1);
20576   StaticSocketDataProvider data2(data_reads2, data_writes2);
20577   session_deps_.socket_factory->AddSocketDataProvider(&data2);
20578   SSLSocketDataProvider ssl(ASYNC, OK);
20579   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
20580 
20581   TestCompletionCallback callback1;
20582 
20583   auto trans =
20584       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20585 
20586   int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
20587   EXPECT_THAT(callback1.GetResult(rv), IsOk());
20588 
20589   const HttpResponseInfo* response = trans->GetResponseInfo();
20590   EXPECT_EQ(407, response->headers->response_code());
20591 
20592   std::string response_data;
20593   rv = ReadTransaction(trans.get(), &response_data);
20594   EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
20595 
20596   // No NEL report is generated for the 407.
20597   EXPECT_EQ(0u, network_error_logging_service()->errors().size());
20598 
20599   TestCompletionCallback callback2;
20600 
20601   rv =
20602       trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
20603   EXPECT_THAT(callback2.GetResult(rv), IsOk());
20604 
20605   response = trans->GetResponseInfo();
20606   EXPECT_EQ(200, response->headers->response_code());
20607 
20608   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
20609   EXPECT_EQ("hello", response_data);
20610 
20611   trans.reset();
20612 
20613   // No NEL report is generated because we are behind a proxy.
20614   EXPECT_EQ(0u, network_error_logging_service()->errors().size());
20615 }
20616 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,ReportContainsUploadDepth)20617 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
20618        ReportContainsUploadDepth) {
20619   reporting_upload_depth_ = 7;
20620   request_.reporting_upload_depth = reporting_upload_depth_;
20621   RequestPolicy();
20622   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
20623   const NetworkErrorLoggingService::RequestDetails& error =
20624       network_error_logging_service()->errors()[0];
20625   EXPECT_EQ(7, error.reporting_upload_depth);
20626 }
20627 
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,ReportElapsedTime)20628 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
20629   std::string extra_header_string = extra_headers_.ToString();
20630   static const base::TimeDelta kSleepDuration =
20631       base::TimeDelta::FromMilliseconds(10);
20632 
20633   std::vector<MockWrite> data_writes = {
20634       MockWrite(ASYNC, 0,
20635                 "GET / HTTP/1.1\r\n"
20636                 "Host: www.example.org\r\n"
20637                 "Connection: keep-alive\r\n"),
20638       MockWrite(ASYNC, 1, extra_header_string.data()),
20639   };
20640 
20641   std::vector<MockRead> data_reads = {
20642       // Write one byte of the status line, followed by a pause.
20643       MockRead(ASYNC, 2, "H"),
20644       MockRead(ASYNC, ERR_IO_PENDING, 3),
20645       MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
20646       MockRead(ASYNC, 5, "hello world"),
20647       MockRead(SYNCHRONOUS, OK, 6),
20648   };
20649 
20650   SequencedSocketData data(data_reads, data_writes);
20651   session_deps_.socket_factory->AddSocketDataProvider(&data);
20652 
20653   SSLSocketDataProvider ssl(ASYNC, OK);
20654   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
20655 
20656   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20657 
20658   auto trans =
20659       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20660 
20661   TestCompletionCallback callback;
20662 
20663   int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
20664   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20665 
20666   data.RunUntilPaused();
20667   ASSERT_TRUE(data.IsPaused());
20668   FastForwardBy(kSleepDuration);
20669   data.Resume();
20670 
20671   EXPECT_THAT(callback.GetResult(rv), IsOk());
20672 
20673   std::string response_data;
20674   ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
20675   EXPECT_EQ("hello world", response_data);
20676 
20677   trans.reset();
20678 
20679   ASSERT_EQ(1u, network_error_logging_service()->errors().size());
20680 
20681   CheckReport(0 /* index */, 200 /* status_code */, OK);
20682 
20683   const NetworkErrorLoggingService::RequestDetails& error =
20684       network_error_logging_service()->errors()[0];
20685 
20686   // Sanity-check elapsed time in error report
20687   EXPECT_EQ(kSleepDuration, error.elapsed_time);
20688 }
20689 
20690 #endif  // BUILDFLAG(ENABLE_REPORTING)
20691 
TEST_F(HttpNetworkTransactionTest,AlwaysFailRequestToCache)20692 TEST_F(HttpNetworkTransactionTest, AlwaysFailRequestToCache) {
20693   HttpRequestInfo request;
20694   request.method = "GET";
20695   request.url = GURL("http://example.org/");
20696 
20697   request.load_flags = LOAD_ONLY_FROM_CACHE;
20698 
20699   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20700   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
20701   TestCompletionCallback callback1;
20702   int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
20703 
20704   EXPECT_THAT(rv, IsError(ERR_CACHE_MISS));
20705 }
20706 
TEST_F(HttpNetworkTransactionTest,ZeroRTTDoesntConfirm)20707 TEST_F(HttpNetworkTransactionTest, ZeroRTTDoesntConfirm) {
20708   static const base::TimeDelta kDelay = base::TimeDelta::FromMilliseconds(10);
20709   HttpRequestInfo request;
20710   request.method = "GET";
20711   request.url = GURL("https://www.example.org/");
20712   request.traffic_annotation =
20713       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20714 
20715   MockWrite data_writes[] = {
20716       MockWrite("GET / HTTP/1.1\r\n"
20717                 "Host: www.example.org\r\n"
20718                 "Connection: keep-alive\r\n\r\n"),
20719   };
20720 
20721   MockRead data_reads[] = {
20722       MockRead("HTTP/1.1 200 OK\r\n"),
20723       MockRead("Content-Length: 1\r\n\r\n"),
20724       MockRead(SYNCHRONOUS, "1"),
20725   };
20726 
20727   StaticSocketDataProvider data(data_reads, data_writes);
20728   session_deps_.socket_factory->AddSocketDataProvider(&data);
20729   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
20730   ssl.connect_callback = FastForwardByCallback(kDelay);
20731   ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
20732   ssl.confirm_callback = FastForwardByCallback(kDelay);
20733   session_deps_.enable_early_data = true;
20734   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
20735 
20736   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20737 
20738   TestCompletionCallback callback;
20739   auto trans =
20740       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20741 
20742   base::TimeTicks start_time = base::TimeTicks::Now();
20743   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
20744   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20745 
20746   rv = callback.WaitForResult();
20747   EXPECT_THAT(rv, IsOk());
20748 
20749   const HttpResponseInfo* response = trans->GetResponseInfo();
20750   ASSERT_TRUE(response);
20751   ASSERT_TRUE(response->headers);
20752   EXPECT_EQ(200, response->headers->response_code());
20753   EXPECT_EQ(1, response->headers->GetContentLength());
20754 
20755   // Check that ConfirmHandshake wasn't called.
20756   ASSERT_FALSE(ssl.ConfirmDataConsumed());
20757   ASSERT_TRUE(ssl.WriteBeforeConfirm());
20758 
20759   // The handshake time should include the time it took to run Connect(), but
20760   // not ConfirmHandshake().
20761   LoadTimingInfo load_timing_info;
20762   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
20763   EXPECT_EQ(load_timing_info.connect_timing.connect_start, start_time);
20764   EXPECT_EQ(load_timing_info.connect_timing.ssl_start, start_time);
20765   EXPECT_EQ(load_timing_info.connect_timing.ssl_end, start_time + kDelay);
20766   EXPECT_EQ(load_timing_info.connect_timing.connect_end, start_time + kDelay);
20767 
20768   trans.reset();
20769 
20770   session->CloseAllConnections(ERR_FAILED, "Very good reason");
20771 }
20772 
TEST_F(HttpNetworkTransactionTest,ZeroRTTSyncConfirmSyncWrite)20773 TEST_F(HttpNetworkTransactionTest, ZeroRTTSyncConfirmSyncWrite) {
20774   static const base::TimeDelta kDelay = base::TimeDelta::FromMilliseconds(10);
20775   HttpRequestInfo request;
20776   request.method = "POST";
20777   request.url = GURL("https://www.example.org/");
20778   request.traffic_annotation =
20779       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20780 
20781   MockWrite data_writes[] = {
20782       MockWrite(SYNCHRONOUS,
20783                 "POST / HTTP/1.1\r\n"
20784                 "Host: www.example.org\r\n"
20785                 "Connection: keep-alive\r\n"
20786                 "Content-Length: 0\r\n\r\n"),
20787   };
20788 
20789   MockRead data_reads[] = {
20790       MockRead("HTTP/1.1 200 OK\r\n"),
20791       MockRead("Content-Length: 1\r\n\r\n"),
20792       MockRead(SYNCHRONOUS, "1"),
20793   };
20794 
20795   StaticSocketDataProvider data(data_reads, data_writes);
20796   session_deps_.socket_factory->AddSocketDataProvider(&data);
20797   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
20798   ssl.connect_callback = FastForwardByCallback(kDelay);
20799   ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
20800   ssl.confirm_callback = FastForwardByCallback(kDelay);
20801   session_deps_.enable_early_data = true;
20802   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
20803 
20804   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20805 
20806   TestCompletionCallback callback;
20807   auto trans =
20808       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20809 
20810   base::TimeTicks start_time = base::TimeTicks::Now();
20811   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
20812   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20813 
20814   rv = callback.WaitForResult();
20815   EXPECT_THAT(rv, IsOk());
20816 
20817   const HttpResponseInfo* response = trans->GetResponseInfo();
20818   ASSERT_TRUE(response);
20819   ASSERT_TRUE(response->headers);
20820   EXPECT_EQ(200, response->headers->response_code());
20821   EXPECT_EQ(1, response->headers->GetContentLength());
20822 
20823   // Check that the Write didn't get called before ConfirmHandshake completed.
20824   ASSERT_FALSE(ssl.WriteBeforeConfirm());
20825 
20826   // The handshake time should include the time it took to run Connect(), but
20827   // not ConfirmHandshake(). If ConfirmHandshake() returns synchronously, we
20828   // assume the connection did not negotiate 0-RTT or the handshake was already
20829   // confirmed.
20830   LoadTimingInfo load_timing_info;
20831   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
20832   EXPECT_EQ(load_timing_info.connect_timing.connect_start, start_time);
20833   EXPECT_EQ(load_timing_info.connect_timing.ssl_start, start_time);
20834   EXPECT_EQ(load_timing_info.connect_timing.ssl_end, start_time + kDelay);
20835   EXPECT_EQ(load_timing_info.connect_timing.connect_end, start_time + kDelay);
20836 
20837   trans.reset();
20838 
20839   session->CloseAllConnections(ERR_FAILED, "Very good reason");
20840 }
20841 
TEST_F(HttpNetworkTransactionTest,ZeroRTTSyncConfirmAsyncWrite)20842 TEST_F(HttpNetworkTransactionTest, ZeroRTTSyncConfirmAsyncWrite) {
20843   HttpRequestInfo request;
20844   request.method = "POST";
20845   request.url = GURL("https://www.example.org/");
20846   request.traffic_annotation =
20847       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20848 
20849   MockWrite data_writes[] = {
20850       MockWrite(ASYNC,
20851                 "POST / HTTP/1.1\r\n"
20852                 "Host: www.example.org\r\n"
20853                 "Connection: keep-alive\r\n"
20854                 "Content-Length: 0\r\n\r\n"),
20855   };
20856 
20857   MockRead data_reads[] = {
20858       MockRead("HTTP/1.1 200 OK\r\n"),
20859       MockRead("Content-Length: 1\r\n\r\n"),
20860       MockRead(SYNCHRONOUS, "1"),
20861   };
20862 
20863   StaticSocketDataProvider data(data_reads, data_writes);
20864   session_deps_.socket_factory->AddSocketDataProvider(&data);
20865   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
20866   ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
20867   session_deps_.enable_early_data = true;
20868   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
20869 
20870   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20871 
20872   TestCompletionCallback callback;
20873   auto trans =
20874       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20875 
20876   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
20877   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20878 
20879   rv = callback.WaitForResult();
20880   EXPECT_THAT(rv, IsOk());
20881 
20882   const HttpResponseInfo* response = trans->GetResponseInfo();
20883   ASSERT_TRUE(response);
20884   ASSERT_TRUE(response->headers);
20885   EXPECT_EQ(200, response->headers->response_code());
20886   EXPECT_EQ(1, response->headers->GetContentLength());
20887 
20888   // Check that the Write didn't get called before ConfirmHandshake completed.
20889   ASSERT_FALSE(ssl.WriteBeforeConfirm());
20890 
20891   trans.reset();
20892 
20893   session->CloseAllConnections(ERR_FAILED, "Very good reason");
20894 }
20895 
TEST_F(HttpNetworkTransactionTest,ZeroRTTAsyncConfirmSyncWrite)20896 TEST_F(HttpNetworkTransactionTest, ZeroRTTAsyncConfirmSyncWrite) {
20897   static const base::TimeDelta kDelay = base::TimeDelta::FromMilliseconds(10);
20898   HttpRequestInfo request;
20899   request.method = "POST";
20900   request.url = GURL("https://www.example.org/");
20901   request.traffic_annotation =
20902       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20903 
20904   MockWrite data_writes[] = {
20905       MockWrite(SYNCHRONOUS,
20906                 "POST / HTTP/1.1\r\n"
20907                 "Host: www.example.org\r\n"
20908                 "Connection: keep-alive\r\n"
20909                 "Content-Length: 0\r\n\r\n"),
20910   };
20911 
20912   MockRead data_reads[] = {
20913       MockRead("HTTP/1.1 200 OK\r\n"),
20914       MockRead("Content-Length: 1\r\n\r\n"),
20915       MockRead(SYNCHRONOUS, "1"),
20916   };
20917 
20918   StaticSocketDataProvider data(data_reads, data_writes);
20919   session_deps_.socket_factory->AddSocketDataProvider(&data);
20920   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
20921   ssl.connect_callback = FastForwardByCallback(kDelay);
20922   ssl.confirm = MockConfirm(ASYNC, OK);
20923   ssl.confirm_callback = FastForwardByCallback(kDelay);
20924   session_deps_.enable_early_data = true;
20925   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
20926 
20927   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20928 
20929   TestCompletionCallback callback;
20930   auto trans =
20931       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20932 
20933   base::TimeTicks start_time = base::TimeTicks::Now();
20934   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
20935   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
20936 
20937   rv = callback.WaitForResult();
20938   EXPECT_THAT(rv, IsOk());
20939 
20940   const HttpResponseInfo* response = trans->GetResponseInfo();
20941   ASSERT_TRUE(response);
20942   ASSERT_TRUE(response->headers);
20943   EXPECT_EQ(200, response->headers->response_code());
20944   EXPECT_EQ(1, response->headers->GetContentLength());
20945 
20946   // Check that the Write didn't get called before ConfirmHandshake completed.
20947   ASSERT_FALSE(ssl.WriteBeforeConfirm());
20948 
20949   // The handshake time should include the time it took to run Connect() and
20950   // ConfirmHandshake().
20951   LoadTimingInfo load_timing_info;
20952   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
20953   EXPECT_EQ(load_timing_info.connect_timing.connect_start, start_time);
20954   EXPECT_EQ(load_timing_info.connect_timing.ssl_start, start_time);
20955   EXPECT_EQ(load_timing_info.connect_timing.ssl_end, start_time + 2 * kDelay);
20956   EXPECT_EQ(load_timing_info.connect_timing.connect_end,
20957             start_time + 2 * kDelay);
20958 
20959   trans.reset();
20960 
20961   session->CloseAllConnections(ERR_FAILED, "Very good reason");
20962 }
20963 
TEST_F(HttpNetworkTransactionTest,ZeroRTTAsyncConfirmAsyncWrite)20964 TEST_F(HttpNetworkTransactionTest, ZeroRTTAsyncConfirmAsyncWrite) {
20965   HttpRequestInfo request;
20966   request.method = "POST";
20967   request.url = GURL("https://www.example.org/");
20968   request.traffic_annotation =
20969       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
20970 
20971   MockWrite data_writes[] = {
20972       MockWrite(ASYNC,
20973                 "POST / HTTP/1.1\r\n"
20974                 "Host: www.example.org\r\n"
20975                 "Connection: keep-alive\r\n"
20976                 "Content-Length: 0\r\n\r\n"),
20977   };
20978 
20979   MockRead data_reads[] = {
20980       MockRead("HTTP/1.1 200 OK\r\n"),
20981       MockRead("Content-Length: 1\r\n\r\n"),
20982       MockRead(SYNCHRONOUS, "1"),
20983   };
20984 
20985   StaticSocketDataProvider data(data_reads, data_writes);
20986   session_deps_.socket_factory->AddSocketDataProvider(&data);
20987   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
20988   ssl.confirm = MockConfirm(ASYNC, OK);
20989   session_deps_.enable_early_data = true;
20990   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
20991 
20992   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20993 
20994   TestCompletionCallback callback;
20995   auto trans =
20996       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
20997 
20998   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
20999   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
21000 
21001   rv = callback.WaitForResult();
21002   EXPECT_THAT(rv, IsOk());
21003 
21004   const HttpResponseInfo* response = trans->GetResponseInfo();
21005   ASSERT_TRUE(response);
21006   ASSERT_TRUE(response->headers);
21007   EXPECT_EQ(200, response->headers->response_code());
21008   EXPECT_EQ(1, response->headers->GetContentLength());
21009 
21010   // Check that the Write didn't get called before ConfirmHandshake completed.
21011   ASSERT_FALSE(ssl.WriteBeforeConfirm());
21012 
21013   trans.reset();
21014 
21015   session->CloseAllConnections(ERR_FAILED, "Very good reason");
21016 }
21017 
21018 // 0-RTT rejects are handled at HttpNetworkTransaction.
TEST_F(HttpNetworkTransactionTest,ZeroRTTReject)21019 TEST_F(HttpNetworkTransactionTest, ZeroRTTReject) {
21020   enum class RejectType {
21021     kRead,
21022     kWrite,
21023     kConfirm,
21024   };
21025 
21026   for (RejectType type :
21027        {RejectType::kRead, RejectType::kWrite, RejectType::kConfirm}) {
21028     SCOPED_TRACE(static_cast<int>(type));
21029     for (Error reject_error :
21030          {ERR_EARLY_DATA_REJECTED, ERR_WRONG_VERSION_ON_EARLY_DATA}) {
21031       SCOPED_TRACE(reject_error);
21032       session_deps_.socket_factory =
21033           std::make_unique<MockClientSocketFactory>();
21034 
21035       HttpRequestInfo request;
21036       request.method = type == RejectType::kConfirm ? "POST" : "GET";
21037       request.url = GURL("https://www.example.org/");
21038       request.traffic_annotation =
21039           net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21040 
21041       // The first request fails.
21042       std::vector<MockWrite> data1_writes;
21043       std::vector<MockRead> data1_reads;
21044       SSLSocketDataProvider ssl1(SYNCHRONOUS, OK);
21045       switch (type) {
21046         case RejectType::kRead:
21047           data1_writes.emplace_back(
21048               "GET / HTTP/1.1\r\n"
21049               "Host: www.example.org\r\n"
21050               "Connection: keep-alive\r\n\r\n");
21051           data1_reads.emplace_back(ASYNC, reject_error);
21052           // Cause ConfirmHandshake to hang (it should not be called).
21053           ssl1.confirm = MockConfirm(SYNCHRONOUS, ERR_IO_PENDING);
21054           break;
21055         case RejectType::kWrite:
21056           data1_writes.emplace_back(ASYNC, reject_error);
21057           // Cause ConfirmHandshake to hang (it should not be called).
21058           ssl1.confirm = MockConfirm(SYNCHRONOUS, ERR_IO_PENDING);
21059           break;
21060         case RejectType::kConfirm:
21061           // The request never gets far enough to read or write.
21062           ssl1.confirm = MockConfirm(ASYNC, reject_error);
21063           break;
21064       }
21065 
21066       StaticSocketDataProvider data1(data1_reads, data1_writes);
21067       session_deps_.socket_factory->AddSocketDataProvider(&data1);
21068       session_deps_.enable_early_data = true;
21069       session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
21070 
21071       // The retry succeeds.
21072       //
21073       // TODO(https://crbug.com/950705): If |reject_error| is
21074       // ERR_EARLY_DATA_REJECTED, the retry should happen over the same socket.
21075       MockWrite data2_writes[] = {
21076           request.method == "POST"
21077               ? MockWrite("POST / HTTP/1.1\r\n"
21078                           "Host: www.example.org\r\n"
21079                           "Connection: keep-alive\r\n"
21080                           "Content-Length: 0\r\n\r\n")
21081               : MockWrite("GET / HTTP/1.1\r\n"
21082                           "Host: www.example.org\r\n"
21083                           "Connection: keep-alive\r\n\r\n"),
21084       };
21085 
21086       MockRead data2_reads[] = {
21087           MockRead("HTTP/1.1 200 OK\r\n"),
21088           MockRead("Content-Length: 1\r\n\r\n"),
21089           MockRead(SYNCHRONOUS, "1"),
21090       };
21091 
21092       StaticSocketDataProvider data2(data2_reads, data2_writes);
21093       session_deps_.socket_factory->AddSocketDataProvider(&data2);
21094       SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
21095       ssl2.confirm = MockConfirm(ASYNC, OK);
21096       session_deps_.enable_early_data = true;
21097       session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
21098 
21099       std::unique_ptr<HttpNetworkSession> session(
21100           CreateSession(&session_deps_));
21101 
21102       TestCompletionCallback callback;
21103       auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
21104                                                             session.get());
21105 
21106       EXPECT_THAT(callback.GetResult(trans->Start(&request, callback.callback(),
21107                                                   NetLogWithSource())),
21108                   IsOk());
21109 
21110       const HttpResponseInfo* response = trans->GetResponseInfo();
21111       ASSERT_TRUE(response);
21112       ASSERT_TRUE(response->headers);
21113       EXPECT_EQ(200, response->headers->response_code());
21114       EXPECT_EQ(1, response->headers->GetContentLength());
21115     }
21116   }
21117 }
21118 
TEST_F(HttpNetworkTransactionTest,ZeroRTTConfirmErrorSync)21119 TEST_F(HttpNetworkTransactionTest, ZeroRTTConfirmErrorSync) {
21120   HttpRequestInfo request;
21121   request.method = "POST";
21122   request.url = GURL("https://www.example.org/");
21123   request.traffic_annotation =
21124       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21125 
21126   MockWrite data_writes[] = {
21127       MockWrite("POST / HTTP/1.1\r\n"
21128                 "Host: www.example.org\r\n"
21129                 "Connection: keep-alive\r\n"
21130                 "Content-Length: 0\r\n\r\n"),
21131   };
21132 
21133   MockRead data_reads[] = {
21134       MockRead("HTTP/1.1 200 OK\r\n"),
21135       MockRead("Content-Length: 1\r\n\r\n"),
21136       MockRead(SYNCHRONOUS, "1"),
21137   };
21138 
21139   StaticSocketDataProvider data(data_reads, data_writes);
21140   session_deps_.socket_factory->AddSocketDataProvider(&data);
21141   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
21142   ssl.confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
21143   session_deps_.enable_early_data = true;
21144   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
21145 
21146   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21147 
21148   TestCompletionCallback callback;
21149   auto trans =
21150       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
21151 
21152   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
21153   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
21154 
21155   rv = callback.WaitForResult();
21156   EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
21157 
21158   // Check that the Write didn't get called before ConfirmHandshake completed.
21159   ASSERT_FALSE(ssl.WriteBeforeConfirm());
21160 
21161   trans.reset();
21162 
21163   session->CloseAllConnections(ERR_FAILED, "Very good reason");
21164 }
21165 
TEST_F(HttpNetworkTransactionTest,ZeroRTTConfirmErrorAsync)21166 TEST_F(HttpNetworkTransactionTest, ZeroRTTConfirmErrorAsync) {
21167   HttpRequestInfo request;
21168   request.method = "POST";
21169   request.url = GURL("https://www.example.org/");
21170   request.traffic_annotation =
21171       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21172 
21173   MockWrite data_writes[] = {
21174       MockWrite("POST / HTTP/1.1\r\n"
21175                 "Host: www.example.org\r\n"
21176                 "Connection: keep-alive\r\n"
21177                 "Content-Length: 0\r\n\r\n"),
21178   };
21179 
21180   MockRead data_reads[] = {
21181       MockRead("HTTP/1.1 200 OK\r\n"),
21182       MockRead("Content-Length: 1\r\n\r\n"),
21183       MockRead(SYNCHRONOUS, "1"),
21184   };
21185 
21186   StaticSocketDataProvider data(data_reads, data_writes);
21187   session_deps_.socket_factory->AddSocketDataProvider(&data);
21188   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
21189   ssl.confirm = MockConfirm(ASYNC, ERR_SSL_PROTOCOL_ERROR);
21190   session_deps_.enable_early_data = true;
21191   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
21192 
21193   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21194 
21195   TestCompletionCallback callback;
21196   auto trans =
21197       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
21198 
21199   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
21200   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
21201 
21202   rv = callback.WaitForResult();
21203   EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
21204 
21205   // Check that the Write didn't get called before ConfirmHandshake completed.
21206   ASSERT_FALSE(ssl.WriteBeforeConfirm());
21207 
21208   trans.reset();
21209 
21210   session->CloseAllConnections(ERR_FAILED, "Very good reason");
21211 }
21212 
21213 // Test the proxy and origin server each requesting both TLS client certificates
21214 // and HTTP auth. This is a regression test for https://crbug.com/946406.
TEST_F(HttpNetworkTransactionTest,AuthEverything)21215 TEST_F(HttpNetworkTransactionTest, AuthEverything) {
21216   // Note these hosts must match the CheckBasic*Auth() functions.
21217   session_deps_.proxy_resolution_service =
21218       ConfiguredProxyResolutionService::CreateFixed(
21219           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
21220 
21221   auto cert_request_info_proxy = base::MakeRefCounted<SSLCertRequestInfo>();
21222   cert_request_info_proxy->host_and_port = HostPortPair("myproxy", 70);
21223 
21224   std::unique_ptr<FakeClientCertIdentity> identity_proxy =
21225       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
21226           GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
21227   ASSERT_TRUE(identity_proxy);
21228 
21229   auto cert_request_info_origin = base::MakeRefCounted<SSLCertRequestInfo>();
21230   cert_request_info_origin->host_and_port =
21231       HostPortPair("www.example.org", 443);
21232 
21233   std::unique_ptr<FakeClientCertIdentity> identity_origin =
21234       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
21235           GetTestCertsDirectory(), "client_2.pem", "client_2.pk8");
21236   ASSERT_TRUE(identity_origin);
21237 
21238   HttpRequestInfo request;
21239   request.method = "GET";
21240   request.url = GURL("https://www.example.org/");
21241   request.traffic_annotation =
21242       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21243 
21244   // First, the client connects to the proxy, which requests a client
21245   // certificate.
21246   SSLSocketDataProvider ssl_proxy1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
21247   ssl_proxy1.cert_request_info = cert_request_info_proxy.get();
21248   ssl_proxy1.expected_send_client_cert = false;
21249   StaticSocketDataProvider data1;
21250   session_deps_.socket_factory->AddSocketDataProvider(&data1);
21251   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy1);
21252 
21253   // The client responds with a certificate on a new connection. The handshake
21254   // succeeds.
21255   SSLSocketDataProvider ssl_proxy2(ASYNC, OK);
21256   ssl_proxy2.expected_send_client_cert = true;
21257   ssl_proxy2.expected_client_cert = identity_proxy->certificate();
21258   // The client attempts an HTTP CONNECT, but the proxy requests basic auth.
21259   std::vector<MockWrite> mock_writes2;
21260   std::vector<MockRead> mock_reads2;
21261   mock_writes2.emplace_back(
21262       "CONNECT www.example.org:443 HTTP/1.1\r\n"
21263       "Host: www.example.org:443\r\n"
21264       "Proxy-Connection: keep-alive\r\n\r\n");
21265   mock_reads2.emplace_back(
21266       "HTTP/1.1 407 Proxy Authentication Required\r\n"
21267       "Content-Length: 0\r\n"
21268       "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n");
21269   // The client retries with credentials.
21270   mock_writes2.emplace_back(
21271       "CONNECT www.example.org:443 HTTP/1.1\r\n"
21272       "Host: www.example.org:443\r\n"
21273       "Proxy-Connection: keep-alive\r\n"
21274       // Authenticate as proxyuser:proxypass.
21275       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
21276   mock_reads2.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
21277   // The origin requests client certificates.
21278   SSLSocketDataProvider ssl_origin2(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
21279   ssl_origin2.cert_request_info = cert_request_info_origin.get();
21280   StaticSocketDataProvider data2(mock_reads2, mock_writes2);
21281   session_deps_.socket_factory->AddSocketDataProvider(&data2);
21282   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy2);
21283   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin2);
21284 
21285   // The client responds to the origin client certificate request on a new
21286   // connection.
21287   SSLSocketDataProvider ssl_proxy3(ASYNC, OK);
21288   ssl_proxy3.expected_send_client_cert = true;
21289   ssl_proxy3.expected_client_cert = identity_proxy->certificate();
21290   std::vector<MockWrite> mock_writes3;
21291   std::vector<MockRead> mock_reads3;
21292   mock_writes3.emplace_back(
21293       "CONNECT www.example.org:443 HTTP/1.1\r\n"
21294       "Host: www.example.org:443\r\n"
21295       "Proxy-Connection: keep-alive\r\n"
21296       // Authenticate as proxyuser:proxypass.
21297       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
21298   mock_reads3.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
21299   SSLSocketDataProvider ssl_origin3(ASYNC, OK);
21300   ssl_origin3.expected_send_client_cert = true;
21301   ssl_origin3.expected_client_cert = identity_origin->certificate();
21302   // The client sends the origin HTTP request, which results in another HTTP
21303   // auth request.
21304   mock_writes3.emplace_back(
21305       "GET / HTTP/1.1\r\n"
21306       "Host: www.example.org\r\n"
21307       "Connection: keep-alive\r\n\r\n");
21308   mock_reads3.emplace_back(
21309       "HTTP/1.1 401 Unauthorized\r\n"
21310       "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
21311       "Content-Length: 0\r\n\r\n");
21312   // The client retries with credentials, and the request finally succeeds.
21313   mock_writes3.emplace_back(
21314       "GET / HTTP/1.1\r\n"
21315       "Host: www.example.org\r\n"
21316       "Connection: keep-alive\r\n"
21317       // Authenticate as user:pass.
21318       "Authorization: Basic dXNlcjpwYXNz\r\n\r\n");
21319   mock_reads3.emplace_back(
21320       "HTTP/1.1 200 OK\r\n"
21321       "Content-Length: 0\r\n\r\n");
21322   // The client makes another request. This should reuse the socket with all
21323   // credentials cached.
21324   mock_writes3.emplace_back(
21325       "GET / HTTP/1.1\r\n"
21326       "Host: www.example.org\r\n"
21327       "Connection: keep-alive\r\n"
21328       // Authenticate as user:pass.
21329       "Authorization: Basic dXNlcjpwYXNz\r\n\r\n");
21330   mock_reads3.emplace_back(
21331       "HTTP/1.1 200 OK\r\n"
21332       "Content-Length: 0\r\n\r\n");
21333   StaticSocketDataProvider data3(mock_reads3, mock_writes3);
21334   session_deps_.socket_factory->AddSocketDataProvider(&data3);
21335   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy3);
21336   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin3);
21337 
21338   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21339 
21340   // Start the request.
21341   TestCompletionCallback callback;
21342   auto trans =
21343       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
21344   int rv = callback.GetResult(
21345       trans->Start(&request, callback.callback(), NetLogWithSource()));
21346 
21347   // Handle the proxy client certificate challenge.
21348   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
21349   SSLCertRequestInfo* cert_request_info =
21350       trans->GetResponseInfo()->cert_request_info.get();
21351   ASSERT_TRUE(cert_request_info);
21352   EXPECT_TRUE(cert_request_info->is_proxy);
21353   EXPECT_EQ(cert_request_info->host_and_port,
21354             cert_request_info_proxy->host_and_port);
21355   rv = callback.GetResult(trans->RestartWithCertificate(
21356       identity_proxy->certificate(), identity_proxy->ssl_private_key(),
21357       callback.callback()));
21358 
21359   // Handle the proxy HTTP auth challenge.
21360   ASSERT_THAT(rv, IsOk());
21361   EXPECT_EQ(407, trans->GetResponseInfo()->headers->response_code());
21362   EXPECT_TRUE(
21363       CheckBasicSecureProxyAuth(trans->GetResponseInfo()->auth_challenge));
21364   rv = callback.GetResult(trans->RestartWithAuth(
21365       AuthCredentials(ASCIIToUTF16("proxyuser"), ASCIIToUTF16("proxypass")),
21366       callback.callback()));
21367 
21368   // Handle the origin client certificate challenge.
21369   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
21370   cert_request_info = trans->GetResponseInfo()->cert_request_info.get();
21371   ASSERT_TRUE(cert_request_info);
21372   EXPECT_FALSE(cert_request_info->is_proxy);
21373   EXPECT_EQ(cert_request_info->host_and_port,
21374             cert_request_info_origin->host_and_port);
21375   rv = callback.GetResult(trans->RestartWithCertificate(
21376       identity_origin->certificate(), identity_origin->ssl_private_key(),
21377       callback.callback()));
21378 
21379   // Handle the origin HTTP auth challenge.
21380   ASSERT_THAT(rv, IsOk());
21381   EXPECT_EQ(401, trans->GetResponseInfo()->headers->response_code());
21382   EXPECT_TRUE(
21383       CheckBasicSecureServerAuth(trans->GetResponseInfo()->auth_challenge));
21384   rv = callback.GetResult(trans->RestartWithAuth(
21385       AuthCredentials(ASCIIToUTF16("user"), ASCIIToUTF16("pass")),
21386       callback.callback()));
21387 
21388   // The request completes.
21389   ASSERT_THAT(rv, IsOk());
21390   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
21391 
21392   // Make a second request. This time all credentials are cached.
21393   trans =
21394       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
21395   ASSERT_THAT(callback.GetResult(trans->Start(&request, callback.callback(),
21396                                               NetLogWithSource())),
21397               IsOk());
21398   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
21399 }
21400 
21401 // Test the proxy and origin server each requesting both TLS client certificates
21402 // and HTTP auth and each HTTP auth closing the connection. This is a regression
21403 // test for https://crbug.com/946406.
TEST_F(HttpNetworkTransactionTest,AuthEverythingWithConnectClose)21404 TEST_F(HttpNetworkTransactionTest, AuthEverythingWithConnectClose) {
21405   // Note these hosts must match the CheckBasic*Auth() functions.
21406   session_deps_.proxy_resolution_service =
21407       ConfiguredProxyResolutionService::CreateFixed(
21408           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
21409 
21410   auto cert_request_info_proxy = base::MakeRefCounted<SSLCertRequestInfo>();
21411   cert_request_info_proxy->host_and_port = HostPortPair("myproxy", 70);
21412 
21413   std::unique_ptr<FakeClientCertIdentity> identity_proxy =
21414       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
21415           GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
21416   ASSERT_TRUE(identity_proxy);
21417 
21418   auto cert_request_info_origin = base::MakeRefCounted<SSLCertRequestInfo>();
21419   cert_request_info_origin->host_and_port =
21420       HostPortPair("www.example.org", 443);
21421 
21422   std::unique_ptr<FakeClientCertIdentity> identity_origin =
21423       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
21424           GetTestCertsDirectory(), "client_2.pem", "client_2.pk8");
21425   ASSERT_TRUE(identity_origin);
21426 
21427   HttpRequestInfo request;
21428   request.method = "GET";
21429   request.url = GURL("https://www.example.org/");
21430   request.traffic_annotation =
21431       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21432 
21433   // First, the client connects to the proxy, which requests a client
21434   // certificate.
21435   SSLSocketDataProvider ssl_proxy1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
21436   ssl_proxy1.cert_request_info = cert_request_info_proxy.get();
21437   ssl_proxy1.expected_send_client_cert = false;
21438   StaticSocketDataProvider data1;
21439   session_deps_.socket_factory->AddSocketDataProvider(&data1);
21440   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy1);
21441 
21442   // The client responds with a certificate on a new connection. The handshake
21443   // succeeds.
21444   SSLSocketDataProvider ssl_proxy2(ASYNC, OK);
21445   ssl_proxy2.expected_send_client_cert = true;
21446   ssl_proxy2.expected_client_cert = identity_proxy->certificate();
21447   // The client attempts an HTTP CONNECT, but the proxy requests basic auth.
21448   std::vector<MockWrite> mock_writes2;
21449   std::vector<MockRead> mock_reads2;
21450   mock_writes2.emplace_back(
21451       "CONNECT www.example.org:443 HTTP/1.1\r\n"
21452       "Host: www.example.org:443\r\n"
21453       "Proxy-Connection: keep-alive\r\n\r\n");
21454   mock_reads2.emplace_back(
21455       "HTTP/1.1 407 Proxy Authentication Required\r\n"
21456       "Content-Length: 0\r\n"
21457       "Proxy-Connection: close\r\n"
21458       "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n");
21459   StaticSocketDataProvider data2(mock_reads2, mock_writes2);
21460   session_deps_.socket_factory->AddSocketDataProvider(&data2);
21461   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy2);
21462 
21463   // The client retries with credentials on a new connection.
21464   SSLSocketDataProvider ssl_proxy3(ASYNC, OK);
21465   ssl_proxy3.expected_send_client_cert = true;
21466   ssl_proxy3.expected_client_cert = identity_proxy->certificate();
21467   std::vector<MockWrite> mock_writes3;
21468   std::vector<MockRead> mock_reads3;
21469   mock_writes3.emplace_back(
21470       "CONNECT www.example.org:443 HTTP/1.1\r\n"
21471       "Host: www.example.org:443\r\n"
21472       "Proxy-Connection: keep-alive\r\n"
21473       // Authenticate as proxyuser:proxypass.
21474       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
21475   mock_reads3.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
21476   // The origin requests client certificates.
21477   SSLSocketDataProvider ssl_origin3(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
21478   ssl_origin3.cert_request_info = cert_request_info_origin.get();
21479   StaticSocketDataProvider data3(mock_reads3, mock_writes3);
21480   session_deps_.socket_factory->AddSocketDataProvider(&data3);
21481   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy3);
21482   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin3);
21483 
21484   // The client responds to the origin client certificate request on a new
21485   // connection.
21486   SSLSocketDataProvider ssl_proxy4(ASYNC, OK);
21487   ssl_proxy4.expected_send_client_cert = true;
21488   ssl_proxy4.expected_client_cert = identity_proxy->certificate();
21489   std::vector<MockWrite> mock_writes4;
21490   std::vector<MockRead> mock_reads4;
21491   mock_writes4.emplace_back(
21492       "CONNECT www.example.org:443 HTTP/1.1\r\n"
21493       "Host: www.example.org:443\r\n"
21494       "Proxy-Connection: keep-alive\r\n"
21495       // Authenticate as proxyuser:proxypass.
21496       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
21497   mock_reads4.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
21498   SSLSocketDataProvider ssl_origin4(ASYNC, OK);
21499   ssl_origin4.expected_send_client_cert = true;
21500   ssl_origin4.expected_client_cert = identity_origin->certificate();
21501   // The client sends the origin HTTP request, which results in another HTTP
21502   // auth request and closed connection.
21503   mock_writes4.emplace_back(
21504       "GET / HTTP/1.1\r\n"
21505       "Host: www.example.org\r\n"
21506       "Connection: keep-alive\r\n\r\n");
21507   mock_reads4.emplace_back(
21508       "HTTP/1.1 401 Unauthorized\r\n"
21509       "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"
21510       "Connection: close\r\n"
21511       "Content-Length: 0\r\n\r\n");
21512   StaticSocketDataProvider data4(mock_reads4, mock_writes4);
21513   session_deps_.socket_factory->AddSocketDataProvider(&data4);
21514   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy4);
21515   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin4);
21516 
21517   // The client retries with credentials on a new connection, and the request
21518   // finally succeeds.
21519   SSLSocketDataProvider ssl_proxy5(ASYNC, OK);
21520   ssl_proxy5.expected_send_client_cert = true;
21521   ssl_proxy5.expected_client_cert = identity_proxy->certificate();
21522   std::vector<MockWrite> mock_writes5;
21523   std::vector<MockRead> mock_reads5;
21524   mock_writes5.emplace_back(
21525       "CONNECT www.example.org:443 HTTP/1.1\r\n"
21526       "Host: www.example.org:443\r\n"
21527       "Proxy-Connection: keep-alive\r\n"
21528       // Authenticate as proxyuser:proxypass.
21529       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
21530   mock_reads5.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
21531   SSLSocketDataProvider ssl_origin5(ASYNC, OK);
21532   ssl_origin5.expected_send_client_cert = true;
21533   ssl_origin5.expected_client_cert = identity_origin->certificate();
21534   mock_writes5.emplace_back(
21535       "GET / HTTP/1.1\r\n"
21536       "Host: www.example.org\r\n"
21537       "Connection: keep-alive\r\n"
21538       // Authenticate as user:pass.
21539       "Authorization: Basic dXNlcjpwYXNz\r\n\r\n");
21540   mock_reads5.emplace_back(
21541       "HTTP/1.1 200 OK\r\n"
21542       "Connection: close\r\n"
21543       "Content-Length: 0\r\n\r\n");
21544   StaticSocketDataProvider data5(mock_reads5, mock_writes5);
21545   session_deps_.socket_factory->AddSocketDataProvider(&data5);
21546   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy5);
21547   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin5);
21548 
21549   // The client makes a second request. This needs yet another connection, but
21550   // all credentials are cached.
21551   SSLSocketDataProvider ssl_proxy6(ASYNC, OK);
21552   ssl_proxy6.expected_send_client_cert = true;
21553   ssl_proxy6.expected_client_cert = identity_proxy->certificate();
21554   std::vector<MockWrite> mock_writes6;
21555   std::vector<MockRead> mock_reads6;
21556   mock_writes6.emplace_back(
21557       "CONNECT www.example.org:443 HTTP/1.1\r\n"
21558       "Host: www.example.org:443\r\n"
21559       "Proxy-Connection: keep-alive\r\n"
21560       // Authenticate as proxyuser:proxypass.
21561       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
21562   mock_reads6.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
21563   SSLSocketDataProvider ssl_origin6(ASYNC, OK);
21564   ssl_origin6.expected_send_client_cert = true;
21565   ssl_origin6.expected_client_cert = identity_origin->certificate();
21566   mock_writes6.emplace_back(
21567       "GET / HTTP/1.1\r\n"
21568       "Host: www.example.org\r\n"
21569       "Connection: keep-alive\r\n"
21570       // Authenticate as user:pass.
21571       "Authorization: Basic dXNlcjpwYXNz\r\n\r\n");
21572   mock_reads6.emplace_back(
21573       "HTTP/1.1 200 OK\r\n"
21574       "Connection: close\r\n"
21575       "Content-Length: 0\r\n\r\n");
21576   StaticSocketDataProvider data6(mock_reads6, mock_writes6);
21577   session_deps_.socket_factory->AddSocketDataProvider(&data6);
21578   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy6);
21579   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin6);
21580 
21581   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21582 
21583   // Start the request.
21584   TestCompletionCallback callback;
21585   auto trans =
21586       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
21587   int rv = callback.GetResult(
21588       trans->Start(&request, callback.callback(), NetLogWithSource()));
21589 
21590   // Handle the proxy client certificate challenge.
21591   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
21592   SSLCertRequestInfo* cert_request_info =
21593       trans->GetResponseInfo()->cert_request_info.get();
21594   ASSERT_TRUE(cert_request_info);
21595   EXPECT_TRUE(cert_request_info->is_proxy);
21596   EXPECT_EQ(cert_request_info->host_and_port,
21597             cert_request_info_proxy->host_and_port);
21598   rv = callback.GetResult(trans->RestartWithCertificate(
21599       identity_proxy->certificate(), identity_proxy->ssl_private_key(),
21600       callback.callback()));
21601 
21602   // Handle the proxy HTTP auth challenge.
21603   ASSERT_THAT(rv, IsOk());
21604   EXPECT_EQ(407, trans->GetResponseInfo()->headers->response_code());
21605   EXPECT_TRUE(
21606       CheckBasicSecureProxyAuth(trans->GetResponseInfo()->auth_challenge));
21607   rv = callback.GetResult(trans->RestartWithAuth(
21608       AuthCredentials(ASCIIToUTF16("proxyuser"), ASCIIToUTF16("proxypass")),
21609       callback.callback()));
21610 
21611   // Handle the origin client certificate challenge.
21612   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
21613   cert_request_info = trans->GetResponseInfo()->cert_request_info.get();
21614   ASSERT_TRUE(cert_request_info);
21615   EXPECT_FALSE(cert_request_info->is_proxy);
21616   EXPECT_EQ(cert_request_info->host_and_port,
21617             cert_request_info_origin->host_and_port);
21618   rv = callback.GetResult(trans->RestartWithCertificate(
21619       identity_origin->certificate(), identity_origin->ssl_private_key(),
21620       callback.callback()));
21621 
21622   // Handle the origin HTTP auth challenge.
21623   ASSERT_THAT(rv, IsOk());
21624   EXPECT_EQ(401, trans->GetResponseInfo()->headers->response_code());
21625   EXPECT_TRUE(
21626       CheckBasicSecureServerAuth(trans->GetResponseInfo()->auth_challenge));
21627   rv = callback.GetResult(trans->RestartWithAuth(
21628       AuthCredentials(ASCIIToUTF16("user"), ASCIIToUTF16("pass")),
21629       callback.callback()));
21630 
21631   // The request completes.
21632   ASSERT_THAT(rv, IsOk());
21633   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
21634 
21635   // Make a second request. This time all credentials are cached.
21636   trans =
21637       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
21638   ASSERT_THAT(callback.GetResult(trans->Start(&request, callback.callback(),
21639                                               NetLogWithSource())),
21640               IsOk());
21641   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
21642 }
21643 
21644 // Test the proxy requesting HTTP auth and the server requesting TLS client
21645 // certificates. This is a regression test for https://crbug.com/946406.
TEST_F(HttpNetworkTransactionTest,ProxyHTTPAndServerTLSAuth)21646 TEST_F(HttpNetworkTransactionTest, ProxyHTTPAndServerTLSAuth) {
21647   // Note these hosts must match the CheckBasic*Auth() functions.
21648   session_deps_.proxy_resolution_service =
21649       ConfiguredProxyResolutionService::CreateFixed(
21650           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
21651 
21652   auto cert_request_info_origin = base::MakeRefCounted<SSLCertRequestInfo>();
21653   cert_request_info_origin->host_and_port =
21654       HostPortPair("www.example.org", 443);
21655 
21656   std::unique_ptr<FakeClientCertIdentity> identity_origin =
21657       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
21658           GetTestCertsDirectory(), "client_2.pem", "client_2.pk8");
21659   ASSERT_TRUE(identity_origin);
21660 
21661   HttpRequestInfo request;
21662   request.method = "GET";
21663   request.url = GURL("https://www.example.org/");
21664   request.traffic_annotation =
21665       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21666 
21667   // The client connects to the proxy. The handshake succeeds.
21668   SSLSocketDataProvider ssl_proxy1(ASYNC, OK);
21669   // The client attempts an HTTP CONNECT, but the proxy requests basic auth.
21670   std::vector<MockWrite> mock_writes1;
21671   std::vector<MockRead> mock_reads1;
21672   mock_writes1.emplace_back(
21673       "CONNECT www.example.org:443 HTTP/1.1\r\n"
21674       "Host: www.example.org:443\r\n"
21675       "Proxy-Connection: keep-alive\r\n\r\n");
21676   mock_reads1.emplace_back(
21677       "HTTP/1.1 407 Proxy Authentication Required\r\n"
21678       "Content-Length: 0\r\n"
21679       "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n");
21680   // The client retries with credentials, and the request finally succeeds.
21681   mock_writes1.emplace_back(
21682       "CONNECT www.example.org:443 HTTP/1.1\r\n"
21683       "Host: www.example.org:443\r\n"
21684       "Proxy-Connection: keep-alive\r\n"
21685       // Authenticate as proxyuser:proxypass.
21686       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
21687   mock_reads1.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
21688   // The origin requests client certificates.
21689   SSLSocketDataProvider ssl_origin1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
21690   ssl_origin1.cert_request_info = cert_request_info_origin.get();
21691   StaticSocketDataProvider data1(mock_reads1, mock_writes1);
21692   session_deps_.socket_factory->AddSocketDataProvider(&data1);
21693   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy1);
21694   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin1);
21695 
21696   // The client responds to the origin client certificate request on a new
21697   // connection.
21698   SSLSocketDataProvider ssl_proxy2(ASYNC, OK);
21699   std::vector<MockWrite> mock_writes2;
21700   std::vector<MockRead> mock_reads2;
21701   mock_writes2.emplace_back(
21702       "CONNECT www.example.org:443 HTTP/1.1\r\n"
21703       "Host: www.example.org:443\r\n"
21704       "Proxy-Connection: keep-alive\r\n"
21705       // Authenticate as proxyuser:proxypass.
21706       "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n");
21707   mock_reads2.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n");
21708   SSLSocketDataProvider ssl_origin2(ASYNC, OK);
21709   ssl_origin2.expected_send_client_cert = true;
21710   ssl_origin2.expected_client_cert = identity_origin->certificate();
21711   // The client sends the origin HTTP request, which succeeds.
21712   mock_writes2.emplace_back(
21713       "GET / HTTP/1.1\r\n"
21714       "Host: www.example.org\r\n"
21715       "Connection: keep-alive\r\n\r\n");
21716   mock_reads2.emplace_back(
21717       "HTTP/1.1 200 OK\r\n"
21718       "Content-Length: 0\r\n\r\n");
21719   StaticSocketDataProvider data2(mock_reads2, mock_writes2);
21720   session_deps_.socket_factory->AddSocketDataProvider(&data2);
21721   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy2);
21722   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin2);
21723 
21724   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21725 
21726   // Start the request.
21727   TestCompletionCallback callback;
21728   auto trans =
21729       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
21730   int rv = callback.GetResult(
21731       trans->Start(&request, callback.callback(), NetLogWithSource()));
21732 
21733   // Handle the proxy HTTP auth challenge.
21734   ASSERT_THAT(rv, IsOk());
21735   EXPECT_EQ(407, trans->GetResponseInfo()->headers->response_code());
21736   EXPECT_TRUE(
21737       CheckBasicSecureProxyAuth(trans->GetResponseInfo()->auth_challenge));
21738   rv = callback.GetResult(trans->RestartWithAuth(
21739       AuthCredentials(ASCIIToUTF16("proxyuser"), ASCIIToUTF16("proxypass")),
21740       callback.callback()));
21741 
21742   // Handle the origin client certificate challenge.
21743   ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
21744   SSLCertRequestInfo* cert_request_info =
21745       trans->GetResponseInfo()->cert_request_info.get();
21746   ASSERT_TRUE(cert_request_info);
21747   EXPECT_FALSE(cert_request_info->is_proxy);
21748   EXPECT_EQ(cert_request_info->host_and_port,
21749             cert_request_info_origin->host_and_port);
21750   rv = callback.GetResult(trans->RestartWithCertificate(
21751       identity_origin->certificate(), identity_origin->ssl_private_key(),
21752       callback.callback()));
21753 
21754   // The request completes.
21755   ASSERT_THAT(rv, IsOk());
21756   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
21757 }
21758 
21759 // Test that socket reuse works with client certificates.
TEST_F(HttpNetworkTransactionTest,ClientCertSocketReuse)21760 TEST_F(HttpNetworkTransactionTest, ClientCertSocketReuse) {
21761   auto cert_request_info = base::MakeRefCounted<SSLCertRequestInfo>();
21762   cert_request_info->host_and_port = HostPortPair("www.example.org", 443);
21763 
21764   std::unique_ptr<FakeClientCertIdentity> identity =
21765       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
21766           GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
21767   ASSERT_TRUE(identity);
21768 
21769   HttpRequestInfo request1;
21770   request1.method = "GET";
21771   request1.url = GURL("https://www.example.org/a");
21772   request1.traffic_annotation =
21773       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21774 
21775   HttpRequestInfo request2;
21776   request2.method = "GET";
21777   request2.url = GURL("https://www.example.org/b");
21778   request2.traffic_annotation =
21779       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21780 
21781   // The first connection results in a client certificate request.
21782   StaticSocketDataProvider data1;
21783   session_deps_.socket_factory->AddSocketDataProvider(&data1);
21784   SSLSocketDataProvider ssl1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
21785   ssl1.cert_request_info = cert_request_info.get();
21786   ssl1.expected_send_client_cert = false;
21787   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
21788 
21789   // The second connection succeeds and is usable for both requests.
21790   MockWrite mock_writes[] = {
21791       MockWrite("GET /a HTTP/1.1\r\n"
21792                 "Host: www.example.org\r\n"
21793                 "Connection: keep-alive\r\n\r\n"),
21794       MockWrite("GET /b HTTP/1.1\r\n"
21795                 "Host: www.example.org\r\n"
21796                 "Connection: keep-alive\r\n\r\n"),
21797   };
21798   MockRead mock_reads[] = {
21799       MockRead("HTTP/1.1 200 OK\r\n"
21800                "Content-Length: 0\r\n\r\n"),
21801       MockRead("HTTP/1.1 200 OK\r\n"
21802                "Content-Length: 0\r\n\r\n"),
21803   };
21804   StaticSocketDataProvider data2(mock_reads, mock_writes);
21805   session_deps_.socket_factory->AddSocketDataProvider(&data2);
21806   SSLSocketDataProvider ssl2(ASYNC, OK);
21807   ssl2.expected_send_client_cert = true;
21808   ssl2.expected_client_cert = identity->certificate();
21809   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
21810 
21811   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21812 
21813   // Start the first request. It succeeds after providing client certificates.
21814   TestCompletionCallback callback;
21815   auto trans =
21816       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
21817   ASSERT_THAT(callback.GetResult(trans->Start(&request1, callback.callback(),
21818                                               NetLogWithSource())),
21819               IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
21820 
21821   SSLCertRequestInfo* info = trans->GetResponseInfo()->cert_request_info.get();
21822   ASSERT_TRUE(info);
21823   EXPECT_FALSE(info->is_proxy);
21824   EXPECT_EQ(info->host_and_port, cert_request_info->host_and_port);
21825 
21826   ASSERT_THAT(callback.GetResult(trans->RestartWithCertificate(
21827                   identity->certificate(), identity->ssl_private_key(),
21828                   callback.callback())),
21829               IsOk());
21830   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
21831 
21832   // Make the second request. It completes without requesting client
21833   // certificates.
21834   trans =
21835       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
21836   ASSERT_THAT(callback.GetResult(trans->Start(&request2, callback.callback(),
21837                                               NetLogWithSource())),
21838               IsOk());
21839   EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code());
21840 }
21841 
21842 // Test for kPartitionConnectionsByNetworkIsolationKey. Runs 3 requests in
21843 // sequence with two different NetworkIsolationKeys, the first and last have the
21844 // same key, the second a different one. Checks that the requests are
21845 // partitioned across sockets as expected.
TEST_F(HttpNetworkTransactionTest,NetworkIsolation)21846 TEST_F(HttpNetworkTransactionTest, NetworkIsolation) {
21847   const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
21848   const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
21849   NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
21850   NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
21851 
21852   for (bool partition_connections : {false, true}) {
21853     SCOPED_TRACE(partition_connections);
21854 
21855     base::test::ScopedFeatureList feature_list;
21856     if (partition_connections) {
21857       feature_list.InitAndEnableFeature(
21858           features::kPartitionConnectionsByNetworkIsolationKey);
21859     } else {
21860       feature_list.InitAndDisableFeature(
21861           features::kPartitionConnectionsByNetworkIsolationKey);
21862     }
21863 
21864     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21865 
21866     // Reads and writes for the unpartitioned case, where only one socket is
21867     // used.
21868 
21869     const MockWrite kUnpartitionedWrites[] = {
21870         MockWrite("GET /1 HTTP/1.1\r\n"
21871                   "Host: foo.test\r\n"
21872                   "Connection: keep-alive\r\n\r\n"),
21873         MockWrite("GET /2 HTTP/1.1\r\n"
21874                   "Host: foo.test\r\n"
21875                   "Connection: keep-alive\r\n\r\n"),
21876         MockWrite("GET /3 HTTP/1.1\r\n"
21877                   "Host: foo.test\r\n"
21878                   "Connection: keep-alive\r\n\r\n"),
21879     };
21880 
21881     const MockRead kUnpartitionedReads[] = {
21882         MockRead("HTTP/1.1 200 OK\r\n"
21883                  "Connection: keep-alive\r\n"
21884                  "Content-Length: 1\r\n\r\n"
21885                  "1"),
21886         MockRead("HTTP/1.1 200 OK\r\n"
21887                  "Connection: keep-alive\r\n"
21888                  "Content-Length: 1\r\n\r\n"
21889                  "2"),
21890         MockRead("HTTP/1.1 200 OK\r\n"
21891                  "Connection: keep-alive\r\n"
21892                  "Content-Length: 1\r\n\r\n"
21893                  "3"),
21894     };
21895 
21896     StaticSocketDataProvider unpartitioned_data(kUnpartitionedReads,
21897                                                 kUnpartitionedWrites);
21898 
21899     // Reads and writes for the partitioned case, where two sockets are used.
21900 
21901     const MockWrite kPartitionedWrites1[] = {
21902         MockWrite("GET /1 HTTP/1.1\r\n"
21903                   "Host: foo.test\r\n"
21904                   "Connection: keep-alive\r\n\r\n"),
21905         MockWrite("GET /3 HTTP/1.1\r\n"
21906                   "Host: foo.test\r\n"
21907                   "Connection: keep-alive\r\n\r\n"),
21908     };
21909 
21910     const MockRead kPartitionedReads1[] = {
21911         MockRead("HTTP/1.1 200 OK\r\n"
21912                  "Connection: keep-alive\r\n"
21913                  "Content-Length: 1\r\n\r\n"
21914                  "1"),
21915         MockRead("HTTP/1.1 200 OK\r\n"
21916                  "Connection: keep-alive\r\n"
21917                  "Content-Length: 1\r\n\r\n"
21918                  "3"),
21919     };
21920 
21921     const MockWrite kPartitionedWrites2[] = {
21922         MockWrite("GET /2 HTTP/1.1\r\n"
21923                   "Host: foo.test\r\n"
21924                   "Connection: keep-alive\r\n\r\n"),
21925     };
21926 
21927     const MockRead kPartitionedReads2[] = {
21928         MockRead("HTTP/1.1 200 OK\r\n"
21929                  "Connection: keep-alive\r\n"
21930                  "Content-Length: 1\r\n\r\n"
21931                  "2"),
21932     };
21933 
21934     StaticSocketDataProvider partitioned_data1(kPartitionedReads1,
21935                                                kPartitionedWrites1);
21936     StaticSocketDataProvider partitioned_data2(kPartitionedReads2,
21937                                                kPartitionedWrites2);
21938 
21939     if (partition_connections) {
21940       session_deps_.socket_factory->AddSocketDataProvider(&partitioned_data1);
21941       session_deps_.socket_factory->AddSocketDataProvider(&partitioned_data2);
21942     } else {
21943       session_deps_.socket_factory->AddSocketDataProvider(&unpartitioned_data);
21944     }
21945 
21946     TestCompletionCallback callback;
21947     HttpRequestInfo request1;
21948     request1.method = "GET";
21949     request1.url = GURL("http://foo.test/1");
21950     request1.traffic_annotation =
21951         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21952     request1.network_isolation_key = network_isolation_key1;
21953     auto trans1 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
21954                                                            session.get());
21955     int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
21956     EXPECT_THAT(callback.GetResult(rv), IsOk());
21957     std::string response_data1;
21958     EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
21959     EXPECT_EQ("1", response_data1);
21960     trans1.reset();
21961 
21962     HttpRequestInfo request2;
21963     request2.method = "GET";
21964     request2.url = GURL("http://foo.test/2");
21965     request2.traffic_annotation =
21966         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21967     request2.network_isolation_key = network_isolation_key2;
21968     auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
21969                                                            session.get());
21970     rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
21971     EXPECT_THAT(callback.GetResult(rv), IsOk());
21972     std::string response_data2;
21973     EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
21974     EXPECT_EQ("2", response_data2);
21975     trans2.reset();
21976 
21977     HttpRequestInfo request3;
21978     request3.method = "GET";
21979     request3.url = GURL("http://foo.test/3");
21980     request3.traffic_annotation =
21981         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
21982     request3.network_isolation_key = network_isolation_key1;
21983     auto trans3 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
21984                                                            session.get());
21985     rv = trans3->Start(&request3, callback.callback(), NetLogWithSource());
21986     EXPECT_THAT(callback.GetResult(rv), IsOk());
21987     std::string response_data3;
21988     EXPECT_THAT(ReadTransaction(trans3.get(), &response_data3), IsOk());
21989     EXPECT_EQ("3", response_data3);
21990     trans3.reset();
21991   }
21992 }
21993 
TEST_F(HttpNetworkTransactionTest,NetworkIsolationH2)21994 TEST_F(HttpNetworkTransactionTest, NetworkIsolationH2) {
21995   const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
21996   const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
21997   NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
21998   NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
21999 
22000   // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
22001   // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
22002   // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
22003   // the same way as the HTTP over H2 proxy case.
22004   for (bool use_proxy : {false, true}) {
22005     SCOPED_TRACE(use_proxy);
22006     if (use_proxy) {
22007       session_deps_.proxy_resolution_service =
22008           ConfiguredProxyResolutionService::CreateFixedFromPacResult(
22009               "HTTPS proxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
22010     } else {
22011       session_deps_.proxy_resolution_service =
22012           ConfiguredProxyResolutionService::CreateDirect();
22013     }
22014     const char* url1 = nullptr;
22015     const char* url2 = nullptr;
22016     const char* url3 = nullptr;
22017     if (use_proxy) {
22018       url1 = "http://foo.test/1";
22019       url2 = "http://foo.test/2";
22020       url3 = "http://foo.test/3";
22021     } else {
22022       url1 = "https://foo.test/1";
22023       url2 = "https://foo.test/2";
22024       url3 = "https://foo.test/3";
22025     }
22026 
22027     for (bool partition_connections : {false, true}) {
22028       SCOPED_TRACE(partition_connections);
22029 
22030       base::test::ScopedFeatureList feature_list;
22031       if (partition_connections) {
22032         feature_list.InitAndEnableFeature(
22033             features::kPartitionConnectionsByNetworkIsolationKey);
22034       } else {
22035         feature_list.InitAndDisableFeature(
22036             features::kPartitionConnectionsByNetworkIsolationKey);
22037       }
22038 
22039       std::unique_ptr<HttpNetworkSession> session(
22040           CreateSession(&session_deps_));
22041 
22042       // Reads and writes for the unpartitioned case, where only one socket is
22043       // used.
22044 
22045       SpdyTestUtil spdy_util;
22046       spdy::SpdySerializedFrame unpartitioned_req1(
22047           spdy_util.ConstructSpdyGet(url1, 1, LOWEST));
22048       spdy::SpdySerializedFrame unpartitioned_response1(
22049           spdy_util.ConstructSpdyGetReply(nullptr, 0, 1));
22050       spdy::SpdySerializedFrame unpartitioned_body1(
22051           spdy_util.ConstructSpdyDataFrame(1, "1", true));
22052       spdy_util.UpdateWithStreamDestruction(1);
22053 
22054       spdy::SpdySerializedFrame unpartitioned_req2(
22055           spdy_util.ConstructSpdyGet(url2, 3, LOWEST));
22056       spdy::SpdySerializedFrame unpartitioned_response2(
22057           spdy_util.ConstructSpdyGetReply(nullptr, 0, 3));
22058       spdy::SpdySerializedFrame unpartitioned_body2(
22059           spdy_util.ConstructSpdyDataFrame(3, "2", true));
22060       spdy_util.UpdateWithStreamDestruction(3);
22061 
22062       spdy::SpdySerializedFrame unpartitioned_req3(
22063           spdy_util.ConstructSpdyGet(url3, 5, LOWEST));
22064       spdy::SpdySerializedFrame unpartitioned_response3(
22065           spdy_util.ConstructSpdyGetReply(nullptr, 0, 5));
22066       spdy::SpdySerializedFrame unpartitioned_body3(
22067           spdy_util.ConstructSpdyDataFrame(5, "3", true));
22068 
22069       const MockWrite kUnpartitionedWrites[] = {
22070           CreateMockWrite(unpartitioned_req1, 0),
22071           CreateMockWrite(unpartitioned_req2, 3),
22072           CreateMockWrite(unpartitioned_req3, 6),
22073       };
22074 
22075       const MockRead kUnpartitionedReads[] = {
22076           CreateMockRead(unpartitioned_response1, 1),
22077           CreateMockRead(unpartitioned_body1, 2),
22078           CreateMockRead(unpartitioned_response2, 4),
22079           CreateMockRead(unpartitioned_body2, 5),
22080           CreateMockRead(unpartitioned_response3, 7),
22081           CreateMockRead(unpartitioned_body3, 8),
22082           MockRead(SYNCHRONOUS, ERR_IO_PENDING, 9),
22083       };
22084 
22085       SequencedSocketData unpartitioned_data(kUnpartitionedReads,
22086                                              kUnpartitionedWrites);
22087 
22088       // Reads and writes for the partitioned case, where two sockets are used.
22089 
22090       SpdyTestUtil spdy_util2;
22091       spdy::SpdySerializedFrame partitioned_req1(
22092           spdy_util2.ConstructSpdyGet(url1, 1, LOWEST));
22093       spdy::SpdySerializedFrame partitioned_response1(
22094           spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
22095       spdy::SpdySerializedFrame partitioned_body1(
22096           spdy_util2.ConstructSpdyDataFrame(1, "1", true));
22097       spdy_util2.UpdateWithStreamDestruction(1);
22098 
22099       spdy::SpdySerializedFrame partitioned_req3(
22100           spdy_util2.ConstructSpdyGet(url3, 3, LOWEST));
22101       spdy::SpdySerializedFrame partitioned_response3(
22102           spdy_util2.ConstructSpdyGetReply(nullptr, 0, 3));
22103       spdy::SpdySerializedFrame partitioned_body3(
22104           spdy_util2.ConstructSpdyDataFrame(3, "3", true));
22105 
22106       const MockWrite kPartitionedWrites1[] = {
22107           CreateMockWrite(partitioned_req1, 0),
22108           CreateMockWrite(partitioned_req3, 3),
22109       };
22110 
22111       const MockRead kPartitionedReads1[] = {
22112           CreateMockRead(partitioned_response1, 1),
22113           CreateMockRead(partitioned_body1, 2),
22114           CreateMockRead(partitioned_response3, 4),
22115           CreateMockRead(partitioned_body3, 5),
22116           MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),
22117       };
22118 
22119       SpdyTestUtil spdy_util3;
22120       spdy::SpdySerializedFrame partitioned_req2(
22121           spdy_util3.ConstructSpdyGet(url2, 1, LOWEST));
22122       spdy::SpdySerializedFrame partitioned_response2(
22123           spdy_util3.ConstructSpdyGetReply(nullptr, 0, 1));
22124       spdy::SpdySerializedFrame partitioned_body2(
22125           spdy_util3.ConstructSpdyDataFrame(1, "2", true));
22126 
22127       const MockWrite kPartitionedWrites2[] = {
22128           CreateMockWrite(partitioned_req2, 0),
22129       };
22130 
22131       const MockRead kPartitionedReads2[] = {
22132           CreateMockRead(partitioned_response2, 1),
22133           CreateMockRead(partitioned_body2, 2),
22134           MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
22135       };
22136 
22137       SequencedSocketData partitioned_data1(kPartitionedReads1,
22138                                             kPartitionedWrites1);
22139       SequencedSocketData partitioned_data2(kPartitionedReads2,
22140                                             kPartitionedWrites2);
22141 
22142       // No need to segment SSLDataProviders by whether or not partitioning is
22143       // enabled.
22144       SSLSocketDataProvider ssl_data1(ASYNC, OK);
22145       ssl_data1.next_proto = kProtoHTTP2;
22146       SSLSocketDataProvider ssl_data2(ASYNC, OK);
22147       ssl_data2.next_proto = kProtoHTTP2;
22148 
22149       if (partition_connections) {
22150         session_deps_.socket_factory->AddSocketDataProvider(&partitioned_data1);
22151         session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
22152         session_deps_.socket_factory->AddSocketDataProvider(&partitioned_data2);
22153         session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
22154       } else {
22155         session_deps_.socket_factory->AddSocketDataProvider(
22156             &unpartitioned_data);
22157         session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
22158       }
22159 
22160       TestCompletionCallback callback;
22161       HttpRequestInfo request1;
22162       request1.method = "GET";
22163       request1.url = GURL(url1);
22164       request1.traffic_annotation =
22165           net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22166       request1.network_isolation_key = network_isolation_key1;
22167       auto trans1 =
22168           std::make_unique<HttpNetworkTransaction>(LOWEST, session.get());
22169       int rv =
22170           trans1->Start(&request1, callback.callback(), NetLogWithSource());
22171       EXPECT_THAT(callback.GetResult(rv), IsOk());
22172       std::string response_data1;
22173       EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
22174       EXPECT_EQ("1", response_data1);
22175       trans1.reset();
22176 
22177       HttpRequestInfo request2;
22178       request2.method = "GET";
22179       request2.url = GURL(url2);
22180       request2.traffic_annotation =
22181           net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22182       request2.network_isolation_key = network_isolation_key2;
22183       auto trans2 =
22184           std::make_unique<HttpNetworkTransaction>(LOWEST, session.get());
22185       rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
22186       EXPECT_THAT(callback.GetResult(rv), IsOk());
22187       std::string response_data2;
22188       EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
22189       EXPECT_EQ("2", response_data2);
22190       trans2.reset();
22191 
22192       HttpRequestInfo request3;
22193       request3.method = "GET";
22194       request3.url = GURL(url3);
22195       request3.traffic_annotation =
22196           net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22197       request3.network_isolation_key = network_isolation_key1;
22198       auto trans3 =
22199           std::make_unique<HttpNetworkTransaction>(LOWEST, session.get());
22200       rv = trans3->Start(&request3, callback.callback(), NetLogWithSource());
22201       EXPECT_THAT(callback.GetResult(rv), IsOk());
22202       std::string response_data3;
22203       EXPECT_THAT(ReadTransaction(trans3.get(), &response_data3), IsOk());
22204       EXPECT_EQ("3", response_data3);
22205       trans3.reset();
22206     }
22207   }
22208 }
22209 
22210 // Preconnect two sockets with different NetworkIsolationKeys when
22211 // features::kPartitionConnectionsByNetworkIsolationKey is enabled. Then issue a
22212 // request and make sure the correct socket is used. Loops three times,
22213 // expecting to use the first preconnect, second preconnect, and neither.
TEST_F(HttpNetworkTransactionTest,NetworkIsolationPreconnect)22214 TEST_F(HttpNetworkTransactionTest, NetworkIsolationPreconnect) {
22215   base::test::ScopedFeatureList feature_list;
22216   feature_list.InitAndEnableFeature(
22217       features::kPartitionConnectionsByNetworkIsolationKey);
22218 
22219   enum class TestCase {
22220     kUseFirstPreconnect,
22221     kUseSecondPreconnect,
22222     kDontUsePreconnect,
22223   };
22224 
22225   const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
22226   const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
22227   const auto kOrigin3 = url::Origin::Create(GURL("http://origin3/"));
22228   NetworkIsolationKey preconnect1_isolation_key(kOrigin1, kOrigin1);
22229   NetworkIsolationKey preconnect2_isolation_key(kOrigin2, kOrigin2);
22230   NetworkIsolationKey not_preconnected_isolation_key(kOrigin3, kOrigin3);
22231 
22232   // Test that only preconnects with
22233   for (TestCase test_case :
22234        {TestCase::kUseFirstPreconnect, TestCase::kUseSecondPreconnect,
22235         TestCase::kDontUsePreconnect}) {
22236     SpdySessionDependencies session_deps;
22237     // Make DNS lookups completely synchronously, so preconnects complete
22238     // immediately.
22239     session_deps.host_resolver->set_synchronous_mode(true);
22240 
22241     const MockWrite kMockWrites[] = {
22242         MockWrite(ASYNC, 0,
22243                   "GET / HTTP/1.1\r\n"
22244                   "Host: www.foo.com\r\n"
22245                   "Connection: keep-alive\r\n\r\n"),
22246     };
22247 
22248     const MockRead kMockReads[] = {
22249         MockRead(ASYNC, 1,
22250                  "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"
22251                  "hello"),
22252     };
22253 
22254     // Used for the socket that will actually be used, which may or may not be
22255     // one of the preconnects
22256     SequencedSocketData used_socket_data(MockConnect(SYNCHRONOUS, OK),
22257                                          kMockReads, kMockWrites);
22258 
22259     // Used for the preconnects that won't actually be used.
22260     SequencedSocketData preconnect1_data(MockConnect(SYNCHRONOUS, OK),
22261                                          base::span<const MockRead>(),
22262                                          base::span<const MockWrite>());
22263     SequencedSocketData preconnect2_data(MockConnect(SYNCHRONOUS, OK),
22264                                          base::span<const MockRead>(),
22265                                          base::span<const MockWrite>());
22266 
22267     NetworkIsolationKey network_isolation_key_for_request;
22268 
22269     switch (test_case) {
22270       case TestCase::kUseFirstPreconnect:
22271         session_deps.socket_factory->AddSocketDataProvider(&used_socket_data);
22272         session_deps.socket_factory->AddSocketDataProvider(&preconnect2_data);
22273         network_isolation_key_for_request = preconnect1_isolation_key;
22274         break;
22275       case TestCase::kUseSecondPreconnect:
22276         session_deps.socket_factory->AddSocketDataProvider(&preconnect1_data);
22277         session_deps.socket_factory->AddSocketDataProvider(&used_socket_data);
22278         network_isolation_key_for_request = preconnect2_isolation_key;
22279         break;
22280       case TestCase::kDontUsePreconnect:
22281         session_deps.socket_factory->AddSocketDataProvider(&preconnect1_data);
22282         session_deps.socket_factory->AddSocketDataProvider(&preconnect2_data);
22283         session_deps.socket_factory->AddSocketDataProvider(&used_socket_data);
22284         network_isolation_key_for_request = not_preconnected_isolation_key;
22285         break;
22286     }
22287 
22288     std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps));
22289 
22290     // Preconnect sockets.
22291     HttpRequestInfo request;
22292     request.method = "GET";
22293     request.url = GURL("http://www.foo.com/");
22294     request.traffic_annotation =
22295         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22296 
22297     request.network_isolation_key = preconnect1_isolation_key;
22298     session->http_stream_factory()->PreconnectStreams(1, request);
22299 
22300     request.network_isolation_key = preconnect2_isolation_key;
22301     session->http_stream_factory()->PreconnectStreams(1, request);
22302 
22303     request.network_isolation_key = network_isolation_key_for_request;
22304 
22305     EXPECT_EQ(2, GetIdleSocketCountInTransportSocketPool(session.get()));
22306 
22307     // Make the request.
22308     TestCompletionCallback callback;
22309 
22310     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
22311 
22312     int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
22313     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22314 
22315     rv = callback.WaitForResult();
22316     EXPECT_THAT(rv, IsOk());
22317 
22318     const HttpResponseInfo* response = trans.GetResponseInfo();
22319     ASSERT_TRUE(response);
22320     ASSERT_TRUE(response->headers);
22321     EXPECT_EQ(200, response->headers->response_code());
22322 
22323     std::string response_data;
22324     rv = ReadTransaction(&trans, &response_data);
22325     EXPECT_THAT(rv, IsOk());
22326     EXPECT_EQ("hello", response_data);
22327 
22328     if (test_case != TestCase::kDontUsePreconnect) {
22329       EXPECT_EQ(2, GetIdleSocketCountInTransportSocketPool(session.get()));
22330     } else {
22331       EXPECT_EQ(3, GetIdleSocketCountInTransportSocketPool(session.get()));
22332     }
22333   }
22334 }
22335 
22336 // Test that the NetworkIsolationKey is passed down to SSLConfig so the session
22337 // cache is isolated.
TEST_F(HttpNetworkTransactionTest,NetworkIsolationSSL)22338 TEST_F(HttpNetworkTransactionTest, NetworkIsolationSSL) {
22339   base::test::ScopedFeatureList feature_list;
22340   feature_list.InitWithFeatures(
22341       {features::kPartitionConnectionsByNetworkIsolationKey,
22342        features::kPartitionSSLSessionsByNetworkIsolationKey},
22343       {});
22344 
22345   const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
22346   const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
22347   const NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
22348   const NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
22349   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22350 
22351   // The server always sends Connection: close, so each request goes over a
22352   // distinct socket.
22353 
22354   const MockWrite kWrites1[] = {
22355       MockWrite("GET /1 HTTP/1.1\r\n"
22356                 "Host: foo.test\r\n"
22357                 "Connection: keep-alive\r\n\r\n")};
22358 
22359   const MockRead kReads1[] = {
22360       MockRead("HTTP/1.1 200 OK\r\n"
22361                "Connection: close\r\n"
22362                "Content-Length: 1\r\n\r\n"
22363                "1")};
22364 
22365   const MockWrite kWrites2[] = {
22366       MockWrite("GET /2 HTTP/1.1\r\n"
22367                 "Host: foo.test\r\n"
22368                 "Connection: keep-alive\r\n\r\n")};
22369 
22370   const MockRead kReads2[] = {
22371       MockRead("HTTP/1.1 200 OK\r\n"
22372                "Connection: close\r\n"
22373                "Content-Length: 1\r\n\r\n"
22374                "2")};
22375 
22376   const MockWrite kWrites3[] = {
22377       MockWrite("GET /3 HTTP/1.1\r\n"
22378                 "Host: foo.test\r\n"
22379                 "Connection: keep-alive\r\n\r\n")};
22380 
22381   const MockRead kReads3[] = {
22382       MockRead("HTTP/1.1 200 OK\r\n"
22383                "Connection: close\r\n"
22384                "Content-Length: 1\r\n\r\n"
22385                "3")};
22386 
22387   StaticSocketDataProvider data1(kReads1, kWrites1);
22388   StaticSocketDataProvider data2(kReads2, kWrites2);
22389   StaticSocketDataProvider data3(kReads3, kWrites3);
22390   session_deps_.socket_factory->AddSocketDataProvider(&data1);
22391   session_deps_.socket_factory->AddSocketDataProvider(&data2);
22392   session_deps_.socket_factory->AddSocketDataProvider(&data3);
22393 
22394   SSLSocketDataProvider ssl_data1(ASYNC, OK);
22395   ssl_data1.expected_host_and_port = HostPortPair("foo.test", 443);
22396   ssl_data1.expected_network_isolation_key = kNetworkIsolationKey1;
22397   SSLSocketDataProvider ssl_data2(ASYNC, OK);
22398   ssl_data2.expected_host_and_port = HostPortPair("foo.test", 443);
22399   ssl_data2.expected_network_isolation_key = kNetworkIsolationKey2;
22400   SSLSocketDataProvider ssl_data3(ASYNC, OK);
22401   ssl_data3.expected_host_and_port = HostPortPair("foo.test", 443);
22402   ssl_data3.expected_network_isolation_key = kNetworkIsolationKey1;
22403   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
22404   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
22405   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
22406 
22407   TestCompletionCallback callback;
22408   HttpRequestInfo request1;
22409   request1.method = "GET";
22410   request1.url = GURL("https://foo.test/1");
22411   request1.traffic_annotation =
22412       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22413   request1.network_isolation_key = kNetworkIsolationKey1;
22414   auto trans1 =
22415       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22416   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
22417   EXPECT_THAT(callback.GetResult(rv), IsOk());
22418   std::string response_data1;
22419   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
22420   EXPECT_EQ("1", response_data1);
22421   trans1.reset();
22422 
22423   HttpRequestInfo request2;
22424   request2.method = "GET";
22425   request2.url = GURL("https://foo.test/2");
22426   request2.traffic_annotation =
22427       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22428   request2.network_isolation_key = kNetworkIsolationKey2;
22429   auto trans2 =
22430       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22431   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
22432   EXPECT_THAT(callback.GetResult(rv), IsOk());
22433   std::string response_data2;
22434   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
22435   EXPECT_EQ("2", response_data2);
22436   trans2.reset();
22437 
22438   HttpRequestInfo request3;
22439   request3.method = "GET";
22440   request3.url = GURL("https://foo.test/3");
22441   request3.traffic_annotation =
22442       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22443   request3.network_isolation_key = kNetworkIsolationKey1;
22444   auto trans3 =
22445       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22446   rv = trans3->Start(&request3, callback.callback(), NetLogWithSource());
22447   EXPECT_THAT(callback.GetResult(rv), IsOk());
22448   std::string response_data3;
22449   EXPECT_THAT(ReadTransaction(trans3.get(), &response_data3), IsOk());
22450   EXPECT_EQ("3", response_data3);
22451   trans3.reset();
22452 }
22453 
22454 // Test that the NetworkIsolationKey is passed down to SSLConfig so the session
22455 // cache is isolated, for both origins and proxies.
TEST_F(HttpNetworkTransactionTest,NetworkIsolationSSLProxy)22456 TEST_F(HttpNetworkTransactionTest, NetworkIsolationSSLProxy) {
22457   base::test::ScopedFeatureList feature_list;
22458   feature_list.InitWithFeatures(
22459       {features::kPartitionConnectionsByNetworkIsolationKey,
22460        features::kPartitionSSLSessionsByNetworkIsolationKey},
22461       {});
22462 
22463   session_deps_.proxy_resolution_service =
22464       ConfiguredProxyResolutionService::CreateFixed(
22465           "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
22466 
22467   const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
22468   const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
22469   const NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
22470   const NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
22471   std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22472 
22473   // Make both a tunneled and non-tunneled request.
22474   HttpRequestInfo request1;
22475   request1.method = "GET";
22476   request1.url = GURL("https://foo.test/1");
22477   request1.traffic_annotation =
22478       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22479   request1.network_isolation_key = kNetworkIsolationKey1;
22480 
22481   HttpRequestInfo request2;
22482   request2.method = "GET";
22483   request2.url = GURL("http://foo.test/2");
22484   request2.traffic_annotation =
22485       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22486   request2.network_isolation_key = kNetworkIsolationKey2;
22487 
22488   const MockWrite kWrites1[] = {
22489       MockWrite("CONNECT foo.test:443 HTTP/1.1\r\n"
22490                 "Host: foo.test:443\r\n"
22491                 "Proxy-Connection: keep-alive\r\n\r\n"),
22492       MockWrite("GET /1 HTTP/1.1\r\n"
22493                 "Host: foo.test\r\n"
22494                 "Connection: keep-alive\r\n\r\n")};
22495 
22496   const MockRead kReads1[] = {
22497       MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
22498       MockRead("HTTP/1.1 200 OK\r\n"
22499                "Connection: close\r\n"
22500                "Content-Length: 1\r\n\r\n"
22501                "1")};
22502 
22503   const MockWrite kWrites2[] = {
22504       MockWrite("GET http://foo.test/2 HTTP/1.1\r\n"
22505                 "Host: foo.test\r\n"
22506                 "Proxy-Connection: keep-alive\r\n\r\n")};
22507 
22508   const MockRead kReads2[] = {
22509       MockRead("HTTP/1.1 200 OK\r\n"
22510                "Connection: close\r\n"
22511                "Content-Length: 1\r\n\r\n"
22512                "2")};
22513 
22514   StaticSocketDataProvider data1(kReads1, kWrites1);
22515   StaticSocketDataProvider data2(kReads2, kWrites2);
22516   session_deps_.socket_factory->AddSocketDataProvider(&data1);
22517   session_deps_.socket_factory->AddSocketDataProvider(&data2);
22518   session_deps_.socket_factory->AddSocketDataProvider(&data2);
22519 
22520   SSLSocketDataProvider ssl_proxy1(ASYNC, OK);
22521   ssl_proxy1.expected_host_and_port = HostPortPair("myproxy", 70);
22522   ssl_proxy1.expected_network_isolation_key = kNetworkIsolationKey1;
22523   SSLSocketDataProvider ssl_origin1(ASYNC, OK);
22524   ssl_origin1.expected_host_and_port = HostPortPair("foo.test", 443);
22525   ssl_origin1.expected_network_isolation_key = kNetworkIsolationKey1;
22526   SSLSocketDataProvider ssl_proxy2(ASYNC, OK);
22527   ssl_proxy2.expected_host_and_port = HostPortPair("myproxy", 70);
22528   ssl_proxy2.expected_network_isolation_key = kNetworkIsolationKey2;
22529   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy1);
22530   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin1);
22531   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy2);
22532 
22533   TestCompletionCallback callback;
22534   auto trans1 =
22535       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22536   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
22537   EXPECT_THAT(callback.GetResult(rv), IsOk());
22538   std::string response_data1;
22539   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
22540   EXPECT_EQ("1", response_data1);
22541   trans1.reset();
22542 
22543   auto trans2 =
22544       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22545   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
22546   EXPECT_THAT(callback.GetResult(rv), IsOk());
22547   std::string response_data2;
22548   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
22549   EXPECT_EQ("2", response_data2);
22550   trans2.reset();
22551 }
22552 
22553 // Test that SSLConfig changes from SSLConfigService are picked up even when
22554 // there are live sockets.
TEST_F(HttpNetworkTransactionTest,SSLConfigChanged)22555 TEST_F(HttpNetworkTransactionTest, SSLConfigChanged) {
22556   SSLContextConfig ssl_context_config;
22557   ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
22558   auto ssl_config_service =
22559       std::make_unique<TestSSLConfigService>(ssl_context_config);
22560   TestSSLConfigService* ssl_config_service_raw = ssl_config_service.get();
22561 
22562   session_deps_.ssl_config_service = std::move(ssl_config_service);
22563 
22564   // Make three requests. Between the second and third, the SSL config will
22565   // change.
22566   HttpRequestInfo request1;
22567   request1.method = "GET";
22568   request1.url = GURL("https://foo.test/1");
22569   request1.traffic_annotation =
22570       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22571 
22572   HttpRequestInfo request2;
22573   request2.method = "GET";
22574   request2.url = GURL("https://foo.test/2");
22575   request2.traffic_annotation =
22576       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22577 
22578   HttpRequestInfo request3;
22579   request3.method = "GET";
22580   request3.url = GURL("https://foo.test/3");
22581   request3.traffic_annotation =
22582       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22583 
22584   const MockWrite kWrites1[] = {
22585       MockWrite("GET /1 HTTP/1.1\r\n"
22586                 "Host: foo.test\r\n"
22587                 "Connection: keep-alive\r\n\r\n"),
22588       MockWrite("GET /2 HTTP/1.1\r\n"
22589                 "Host: foo.test\r\n"
22590                 "Connection: keep-alive\r\n\r\n"),
22591   };
22592 
22593   const MockRead kReads1[] = {
22594       MockRead("HTTP/1.1 200 OK\r\n"
22595                "Connection: keep-alive\r\n"
22596                "Content-Length: 1\r\n\r\n"
22597                "1"),
22598       MockRead("HTTP/1.1 200 OK\r\n"
22599                "Connection: keep-alive\r\n"
22600                "Content-Length: 1\r\n\r\n"
22601                "2"),
22602   };
22603 
22604   // The third request goes on a different socket because the SSL config has
22605   // changed.
22606   const MockWrite kWrites2[] = {
22607       MockWrite("GET /3 HTTP/1.1\r\n"
22608                 "Host: foo.test\r\n"
22609                 "Connection: keep-alive\r\n\r\n")};
22610 
22611   const MockRead kReads2[] = {
22612       MockRead("HTTP/1.1 200 OK\r\n"
22613                "Connection: keep-alive\r\n"
22614                "Content-Length: 1\r\n\r\n"
22615                "3")};
22616 
22617   StaticSocketDataProvider data1(kReads1, kWrites1);
22618   StaticSocketDataProvider data2(kReads2, kWrites2);
22619   session_deps_.socket_factory->AddSocketDataProvider(&data1);
22620   session_deps_.socket_factory->AddSocketDataProvider(&data2);
22621 
22622   SSLSocketDataProvider ssl1(ASYNC, OK);
22623   ssl1.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_3;
22624   SSLSocketDataProvider ssl2(ASYNC, OK);
22625   ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
22626   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
22627   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
22628 
22629   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
22630 
22631   TestCompletionCallback callback;
22632   auto trans1 =
22633       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22634   int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
22635   EXPECT_THAT(callback.GetResult(rv), IsOk());
22636   std::string response_data1;
22637   EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
22638   EXPECT_EQ("1", response_data1);
22639   trans1.reset();
22640 
22641   auto trans2 =
22642       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22643   rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
22644   EXPECT_THAT(callback.GetResult(rv), IsOk());
22645   std::string response_data2;
22646   EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
22647   EXPECT_EQ("2", response_data2);
22648   trans2.reset();
22649 
22650   ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
22651   ssl_config_service_raw->UpdateSSLConfigAndNotify(ssl_context_config);
22652 
22653   auto trans3 =
22654       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22655   rv = trans3->Start(&request3, callback.callback(), NetLogWithSource());
22656   EXPECT_THAT(callback.GetResult(rv), IsOk());
22657   std::string response_data3;
22658   EXPECT_THAT(ReadTransaction(trans3.get(), &response_data3), IsOk());
22659   EXPECT_EQ("3", response_data3);
22660   trans3.reset();
22661 }
22662 
TEST_F(HttpNetworkTransactionTest,SSLConfigChangedPendingConnect)22663 TEST_F(HttpNetworkTransactionTest, SSLConfigChangedPendingConnect) {
22664   SSLContextConfig ssl_context_config;
22665   ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
22666   auto ssl_config_service =
22667       std::make_unique<TestSSLConfigService>(ssl_context_config);
22668   TestSSLConfigService* ssl_config_service_raw = ssl_config_service.get();
22669 
22670   session_deps_.ssl_config_service = std::move(ssl_config_service);
22671 
22672   HttpRequestInfo request;
22673   request.method = "GET";
22674   request.url = GURL("https://foo.test/1");
22675   request.traffic_annotation =
22676       net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
22677 
22678   // Make a socket which never connects.
22679   StaticSocketDataProvider data({}, {});
22680   session_deps_.socket_factory->AddSocketDataProvider(&data);
22681   SSLSocketDataProvider ssl_data(SYNCHRONOUS, ERR_IO_PENDING);
22682   ssl_data.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_3;
22683   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
22684 
22685   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
22686 
22687   TestCompletionCallback callback;
22688   auto trans =
22689       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22690   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
22691   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
22692 
22693   ssl_context_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
22694   ssl_config_service_raw->UpdateSSLConfigAndNotify(ssl_context_config);
22695 
22696   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NETWORK_CHANGED));
22697 }
22698 
22699 // Test that HttpNetworkTransaction correctly handles existing sockets when the
22700 // server requests a client certificate post-handshake (via a TLS
22701 // renegotiation). This is a regression test for https://crbug.com/829184.
TEST_F(HttpNetworkTransactionTest,PostHandshakeClientCertWithSockets)22702 TEST_F(HttpNetworkTransactionTest, PostHandshakeClientCertWithSockets) {
22703   const MutableNetworkTrafficAnnotationTag kTrafficAnnotation(
22704       TRAFFIC_ANNOTATION_FOR_TESTS);
22705 
22706   auto cert_request_info = base::MakeRefCounted<SSLCertRequestInfo>();
22707   cert_request_info->host_and_port = HostPortPair("foo.test", 443);
22708 
22709   std::unique_ptr<FakeClientCertIdentity> identity =
22710       FakeClientCertIdentity::CreateFromCertAndKeyFiles(
22711           GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
22712   ASSERT_TRUE(identity);
22713 
22714   // This test will make several requests so that, when the client certificate
22715   // request comes in, we have a socket in use, an idle socket, and a socket for
22716   // an unrelated host.
22717   //
22718   // First, two long-lived requests which do not complete until after the client
22719   // certificate request. This arranges for sockets to be in use during the
22720   // request. They should not be interrupted.
22721   HttpRequestInfo request_long_lived;
22722   request_long_lived.method = "GET";
22723   request_long_lived.url = GURL("https://foo.test/long-lived");
22724   request_long_lived.traffic_annotation = kTrafficAnnotation;
22725 
22726   HttpRequestInfo request_long_lived_bar;
22727   request_long_lived_bar.method = "GET";
22728   request_long_lived_bar.url = GURL("https://bar.test/long-lived");
22729   request_long_lived_bar.traffic_annotation = kTrafficAnnotation;
22730 
22731   // Next, make a request that needs client certificates.
22732   HttpRequestInfo request_auth;
22733   request_auth.method = "GET";
22734   request_auth.url = GURL("https://foo.test/auth");
22735   request_auth.traffic_annotation = kTrafficAnnotation;
22736 
22737   // Before responding to the challenge, make a request to an unauthenticated
22738   // endpoint. This will result in an idle socket when the client certificate
22739   // challenge is resolved.
22740   HttpRequestInfo request_unauth;
22741   request_unauth.method = "GET";
22742   request_unauth.url = GURL("https://foo.test/unauth");
22743   request_unauth.traffic_annotation = kTrafficAnnotation;
22744 
22745   // After all the preceding requests complete, end with two additional requests
22746   // to ensure pre-authentication foo.test sockets are not used and bar.test
22747   // sockets are unaffected.
22748   HttpRequestInfo request_post_auth;
22749   request_post_auth.method = "GET";
22750   request_post_auth.url = GURL("https://foo.test/post-auth");
22751   request_post_auth.traffic_annotation = kTrafficAnnotation;
22752 
22753   HttpRequestInfo request_post_auth_bar;
22754   request_post_auth_bar.method = "GET";
22755   request_post_auth_bar.url = GURL("https://bar.test/post-auth");
22756   request_post_auth_bar.traffic_annotation = kTrafficAnnotation;
22757 
22758   // The sockets for /long-lived and /unauth complete their request but are
22759   // not allocated for /post-auth or /retry because SSL state has since changed.
22760   const MockWrite kLongLivedWrites[] = {
22761       MockWrite(ASYNC, 0,
22762                 "GET /long-lived HTTP/1.1\r\n"
22763                 "Host: foo.test\r\n"
22764                 "Connection: keep-alive\r\n\r\n"),
22765   };
22766   const MockRead kLongLivedReads[] = {
22767       // Pause so /long-lived completes after the client presents client
22768       // certificates.
22769       MockRead(ASYNC, ERR_IO_PENDING, 1),
22770       MockRead(ASYNC, 2,
22771                "HTTP/1.1 200 OK\r\n"
22772                "Connection: keep-alive\r\n"
22773                "Content-Length: 10\r\n\r\n"
22774                "long-lived"),
22775   };
22776   SequencedSocketData data_long_lived(kLongLivedReads, kLongLivedWrites);
22777   SSLSocketDataProvider ssl_long_lived(ASYNC, OK);
22778   session_deps_.socket_factory->AddSocketDataProvider(&data_long_lived);
22779   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_long_lived);
22780 
22781   // Requests for bar.test should be unaffected by foo.test and get allocated
22782   // a single socket.
22783   const MockWrite kBarWrites[] = {
22784       MockWrite(ASYNC, 0,
22785                 "GET /long-lived HTTP/1.1\r\n"
22786                 "Host: bar.test\r\n"
22787                 "Connection: keep-alive\r\n\r\n"),
22788       MockWrite(ASYNC, 3,
22789                 "GET /post-auth HTTP/1.1\r\n"
22790                 "Host: bar.test\r\n"
22791                 "Connection: keep-alive\r\n\r\n"),
22792   };
22793   const MockRead kBarReads[] = {
22794       // Pause on /long-lived so it completes after foo.test's authentication.
22795       MockRead(ASYNC, ERR_IO_PENDING, 1),
22796       MockRead(ASYNC, 2,
22797                "HTTP/1.1 200 OK\r\n"
22798                "Connection: keep-alive\r\n"
22799                "Content-Length: 10\r\n\r\n"
22800                "long-lived"),
22801       MockRead(ASYNC, 4,
22802                "HTTP/1.1 200 OK\r\n"
22803                "Connection: keep-alive\r\n"
22804                "Content-Length: 9\r\n\r\n"
22805                "post-auth"),
22806   };
22807   SequencedSocketData data_bar(kBarReads, kBarWrites);
22808   SSLSocketDataProvider ssl_bar(ASYNC, OK);
22809   session_deps_.socket_factory->AddSocketDataProvider(&data_bar);
22810   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bar);
22811 
22812   // Requesting /auth results in a post-handshake client certificate challenge.
22813   const MockWrite kAuthWrites[] = {
22814       MockWrite(ASYNC, 0,
22815                 "GET /auth HTTP/1.1\r\n"
22816                 "Host: foo.test\r\n"
22817                 "Connection: keep-alive\r\n\r\n"),
22818   };
22819   const MockRead kAuthReads[] = {
22820       MockRead(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED, 1),
22821   };
22822   SequencedSocketData data_auth(kAuthReads, kAuthWrites);
22823   SSLSocketDataProvider ssl_auth(ASYNC, OK);
22824   ssl_auth.cert_request_info = cert_request_info.get();
22825   session_deps_.socket_factory->AddSocketDataProvider(&data_auth);
22826   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_auth);
22827 
22828   // Requesting /unauth completes.
22829   const MockWrite kUnauthWrites[] = {
22830       MockWrite(ASYNC, 0,
22831                 "GET /unauth HTTP/1.1\r\n"
22832                 "Host: foo.test\r\n"
22833                 "Connection: keep-alive\r\n\r\n"),
22834   };
22835   const MockRead kUnauthReads[] = {
22836       MockRead(ASYNC, 1,
22837                "HTTP/1.1 200 OK\r\n"
22838                "Connection: keep-alive\r\n"
22839                "Content-Length: 6\r\n\r\n"
22840                "unauth"),
22841   };
22842   SequencedSocketData data_unauth(kUnauthReads, kUnauthWrites);
22843   SSLSocketDataProvider ssl_unauth(ASYNC, OK);
22844   session_deps_.socket_factory->AddSocketDataProvider(&data_unauth);
22845   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_unauth);
22846 
22847   // When the client certificate is selected, /auth is retried on a new
22848   // connection. In particular, it should not be retried on |data_unauth|,
22849   // which would not honor the new client certificate configuration.
22850   const MockWrite kRetryWrites[] = {
22851       MockWrite(ASYNC, 0,
22852                 "GET /auth HTTP/1.1\r\n"
22853                 "Host: foo.test\r\n"
22854                 "Connection: keep-alive\r\n\r\n"),
22855   };
22856   const MockRead kRetryReads[] = {
22857       MockRead(ASYNC, 1,
22858                "HTTP/1.1 200 OK\r\n"
22859                // Close the connection so we test that /post-auth is not
22860                // allocated to |data_unauth| or |data_long_lived|.
22861                "Connection: close\r\n"
22862                "Content-Length: 4\r\n\r\n"
22863                "auth"),
22864   };
22865   SequencedSocketData data_retry(kRetryReads, kRetryWrites);
22866   SSLSocketDataProvider ssl_retry(ASYNC, OK);
22867   ssl_retry.expected_send_client_cert = true;
22868   ssl_retry.expected_client_cert = identity->certificate();
22869   session_deps_.socket_factory->AddSocketDataProvider(&data_retry);
22870   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_retry);
22871 
22872   // /post-auth gets its own socket.
22873   const MockWrite kPostAuthWrites[] = {
22874       MockWrite(ASYNC, 0,
22875                 "GET /post-auth HTTP/1.1\r\n"
22876                 "Host: foo.test\r\n"
22877                 "Connection: keep-alive\r\n\r\n"),
22878   };
22879   const MockRead kPostAuthReads[] = {
22880       MockRead(ASYNC, 1,
22881                "HTTP/1.1 200 OK\r\n"
22882                "Connection: keep-alive\r\n"
22883                "Content-Length: 9\r\n\r\n"
22884                "post-auth"),
22885   };
22886   SequencedSocketData data_post_auth(kPostAuthReads, kPostAuthWrites);
22887   SSLSocketDataProvider ssl_post_auth(ASYNC, OK);
22888   ssl_post_auth.expected_send_client_cert = true;
22889   ssl_post_auth.expected_client_cert = identity->certificate();
22890   session_deps_.socket_factory->AddSocketDataProvider(&data_post_auth);
22891   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_post_auth);
22892 
22893   std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
22894 
22895   // Start the two long-lived requests.
22896   TestCompletionCallback callback_long_lived;
22897   auto trans_long_lived =
22898       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22899   int rv = trans_long_lived->Start(
22900       &request_long_lived, callback_long_lived.callback(), NetLogWithSource());
22901   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
22902   data_long_lived.RunUntilPaused();
22903 
22904   TestCompletionCallback callback_long_lived_bar;
22905   auto trans_long_lived_bar =
22906       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22907   rv = trans_long_lived_bar->Start(&request_long_lived_bar,
22908                                    callback_long_lived_bar.callback(),
22909                                    NetLogWithSource());
22910   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
22911   data_bar.RunUntilPaused();
22912 
22913   // Request /auth. This gives a client certificate challenge.
22914   TestCompletionCallback callback_auth;
22915   auto trans_auth =
22916       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22917   rv = trans_auth->Start(&request_auth, callback_auth.callback(),
22918                          NetLogWithSource());
22919   EXPECT_THAT(callback_auth.GetResult(rv),
22920               IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
22921 
22922   // Make an unauthenticated request. This completes.
22923   TestCompletionCallback callback_unauth;
22924   auto trans_unauth =
22925       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22926   rv = trans_unauth->Start(&request_unauth, callback_unauth.callback(),
22927                            NetLogWithSource());
22928   EXPECT_THAT(callback_unauth.GetResult(rv), IsOk());
22929   std::string response_unauth;
22930   EXPECT_THAT(ReadTransaction(trans_unauth.get(), &response_unauth), IsOk());
22931   EXPECT_EQ("unauth", response_unauth);
22932   trans_unauth.reset();
22933 
22934   // Complete the authenticated request.
22935   rv = trans_auth->RestartWithCertificate(identity->certificate(),
22936                                           identity->ssl_private_key(),
22937                                           callback_auth.callback());
22938   EXPECT_THAT(callback_auth.GetResult(rv), IsOk());
22939   std::string response_auth;
22940   EXPECT_THAT(ReadTransaction(trans_auth.get(), &response_auth), IsOk());
22941   EXPECT_EQ("auth", response_auth);
22942   trans_auth.reset();
22943 
22944   // Complete the long-lived requests.
22945   data_long_lived.Resume();
22946   EXPECT_THAT(callback_long_lived.GetResult(ERR_IO_PENDING), IsOk());
22947   std::string response_long_lived;
22948   EXPECT_THAT(ReadTransaction(trans_long_lived.get(), &response_long_lived),
22949               IsOk());
22950   EXPECT_EQ("long-lived", response_long_lived);
22951   trans_long_lived.reset();
22952 
22953   data_bar.Resume();
22954   EXPECT_THAT(callback_long_lived_bar.GetResult(ERR_IO_PENDING), IsOk());
22955   std::string response_long_lived_bar;
22956   EXPECT_THAT(
22957       ReadTransaction(trans_long_lived_bar.get(), &response_long_lived_bar),
22958       IsOk());
22959   EXPECT_EQ("long-lived", response_long_lived_bar);
22960   trans_long_lived_bar.reset();
22961 
22962   // Run the post-authentication requests.
22963   TestCompletionCallback callback_post_auth;
22964   auto trans_post_auth =
22965       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22966   rv = trans_post_auth->Start(&request_post_auth, callback_post_auth.callback(),
22967                               NetLogWithSource());
22968   EXPECT_THAT(callback_post_auth.GetResult(rv), IsOk());
22969   std::string response_post_auth;
22970   EXPECT_THAT(ReadTransaction(trans_post_auth.get(), &response_post_auth),
22971               IsOk());
22972   EXPECT_EQ("post-auth", response_post_auth);
22973   trans_post_auth.reset();
22974 
22975   TestCompletionCallback callback_post_auth_bar;
22976   auto trans_post_auth_bar =
22977       std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
22978   rv = trans_post_auth_bar->Start(&request_post_auth_bar,
22979                                   callback_post_auth_bar.callback(),
22980                                   NetLogWithSource());
22981   EXPECT_THAT(callback_post_auth_bar.GetResult(rv), IsOk());
22982   std::string response_post_auth_bar;
22983   EXPECT_THAT(
22984       ReadTransaction(trans_post_auth_bar.get(), &response_post_auth_bar),
22985       IsOk());
22986   EXPECT_EQ("post-auth", response_post_auth_bar);
22987   trans_post_auth_bar.reset();
22988 }
22989 
22990 }  // namespace net
22991