Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / http / http_network_transaction_unittest.cc
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 <string>
10 #include <vector>
11
12 #include "base/basictypes.h"
13 #include "base/compiler_specific.h"
14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
16 #include "base/json/json_writer.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/run_loop.h"
20 #include "base/strings/string_util.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "base/test/test_file_util.h"
23 #include "net/base/auth.h"
24 #include "net/base/capturing_net_log.h"
25 #include "net/base/chunked_upload_data_stream.h"
26 #include "net/base/completion_callback.h"
27 #include "net/base/elements_upload_data_stream.h"
28 #include "net/base/load_timing_info.h"
29 #include "net/base/load_timing_info_test_util.h"
30 #include "net/base/net_log.h"
31 #include "net/base/net_log_unittest.h"
32 #include "net/base/request_priority.h"
33 #include "net/base/test_completion_callback.h"
34 #include "net/base/test_data_directory.h"
35 #include "net/base/upload_bytes_element_reader.h"
36 #include "net/base/upload_file_element_reader.h"
37 #include "net/cert/mock_cert_verifier.h"
38 #include "net/dns/host_cache.h"
39 #include "net/dns/mock_host_resolver.h"
40 #include "net/http/http_auth_challenge_tokenizer.h"
41 #include "net/http/http_auth_handler_digest.h"
42 #include "net/http/http_auth_handler_mock.h"
43 #include "net/http/http_auth_handler_ntlm.h"
44 #include "net/http/http_basic_stream.h"
45 #include "net/http/http_network_session.h"
46 #include "net/http/http_network_session_peer.h"
47 #include "net/http/http_server_properties_impl.h"
48 #include "net/http/http_stream.h"
49 #include "net/http/http_stream_factory.h"
50 #include "net/http/http_transaction_test_util.h"
51 #include "net/proxy/proxy_config_service_fixed.h"
52 #include "net/proxy/proxy_info.h"
53 #include "net/proxy/proxy_resolver.h"
54 #include "net/proxy/proxy_service.h"
55 #include "net/socket/client_socket_factory.h"
56 #include "net/socket/client_socket_pool_manager.h"
57 #include "net/socket/mock_client_socket_pool_manager.h"
58 #include "net/socket/next_proto.h"
59 #include "net/socket/socket_test_util.h"
60 #include "net/socket/ssl_client_socket.h"
61 #include "net/spdy/spdy_framer.h"
62 #include "net/spdy/spdy_session.h"
63 #include "net/spdy/spdy_session_pool.h"
64 #include "net/spdy/spdy_test_util_common.h"
65 #include "net/ssl/ssl_cert_request_info.h"
66 #include "net/ssl/ssl_config_service.h"
67 #include "net/ssl/ssl_config_service_defaults.h"
68 #include "net/ssl/ssl_info.h"
69 #include "net/test/cert_test_util.h"
70 #include "net/websockets/websocket_handshake_stream_base.h"
71 #include "testing/gtest/include/gtest/gtest.h"
72 #include "testing/platform_test.h"
73 #include "url/gurl.h"
74
75 using base::ASCIIToUTF16;
76
77 //-----------------------------------------------------------------------------
78
79 namespace {
80
81 const base::string16 kBar(ASCIIToUTF16("bar"));
82 const base::string16 kBar2(ASCIIToUTF16("bar2"));
83 const base::string16 kBar3(ASCIIToUTF16("bar3"));
84 const base::string16 kBaz(ASCIIToUTF16("baz"));
85 const base::string16 kFirst(ASCIIToUTF16("first"));
86 const base::string16 kFoo(ASCIIToUTF16("foo"));
87 const base::string16 kFoo2(ASCIIToUTF16("foo2"));
88 const base::string16 kFoo3(ASCIIToUTF16("foo3"));
89 const base::string16 kFou(ASCIIToUTF16("fou"));
90 const base::string16 kSecond(ASCIIToUTF16("second"));
91 const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
92 const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
93
94 int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
95   return session->GetTransportSocketPool(
96       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
97 }
98
99 int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
100   return session->GetSSLSocketPool(
101       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
102 }
103
104 bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
105   return session->GetTransportSocketPool(
106       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
107 }
108
109 // Takes in a Value created from a NetLogHttpResponseParameter, and returns
110 // a JSONified list of headers as a single string.  Uses single quotes instead
111 // of double quotes for easier comparison.  Returns false on failure.
112 bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
113   if (!params)
114     return false;
115   base::ListValue* header_list;
116   if (!params->GetList("headers", &header_list))
117     return false;
118   std::string double_quote_headers;
119   base::JSONWriter::Write(header_list, &double_quote_headers);
120   base::ReplaceChars(double_quote_headers, "\"", "'", headers);
121   return true;
122 }
123
124 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is
125 // used.
126 void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
127   EXPECT_TRUE(load_timing_info.socket_reused);
128   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
129
130   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
131   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
132
133   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
134   EXPECT_FALSE(load_timing_info.send_start.is_null());
135
136   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
137
138   // Set at a higher level.
139   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
140   EXPECT_TRUE(load_timing_info.request_start.is_null());
141   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
142 }
143
144 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is
145 // used.
146 void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
147                              int connect_timing_flags) {
148   EXPECT_FALSE(load_timing_info.socket_reused);
149   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
150
151   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
152   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
153
154   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
155                                    connect_timing_flags);
156   EXPECT_LE(load_timing_info.connect_timing.connect_end,
157             load_timing_info.send_start);
158
159   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
160
161   // Set at a higher level.
162   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
163   EXPECT_TRUE(load_timing_info.request_start.is_null());
164   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
165 }
166
167 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is
168 // used.
169 void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
170   EXPECT_TRUE(load_timing_info.socket_reused);
171   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
172
173   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
174
175   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
176   EXPECT_LE(load_timing_info.proxy_resolve_start,
177             load_timing_info.proxy_resolve_end);
178   EXPECT_LE(load_timing_info.proxy_resolve_end,
179             load_timing_info.send_start);
180   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
181
182   // Set at a higher level.
183   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
184   EXPECT_TRUE(load_timing_info.request_start.is_null());
185   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
186 }
187
188 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is
189 // used.
190 void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
191                                     int connect_timing_flags) {
192   EXPECT_FALSE(load_timing_info.socket_reused);
193   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
194
195   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
196   EXPECT_LE(load_timing_info.proxy_resolve_start,
197             load_timing_info.proxy_resolve_end);
198   EXPECT_LE(load_timing_info.proxy_resolve_end,
199             load_timing_info.connect_timing.connect_start);
200   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
201                                    connect_timing_flags);
202   EXPECT_LE(load_timing_info.connect_timing.connect_end,
203             load_timing_info.send_start);
204
205   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
206
207   // Set at a higher level.
208   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
209   EXPECT_TRUE(load_timing_info.request_start.is_null());
210   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
211 }
212
213 }  // namespace
214
215 namespace net {
216
217 namespace {
218
219 HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
220   return SpdySessionDependencies::SpdyCreateSession(session_deps);
221 }
222
223 }  // namespace
224
225 class HttpNetworkTransactionTest
226     : public PlatformTest,
227       public ::testing::WithParamInterface<NextProto> {
228  public:
229   virtual ~HttpNetworkTransactionTest() {
230     // Important to restore the per-pool limit first, since the pool limit must
231     // always be greater than group limit, and the tests reduce both limits.
232     ClientSocketPoolManager::set_max_sockets_per_pool(
233         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
234     ClientSocketPoolManager::set_max_sockets_per_group(
235         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
236   }
237
238  protected:
239   HttpNetworkTransactionTest()
240       : spdy_util_(GetParam()),
241         session_deps_(GetParam()),
242         old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
243             HttpNetworkSession::NORMAL_SOCKET_POOL)),
244         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
245             HttpNetworkSession::NORMAL_SOCKET_POOL)) {
246   }
247
248   struct SimpleGetHelperResult {
249     int rv;
250     std::string status_line;
251     std::string response_data;
252     int64 totalReceivedBytes;
253     LoadTimingInfo load_timing_info;
254   };
255
256   void SetUp() override {
257     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
258     base::MessageLoop::current()->RunUntilIdle();
259   }
260
261   void TearDown() override {
262     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
263     base::MessageLoop::current()->RunUntilIdle();
264     // Empty the current queue.
265     base::MessageLoop::current()->RunUntilIdle();
266     PlatformTest::TearDown();
267     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
268     base::MessageLoop::current()->RunUntilIdle();
269   }
270
271   // This is the expected return from a current server advertising SPDY.
272   std::string GetAlternateProtocolHttpHeader() {
273     return
274         std::string("Alternate-Protocol: 443:") +
275         AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
276         "\r\n\r\n";
277   }
278
279   // Either |write_failure| specifies a write failure or |read_failure|
280   // specifies a read failure when using a reused socket.  In either case, the
281   // failure should cause the network transaction to resend the request, and the
282   // other argument should be NULL.
283   void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
284                                             const MockRead* read_failure);
285
286   // Either |write_failure| specifies a write failure or |read_failure|
287   // specifies a read failure when using a reused socket.  In either case, the
288   // failure should cause the network transaction to resend the request, and the
289   // other argument should be NULL.
290   void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
291                                         const MockRead* read_failure,
292                                         bool use_spdy);
293
294   SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
295                                                size_t data_count) {
296     SimpleGetHelperResult out;
297
298     HttpRequestInfo request;
299     request.method = "GET";
300     request.url = GURL("http://www.google.com/");
301     request.load_flags = 0;
302
303     CapturingBoundNetLog log;
304     session_deps_.net_log = log.bound().net_log();
305     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
306     scoped_ptr<HttpTransaction> trans(
307         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
308
309     for (size_t i = 0; i < data_count; ++i) {
310       session_deps_.socket_factory->AddSocketDataProvider(data[i]);
311     }
312
313     TestCompletionCallback callback;
314
315     EXPECT_TRUE(log.bound().IsLogging());
316     int rv = trans->Start(&request, callback.callback(), log.bound());
317     EXPECT_EQ(ERR_IO_PENDING, rv);
318
319     out.rv = callback.WaitForResult();
320
321     // Even in the failure cases that use this function, connections are always
322     // successfully established before the error.
323     EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
324     TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
325
326     if (out.rv != OK)
327       return out;
328
329     const HttpResponseInfo* response = trans->GetResponseInfo();
330     // Can't use ASSERT_* inside helper functions like this, so
331     // return an error.
332     if (response == NULL || response->headers.get() == NULL) {
333       out.rv = ERR_UNEXPECTED;
334       return out;
335     }
336     out.status_line = response->headers->GetStatusLine();
337
338     EXPECT_EQ("127.0.0.1", response->socket_address.host());
339     EXPECT_EQ(80, response->socket_address.port());
340
341     rv = ReadTransaction(trans.get(), &out.response_data);
342     EXPECT_EQ(OK, rv);
343
344     net::CapturingNetLog::CapturedEntryList entries;
345     log.GetEntries(&entries);
346     size_t pos = ExpectLogContainsSomewhere(
347         entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
348         NetLog::PHASE_NONE);
349     ExpectLogContainsSomewhere(
350         entries, pos,
351         NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
352         NetLog::PHASE_NONE);
353
354     std::string line;
355     EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
356     EXPECT_EQ("GET / HTTP/1.1\r\n", line);
357
358     HttpRequestHeaders request_headers;
359     EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
360     std::string value;
361     EXPECT_TRUE(request_headers.GetHeader("Host", &value));
362     EXPECT_EQ("www.google.com", value);
363     EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
364     EXPECT_EQ("keep-alive", value);
365
366     std::string response_headers;
367     EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
368     EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
369               response_headers);
370
371     out.totalReceivedBytes = trans->GetTotalReceivedBytes();
372     return out;
373   }
374
375   SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
376                                         size_t reads_count) {
377     StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
378     StaticSocketDataProvider* data[] = { &reads };
379     return SimpleGetHelperForData(data, 1);
380   }
381
382   int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
383     int64 size = 0;
384     for (size_t i = 0; i < reads_count; ++i)
385       size += data_reads[i].data_len;
386     return size;
387   }
388
389   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
390                                              int expected_status);
391
392   void ConnectStatusHelper(const MockRead& status);
393
394   void BypassHostCacheOnRefreshHelper(int load_flags);
395
396   void CheckErrorIsPassedBack(int error, IoMode mode);
397
398   SpdyTestUtil spdy_util_;
399   SpdySessionDependencies session_deps_;
400
401   // Original socket limits.  Some tests set these.  Safest to always restore
402   // them once each test has been run.
403   int old_max_group_sockets_;
404   int old_max_pool_sockets_;
405 };
406
407 INSTANTIATE_TEST_CASE_P(
408     NextProto,
409     HttpNetworkTransactionTest,
410     testing::Values(kProtoDeprecatedSPDY2,
411                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
412
413 namespace {
414
415 class BeforeNetworkStartHandler {
416  public:
417   explicit BeforeNetworkStartHandler(bool defer)
418       : defer_on_before_network_start_(defer),
419         observed_before_network_start_(false) {}
420
421   void OnBeforeNetworkStart(bool* defer) {
422     *defer = defer_on_before_network_start_;
423     observed_before_network_start_ = true;
424   }
425
426   bool observed_before_network_start() const {
427     return observed_before_network_start_;
428   }
429
430  private:
431   const bool defer_on_before_network_start_;
432   bool observed_before_network_start_;
433
434   DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
435 };
436
437 class BeforeProxyHeadersSentHandler {
438  public:
439   BeforeProxyHeadersSentHandler()
440       : observed_before_proxy_headers_sent_(false) {}
441
442   void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
443                                 HttpRequestHeaders* request_headers) {
444     observed_before_proxy_headers_sent_ = true;
445     observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
446   }
447
448   bool observed_before_proxy_headers_sent() const {
449     return observed_before_proxy_headers_sent_;
450   }
451
452   std::string observed_proxy_server_uri() const {
453     return observed_proxy_server_uri_;
454   }
455
456  private:
457   bool observed_before_proxy_headers_sent_;
458   std::string observed_proxy_server_uri_;
459
460   DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
461 };
462
463 // Fill |str| with a long header list that consumes >= |size| bytes.
464 void FillLargeHeadersString(std::string* str, int size) {
465   const char* row =
466       "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
467   const int sizeof_row = strlen(row);
468   const int num_rows = static_cast<int>(
469       ceil(static_cast<float>(size) / sizeof_row));
470   const int sizeof_data = num_rows * sizeof_row;
471   DCHECK(sizeof_data >= size);
472   str->reserve(sizeof_data);
473
474   for (int i = 0; i < num_rows; ++i)
475     str->append(row, sizeof_row);
476 }
477
478 // Alternative functions that eliminate randomness and dependency on the local
479 // host name so that the generated NTLM messages are reproducible.
480 void MockGenerateRandom1(uint8* output, size_t n) {
481   static const uint8 bytes[] = {
482     0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
483   };
484   static size_t current_byte = 0;
485   for (size_t i = 0; i < n; ++i) {
486     output[i] = bytes[current_byte++];
487     current_byte %= arraysize(bytes);
488   }
489 }
490
491 void MockGenerateRandom2(uint8* output, size_t n) {
492   static const uint8 bytes[] = {
493     0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
494     0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
495   };
496   static size_t current_byte = 0;
497   for (size_t i = 0; i < n; ++i) {
498     output[i] = bytes[current_byte++];
499     current_byte %= arraysize(bytes);
500   }
501 }
502
503 std::string MockGetHostName() {
504   return "WTC-WIN7";
505 }
506
507 template<typename ParentPool>
508 class CaptureGroupNameSocketPool : public ParentPool {
509  public:
510   CaptureGroupNameSocketPool(HostResolver* host_resolver,
511                              CertVerifier* cert_verifier);
512
513   const std::string last_group_name_received() const {
514     return last_group_name_;
515   }
516
517   virtual int RequestSocket(const std::string& group_name,
518                             const void* socket_params,
519                             RequestPriority priority,
520                             ClientSocketHandle* handle,
521                             const CompletionCallback& callback,
522                             const BoundNetLog& net_log) {
523     last_group_name_ = group_name;
524     return ERR_IO_PENDING;
525   }
526   virtual void CancelRequest(const std::string& group_name,
527                              ClientSocketHandle* handle) {}
528   virtual void ReleaseSocket(const std::string& group_name,
529                              scoped_ptr<StreamSocket> socket,
530                              int id) {}
531   virtual void CloseIdleSockets() {}
532   virtual int IdleSocketCount() const {
533     return 0;
534   }
535   virtual int IdleSocketCountInGroup(const std::string& group_name) const {
536     return 0;
537   }
538   virtual LoadState GetLoadState(const std::string& group_name,
539                                  const ClientSocketHandle* handle) const {
540     return LOAD_STATE_IDLE;
541   }
542   virtual base::TimeDelta ConnectionTimeout() const {
543     return base::TimeDelta();
544   }
545
546  private:
547   std::string last_group_name_;
548 };
549
550 typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
551 CaptureGroupNameTransportSocketPool;
552 typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
553 CaptureGroupNameHttpProxySocketPool;
554 typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
555 CaptureGroupNameSOCKSSocketPool;
556 typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
557 CaptureGroupNameSSLSocketPool;
558
559 template<typename ParentPool>
560 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
561     HostResolver* host_resolver,
562     CertVerifier* /* cert_verifier */)
563     : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
564
565 template<>
566 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
567     HostResolver* host_resolver,
568     CertVerifier* /* cert_verifier */)
569     : HttpProxyClientSocketPool(
570           0, 0, NULL, host_resolver, NULL, NULL, NULL, NULL) {}
571
572 template <>
573 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
574     HostResolver* host_resolver,
575     CertVerifier* cert_verifier)
576     : SSLClientSocketPool(0,
577                           0,
578                           NULL,
579                           host_resolver,
580                           cert_verifier,
581                           NULL,
582                           NULL,
583                           NULL,
584                           std::string(),
585                           NULL,
586                           NULL,
587                           NULL,
588                           NULL,
589                           NULL,
590                           false,
591                           NULL) {
592 }
593
594 //-----------------------------------------------------------------------------
595
596 // Helper functions for validating that AuthChallengeInfo's are correctly
597 // configured for common cases.
598 bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
599   if (!auth_challenge)
600     return false;
601   EXPECT_FALSE(auth_challenge->is_proxy);
602   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
603   EXPECT_EQ("MyRealm1", auth_challenge->realm);
604   EXPECT_EQ("basic", auth_challenge->scheme);
605   return true;
606 }
607
608 bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
609   if (!auth_challenge)
610     return false;
611   EXPECT_TRUE(auth_challenge->is_proxy);
612   EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
613   EXPECT_EQ("MyRealm1", auth_challenge->realm);
614   EXPECT_EQ("basic", auth_challenge->scheme);
615   return true;
616 }
617
618 bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
619   if (!auth_challenge)
620     return false;
621   EXPECT_FALSE(auth_challenge->is_proxy);
622   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
623   EXPECT_EQ("digestive", auth_challenge->realm);
624   EXPECT_EQ("digest", auth_challenge->scheme);
625   return true;
626 }
627
628 bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
629   if (!auth_challenge)
630     return false;
631   EXPECT_FALSE(auth_challenge->is_proxy);
632   EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
633   EXPECT_EQ(std::string(), auth_challenge->realm);
634   EXPECT_EQ("ntlm", auth_challenge->scheme);
635   return true;
636 }
637
638 }  // namespace
639
640 TEST_P(HttpNetworkTransactionTest, Basic) {
641   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
642   scoped_ptr<HttpTransaction> trans(
643       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
644 }
645
646 TEST_P(HttpNetworkTransactionTest, SimpleGET) {
647   MockRead data_reads[] = {
648     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
649     MockRead("hello world"),
650     MockRead(SYNCHRONOUS, OK),
651   };
652   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
653                                               arraysize(data_reads));
654   EXPECT_EQ(OK, out.rv);
655   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
656   EXPECT_EQ("hello world", out.response_data);
657   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
658   EXPECT_EQ(reads_size, out.totalReceivedBytes);
659 }
660
661 // Response with no status line.
662 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
663   MockRead data_reads[] = {
664     MockRead("hello world"),
665     MockRead(SYNCHRONOUS, OK),
666   };
667   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
668                                               arraysize(data_reads));
669   EXPECT_EQ(OK, out.rv);
670   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
671   EXPECT_EQ("hello world", out.response_data);
672   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
673   EXPECT_EQ(reads_size, out.totalReceivedBytes);
674 }
675
676 // Allow up to 4 bytes of junk to precede status line.
677 TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
678   MockRead data_reads[] = {
679     MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
680     MockRead(SYNCHRONOUS, OK),
681   };
682   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
683                                               arraysize(data_reads));
684   EXPECT_EQ(OK, out.rv);
685   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
686   EXPECT_EQ("DATA", out.response_data);
687   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
688   EXPECT_EQ(reads_size, out.totalReceivedBytes);
689 }
690
691 // Allow up to 4 bytes of junk to precede status line.
692 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
693   MockRead data_reads[] = {
694     MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
695     MockRead(SYNCHRONOUS, OK),
696   };
697   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
698                                               arraysize(data_reads));
699   EXPECT_EQ(OK, out.rv);
700   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
701   EXPECT_EQ("DATA", out.response_data);
702   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
703   EXPECT_EQ(reads_size, out.totalReceivedBytes);
704 }
705
706 // Beyond 4 bytes of slop and it should fail to find a status line.
707 TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
708   MockRead data_reads[] = {
709     MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
710     MockRead(SYNCHRONOUS, OK),
711   };
712   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
713                                               arraysize(data_reads));
714   EXPECT_EQ(OK, out.rv);
715   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
716   EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
717   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
718   EXPECT_EQ(reads_size, out.totalReceivedBytes);
719 }
720
721 // Same as StatusLineJunk4Bytes, except the read chunks are smaller.
722 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
723   MockRead data_reads[] = {
724     MockRead("\n"),
725     MockRead("\n"),
726     MockRead("Q"),
727     MockRead("J"),
728     MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
729     MockRead(SYNCHRONOUS, OK),
730   };
731   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
732                                               arraysize(data_reads));
733   EXPECT_EQ(OK, out.rv);
734   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
735   EXPECT_EQ("DATA", out.response_data);
736   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
737   EXPECT_EQ(reads_size, out.totalReceivedBytes);
738 }
739
740 // Close the connection before enough bytes to have a status line.
741 TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
742   MockRead data_reads[] = {
743     MockRead("HTT"),
744     MockRead(SYNCHRONOUS, OK),
745   };
746   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
747                                               arraysize(data_reads));
748   EXPECT_EQ(OK, out.rv);
749   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
750   EXPECT_EQ("HTT", out.response_data);
751   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
752   EXPECT_EQ(reads_size, out.totalReceivedBytes);
753 }
754
755 // Simulate a 204 response, lacking a Content-Length header, sent over a
756 // persistent connection.  The response should still terminate since a 204
757 // cannot have a response body.
758 TEST_P(HttpNetworkTransactionTest, StopsReading204) {
759   char junk[] = "junk";
760   MockRead data_reads[] = {
761     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
762     MockRead(junk),  // Should not be read!!
763     MockRead(SYNCHRONOUS, OK),
764   };
765   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
766                                               arraysize(data_reads));
767   EXPECT_EQ(OK, out.rv);
768   EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
769   EXPECT_EQ("", out.response_data);
770   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
771   int64 response_size = reads_size - strlen(junk);
772   EXPECT_EQ(response_size, out.totalReceivedBytes);
773 }
774
775 // A simple request using chunked encoding with some extra data after.
776 TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
777   std::string final_chunk = "0\r\n\r\n";
778   std::string extra_data = "HTTP/1.1 200 OK\r\n";
779   std::string last_read = final_chunk + extra_data;
780   MockRead data_reads[] = {
781     MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
782     MockRead("5\r\nHello\r\n"),
783     MockRead("1\r\n"),
784     MockRead(" \r\n"),
785     MockRead("5\r\nworld\r\n"),
786     MockRead(last_read.data()),
787     MockRead(SYNCHRONOUS, OK),
788   };
789   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
790                                               arraysize(data_reads));
791   EXPECT_EQ(OK, out.rv);
792   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
793   EXPECT_EQ("Hello world", out.response_data);
794   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
795   int64 response_size = reads_size - extra_data.size();
796   EXPECT_EQ(response_size, out.totalReceivedBytes);
797 }
798
799 // Next tests deal with http://crbug.com/56344.
800
801 TEST_P(HttpNetworkTransactionTest,
802        MultipleContentLengthHeadersNoTransferEncoding) {
803   MockRead data_reads[] = {
804     MockRead("HTTP/1.1 200 OK\r\n"),
805     MockRead("Content-Length: 10\r\n"),
806     MockRead("Content-Length: 5\r\n\r\n"),
807   };
808   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
809                                               arraysize(data_reads));
810   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
811 }
812
813 TEST_P(HttpNetworkTransactionTest,
814        DuplicateContentLengthHeadersNoTransferEncoding) {
815   MockRead data_reads[] = {
816     MockRead("HTTP/1.1 200 OK\r\n"),
817     MockRead("Content-Length: 5\r\n"),
818     MockRead("Content-Length: 5\r\n\r\n"),
819     MockRead("Hello"),
820   };
821   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
822                                               arraysize(data_reads));
823   EXPECT_EQ(OK, out.rv);
824   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
825   EXPECT_EQ("Hello", out.response_data);
826 }
827
828 TEST_P(HttpNetworkTransactionTest,
829        ComplexContentLengthHeadersNoTransferEncoding) {
830   // More than 2 dupes.
831   {
832     MockRead data_reads[] = {
833       MockRead("HTTP/1.1 200 OK\r\n"),
834       MockRead("Content-Length: 5\r\n"),
835       MockRead("Content-Length: 5\r\n"),
836       MockRead("Content-Length: 5\r\n\r\n"),
837       MockRead("Hello"),
838     };
839     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
840                                                 arraysize(data_reads));
841     EXPECT_EQ(OK, out.rv);
842     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
843     EXPECT_EQ("Hello", out.response_data);
844   }
845   // HTTP/1.0
846   {
847     MockRead data_reads[] = {
848       MockRead("HTTP/1.0 200 OK\r\n"),
849       MockRead("Content-Length: 5\r\n"),
850       MockRead("Content-Length: 5\r\n"),
851       MockRead("Content-Length: 5\r\n\r\n"),
852       MockRead("Hello"),
853     };
854     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
855                                                 arraysize(data_reads));
856     EXPECT_EQ(OK, out.rv);
857     EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
858     EXPECT_EQ("Hello", out.response_data);
859   }
860   // 2 dupes and one mismatched.
861   {
862     MockRead data_reads[] = {
863       MockRead("HTTP/1.1 200 OK\r\n"),
864       MockRead("Content-Length: 10\r\n"),
865       MockRead("Content-Length: 10\r\n"),
866       MockRead("Content-Length: 5\r\n\r\n"),
867     };
868     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
869                                                 arraysize(data_reads));
870     EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
871   }
872 }
873
874 TEST_P(HttpNetworkTransactionTest,
875        MultipleContentLengthHeadersTransferEncoding) {
876   MockRead data_reads[] = {
877     MockRead("HTTP/1.1 200 OK\r\n"),
878     MockRead("Content-Length: 666\r\n"),
879     MockRead("Content-Length: 1337\r\n"),
880     MockRead("Transfer-Encoding: chunked\r\n\r\n"),
881     MockRead("5\r\nHello\r\n"),
882     MockRead("1\r\n"),
883     MockRead(" \r\n"),
884     MockRead("5\r\nworld\r\n"),
885     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
886     MockRead(SYNCHRONOUS, OK),
887   };
888   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
889                                               arraysize(data_reads));
890   EXPECT_EQ(OK, out.rv);
891   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
892   EXPECT_EQ("Hello world", out.response_data);
893 }
894
895 // Next tests deal with http://crbug.com/98895.
896
897 // Checks that a single Content-Disposition header results in no error.
898 TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
899   MockRead data_reads[] = {
900     MockRead("HTTP/1.1 200 OK\r\n"),
901     MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
902     MockRead("Content-Length: 5\r\n\r\n"),
903     MockRead("Hello"),
904   };
905   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
906                                               arraysize(data_reads));
907   EXPECT_EQ(OK, out.rv);
908   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
909   EXPECT_EQ("Hello", out.response_data);
910 }
911
912 // Checks that two identical Content-Disposition headers result in no error.
913 TEST_P(HttpNetworkTransactionTest,
914        TwoIdenticalContentDispositionHeaders) {
915   MockRead data_reads[] = {
916     MockRead("HTTP/1.1 200 OK\r\n"),
917     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
918     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
919     MockRead("Content-Length: 5\r\n\r\n"),
920     MockRead("Hello"),
921   };
922   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
923                                               arraysize(data_reads));
924   EXPECT_EQ(OK, out.rv);
925   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
926   EXPECT_EQ("Hello", out.response_data);
927 }
928
929 // Checks that two distinct Content-Disposition headers result in an error.
930 TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
931   MockRead data_reads[] = {
932     MockRead("HTTP/1.1 200 OK\r\n"),
933     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
934     MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
935     MockRead("Content-Length: 5\r\n\r\n"),
936     MockRead("Hello"),
937   };
938   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
939                                               arraysize(data_reads));
940   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
941 }
942
943 // Checks that two identical Location headers result in no error.
944 // Also tests Location header behavior.
945 TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
946   MockRead data_reads[] = {
947     MockRead("HTTP/1.1 302 Redirect\r\n"),
948     MockRead("Location: http://good.com/\r\n"),
949     MockRead("Location: http://good.com/\r\n"),
950     MockRead("Content-Length: 0\r\n\r\n"),
951     MockRead(SYNCHRONOUS, OK),
952   };
953
954   HttpRequestInfo request;
955   request.method = "GET";
956   request.url = GURL("http://redirect.com/");
957   request.load_flags = 0;
958
959   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
960   scoped_ptr<HttpTransaction> trans(
961       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
962
963   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
964   session_deps_.socket_factory->AddSocketDataProvider(&data);
965
966   TestCompletionCallback callback;
967
968   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
969   EXPECT_EQ(ERR_IO_PENDING, rv);
970
971   EXPECT_EQ(OK, callback.WaitForResult());
972
973   const HttpResponseInfo* response = trans->GetResponseInfo();
974   ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
975   EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
976   std::string url;
977   EXPECT_TRUE(response->headers->IsRedirect(&url));
978   EXPECT_EQ("http://good.com/", url);
979   EXPECT_TRUE(response->proxy_server.IsEmpty());
980 }
981
982 // Checks that two distinct Location headers result in an error.
983 TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
984   MockRead data_reads[] = {
985     MockRead("HTTP/1.1 302 Redirect\r\n"),
986     MockRead("Location: http://good.com/\r\n"),
987     MockRead("Location: http://evil.com/\r\n"),
988     MockRead("Content-Length: 0\r\n\r\n"),
989     MockRead(SYNCHRONOUS, OK),
990   };
991   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
992                                               arraysize(data_reads));
993   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
994 }
995
996 // Do a request using the HEAD method. Verify that we don't try to read the
997 // message body (since HEAD has none).
998 TEST_P(HttpNetworkTransactionTest, Head) {
999   HttpRequestInfo request;
1000   request.method = "HEAD";
1001   request.url = GURL("http://www.google.com/");
1002   request.load_flags = 0;
1003
1004   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1005   scoped_ptr<HttpTransaction> trans(
1006       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1007   BeforeProxyHeadersSentHandler proxy_headers_handler;
1008   trans->SetBeforeProxyHeadersSentCallback(
1009       base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1010                  base::Unretained(&proxy_headers_handler)));
1011
1012   MockWrite data_writes1[] = {
1013     MockWrite("HEAD / HTTP/1.1\r\n"
1014               "Host: www.google.com\r\n"
1015               "Connection: keep-alive\r\n"
1016               "Content-Length: 0\r\n\r\n"),
1017   };
1018   MockRead data_reads1[] = {
1019     MockRead("HTTP/1.1 404 Not Found\r\n"),
1020     MockRead("Server: Blah\r\n"),
1021     MockRead("Content-Length: 1234\r\n\r\n"),
1022
1023     // No response body because the test stops reading here.
1024     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
1025   };
1026
1027   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1028                                  data_writes1, arraysize(data_writes1));
1029   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1030
1031   TestCompletionCallback callback1;
1032
1033   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
1034   EXPECT_EQ(ERR_IO_PENDING, rv);
1035
1036   rv = callback1.WaitForResult();
1037   EXPECT_EQ(OK, rv);
1038
1039   const HttpResponseInfo* response = trans->GetResponseInfo();
1040   ASSERT_TRUE(response != NULL);
1041
1042   // Check that the headers got parsed.
1043   EXPECT_TRUE(response->headers.get() != NULL);
1044   EXPECT_EQ(1234, response->headers->GetContentLength());
1045   EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
1046   EXPECT_TRUE(response->proxy_server.IsEmpty());
1047   EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
1048
1049   std::string server_header;
1050   void* iter = NULL;
1051   bool has_server_header = response->headers->EnumerateHeader(
1052       &iter, "Server", &server_header);
1053   EXPECT_TRUE(has_server_header);
1054   EXPECT_EQ("Blah", server_header);
1055
1056   // Reading should give EOF right away, since there is no message body
1057   // (despite non-zero content-length).
1058   std::string response_data;
1059   rv = ReadTransaction(trans.get(), &response_data);
1060   EXPECT_EQ(OK, rv);
1061   EXPECT_EQ("", response_data);
1062 }
1063
1064 TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
1065   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1066
1067   MockRead data_reads[] = {
1068     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1069     MockRead("hello"),
1070     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1071     MockRead("world"),
1072     MockRead(SYNCHRONOUS, OK),
1073   };
1074   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1075   session_deps_.socket_factory->AddSocketDataProvider(&data);
1076
1077   const char* const kExpectedResponseData[] = {
1078     "hello", "world"
1079   };
1080
1081   for (int i = 0; i < 2; ++i) {
1082     HttpRequestInfo request;
1083     request.method = "GET";
1084     request.url = GURL("http://www.google.com/");
1085     request.load_flags = 0;
1086
1087     scoped_ptr<HttpTransaction> trans(
1088         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1089
1090     TestCompletionCallback callback;
1091
1092     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1093     EXPECT_EQ(ERR_IO_PENDING, rv);
1094
1095     rv = callback.WaitForResult();
1096     EXPECT_EQ(OK, rv);
1097
1098     const HttpResponseInfo* response = trans->GetResponseInfo();
1099     ASSERT_TRUE(response != NULL);
1100
1101     EXPECT_TRUE(response->headers.get() != NULL);
1102     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1103     EXPECT_TRUE(response->proxy_server.IsEmpty());
1104
1105     std::string response_data;
1106     rv = ReadTransaction(trans.get(), &response_data);
1107     EXPECT_EQ(OK, rv);
1108     EXPECT_EQ(kExpectedResponseData[i], response_data);
1109   }
1110 }
1111
1112 TEST_P(HttpNetworkTransactionTest, Ignores100) {
1113   ScopedVector<UploadElementReader> element_readers;
1114   element_readers.push_back(new UploadBytesElementReader("foo", 3));
1115   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
1116
1117   HttpRequestInfo request;
1118   request.method = "POST";
1119   request.url = GURL("http://www.foo.com/");
1120   request.upload_data_stream = &upload_data_stream;
1121   request.load_flags = 0;
1122
1123   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1124   scoped_ptr<HttpTransaction> trans(
1125       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1126
1127   MockRead data_reads[] = {
1128     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1129     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1130     MockRead("hello world"),
1131     MockRead(SYNCHRONOUS, OK),
1132   };
1133   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1134   session_deps_.socket_factory->AddSocketDataProvider(&data);
1135
1136   TestCompletionCallback callback;
1137
1138   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1139   EXPECT_EQ(ERR_IO_PENDING, rv);
1140
1141   rv = callback.WaitForResult();
1142   EXPECT_EQ(OK, rv);
1143
1144   const HttpResponseInfo* response = trans->GetResponseInfo();
1145   ASSERT_TRUE(response != NULL);
1146
1147   EXPECT_TRUE(response->headers.get() != NULL);
1148   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
1149
1150   std::string response_data;
1151   rv = ReadTransaction(trans.get(), &response_data);
1152   EXPECT_EQ(OK, rv);
1153   EXPECT_EQ("hello world", response_data);
1154 }
1155
1156 // This test is almost the same as Ignores100 above, but the response contains
1157 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
1158 // HTTP/1.1 and the two status headers are read in one read.
1159 TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
1160   HttpRequestInfo request;
1161   request.method = "GET";
1162   request.url = GURL("http://www.foo.com/");
1163   request.load_flags = 0;
1164
1165   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1166   scoped_ptr<HttpTransaction> trans(
1167       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1168
1169   MockRead data_reads[] = {
1170     MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1171              "HTTP/1.1 200 OK\r\n\r\n"),
1172     MockRead("hello world"),
1173     MockRead(SYNCHRONOUS, OK),
1174   };
1175   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1176   session_deps_.socket_factory->AddSocketDataProvider(&data);
1177
1178   TestCompletionCallback callback;
1179
1180   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1181   EXPECT_EQ(ERR_IO_PENDING, rv);
1182
1183   rv = callback.WaitForResult();
1184   EXPECT_EQ(OK, rv);
1185
1186   const HttpResponseInfo* response = trans->GetResponseInfo();
1187   ASSERT_TRUE(response != NULL);
1188
1189   EXPECT_TRUE(response->headers.get() != NULL);
1190   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1191
1192   std::string response_data;
1193   rv = ReadTransaction(trans.get(), &response_data);
1194   EXPECT_EQ(OK, rv);
1195   EXPECT_EQ("hello world", response_data);
1196 }
1197
1198 TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
1199   HttpRequestInfo request;
1200   request.method = "POST";
1201   request.url = GURL("http://www.foo.com/");
1202   request.load_flags = 0;
1203
1204   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1205   scoped_ptr<HttpTransaction> trans(
1206       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1207
1208   MockRead data_reads[] = {
1209     MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1210     MockRead(ASYNC, 0),
1211   };
1212   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1213   session_deps_.socket_factory->AddSocketDataProvider(&data);
1214
1215   TestCompletionCallback callback;
1216
1217   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1218   EXPECT_EQ(ERR_IO_PENDING, rv);
1219
1220   rv = callback.WaitForResult();
1221   EXPECT_EQ(OK, rv);
1222
1223   std::string response_data;
1224   rv = ReadTransaction(trans.get(), &response_data);
1225   EXPECT_EQ(OK, rv);
1226   EXPECT_EQ("", response_data);
1227 }
1228
1229 TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
1230   HttpRequestInfo request;
1231   request.method = "POST";
1232   request.url = GURL("http://www.foo.com/");
1233   request.load_flags = 0;
1234
1235   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1236   scoped_ptr<HttpTransaction> trans(
1237       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1238
1239   MockRead data_reads[] = {
1240     MockRead(ASYNC, 0),
1241   };
1242   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1243   session_deps_.socket_factory->AddSocketDataProvider(&data);
1244
1245   TestCompletionCallback callback;
1246
1247   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1248   EXPECT_EQ(ERR_IO_PENDING, rv);
1249
1250   rv = callback.WaitForResult();
1251   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1252 }
1253
1254 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
1255     const MockWrite* write_failure,
1256     const MockRead* read_failure) {
1257   HttpRequestInfo request;
1258   request.method = "GET";
1259   request.url = GURL("http://www.foo.com/");
1260   request.load_flags = 0;
1261
1262   CapturingNetLog net_log;
1263   session_deps_.net_log = &net_log;
1264   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1265
1266   // Written data for successfully sending both requests.
1267   MockWrite data1_writes[] = {
1268     MockWrite("GET / HTTP/1.1\r\n"
1269               "Host: www.foo.com\r\n"
1270               "Connection: keep-alive\r\n\r\n"),
1271     MockWrite("GET / HTTP/1.1\r\n"
1272               "Host: www.foo.com\r\n"
1273               "Connection: keep-alive\r\n\r\n")
1274   };
1275
1276   // Read results for the first request.
1277   MockRead data1_reads[] = {
1278     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1279     MockRead("hello"),
1280     MockRead(ASYNC, OK),
1281   };
1282
1283   if (write_failure) {
1284     ASSERT_FALSE(read_failure);
1285     data1_writes[1] = *write_failure;
1286   } else {
1287     ASSERT_TRUE(read_failure);
1288     data1_reads[2] = *read_failure;
1289   }
1290
1291   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1292                                  data1_writes, arraysize(data1_writes));
1293   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1294
1295   MockRead data2_reads[] = {
1296     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1297     MockRead("world"),
1298     MockRead(ASYNC, OK),
1299   };
1300   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1301   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1302
1303   const char* kExpectedResponseData[] = {
1304     "hello", "world"
1305   };
1306
1307   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
1308   for (int i = 0; i < 2; ++i) {
1309     TestCompletionCallback callback;
1310
1311     scoped_ptr<HttpTransaction> trans(
1312         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1313
1314     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1315     EXPECT_EQ(ERR_IO_PENDING, rv);
1316
1317     rv = callback.WaitForResult();
1318     EXPECT_EQ(OK, rv);
1319
1320     LoadTimingInfo load_timing_info;
1321     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1322     TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1323     if (i == 0) {
1324       first_socket_log_id = load_timing_info.socket_log_id;
1325     } else {
1326       // The second request should be using a new socket.
1327       EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1328     }
1329
1330     const HttpResponseInfo* response = trans->GetResponseInfo();
1331     ASSERT_TRUE(response != NULL);
1332
1333     EXPECT_TRUE(response->headers.get() != NULL);
1334     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1335
1336     std::string response_data;
1337     rv = ReadTransaction(trans.get(), &response_data);
1338     EXPECT_EQ(OK, rv);
1339     EXPECT_EQ(kExpectedResponseData[i], response_data);
1340   }
1341 }
1342
1343 void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1344     const MockWrite* write_failure,
1345     const MockRead* read_failure,
1346     bool use_spdy) {
1347   HttpRequestInfo request;
1348   request.method = "GET";
1349   request.url = GURL("https://www.foo.com/");
1350   request.load_flags = 0;
1351
1352   CapturingNetLog net_log;
1353   session_deps_.net_log = &net_log;
1354   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1355
1356   SSLSocketDataProvider ssl1(ASYNC, OK);
1357   SSLSocketDataProvider ssl2(ASYNC, OK);
1358   if (use_spdy) {
1359     ssl1.SetNextProto(GetParam());
1360     ssl2.SetNextProto(GetParam());
1361   }
1362   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1363   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
1364
1365   // SPDY versions of the request and response.
1366   scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1367       request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1368   scoped_ptr<SpdyFrame> spdy_response(
1369       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1370   scoped_ptr<SpdyFrame> spdy_data(
1371       spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
1372
1373   // HTTP/1.1 versions of the request and response.
1374   const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1375       "Host: www.foo.com\r\n"
1376       "Connection: keep-alive\r\n\r\n";
1377   const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1378   const char kHttpData[] = "hello";
1379
1380   std::vector<MockRead> data1_reads;
1381   std::vector<MockWrite> data1_writes;
1382   if (write_failure) {
1383     ASSERT_FALSE(read_failure);
1384     data1_writes.push_back(*write_failure);
1385     data1_reads.push_back(MockRead(ASYNC, OK));
1386   } else {
1387     ASSERT_TRUE(read_failure);
1388     if (use_spdy) {
1389       data1_writes.push_back(CreateMockWrite(*spdy_request));
1390     } else {
1391       data1_writes.push_back(MockWrite(kHttpRequest));
1392     }
1393     data1_reads.push_back(*read_failure);
1394   }
1395
1396   StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1397                                  &data1_writes[0], data1_writes.size());
1398   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1399
1400   std::vector<MockRead> data2_reads;
1401   std::vector<MockWrite> data2_writes;
1402
1403   if (use_spdy) {
1404     data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1405
1406     data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1407     data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1408     data2_reads.push_back(MockRead(ASYNC, OK, 3));
1409   } else {
1410     data2_writes.push_back(
1411         MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1412
1413     data2_reads.push_back(
1414         MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1415     data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1416     data2_reads.push_back(MockRead(ASYNC, OK, 3));
1417   }
1418   OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1419                           &data2_writes[0], data2_writes.size());
1420   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1421
1422   // Preconnect a socket.
1423   net::SSLConfig ssl_config;
1424   session->ssl_config_service()->GetSSLConfig(&ssl_config);
1425   session->GetNextProtos(&ssl_config.next_protos);
1426   session->http_stream_factory()->PreconnectStreams(
1427       1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1428   // Wait for the preconnect to complete.
1429   // TODO(davidben): Some way to wait for an idle socket count might be handy.
1430   base::RunLoop().RunUntilIdle();
1431   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
1432
1433   // Make the request.
1434   TestCompletionCallback callback;
1435
1436   scoped_ptr<HttpTransaction> trans(
1437       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1438
1439   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1440   EXPECT_EQ(ERR_IO_PENDING, rv);
1441
1442   rv = callback.WaitForResult();
1443   EXPECT_EQ(OK, rv);
1444
1445   LoadTimingInfo load_timing_info;
1446   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1447   TestLoadTimingNotReused(
1448       load_timing_info,
1449       CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
1450
1451   const HttpResponseInfo* response = trans->GetResponseInfo();
1452   ASSERT_TRUE(response != NULL);
1453
1454   EXPECT_TRUE(response->headers.get() != NULL);
1455   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1456
1457   std::string response_data;
1458   rv = ReadTransaction(trans.get(), &response_data);
1459   EXPECT_EQ(OK, rv);
1460   EXPECT_EQ(kHttpData, response_data);
1461 }
1462
1463 TEST_P(HttpNetworkTransactionTest,
1464        KeepAliveConnectionNotConnectedOnWrite) {
1465   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1466   KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1467 }
1468
1469 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
1470   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1471   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1472 }
1473
1474 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
1475   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1476   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1477 }
1478
1479 // Make sure that on a 408 response (Request Timeout), the request is retried,
1480 // if the socket was a reused keep alive socket.
1481 TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1482   MockRead read_failure(SYNCHRONOUS,
1483                         "HTTP/1.1 408 Request Timeout\r\n"
1484                         "Connection: Keep-Alive\r\n"
1485                         "Content-Length: 6\r\n\r\n"
1486                         "Pickle");
1487   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1488 }
1489
1490 TEST_P(HttpNetworkTransactionTest,
1491        PreconnectErrorNotConnectedOnWrite) {
1492   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1493   PreconnectErrorResendRequestTest(&write_failure, NULL, false);
1494 }
1495
1496 TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1497   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1498   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1499 }
1500
1501 TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1502   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1503   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1504 }
1505
1506 TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1507   MockRead read_failure(ASYNC, OK);  // EOF
1508   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1509 }
1510
1511 // Make sure that on a 408 response (Request Timeout), the request is retried,
1512 // if the socket was a preconnected (UNUSED_IDLE) socket.
1513 TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1514   MockRead read_failure(SYNCHRONOUS,
1515                         "HTTP/1.1 408 Request Timeout\r\n"
1516                         "Connection: Keep-Alive\r\n"
1517                         "Content-Length: 6\r\n\r\n"
1518                         "Pickle");
1519   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1520   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1521 }
1522
1523 TEST_P(HttpNetworkTransactionTest,
1524        SpdyPreconnectErrorNotConnectedOnWrite) {
1525   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1526   PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1527 }
1528
1529 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1530   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1531   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1532 }
1533
1534 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1535   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1536   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1537 }
1538
1539 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1540   MockRead read_failure(ASYNC, OK);  // EOF
1541   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1542 }
1543
1544 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
1545   HttpRequestInfo request;
1546   request.method = "GET";
1547   request.url = GURL("http://www.google.com/");
1548   request.load_flags = 0;
1549
1550   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1551   scoped_ptr<HttpTransaction> trans(
1552       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1553
1554   MockRead data_reads[] = {
1555     MockRead(ASYNC, ERR_CONNECTION_RESET),
1556     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
1557     MockRead("hello world"),
1558     MockRead(SYNCHRONOUS, OK),
1559   };
1560   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1561   session_deps_.socket_factory->AddSocketDataProvider(&data);
1562
1563   TestCompletionCallback callback;
1564
1565   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1566   EXPECT_EQ(ERR_IO_PENDING, rv);
1567
1568   rv = callback.WaitForResult();
1569   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1570
1571   const HttpResponseInfo* response = trans->GetResponseInfo();
1572   EXPECT_TRUE(response == NULL);
1573 }
1574
1575 // What do various browsers do when the server closes a non-keepalive
1576 // connection without sending any response header or body?
1577 //
1578 // IE7: error page
1579 // Safari 3.1.2 (Windows): error page
1580 // Firefox 3.0.1: blank page
1581 // Opera 9.52: after five attempts, blank page
1582 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1583 // Us: error page (EMPTY_RESPONSE)
1584 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
1585   MockRead data_reads[] = {
1586     MockRead(SYNCHRONOUS, OK),  // EOF
1587     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
1588     MockRead("hello world"),
1589     MockRead(SYNCHRONOUS, OK),
1590   };
1591   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1592                                               arraysize(data_reads));
1593   EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
1594 }
1595
1596 // Test that network access can be deferred and resumed.
1597 TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1598   HttpRequestInfo request;
1599   request.method = "GET";
1600   request.url = GURL("http://www.google.com/");
1601   request.load_flags = 0;
1602
1603   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1604   scoped_ptr<HttpTransaction> trans(
1605       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1606
1607   // Defer on OnBeforeNetworkStart.
1608   BeforeNetworkStartHandler net_start_handler(true);  // defer
1609   trans->SetBeforeNetworkStartCallback(
1610       base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1611                  base::Unretained(&net_start_handler)));
1612
1613   MockRead data_reads[] = {
1614     MockRead("HTTP/1.0 200 OK\r\n"),
1615     MockRead("Content-Length: 5\r\n\r\n"),
1616     MockRead("hello"),
1617     MockRead(SYNCHRONOUS, 0),
1618   };
1619   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1620   session_deps_.socket_factory->AddSocketDataProvider(&data);
1621
1622   TestCompletionCallback callback;
1623
1624   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1625   EXPECT_EQ(ERR_IO_PENDING, rv);
1626   base::MessageLoop::current()->RunUntilIdle();
1627
1628   // Should have deferred for network start.
1629   EXPECT_TRUE(net_start_handler.observed_before_network_start());
1630   EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1631   EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1632
1633   trans->ResumeNetworkStart();
1634   rv = callback.WaitForResult();
1635   EXPECT_EQ(OK, rv);
1636   EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1637
1638   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1639   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1640   if (rv == ERR_IO_PENDING)
1641     rv = callback.WaitForResult();
1642   EXPECT_EQ(5, rv);
1643   trans.reset();
1644 }
1645
1646 // Test that network use can be deferred and canceled.
1647 TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1648   HttpRequestInfo request;
1649   request.method = "GET";
1650   request.url = GURL("http://www.google.com/");
1651   request.load_flags = 0;
1652
1653   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1654   scoped_ptr<HttpTransaction> trans(
1655       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1656
1657   // Defer on OnBeforeNetworkStart.
1658   BeforeNetworkStartHandler net_start_handler(true);  // defer
1659   trans->SetBeforeNetworkStartCallback(
1660       base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1661                  base::Unretained(&net_start_handler)));
1662
1663   TestCompletionCallback callback;
1664
1665   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1666   EXPECT_EQ(ERR_IO_PENDING, rv);
1667   base::MessageLoop::current()->RunUntilIdle();
1668
1669   // Should have deferred for network start.
1670   EXPECT_TRUE(net_start_handler.observed_before_network_start());
1671   EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1672   EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1673 }
1674
1675 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1676 // tests. There was a bug causing HttpNetworkTransaction to hang in the
1677 // destructor in such situations.
1678 // See http://crbug.com/154712 and http://crbug.com/156609.
1679 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
1680   HttpRequestInfo request;
1681   request.method = "GET";
1682   request.url = GURL("http://www.google.com/");
1683   request.load_flags = 0;
1684
1685   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1686   scoped_ptr<HttpTransaction> trans(
1687       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1688
1689   MockRead data_reads[] = {
1690     MockRead("HTTP/1.0 200 OK\r\n"),
1691     MockRead("Connection: keep-alive\r\n"),
1692     MockRead("Content-Length: 100\r\n\r\n"),
1693     MockRead("hello"),
1694     MockRead(SYNCHRONOUS, 0),
1695   };
1696   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1697   session_deps_.socket_factory->AddSocketDataProvider(&data);
1698
1699   TestCompletionCallback callback;
1700
1701   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1702   EXPECT_EQ(ERR_IO_PENDING, rv);
1703
1704   rv = callback.WaitForResult();
1705   EXPECT_EQ(OK, rv);
1706
1707   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1708   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1709   if (rv == ERR_IO_PENDING)
1710     rv = callback.WaitForResult();
1711   EXPECT_EQ(5, rv);
1712   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1713   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1714
1715   trans.reset();
1716   base::MessageLoop::current()->RunUntilIdle();
1717   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1718 }
1719
1720 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
1721   HttpRequestInfo request;
1722   request.method = "GET";
1723   request.url = GURL("http://www.google.com/");
1724   request.load_flags = 0;
1725
1726   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1727   scoped_ptr<HttpTransaction> trans(
1728       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1729
1730   MockRead data_reads[] = {
1731     MockRead("HTTP/1.0 200 OK\r\n"),
1732     MockRead("Connection: keep-alive\r\n"),
1733     MockRead("Content-Length: 100\r\n\r\n"),
1734     MockRead(SYNCHRONOUS, 0),
1735   };
1736   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1737   session_deps_.socket_factory->AddSocketDataProvider(&data);
1738
1739   TestCompletionCallback callback;
1740
1741   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1742   EXPECT_EQ(ERR_IO_PENDING, rv);
1743
1744   rv = callback.WaitForResult();
1745   EXPECT_EQ(OK, rv);
1746
1747   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1748   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1749   if (rv == ERR_IO_PENDING)
1750     rv = callback.WaitForResult();
1751   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1752
1753   trans.reset();
1754   base::MessageLoop::current()->RunUntilIdle();
1755   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1756 }
1757
1758 // Test that we correctly reuse a keep-alive connection after not explicitly
1759 // reading the body.
1760 TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
1761   HttpRequestInfo request;
1762   request.method = "GET";
1763   request.url = GURL("http://www.foo.com/");
1764   request.load_flags = 0;
1765
1766   CapturingNetLog net_log;
1767   session_deps_.net_log = &net_log;
1768   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1769
1770   // Note that because all these reads happen in the same
1771   // StaticSocketDataProvider, it shows that the same socket is being reused for
1772   // all transactions.
1773   MockRead data1_reads[] = {
1774     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1775     MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
1776     MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
1777     MockRead("HTTP/1.1 302 Found\r\n"
1778              "Content-Length: 0\r\n\r\n"),
1779     MockRead("HTTP/1.1 302 Found\r\n"
1780              "Content-Length: 5\r\n\r\n"
1781              "hello"),
1782     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1783              "Content-Length: 0\r\n\r\n"),
1784     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1785              "Content-Length: 5\r\n\r\n"
1786              "hello"),
1787     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1788     MockRead("hello"),
1789   };
1790   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
1791   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1792
1793   MockRead data2_reads[] = {
1794     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
1795   };
1796   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1797   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1798
1799   const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1800   std::string response_lines[kNumUnreadBodies];
1801
1802   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
1803   for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
1804     TestCompletionCallback callback;
1805
1806     scoped_ptr<HttpTransaction> trans(
1807         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1808
1809     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1810     EXPECT_EQ(ERR_IO_PENDING, rv);
1811
1812     rv = callback.WaitForResult();
1813     EXPECT_EQ(OK, rv);
1814
1815     LoadTimingInfo load_timing_info;
1816     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1817     if (i == 0) {
1818       TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1819       first_socket_log_id = load_timing_info.socket_log_id;
1820     } else {
1821       TestLoadTimingReused(load_timing_info);
1822       EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1823     }
1824
1825     const HttpResponseInfo* response = trans->GetResponseInfo();
1826     ASSERT_TRUE(response != NULL);
1827
1828     ASSERT_TRUE(response->headers.get() != NULL);
1829     response_lines[i] = response->headers->GetStatusLine();
1830
1831     // We intentionally don't read the response bodies.
1832   }
1833
1834   const char* const kStatusLines[] = {
1835     "HTTP/1.1 204 No Content",
1836     "HTTP/1.1 205 Reset Content",
1837     "HTTP/1.1 304 Not Modified",
1838     "HTTP/1.1 302 Found",
1839     "HTTP/1.1 302 Found",
1840     "HTTP/1.1 301 Moved Permanently",
1841     "HTTP/1.1 301 Moved Permanently",
1842   };
1843
1844   COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1845                  forgot_to_update_kStatusLines);
1846
1847   for (int i = 0; i < kNumUnreadBodies; ++i)
1848     EXPECT_EQ(kStatusLines[i], response_lines[i]);
1849
1850   TestCompletionCallback callback;
1851   scoped_ptr<HttpTransaction> trans(
1852       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1853   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1854   EXPECT_EQ(ERR_IO_PENDING, rv);
1855   rv = callback.WaitForResult();
1856   EXPECT_EQ(OK, rv);
1857   const HttpResponseInfo* response = trans->GetResponseInfo();
1858   ASSERT_TRUE(response != NULL);
1859   ASSERT_TRUE(response->headers.get() != NULL);
1860   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1861   std::string response_data;
1862   rv = ReadTransaction(trans.get(), &response_data);
1863   EXPECT_EQ(OK, rv);
1864   EXPECT_EQ("hello", response_data);
1865 }
1866
1867 // Test the request-challenge-retry sequence for basic auth.
1868 // (basic auth is the easiest to mock, because it has no randomness).
1869 TEST_P(HttpNetworkTransactionTest, BasicAuth) {
1870   HttpRequestInfo request;
1871   request.method = "GET";
1872   request.url = GURL("http://www.google.com/");
1873   request.load_flags = 0;
1874
1875   CapturingNetLog log;
1876   session_deps_.net_log = &log;
1877   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1878   scoped_ptr<HttpTransaction> trans(
1879       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1880
1881   MockWrite data_writes1[] = {
1882     MockWrite("GET / HTTP/1.1\r\n"
1883               "Host: www.google.com\r\n"
1884               "Connection: keep-alive\r\n\r\n"),
1885   };
1886
1887   MockRead data_reads1[] = {
1888     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1889     // Give a couple authenticate options (only the middle one is actually
1890     // supported).
1891     MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
1892     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1893     MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1894     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1895     // Large content-length -- won't matter, as connection will be reset.
1896     MockRead("Content-Length: 10000\r\n\r\n"),
1897     MockRead(SYNCHRONOUS, ERR_FAILED),
1898   };
1899
1900   // After calling trans->RestartWithAuth(), this is the request we should
1901   // be issuing -- the final header line contains the credentials.
1902   MockWrite data_writes2[] = {
1903     MockWrite("GET / HTTP/1.1\r\n"
1904               "Host: www.google.com\r\n"
1905               "Connection: keep-alive\r\n"
1906               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1907   };
1908
1909   // Lastly, the server responds with the actual content.
1910   MockRead data_reads2[] = {
1911     MockRead("HTTP/1.0 200 OK\r\n"),
1912     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1913     MockRead("Content-Length: 100\r\n\r\n"),
1914     MockRead(SYNCHRONOUS, OK),
1915   };
1916
1917   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1918                                  data_writes1, arraysize(data_writes1));
1919   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1920                                  data_writes2, arraysize(data_writes2));
1921   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1922   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1923
1924   TestCompletionCallback callback1;
1925
1926   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
1927   EXPECT_EQ(ERR_IO_PENDING, rv);
1928
1929   rv = callback1.WaitForResult();
1930   EXPECT_EQ(OK, rv);
1931
1932   LoadTimingInfo load_timing_info1;
1933   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1934   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1935
1936   int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1937   EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1938
1939   const HttpResponseInfo* response = trans->GetResponseInfo();
1940   ASSERT_TRUE(response != NULL);
1941   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
1942
1943   TestCompletionCallback callback2;
1944
1945   rv = trans->RestartWithAuth(
1946       AuthCredentials(kFoo, kBar), callback2.callback());
1947   EXPECT_EQ(ERR_IO_PENDING, rv);
1948
1949   rv = callback2.WaitForResult();
1950   EXPECT_EQ(OK, rv);
1951
1952   LoadTimingInfo load_timing_info2;
1953   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1954   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1955   // The load timing after restart should have a new socket ID, and times after
1956   // those of the first load timing.
1957   EXPECT_LE(load_timing_info1.receive_headers_end,
1958             load_timing_info2.connect_timing.connect_start);
1959   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1960
1961   int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1962   EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1963
1964   response = trans->GetResponseInfo();
1965   ASSERT_TRUE(response != NULL);
1966   EXPECT_TRUE(response->auth_challenge.get() == NULL);
1967   EXPECT_EQ(100, response->headers->GetContentLength());
1968 }
1969
1970 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
1971   HttpRequestInfo request;
1972   request.method = "GET";
1973   request.url = GURL("http://www.google.com/");
1974   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1975
1976   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1977   scoped_ptr<HttpTransaction> trans(
1978       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1979
1980   MockWrite data_writes[] = {
1981     MockWrite("GET / HTTP/1.1\r\n"
1982               "Host: www.google.com\r\n"
1983               "Connection: keep-alive\r\n\r\n"),
1984   };
1985
1986   MockRead data_reads[] = {
1987     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1988     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1989     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1990     // Large content-length -- won't matter, as connection will be reset.
1991     MockRead("Content-Length: 10000\r\n\r\n"),
1992     MockRead(SYNCHRONOUS, ERR_FAILED),
1993   };
1994
1995   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1996                                 data_writes, arraysize(data_writes));
1997   session_deps_.socket_factory->AddSocketDataProvider(&data);
1998   TestCompletionCallback callback;
1999
2000   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2001   EXPECT_EQ(ERR_IO_PENDING, rv);
2002
2003   rv = callback.WaitForResult();
2004   EXPECT_EQ(0, rv);
2005
2006   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2007   EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2008
2009   const HttpResponseInfo* response = trans->GetResponseInfo();
2010   ASSERT_TRUE(response != NULL);
2011   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2012 }
2013
2014 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2015 // connection.
2016 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
2017   HttpRequestInfo request;
2018   request.method = "GET";
2019   request.url = GURL("http://www.google.com/");
2020   request.load_flags = 0;
2021
2022   CapturingNetLog log;
2023   session_deps_.net_log = &log;
2024   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2025
2026   MockWrite data_writes1[] = {
2027     MockWrite("GET / HTTP/1.1\r\n"
2028               "Host: www.google.com\r\n"
2029               "Connection: keep-alive\r\n\r\n"),
2030
2031     // After calling trans->RestartWithAuth(), this is the request we should
2032     // be issuing -- the final header line contains the credentials.
2033     MockWrite("GET / HTTP/1.1\r\n"
2034               "Host: www.google.com\r\n"
2035               "Connection: keep-alive\r\n"
2036               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2037   };
2038
2039   MockRead data_reads1[] = {
2040     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2041     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2042     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2043     MockRead("Content-Length: 14\r\n\r\n"),
2044     MockRead("Unauthorized\r\n"),
2045
2046     // Lastly, the server responds with the actual content.
2047     MockRead("HTTP/1.1 200 OK\r\n"),
2048     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2049     MockRead("Content-Length: 5\r\n\r\n"),
2050     MockRead("Hello"),
2051   };
2052
2053   // If there is a regression where we disconnect a Keep-Alive
2054   // connection during an auth roundtrip, we'll end up reading this.
2055   MockRead data_reads2[] = {
2056     MockRead(SYNCHRONOUS, ERR_FAILED),
2057   };
2058
2059   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2060                                  data_writes1, arraysize(data_writes1));
2061   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2062                                  NULL, 0);
2063   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2064   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2065
2066   TestCompletionCallback callback1;
2067
2068   scoped_ptr<HttpTransaction> trans(
2069       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2070   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2071   EXPECT_EQ(ERR_IO_PENDING, rv);
2072
2073   rv = callback1.WaitForResult();
2074   EXPECT_EQ(OK, rv);
2075
2076   LoadTimingInfo load_timing_info1;
2077   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2078   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2079
2080   const HttpResponseInfo* response = trans->GetResponseInfo();
2081   ASSERT_TRUE(response != NULL);
2082   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2083
2084   TestCompletionCallback callback2;
2085
2086   rv = trans->RestartWithAuth(
2087       AuthCredentials(kFoo, kBar), callback2.callback());
2088   EXPECT_EQ(ERR_IO_PENDING, rv);
2089
2090   rv = callback2.WaitForResult();
2091   EXPECT_EQ(OK, rv);
2092
2093   LoadTimingInfo load_timing_info2;
2094   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2095   TestLoadTimingReused(load_timing_info2);
2096   // The load timing after restart should have the same socket ID, and times
2097   // those of the first load timing.
2098   EXPECT_LE(load_timing_info1.receive_headers_end,
2099             load_timing_info2.send_start);
2100   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2101
2102   response = trans->GetResponseInfo();
2103   ASSERT_TRUE(response != NULL);
2104   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2105   EXPECT_EQ(5, response->headers->GetContentLength());
2106
2107   std::string response_data;
2108   rv = ReadTransaction(trans.get(), &response_data);
2109   EXPECT_EQ(OK, rv);
2110   int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2111   EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2112 }
2113
2114 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2115 // connection and with no response body to drain.
2116 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
2117   HttpRequestInfo request;
2118   request.method = "GET";
2119   request.url = GURL("http://www.google.com/");
2120   request.load_flags = 0;
2121
2122   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2123
2124   MockWrite data_writes1[] = {
2125     MockWrite("GET / HTTP/1.1\r\n"
2126               "Host: www.google.com\r\n"
2127               "Connection: keep-alive\r\n\r\n"),
2128
2129     // After calling trans->RestartWithAuth(), this is the request we should
2130     // be issuing -- the final header line contains the credentials.
2131     MockWrite("GET / HTTP/1.1\r\n"
2132               "Host: www.google.com\r\n"
2133               "Connection: keep-alive\r\n"
2134               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2135   };
2136
2137   MockRead data_reads1[] = {
2138     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2139     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2140     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
2141
2142     // Lastly, the server responds with the actual content.
2143     MockRead("HTTP/1.1 200 OK\r\n"),
2144     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2145     MockRead("Content-Length: 5\r\n\r\n"),
2146     MockRead("hello"),
2147   };
2148
2149   // An incorrect reconnect would cause this to be read.
2150   MockRead data_reads2[] = {
2151     MockRead(SYNCHRONOUS, ERR_FAILED),
2152   };
2153
2154   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2155                                  data_writes1, arraysize(data_writes1));
2156   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2157                                  NULL, 0);
2158   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2159   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2160
2161   TestCompletionCallback callback1;
2162
2163   scoped_ptr<HttpTransaction> trans(
2164       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2165   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2166   EXPECT_EQ(ERR_IO_PENDING, rv);
2167
2168   rv = callback1.WaitForResult();
2169   EXPECT_EQ(OK, rv);
2170
2171   const HttpResponseInfo* response = trans->GetResponseInfo();
2172   ASSERT_TRUE(response != NULL);
2173   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2174
2175   TestCompletionCallback callback2;
2176
2177   rv = trans->RestartWithAuth(
2178       AuthCredentials(kFoo, kBar), callback2.callback());
2179   EXPECT_EQ(ERR_IO_PENDING, rv);
2180
2181   rv = callback2.WaitForResult();
2182   EXPECT_EQ(OK, rv);
2183
2184   response = trans->GetResponseInfo();
2185   ASSERT_TRUE(response != NULL);
2186   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2187   EXPECT_EQ(5, response->headers->GetContentLength());
2188 }
2189
2190 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2191 // connection and with a large response body to drain.
2192 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
2193   HttpRequestInfo request;
2194   request.method = "GET";
2195   request.url = GURL("http://www.google.com/");
2196   request.load_flags = 0;
2197
2198   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2199
2200   MockWrite data_writes1[] = {
2201     MockWrite("GET / HTTP/1.1\r\n"
2202               "Host: www.google.com\r\n"
2203               "Connection: keep-alive\r\n\r\n"),
2204
2205     // After calling trans->RestartWithAuth(), this is the request we should
2206     // be issuing -- the final header line contains the credentials.
2207     MockWrite("GET / HTTP/1.1\r\n"
2208               "Host: www.google.com\r\n"
2209               "Connection: keep-alive\r\n"
2210               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2211   };
2212
2213   // Respond with 5 kb of response body.
2214   std::string large_body_string("Unauthorized");
2215   large_body_string.append(5 * 1024, ' ');
2216   large_body_string.append("\r\n");
2217
2218   MockRead data_reads1[] = {
2219     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2220     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2221     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2222     // 5134 = 12 + 5 * 1024 + 2
2223     MockRead("Content-Length: 5134\r\n\r\n"),
2224     MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
2225
2226     // Lastly, the server responds with the actual content.
2227     MockRead("HTTP/1.1 200 OK\r\n"),
2228     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2229     MockRead("Content-Length: 5\r\n\r\n"),
2230     MockRead("hello"),
2231   };
2232
2233   // An incorrect reconnect would cause this to be read.
2234   MockRead data_reads2[] = {
2235     MockRead(SYNCHRONOUS, ERR_FAILED),
2236   };
2237
2238   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2239                                  data_writes1, arraysize(data_writes1));
2240   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2241                                  NULL, 0);
2242   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2243   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2244
2245   TestCompletionCallback callback1;
2246
2247   scoped_ptr<HttpTransaction> trans(
2248       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2249   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2250   EXPECT_EQ(ERR_IO_PENDING, rv);
2251
2252   rv = callback1.WaitForResult();
2253   EXPECT_EQ(OK, rv);
2254
2255   const HttpResponseInfo* response = trans->GetResponseInfo();
2256   ASSERT_TRUE(response != NULL);
2257   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2258
2259   TestCompletionCallback callback2;
2260
2261   rv = trans->RestartWithAuth(
2262       AuthCredentials(kFoo, kBar), callback2.callback());
2263   EXPECT_EQ(ERR_IO_PENDING, rv);
2264
2265   rv = callback2.WaitForResult();
2266   EXPECT_EQ(OK, rv);
2267
2268   response = trans->GetResponseInfo();
2269   ASSERT_TRUE(response != NULL);
2270   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2271   EXPECT_EQ(5, response->headers->GetContentLength());
2272 }
2273
2274 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2275 // connection, but the server gets impatient and closes the connection.
2276 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
2277   HttpRequestInfo request;
2278   request.method = "GET";
2279   request.url = GURL("http://www.google.com/");
2280   request.load_flags = 0;
2281
2282   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2283
2284   MockWrite data_writes1[] = {
2285     MockWrite("GET / HTTP/1.1\r\n"
2286               "Host: www.google.com\r\n"
2287               "Connection: keep-alive\r\n\r\n"),
2288     // This simulates the seemingly successful write to a closed connection
2289     // if the bug is not fixed.
2290     MockWrite("GET / HTTP/1.1\r\n"
2291               "Host: www.google.com\r\n"
2292               "Connection: keep-alive\r\n"
2293               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2294   };
2295
2296   MockRead data_reads1[] = {
2297     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2298     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2299     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2300     MockRead("Content-Length: 14\r\n\r\n"),
2301     // Tell MockTCPClientSocket to simulate the server closing the connection.
2302     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2303     MockRead("Unauthorized\r\n"),
2304     MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
2305   };
2306
2307   // After calling trans->RestartWithAuth(), this is the request we should
2308   // be issuing -- the final header line contains the credentials.
2309   MockWrite data_writes2[] = {
2310     MockWrite("GET / HTTP/1.1\r\n"
2311               "Host: www.google.com\r\n"
2312               "Connection: keep-alive\r\n"
2313               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2314   };
2315
2316   // Lastly, the server responds with the actual content.
2317   MockRead data_reads2[] = {
2318     MockRead("HTTP/1.1 200 OK\r\n"),
2319     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2320     MockRead("Content-Length: 5\r\n\r\n"),
2321     MockRead("hello"),
2322   };
2323
2324   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2325                                  data_writes1, arraysize(data_writes1));
2326   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2327                                  data_writes2, arraysize(data_writes2));
2328   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2329   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2330
2331   TestCompletionCallback callback1;
2332
2333   scoped_ptr<HttpTransaction> trans(
2334       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2335   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2336   EXPECT_EQ(ERR_IO_PENDING, rv);
2337
2338   rv = callback1.WaitForResult();
2339   EXPECT_EQ(OK, rv);
2340
2341   const HttpResponseInfo* response = trans->GetResponseInfo();
2342   ASSERT_TRUE(response != NULL);
2343   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2344
2345   TestCompletionCallback callback2;
2346
2347   rv = trans->RestartWithAuth(
2348       AuthCredentials(kFoo, kBar), callback2.callback());
2349   EXPECT_EQ(ERR_IO_PENDING, rv);
2350
2351   rv = callback2.WaitForResult();
2352   EXPECT_EQ(OK, rv);
2353
2354   response = trans->GetResponseInfo();
2355   ASSERT_TRUE(response != NULL);
2356   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2357   EXPECT_EQ(5, response->headers->GetContentLength());
2358 }
2359
2360 // Test the request-challenge-retry sequence for basic auth, over a connection
2361 // that requires a restart when setting up an SSL tunnel.
2362 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
2363   HttpRequestInfo request;
2364   request.method = "GET";
2365   request.url = GURL("https://www.google.com/");
2366   // when the no authentication data flag is set.
2367   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2368
2369   // Configure against proxy server "myproxy:70".
2370   session_deps_.proxy_service.reset(
2371       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2372   CapturingBoundNetLog log;
2373   session_deps_.net_log = log.bound().net_log();
2374   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2375
2376   // Since we have proxy, should try to establish tunnel.
2377   MockWrite data_writes1[] = {
2378     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2379               "Host: www.google.com\r\n"
2380               "Proxy-Connection: keep-alive\r\n\r\n"),
2381
2382     // After calling trans->RestartWithAuth(), this is the request we should
2383     // be issuing -- the final header line contains the credentials.
2384     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2385               "Host: www.google.com\r\n"
2386               "Proxy-Connection: keep-alive\r\n"
2387               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2388
2389     MockWrite("GET / HTTP/1.1\r\n"
2390               "Host: www.google.com\r\n"
2391               "Connection: keep-alive\r\n\r\n"),
2392   };
2393
2394   // The proxy responds to the connect with a 407, using a persistent
2395   // connection.
2396   MockRead data_reads1[] = {
2397     // No credentials.
2398     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2399     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2400     MockRead("Proxy-Connection: close\r\n\r\n"),
2401
2402     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2403
2404     MockRead("HTTP/1.1 200 OK\r\n"),
2405     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2406     MockRead("Content-Length: 5\r\n\r\n"),
2407     MockRead(SYNCHRONOUS, "hello"),
2408   };
2409
2410   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2411                                  data_writes1, arraysize(data_writes1));
2412   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2413   SSLSocketDataProvider ssl(ASYNC, OK);
2414   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2415
2416   TestCompletionCallback callback1;
2417
2418   scoped_ptr<HttpTransaction> trans(
2419       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2420
2421   int rv = trans->Start(&request, callback1.callback(), log.bound());
2422   EXPECT_EQ(ERR_IO_PENDING, rv);
2423
2424   rv = callback1.WaitForResult();
2425   EXPECT_EQ(OK, rv);
2426   net::CapturingNetLog::CapturedEntryList entries;
2427   log.GetEntries(&entries);
2428   size_t pos = ExpectLogContainsSomewhere(
2429       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2430       NetLog::PHASE_NONE);
2431   ExpectLogContainsSomewhere(
2432       entries, pos,
2433       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2434       NetLog::PHASE_NONE);
2435
2436   const HttpResponseInfo* response = trans->GetResponseInfo();
2437   ASSERT_TRUE(response != NULL);
2438   ASSERT_FALSE(response->headers.get() == NULL);
2439   EXPECT_EQ(407, response->headers->response_code());
2440   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2441   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2442
2443   LoadTimingInfo load_timing_info;
2444   // CONNECT requests and responses are handled at the connect job level, so
2445   // the transaction does not yet have a connection.
2446   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2447
2448   TestCompletionCallback callback2;
2449
2450   rv = trans->RestartWithAuth(
2451       AuthCredentials(kFoo, kBar), callback2.callback());
2452   EXPECT_EQ(ERR_IO_PENDING, rv);
2453
2454   rv = callback2.WaitForResult();
2455   EXPECT_EQ(OK, rv);
2456
2457   response = trans->GetResponseInfo();
2458   ASSERT_TRUE(response != NULL);
2459
2460   EXPECT_TRUE(response->headers->IsKeepAlive());
2461   EXPECT_EQ(200, response->headers->response_code());
2462   EXPECT_EQ(5, response->headers->GetContentLength());
2463   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2464
2465   // The password prompt info should not be set.
2466   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2467
2468   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2469   TestLoadTimingNotReusedWithPac(load_timing_info,
2470                                  CONNECT_TIMING_HAS_SSL_TIMES);
2471
2472   trans.reset();
2473   session->CloseAllConnections();
2474 }
2475
2476 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2477 // proxy connection, when setting up an SSL tunnel.
2478 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
2479   HttpRequestInfo request;
2480   request.method = "GET";
2481   request.url = GURL("https://www.google.com/");
2482   // Ensure that proxy authentication is attempted even
2483   // when the no authentication data flag is set.
2484   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2485
2486   // Configure against proxy server "myproxy:70".
2487   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2488   CapturingBoundNetLog log;
2489   session_deps_.net_log = log.bound().net_log();
2490   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2491
2492   scoped_ptr<HttpTransaction> trans(
2493       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2494
2495   // Since we have proxy, should try to establish tunnel.
2496   MockWrite data_writes1[] = {
2497     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2498               "Host: www.google.com\r\n"
2499               "Proxy-Connection: keep-alive\r\n\r\n"),
2500
2501     // After calling trans->RestartWithAuth(), this is the request we should
2502     // be issuing -- the final header line contains the credentials.
2503     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2504               "Host: www.google.com\r\n"
2505               "Proxy-Connection: keep-alive\r\n"
2506               "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2507   };
2508
2509   // The proxy responds to the connect with a 407, using a persistent
2510   // connection.
2511   MockRead data_reads1[] = {
2512     // No credentials.
2513     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2514     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2515     MockRead("Content-Length: 10\r\n\r\n"),
2516     MockRead("0123456789"),
2517
2518     // Wrong credentials (wrong password).
2519     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2520     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2521     MockRead("Content-Length: 10\r\n\r\n"),
2522     // No response body because the test stops reading here.
2523     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
2524   };
2525
2526   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2527                                  data_writes1, arraysize(data_writes1));
2528   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2529
2530   TestCompletionCallback callback1;
2531
2532   int rv = trans->Start(&request, callback1.callback(), log.bound());
2533   EXPECT_EQ(ERR_IO_PENDING, rv);
2534
2535   rv = callback1.WaitForResult();
2536   EXPECT_EQ(OK, rv);
2537   net::CapturingNetLog::CapturedEntryList entries;
2538   log.GetEntries(&entries);
2539   size_t pos = ExpectLogContainsSomewhere(
2540       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2541       NetLog::PHASE_NONE);
2542   ExpectLogContainsSomewhere(
2543       entries, pos,
2544       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2545       NetLog::PHASE_NONE);
2546
2547   const HttpResponseInfo* response = trans->GetResponseInfo();
2548   ASSERT_TRUE(response != NULL);
2549   ASSERT_FALSE(response->headers.get() == NULL);
2550   EXPECT_TRUE(response->headers->IsKeepAlive());
2551   EXPECT_EQ(407, response->headers->response_code());
2552   EXPECT_EQ(10, response->headers->GetContentLength());
2553   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2554   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2555
2556   TestCompletionCallback callback2;
2557
2558   // Wrong password (should be "bar").
2559   rv = trans->RestartWithAuth(
2560       AuthCredentials(kFoo, kBaz), callback2.callback());
2561   EXPECT_EQ(ERR_IO_PENDING, rv);
2562
2563   rv = callback2.WaitForResult();
2564   EXPECT_EQ(OK, rv);
2565
2566   response = trans->GetResponseInfo();
2567   ASSERT_TRUE(response != NULL);
2568   ASSERT_FALSE(response->headers.get() == NULL);
2569   EXPECT_TRUE(response->headers->IsKeepAlive());
2570   EXPECT_EQ(407, response->headers->response_code());
2571   EXPECT_EQ(10, response->headers->GetContentLength());
2572   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2573   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2574
2575   // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2576   // out of scope.
2577   session->CloseAllConnections();
2578 }
2579
2580 // Test that we don't read the response body when we fail to establish a tunnel,
2581 // even if the user cancels the proxy's auth attempt.
2582 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
2583   HttpRequestInfo request;
2584   request.method = "GET";
2585   request.url = GURL("https://www.google.com/");
2586   request.load_flags = 0;
2587
2588   // Configure against proxy server "myproxy:70".
2589   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2590
2591   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2592
2593   scoped_ptr<HttpTransaction> trans(
2594       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2595
2596   // Since we have proxy, should try to establish tunnel.
2597   MockWrite data_writes[] = {
2598     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2599               "Host: www.google.com\r\n"
2600               "Proxy-Connection: keep-alive\r\n\r\n"),
2601   };
2602
2603   // The proxy responds to the connect with a 407.
2604   MockRead data_reads[] = {
2605     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2606     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2607     MockRead("Content-Length: 10\r\n\r\n"),
2608     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
2609   };
2610
2611   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2612                                 data_writes, arraysize(data_writes));
2613   session_deps_.socket_factory->AddSocketDataProvider(&data);
2614
2615   TestCompletionCallback callback;
2616
2617   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2618   EXPECT_EQ(ERR_IO_PENDING, rv);
2619
2620   rv = callback.WaitForResult();
2621   EXPECT_EQ(OK, rv);
2622
2623   const HttpResponseInfo* response = trans->GetResponseInfo();
2624   ASSERT_TRUE(response != NULL);
2625
2626   EXPECT_TRUE(response->headers->IsKeepAlive());
2627   EXPECT_EQ(407, response->headers->response_code());
2628   EXPECT_EQ(10, response->headers->GetContentLength());
2629   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2630
2631   std::string response_data;
2632   rv = ReadTransaction(trans.get(), &response_data);
2633   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
2634
2635   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
2636   session->CloseAllConnections();
2637 }
2638
2639 // Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2640 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
2641 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
2642   HttpRequestInfo request;
2643   request.method = "GET";
2644   request.url = GURL("http://www.google.com/");
2645   request.load_flags = 0;
2646
2647   // We are using a DIRECT connection (i.e. no proxy) for this session.
2648   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2649   scoped_ptr<HttpTransaction> trans(
2650       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2651
2652   MockWrite data_writes1[] = {
2653     MockWrite("GET / HTTP/1.1\r\n"
2654               "Host: www.google.com\r\n"
2655               "Connection: keep-alive\r\n\r\n"),
2656   };
2657
2658   MockRead data_reads1[] = {
2659     MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2660     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2661     // Large content-length -- won't matter, as connection will be reset.
2662     MockRead("Content-Length: 10000\r\n\r\n"),
2663     MockRead(SYNCHRONOUS, ERR_FAILED),
2664   };
2665
2666   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2667                                  data_writes1, arraysize(data_writes1));
2668   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2669
2670   TestCompletionCallback callback;
2671
2672   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2673   EXPECT_EQ(ERR_IO_PENDING, rv);
2674
2675   rv = callback.WaitForResult();
2676   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2677 }
2678
2679 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2680 // through a non-authenticating proxy. The request should fail with
2681 // ERR_UNEXPECTED_PROXY_AUTH.
2682 // Note that it is impossible to detect if an HTTP server returns a 407 through
2683 // a non-authenticating proxy - there is nothing to indicate whether the
2684 // response came from the proxy or the server, so it is treated as if the proxy
2685 // issued the challenge.
2686 TEST_P(HttpNetworkTransactionTest,
2687        HttpsServerRequestsProxyAuthThroughProxy) {
2688   HttpRequestInfo request;
2689   request.method = "GET";
2690   request.url = GURL("https://www.google.com/");
2691
2692   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2693   CapturingBoundNetLog log;
2694   session_deps_.net_log = log.bound().net_log();
2695   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2696
2697   // Since we have proxy, should try to establish tunnel.
2698   MockWrite data_writes1[] = {
2699     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2700               "Host: www.google.com\r\n"
2701               "Proxy-Connection: keep-alive\r\n\r\n"),
2702
2703     MockWrite("GET / HTTP/1.1\r\n"
2704               "Host: www.google.com\r\n"
2705               "Connection: keep-alive\r\n\r\n"),
2706   };
2707
2708   MockRead data_reads1[] = {
2709     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2710
2711     MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2712     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2713     MockRead("\r\n"),
2714     MockRead(SYNCHRONOUS, OK),
2715   };
2716
2717   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2718                                  data_writes1, arraysize(data_writes1));
2719   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2720   SSLSocketDataProvider ssl(ASYNC, OK);
2721   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2722
2723   TestCompletionCallback callback1;
2724
2725   scoped_ptr<HttpTransaction> trans(
2726       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2727
2728   int rv = trans->Start(&request, callback1.callback(), log.bound());
2729   EXPECT_EQ(ERR_IO_PENDING, rv);
2730
2731   rv = callback1.WaitForResult();
2732   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2733   net::CapturingNetLog::CapturedEntryList entries;
2734   log.GetEntries(&entries);
2735   size_t pos = ExpectLogContainsSomewhere(
2736       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2737       NetLog::PHASE_NONE);
2738   ExpectLogContainsSomewhere(
2739       entries, pos,
2740       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2741       NetLog::PHASE_NONE);
2742 }
2743
2744 // Test the load timing for HTTPS requests with an HTTP proxy.
2745 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
2746   HttpRequestInfo request1;
2747   request1.method = "GET";
2748   request1.url = GURL("https://www.google.com/1");
2749
2750   HttpRequestInfo request2;
2751   request2.method = "GET";
2752   request2.url = GURL("https://www.google.com/2");
2753
2754   // Configure against proxy server "myproxy:70".
2755   session_deps_.proxy_service.reset(
2756       ProxyService::CreateFixed("PROXY myproxy:70"));
2757   CapturingBoundNetLog log;
2758   session_deps_.net_log = log.bound().net_log();
2759   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2760
2761   // Since we have proxy, should try to establish tunnel.
2762   MockWrite data_writes1[] = {
2763     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2764               "Host: www.google.com\r\n"
2765               "Proxy-Connection: keep-alive\r\n\r\n"),
2766
2767     MockWrite("GET /1 HTTP/1.1\r\n"
2768               "Host: www.google.com\r\n"
2769               "Connection: keep-alive\r\n\r\n"),
2770
2771     MockWrite("GET /2 HTTP/1.1\r\n"
2772               "Host: www.google.com\r\n"
2773               "Connection: keep-alive\r\n\r\n"),
2774   };
2775
2776   // The proxy responds to the connect with a 407, using a persistent
2777   // connection.
2778   MockRead data_reads1[] = {
2779     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2780
2781     MockRead("HTTP/1.1 200 OK\r\n"),
2782     MockRead("Content-Length: 1\r\n\r\n"),
2783     MockRead(SYNCHRONOUS, "1"),
2784
2785     MockRead("HTTP/1.1 200 OK\r\n"),
2786     MockRead("Content-Length: 2\r\n\r\n"),
2787     MockRead(SYNCHRONOUS, "22"),
2788   };
2789
2790   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2791                                  data_writes1, arraysize(data_writes1));
2792   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2793   SSLSocketDataProvider ssl(ASYNC, OK);
2794   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2795
2796   TestCompletionCallback callback1;
2797   scoped_ptr<HttpTransaction> trans1(
2798       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2799
2800   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2801   EXPECT_EQ(ERR_IO_PENDING, rv);
2802
2803   rv = callback1.WaitForResult();
2804   EXPECT_EQ(OK, rv);
2805
2806   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2807   ASSERT_TRUE(response1 != NULL);
2808   ASSERT_TRUE(response1->headers.get() != NULL);
2809   EXPECT_EQ(1, response1->headers->GetContentLength());
2810
2811   LoadTimingInfo load_timing_info1;
2812   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2813   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2814
2815   trans1.reset();
2816
2817   TestCompletionCallback callback2;
2818   scoped_ptr<HttpTransaction> trans2(
2819       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2820
2821   rv = trans2->Start(&request2, callback2.callback(), log.bound());
2822   EXPECT_EQ(ERR_IO_PENDING, rv);
2823
2824   rv = callback2.WaitForResult();
2825   EXPECT_EQ(OK, rv);
2826
2827   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2828   ASSERT_TRUE(response2 != NULL);
2829   ASSERT_TRUE(response2->headers.get() != NULL);
2830   EXPECT_EQ(2, response2->headers->GetContentLength());
2831
2832   LoadTimingInfo load_timing_info2;
2833   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2834   TestLoadTimingReused(load_timing_info2);
2835
2836   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2837
2838   trans2.reset();
2839   session->CloseAllConnections();
2840 }
2841
2842 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
2843 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
2844   HttpRequestInfo request1;
2845   request1.method = "GET";
2846   request1.url = GURL("https://www.google.com/1");
2847
2848   HttpRequestInfo request2;
2849   request2.method = "GET";
2850   request2.url = GURL("https://www.google.com/2");
2851
2852   // Configure against proxy server "myproxy:70".
2853   session_deps_.proxy_service.reset(
2854       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2855   CapturingBoundNetLog log;
2856   session_deps_.net_log = log.bound().net_log();
2857   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2858
2859   // Since we have proxy, should try to establish tunnel.
2860   MockWrite data_writes1[] = {
2861     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2862               "Host: www.google.com\r\n"
2863               "Proxy-Connection: keep-alive\r\n\r\n"),
2864
2865     MockWrite("GET /1 HTTP/1.1\r\n"
2866               "Host: www.google.com\r\n"
2867               "Connection: keep-alive\r\n\r\n"),
2868
2869     MockWrite("GET /2 HTTP/1.1\r\n"
2870               "Host: www.google.com\r\n"
2871               "Connection: keep-alive\r\n\r\n"),
2872   };
2873
2874   // The proxy responds to the connect with a 407, using a persistent
2875   // connection.
2876   MockRead data_reads1[] = {
2877     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2878
2879     MockRead("HTTP/1.1 200 OK\r\n"),
2880     MockRead("Content-Length: 1\r\n\r\n"),
2881     MockRead(SYNCHRONOUS, "1"),
2882
2883     MockRead("HTTP/1.1 200 OK\r\n"),
2884     MockRead("Content-Length: 2\r\n\r\n"),
2885     MockRead(SYNCHRONOUS, "22"),
2886   };
2887
2888   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2889                                  data_writes1, arraysize(data_writes1));
2890   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2891   SSLSocketDataProvider ssl(ASYNC, OK);
2892   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2893
2894   TestCompletionCallback callback1;
2895   scoped_ptr<HttpTransaction> trans1(
2896       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2897
2898   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2899   EXPECT_EQ(ERR_IO_PENDING, rv);
2900
2901   rv = callback1.WaitForResult();
2902   EXPECT_EQ(OK, rv);
2903
2904   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2905   ASSERT_TRUE(response1 != NULL);
2906   ASSERT_TRUE(response1->headers.get() != NULL);
2907   EXPECT_EQ(1, response1->headers->GetContentLength());
2908
2909   LoadTimingInfo load_timing_info1;
2910   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2911   TestLoadTimingNotReusedWithPac(load_timing_info1,
2912                                  CONNECT_TIMING_HAS_SSL_TIMES);
2913
2914   trans1.reset();
2915
2916   TestCompletionCallback callback2;
2917   scoped_ptr<HttpTransaction> trans2(
2918       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2919
2920   rv = trans2->Start(&request2, callback2.callback(), log.bound());
2921   EXPECT_EQ(ERR_IO_PENDING, rv);
2922
2923   rv = callback2.WaitForResult();
2924   EXPECT_EQ(OK, rv);
2925
2926   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2927   ASSERT_TRUE(response2 != NULL);
2928   ASSERT_TRUE(response2->headers.get() != NULL);
2929   EXPECT_EQ(2, response2->headers->GetContentLength());
2930
2931   LoadTimingInfo load_timing_info2;
2932   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2933   TestLoadTimingReusedWithPac(load_timing_info2);
2934
2935   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2936
2937   trans2.reset();
2938   session->CloseAllConnections();
2939 }
2940
2941 // Test a simple get through an HTTPS Proxy.
2942 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
2943   HttpRequestInfo request;
2944   request.method = "GET";
2945   request.url = GURL("http://www.google.com/");
2946
2947   // Configure against https proxy server "proxy:70".
2948   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
2949       "https://proxy:70"));
2950   CapturingBoundNetLog log;
2951   session_deps_.net_log = log.bound().net_log();
2952   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2953
2954   // Since we have proxy, should use full url
2955   MockWrite data_writes1[] = {
2956     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2957               "Host: www.google.com\r\n"
2958               "Proxy-Connection: keep-alive\r\n\r\n"),
2959   };
2960
2961   MockRead data_reads1[] = {
2962     MockRead("HTTP/1.1 200 OK\r\n"),
2963     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2964     MockRead("Content-Length: 100\r\n\r\n"),
2965     MockRead(SYNCHRONOUS, OK),
2966   };
2967
2968   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2969                                  data_writes1, arraysize(data_writes1));
2970   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2971   SSLSocketDataProvider ssl(ASYNC, OK);
2972   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2973
2974   TestCompletionCallback callback1;
2975
2976   scoped_ptr<HttpTransaction> trans(
2977       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2978
2979   int rv = trans->Start(&request, callback1.callback(), log.bound());
2980   EXPECT_EQ(ERR_IO_PENDING, rv);
2981
2982   rv = callback1.WaitForResult();
2983   EXPECT_EQ(OK, rv);
2984
2985   LoadTimingInfo load_timing_info;
2986   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2987   TestLoadTimingNotReused(load_timing_info,
2988                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2989
2990   const HttpResponseInfo* response = trans->GetResponseInfo();
2991   ASSERT_TRUE(response != NULL);
2992
2993   EXPECT_TRUE(response->headers->IsKeepAlive());
2994   EXPECT_EQ(200, response->headers->response_code());
2995   EXPECT_EQ(100, response->headers->GetContentLength());
2996   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2997
2998   // The password prompt info should not be set.
2999   EXPECT_TRUE(response->auth_challenge.get() == NULL);
3000 }
3001
3002 // Test a SPDY get through an HTTPS Proxy.
3003 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
3004   HttpRequestInfo request;
3005   request.method = "GET";
3006   request.url = GURL("http://www.google.com/");
3007   request.load_flags = 0;
3008
3009   // Configure against https proxy server "proxy:70".
3010   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3011       "https://proxy:70"));
3012   CapturingBoundNetLog log;
3013   session_deps_.net_log = log.bound().net_log();
3014   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3015
3016   // fetch http://www.google.com/ via SPDY
3017   scoped_ptr<SpdyFrame> req(
3018       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3019   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
3020
3021   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3022   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3023   MockRead spdy_reads[] = {
3024     CreateMockRead(*resp),
3025     CreateMockRead(*data),
3026     MockRead(ASYNC, 0, 0),
3027   };
3028
3029   DelayedSocketData spdy_data(
3030       1,  // wait for one write to finish before reading.
3031       spdy_reads, arraysize(spdy_reads),
3032       spdy_writes, arraysize(spdy_writes));
3033   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3034
3035   SSLSocketDataProvider ssl(ASYNC, OK);
3036   ssl.SetNextProto(GetParam());
3037   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3038
3039   TestCompletionCallback callback1;
3040
3041   scoped_ptr<HttpTransaction> trans(
3042       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3043
3044   int rv = trans->Start(&request, callback1.callback(), log.bound());
3045   EXPECT_EQ(ERR_IO_PENDING, rv);
3046
3047   rv = callback1.WaitForResult();
3048   EXPECT_EQ(OK, rv);
3049
3050   LoadTimingInfo load_timing_info;
3051   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3052   TestLoadTimingNotReused(load_timing_info,
3053                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3054
3055   const HttpResponseInfo* response = trans->GetResponseInfo();
3056   ASSERT_TRUE(response != NULL);
3057   ASSERT_TRUE(response->headers.get() != NULL);
3058   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3059
3060   std::string response_data;
3061   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3062   EXPECT_EQ(kUploadData, response_data);
3063 }
3064
3065 // Verifies that a session which races and wins against the owning transaction
3066 // (completing prior to host resolution), doesn't fail the transaction.
3067 // Regression test for crbug.com/334413.
3068 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3069   HttpRequestInfo request;
3070   request.method = "GET";
3071   request.url = GURL("http://www.google.com/");
3072   request.load_flags = 0;
3073
3074   // Configure SPDY proxy server "proxy:70".
3075   session_deps_.proxy_service.reset(
3076       ProxyService::CreateFixed("https://proxy:70"));
3077   CapturingBoundNetLog log;
3078   session_deps_.net_log = log.bound().net_log();
3079   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3080
3081   // Fetch http://www.google.com/ through the SPDY proxy.
3082   scoped_ptr<SpdyFrame> req(
3083       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3084   MockWrite spdy_writes[] = {CreateMockWrite(*req)};
3085
3086   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3087   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3088   MockRead spdy_reads[] = {
3089       CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
3090   };
3091
3092   DelayedSocketData spdy_data(
3093       1,  // wait for one write to finish before reading.
3094       spdy_reads,
3095       arraysize(spdy_reads),
3096       spdy_writes,
3097       arraysize(spdy_writes));
3098   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3099
3100   SSLSocketDataProvider ssl(ASYNC, OK);
3101   ssl.SetNextProto(GetParam());
3102   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3103
3104   TestCompletionCallback callback1;
3105
3106   scoped_ptr<HttpTransaction> trans(
3107       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3108
3109   // Stall the hostname resolution begun by the transaction.
3110   session_deps_.host_resolver->set_synchronous_mode(false);
3111   session_deps_.host_resolver->set_ondemand_mode(true);
3112
3113   int rv = trans->Start(&request, callback1.callback(), log.bound());
3114   EXPECT_EQ(ERR_IO_PENDING, rv);
3115
3116   // Race a session to the proxy, which completes first.
3117   session_deps_.host_resolver->set_ondemand_mode(false);
3118   SpdySessionKey key(
3119       HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3120   base::WeakPtr<SpdySession> spdy_session =
3121       CreateSecureSpdySession(session, key, log.bound());
3122
3123   // Unstall the resolution begun by the transaction.
3124   session_deps_.host_resolver->set_ondemand_mode(true);
3125   session_deps_.host_resolver->ResolveAllPending();
3126
3127   EXPECT_FALSE(callback1.have_result());
3128   rv = callback1.WaitForResult();
3129   EXPECT_EQ(OK, rv);
3130
3131   const HttpResponseInfo* response = trans->GetResponseInfo();
3132   ASSERT_TRUE(response != NULL);
3133   ASSERT_TRUE(response->headers.get() != NULL);
3134   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3135
3136   std::string response_data;
3137   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3138   EXPECT_EQ(kUploadData, response_data);
3139 }
3140
3141 // Test a SPDY get through an HTTPS Proxy.
3142 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
3143   HttpRequestInfo request;
3144   request.method = "GET";
3145   request.url = GURL("http://www.google.com/");
3146   request.load_flags = 0;
3147
3148   // Configure against https proxy server "myproxy:70".
3149   session_deps_.proxy_service.reset(
3150       ProxyService::CreateFixed("https://myproxy:70"));
3151   CapturingBoundNetLog log;
3152   session_deps_.net_log = log.bound().net_log();
3153   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3154
3155   // The first request will be a bare GET, the second request will be a
3156   // GET with a Proxy-Authorization header.
3157   scoped_ptr<SpdyFrame> req_get(
3158       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3159   const char* const kExtraAuthorizationHeaders[] = {
3160     "proxy-authorization", "Basic Zm9vOmJhcg=="
3161   };
3162   scoped_ptr<SpdyFrame> req_get_authorization(
3163       spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3164                                   arraysize(kExtraAuthorizationHeaders) / 2,
3165                                   false,
3166                                   3,
3167                                   LOWEST,
3168                                   false));
3169   MockWrite spdy_writes[] = {
3170     CreateMockWrite(*req_get, 1),
3171     CreateMockWrite(*req_get_authorization, 4),
3172   };
3173
3174   // The first response is a 407 proxy authentication challenge, and the second
3175   // response will be a 200 response since the second request includes a valid
3176   // Authorization header.
3177   const char* const kExtraAuthenticationHeaders[] = {
3178     "proxy-authenticate", "Basic realm=\"MyRealm1\""
3179   };
3180   scoped_ptr<SpdyFrame> resp_authentication(
3181       spdy_util_.ConstructSpdySynReplyError(
3182           "407 Proxy Authentication Required",
3183           kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3184           1));
3185   scoped_ptr<SpdyFrame> body_authentication(
3186       spdy_util_.ConstructSpdyBodyFrame(1, true));
3187   scoped_ptr<SpdyFrame> resp_data(
3188       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3189   scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
3190   MockRead spdy_reads[] = {
3191     CreateMockRead(*resp_authentication, 2),
3192     CreateMockRead(*body_authentication, 3),
3193     CreateMockRead(*resp_data, 5),
3194     CreateMockRead(*body_data, 6),
3195     MockRead(ASYNC, 0, 7),
3196   };
3197
3198   OrderedSocketData data(
3199       spdy_reads, arraysize(spdy_reads),
3200       spdy_writes, arraysize(spdy_writes));
3201   session_deps_.socket_factory->AddSocketDataProvider(&data);
3202
3203   SSLSocketDataProvider ssl(ASYNC, OK);
3204   ssl.SetNextProto(GetParam());
3205   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3206
3207   TestCompletionCallback callback1;
3208
3209   scoped_ptr<HttpTransaction> trans(
3210       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3211
3212   int rv = trans->Start(&request, callback1.callback(), log.bound());
3213   EXPECT_EQ(ERR_IO_PENDING, rv);
3214
3215   rv = callback1.WaitForResult();
3216   EXPECT_EQ(OK, rv);
3217
3218   const HttpResponseInfo* const response = trans->GetResponseInfo();
3219
3220   ASSERT_TRUE(response != NULL);
3221   ASSERT_TRUE(response->headers.get() != NULL);
3222   EXPECT_EQ(407, response->headers->response_code());
3223   EXPECT_TRUE(response->was_fetched_via_spdy);
3224   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3225
3226   TestCompletionCallback callback2;
3227
3228   rv = trans->RestartWithAuth(
3229       AuthCredentials(kFoo, kBar), callback2.callback());
3230   EXPECT_EQ(ERR_IO_PENDING, rv);
3231
3232   rv = callback2.WaitForResult();
3233   EXPECT_EQ(OK, rv);
3234
3235   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3236
3237   ASSERT_TRUE(response_restart != NULL);
3238   ASSERT_TRUE(response_restart->headers.get() != NULL);
3239   EXPECT_EQ(200, response_restart->headers->response_code());
3240   // The password prompt info should not be set.
3241   EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3242 }
3243
3244 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
3245 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
3246   HttpRequestInfo request;
3247   request.method = "GET";
3248   request.url = GURL("https://www.google.com/");
3249   request.load_flags = 0;
3250
3251   // Configure against https proxy server "proxy:70".
3252   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3253       "https://proxy:70"));
3254   CapturingBoundNetLog log;
3255   session_deps_.net_log = log.bound().net_log();
3256   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3257
3258   scoped_ptr<HttpTransaction> trans(
3259       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3260
3261   // CONNECT to www.google.com:443 via SPDY
3262   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3263                                                                 LOWEST));
3264   // fetch https://www.google.com/ via HTTP
3265
3266   const char get[] = "GET / HTTP/1.1\r\n"
3267     "Host: www.google.com\r\n"
3268     "Connection: keep-alive\r\n\r\n";
3269   scoped_ptr<SpdyFrame> wrapped_get(
3270       spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3271   scoped_ptr<SpdyFrame> conn_resp(
3272       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3273   const char resp[] = "HTTP/1.1 200 OK\r\n"
3274       "Content-Length: 10\r\n\r\n";
3275   scoped_ptr<SpdyFrame> wrapped_get_resp(
3276       spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
3277   scoped_ptr<SpdyFrame> wrapped_body(
3278       spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
3279   scoped_ptr<SpdyFrame> window_update(
3280       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
3281
3282   MockWrite spdy_writes[] = {
3283       CreateMockWrite(*connect, 1),
3284       CreateMockWrite(*wrapped_get, 3),
3285       CreateMockWrite(*window_update, 5),
3286   };
3287
3288   MockRead spdy_reads[] = {
3289     CreateMockRead(*conn_resp, 2, ASYNC),
3290     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3291     CreateMockRead(*wrapped_body, 6, ASYNC),
3292     CreateMockRead(*wrapped_body, 7, ASYNC),
3293     MockRead(ASYNC, 0, 8),
3294   };
3295
3296   OrderedSocketData spdy_data(
3297       spdy_reads, arraysize(spdy_reads),
3298       spdy_writes, arraysize(spdy_writes));
3299   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3300
3301   SSLSocketDataProvider ssl(ASYNC, OK);
3302   ssl.SetNextProto(GetParam());
3303   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3304   SSLSocketDataProvider ssl2(ASYNC, OK);
3305   ssl2.was_npn_negotiated = false;
3306   ssl2.protocol_negotiated = kProtoUnknown;
3307   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
3308
3309   TestCompletionCallback callback1;
3310
3311   int rv = trans->Start(&request, callback1.callback(), log.bound());
3312   EXPECT_EQ(ERR_IO_PENDING, rv);
3313
3314   rv = callback1.WaitForResult();
3315   EXPECT_EQ(OK, rv);
3316
3317   LoadTimingInfo load_timing_info;
3318   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3319   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3320
3321   const HttpResponseInfo* response = trans->GetResponseInfo();
3322   ASSERT_TRUE(response != NULL);
3323   ASSERT_TRUE(response->headers.get() != NULL);
3324   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3325
3326   std::string response_data;
3327   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3328   EXPECT_EQ("1234567890", response_data);
3329 }
3330
3331 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
3332 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
3333   HttpRequestInfo request;
3334   request.method = "GET";
3335   request.url = GURL("https://www.google.com/");
3336   request.load_flags = 0;
3337
3338   // Configure against https proxy server "proxy:70".
3339   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3340       "https://proxy:70"));
3341   CapturingBoundNetLog log;
3342   session_deps_.net_log = log.bound().net_log();
3343   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3344
3345   scoped_ptr<HttpTransaction> trans(
3346       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3347
3348   // CONNECT to www.google.com:443 via SPDY
3349   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3350                                                                 LOWEST));
3351   // fetch https://www.google.com/ via SPDY
3352   const char* const kMyUrl = "https://www.google.com/";
3353   scoped_ptr<SpdyFrame> get(
3354       spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
3355   scoped_ptr<SpdyFrame> wrapped_get(
3356       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3357   scoped_ptr<SpdyFrame> conn_resp(
3358       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3359   scoped_ptr<SpdyFrame> get_resp(
3360       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3361   scoped_ptr<SpdyFrame> wrapped_get_resp(
3362       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3363   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3364   scoped_ptr<SpdyFrame> wrapped_body(
3365       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
3366   scoped_ptr<SpdyFrame> window_update_get_resp(
3367       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
3368   scoped_ptr<SpdyFrame> window_update_body(
3369       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
3370
3371   MockWrite spdy_writes[] = {
3372       CreateMockWrite(*connect, 1),
3373       CreateMockWrite(*wrapped_get, 3),
3374       CreateMockWrite(*window_update_get_resp, 5),
3375       CreateMockWrite(*window_update_body, 7),
3376   };
3377
3378   MockRead spdy_reads[] = {
3379     CreateMockRead(*conn_resp, 2, ASYNC),
3380     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3381     CreateMockRead(*wrapped_body, 6, ASYNC),
3382     MockRead(ASYNC, 0, 8),
3383   };
3384
3385   OrderedSocketData spdy_data(
3386       spdy_reads, arraysize(spdy_reads),
3387       spdy_writes, arraysize(spdy_writes));
3388   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3389
3390   SSLSocketDataProvider ssl(ASYNC, OK);
3391   ssl.SetNextProto(GetParam());
3392   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3393   SSLSocketDataProvider ssl2(ASYNC, OK);
3394   ssl2.SetNextProto(GetParam());
3395   ssl2.protocol_negotiated = GetParam();
3396   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
3397
3398   TestCompletionCallback callback1;
3399
3400   int rv = trans->Start(&request, callback1.callback(), log.bound());
3401   EXPECT_EQ(ERR_IO_PENDING, rv);
3402
3403   rv = callback1.WaitForResult();
3404   EXPECT_EQ(OK, rv);
3405
3406   LoadTimingInfo load_timing_info;
3407   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3408   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3409
3410   const HttpResponseInfo* response = trans->GetResponseInfo();
3411   ASSERT_TRUE(response != NULL);
3412   ASSERT_TRUE(response->headers.get() != NULL);
3413   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3414
3415   std::string response_data;
3416   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3417   EXPECT_EQ(kUploadData, response_data);
3418 }
3419
3420 // Test a SPDY CONNECT failure through an HTTPS Proxy.
3421 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
3422   HttpRequestInfo request;
3423   request.method = "GET";
3424   request.url = GURL("https://www.google.com/");
3425   request.load_flags = 0;
3426
3427   // Configure against https proxy server "proxy:70".
3428   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3429       "https://proxy:70"));
3430   CapturingBoundNetLog log;
3431   session_deps_.net_log = log.bound().net_log();
3432   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3433
3434   scoped_ptr<HttpTransaction> trans(
3435       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3436
3437   // CONNECT to www.google.com:443 via SPDY
3438   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3439                                                                 LOWEST));
3440   scoped_ptr<SpdyFrame> get(
3441       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
3442
3443   MockWrite spdy_writes[] = {
3444       CreateMockWrite(*connect, 1),
3445       CreateMockWrite(*get, 3),
3446   };
3447
3448   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3449   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3450   MockRead spdy_reads[] = {
3451     CreateMockRead(*resp, 2, ASYNC),
3452     MockRead(ASYNC, 0, 4),
3453   };
3454
3455   OrderedSocketData spdy_data(
3456       spdy_reads, arraysize(spdy_reads),
3457       spdy_writes, arraysize(spdy_writes));
3458   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3459
3460   SSLSocketDataProvider ssl(ASYNC, OK);
3461   ssl.SetNextProto(GetParam());
3462   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3463   SSLSocketDataProvider ssl2(ASYNC, OK);
3464   ssl2.SetNextProto(GetParam());
3465   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
3466
3467   TestCompletionCallback callback1;
3468
3469   int rv = trans->Start(&request, callback1.callback(), log.bound());
3470   EXPECT_EQ(ERR_IO_PENDING, rv);
3471
3472   rv = callback1.WaitForResult();
3473   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3474
3475   // TODO(ttuttle): Anything else to check here?
3476 }
3477
3478 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3479 // HTTPS Proxy to different servers.
3480 TEST_P(HttpNetworkTransactionTest,
3481        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3482   // Configure against https proxy server "proxy:70".
3483   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3484       "https://proxy:70"));
3485   CapturingBoundNetLog log;
3486   session_deps_.net_log = log.bound().net_log();
3487   scoped_refptr<HttpNetworkSession> session(
3488       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
3489
3490   HttpRequestInfo request1;
3491   request1.method = "GET";
3492   request1.url = GURL("https://www.google.com/");
3493   request1.load_flags = 0;
3494
3495   HttpRequestInfo request2;
3496   request2.method = "GET";
3497   request2.url = GURL("https://news.google.com/");
3498   request2.load_flags = 0;
3499
3500   // CONNECT to www.google.com:443 via SPDY.
3501   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3502                                                                  LOWEST));
3503   scoped_ptr<SpdyFrame> conn_resp1(
3504       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3505
3506   // Fetch https://www.google.com/ via HTTP.
3507   const char get1[] = "GET / HTTP/1.1\r\n"
3508       "Host: www.google.com\r\n"
3509       "Connection: keep-alive\r\n\r\n";
3510   scoped_ptr<SpdyFrame> wrapped_get1(
3511       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
3512   const char resp1[] = "HTTP/1.1 200 OK\r\n"
3513       "Content-Length: 1\r\n\r\n";
3514   scoped_ptr<SpdyFrame> wrapped_get_resp1(
3515       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3516   scoped_ptr<SpdyFrame> wrapped_body1(
3517       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
3518   scoped_ptr<SpdyFrame> window_update(
3519       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
3520
3521   // CONNECT to news.google.com:443 via SPDY.
3522   SpdyHeaderBlock connect2_block;
3523   connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
3524   connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443";
3525   connect2_block[spdy_util_.GetHostKey()] = "news.google.com";
3526   spdy_util_.MaybeAddVersionHeader(&connect2_block);
3527   scoped_ptr<SpdyFrame> connect2(
3528       spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
3529
3530   scoped_ptr<SpdyFrame> conn_resp2(
3531       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3532
3533   // Fetch https://news.google.com/ via HTTP.
3534   const char get2[] = "GET / HTTP/1.1\r\n"
3535       "Host: news.google.com\r\n"
3536       "Connection: keep-alive\r\n\r\n";
3537   scoped_ptr<SpdyFrame> wrapped_get2(
3538       spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
3539   const char resp2[] = "HTTP/1.1 200 OK\r\n"
3540       "Content-Length: 2\r\n\r\n";
3541   scoped_ptr<SpdyFrame> wrapped_get_resp2(
3542       spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
3543   scoped_ptr<SpdyFrame> wrapped_body2(
3544       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
3545
3546   MockWrite spdy_writes[] = {
3547       CreateMockWrite(*connect1, 0),
3548       CreateMockWrite(*wrapped_get1, 2),
3549       CreateMockWrite(*connect2, 5),
3550       CreateMockWrite(*wrapped_get2, 7),
3551   };
3552
3553   MockRead spdy_reads[] = {
3554     CreateMockRead(*conn_resp1, 1, ASYNC),
3555     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3556     CreateMockRead(*wrapped_body1, 4, ASYNC),
3557     CreateMockRead(*conn_resp2, 6, ASYNC),
3558     CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3559     CreateMockRead(*wrapped_body2, 9, ASYNC),
3560     MockRead(ASYNC, 0, 10),
3561   };
3562
3563   DeterministicSocketData spdy_data(
3564       spdy_reads, arraysize(spdy_reads),
3565       spdy_writes, arraysize(spdy_writes));
3566   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
3567
3568   SSLSocketDataProvider ssl(ASYNC, OK);
3569   ssl.SetNextProto(GetParam());
3570   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3571   SSLSocketDataProvider ssl2(ASYNC, OK);
3572   ssl2.was_npn_negotiated = false;
3573   ssl2.protocol_negotiated = kProtoUnknown;
3574   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
3575   SSLSocketDataProvider ssl3(ASYNC, OK);
3576   ssl3.was_npn_negotiated = false;
3577   ssl3.protocol_negotiated = kProtoUnknown;
3578   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
3579
3580   TestCompletionCallback callback;
3581
3582   scoped_ptr<HttpTransaction> trans(
3583       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3584   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3585   EXPECT_EQ(ERR_IO_PENDING, rv);
3586   // The first connect and request, each of their responses, and the body.
3587   spdy_data.RunFor(5);
3588
3589   rv = callback.WaitForResult();
3590   EXPECT_EQ(OK, rv);
3591
3592   LoadTimingInfo load_timing_info;
3593   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3594   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3595
3596   const HttpResponseInfo* response = trans->GetResponseInfo();
3597   ASSERT_TRUE(response != NULL);
3598   ASSERT_TRUE(response->headers.get() != NULL);
3599   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3600
3601   std::string response_data;
3602   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3603   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
3604
3605   scoped_ptr<HttpTransaction> trans2(
3606       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3607   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3608   EXPECT_EQ(ERR_IO_PENDING, rv);
3609
3610   // The second connect and request, each of their responses, and the body.
3611   spdy_data.RunFor(5);
3612   rv = callback.WaitForResult();
3613   EXPECT_EQ(OK, rv);
3614
3615   LoadTimingInfo load_timing_info2;
3616   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3617   // Even though the SPDY connection is reused, a new tunnelled connection has
3618   // to be created, so the socket's load timing looks like a fresh connection.
3619   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3620
3621   // The requests should have different IDs, since they each are using their own
3622   // separate stream.
3623   EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3624
3625   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
3626 }
3627
3628 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3629 // HTTPS Proxy to the same server.
3630 TEST_P(HttpNetworkTransactionTest,
3631        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3632   // Configure against https proxy server "proxy:70".
3633   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3634       "https://proxy:70"));
3635   CapturingBoundNetLog log;
3636   session_deps_.net_log = log.bound().net_log();
3637   scoped_refptr<HttpNetworkSession> session(
3638       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
3639
3640   HttpRequestInfo request1;
3641   request1.method = "GET";
3642   request1.url = GURL("https://www.google.com/");
3643   request1.load_flags = 0;
3644
3645   HttpRequestInfo request2;
3646   request2.method = "GET";
3647   request2.url = GURL("https://www.google.com/2");
3648   request2.load_flags = 0;
3649
3650   // CONNECT to www.google.com:443 via SPDY.
3651   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3652                                                                  LOWEST));
3653   scoped_ptr<SpdyFrame> conn_resp1(
3654       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3655
3656   // Fetch https://www.google.com/ via HTTP.
3657   const char get1[] = "GET / HTTP/1.1\r\n"
3658       "Host: www.google.com\r\n"
3659       "Connection: keep-alive\r\n\r\n";
3660   scoped_ptr<SpdyFrame> wrapped_get1(
3661       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
3662   const char resp1[] = "HTTP/1.1 200 OK\r\n"
3663       "Content-Length: 1\r\n\r\n";
3664   scoped_ptr<SpdyFrame> wrapped_get_resp1(
3665       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3666   scoped_ptr<SpdyFrame> wrapped_body1(
3667       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
3668   scoped_ptr<SpdyFrame> window_update(
3669       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
3670
3671   // Fetch https://www.google.com/2 via HTTP.
3672   const char get2[] = "GET /2 HTTP/1.1\r\n"
3673       "Host: www.google.com\r\n"
3674       "Connection: keep-alive\r\n\r\n";
3675   scoped_ptr<SpdyFrame> wrapped_get2(
3676       spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
3677   const char resp2[] = "HTTP/1.1 200 OK\r\n"
3678       "Content-Length: 2\r\n\r\n";
3679   scoped_ptr<SpdyFrame> wrapped_get_resp2(
3680       spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
3681   scoped_ptr<SpdyFrame> wrapped_body2(
3682       spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
3683
3684   MockWrite spdy_writes[] = {
3685       CreateMockWrite(*connect1, 0),
3686       CreateMockWrite(*wrapped_get1, 2),
3687       CreateMockWrite(*wrapped_get2, 5),
3688   };
3689
3690   MockRead spdy_reads[] = {
3691     CreateMockRead(*conn_resp1, 1, ASYNC),
3692     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3693     CreateMockRead(*wrapped_body1, 4, ASYNC),
3694     CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3695     CreateMockRead(*wrapped_body2, 7, ASYNC),
3696     MockRead(ASYNC, 0, 8),
3697   };
3698
3699   DeterministicSocketData spdy_data(
3700       spdy_reads, arraysize(spdy_reads),
3701       spdy_writes, arraysize(spdy_writes));
3702   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
3703
3704   SSLSocketDataProvider ssl(ASYNC, OK);
3705   ssl.SetNextProto(GetParam());
3706   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3707   SSLSocketDataProvider ssl2(ASYNC, OK);
3708   ssl2.was_npn_negotiated = false;
3709   ssl2.protocol_negotiated = kProtoUnknown;
3710   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
3711
3712   TestCompletionCallback callback;
3713
3714   scoped_ptr<HttpTransaction> trans(
3715       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3716   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3717   EXPECT_EQ(ERR_IO_PENDING, rv);
3718   // The first connect and request, each of their responses, and the body.
3719   spdy_data.RunFor(5);
3720
3721   rv = callback.WaitForResult();
3722   EXPECT_EQ(OK, rv);
3723
3724   LoadTimingInfo load_timing_info;
3725   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3726   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3727
3728   const HttpResponseInfo* response = trans->GetResponseInfo();
3729   ASSERT_TRUE(response != NULL);
3730   ASSERT_TRUE(response->headers.get() != NULL);
3731   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3732
3733   std::string response_data;
3734   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3735   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
3736   trans.reset();
3737
3738   scoped_ptr<HttpTransaction> trans2(
3739       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3740   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3741   EXPECT_EQ(ERR_IO_PENDING, rv);
3742
3743   // The second request, response, and body.  There should not be a second
3744   // connect.
3745   spdy_data.RunFor(3);
3746   rv = callback.WaitForResult();
3747   EXPECT_EQ(OK, rv);
3748
3749   LoadTimingInfo load_timing_info2;
3750   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3751   TestLoadTimingReused(load_timing_info2);
3752
3753   // The requests should have the same ID.
3754   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3755
3756   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
3757 }
3758
3759 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3760 // Proxy to different servers.
3761 TEST_P(HttpNetworkTransactionTest,
3762        HttpsProxySpdyLoadTimingTwoHttpRequests) {
3763   // Configure against https proxy server "proxy:70".
3764   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3765       "https://proxy:70"));
3766   CapturingBoundNetLog log;
3767   session_deps_.net_log = log.bound().net_log();
3768   scoped_refptr<HttpNetworkSession> session(
3769       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
3770
3771   HttpRequestInfo request1;
3772   request1.method = "GET";
3773   request1.url = GURL("http://www.google.com/");
3774   request1.load_flags = 0;
3775
3776   HttpRequestInfo request2;
3777   request2.method = "GET";
3778   request2.url = GURL("http://news.google.com/");
3779   request2.load_flags = 0;
3780
3781   // http://www.google.com/
3782   scoped_ptr<SpdyHeaderBlock> headers(
3783       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
3784   scoped_ptr<SpdyFrame> get1(
3785       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
3786   scoped_ptr<SpdyFrame> get_resp1(
3787       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3788   scoped_ptr<SpdyFrame> body1(
3789       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
3790
3791   // http://news.google.com/
3792   scoped_ptr<SpdyHeaderBlock> headers2(
3793       spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
3794   scoped_ptr<SpdyFrame> get2(
3795       spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
3796   scoped_ptr<SpdyFrame> get_resp2(
3797       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3798   scoped_ptr<SpdyFrame> body2(
3799       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
3800
3801   MockWrite spdy_writes[] = {
3802       CreateMockWrite(*get1, 0),
3803       CreateMockWrite(*get2, 3),
3804   };
3805
3806   MockRead spdy_reads[] = {
3807     CreateMockRead(*get_resp1, 1, ASYNC),
3808     CreateMockRead(*body1, 2, ASYNC),
3809     CreateMockRead(*get_resp2, 4, ASYNC),
3810     CreateMockRead(*body2, 5, ASYNC),
3811     MockRead(ASYNC, 0, 6),
3812   };
3813
3814   DeterministicSocketData spdy_data(
3815       spdy_reads, arraysize(spdy_reads),
3816       spdy_writes, arraysize(spdy_writes));
3817   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
3818
3819   SSLSocketDataProvider ssl(ASYNC, OK);
3820   ssl.SetNextProto(GetParam());
3821   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3822
3823   TestCompletionCallback callback;
3824
3825   scoped_ptr<HttpTransaction> trans(
3826       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3827   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3828   EXPECT_EQ(ERR_IO_PENDING, rv);
3829   spdy_data.RunFor(2);
3830
3831   rv = callback.WaitForResult();
3832   EXPECT_EQ(OK, rv);
3833
3834   LoadTimingInfo load_timing_info;
3835   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3836   TestLoadTimingNotReused(load_timing_info,
3837                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3838
3839   const HttpResponseInfo* response = trans->GetResponseInfo();
3840   ASSERT_TRUE(response != NULL);
3841   ASSERT_TRUE(response->headers.get() != NULL);
3842   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3843
3844   std::string response_data;
3845   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3846   EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
3847   spdy_data.RunFor(1);
3848   EXPECT_EQ(1, callback.WaitForResult());
3849   // Delete the first request, so the second one can reuse the socket.
3850   trans.reset();
3851
3852   scoped_ptr<HttpTransaction> trans2(
3853       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3854   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3855   EXPECT_EQ(ERR_IO_PENDING, rv);
3856
3857   spdy_data.RunFor(2);
3858   rv = callback.WaitForResult();
3859   EXPECT_EQ(OK, rv);
3860
3861   LoadTimingInfo load_timing_info2;
3862   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3863   TestLoadTimingReused(load_timing_info2);
3864
3865   // The requests should have the same ID.
3866   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3867
3868   EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
3869   spdy_data.RunFor(1);
3870   EXPECT_EQ(2, callback.WaitForResult());
3871 }
3872
3873 // Test the challenge-response-retry sequence through an HTTPS Proxy
3874 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
3875   HttpRequestInfo request;
3876   request.method = "GET";
3877   request.url = GURL("http://www.google.com/");
3878   // when the no authentication data flag is set.
3879   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3880
3881   // Configure against https proxy server "myproxy:70".
3882   session_deps_.proxy_service.reset(
3883       ProxyService::CreateFixed("https://myproxy:70"));
3884   CapturingBoundNetLog log;
3885   session_deps_.net_log = log.bound().net_log();
3886   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3887
3888   // Since we have proxy, should use full url
3889   MockWrite data_writes1[] = {
3890     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3891               "Host: www.google.com\r\n"
3892               "Proxy-Connection: keep-alive\r\n\r\n"),
3893
3894     // After calling trans->RestartWithAuth(), this is the request we should
3895     // be issuing -- the final header line contains the credentials.
3896     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3897               "Host: www.google.com\r\n"
3898               "Proxy-Connection: keep-alive\r\n"
3899               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3900   };
3901
3902   // The proxy responds to the GET with a 407, using a persistent
3903   // connection.
3904   MockRead data_reads1[] = {
3905     // No credentials.
3906     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3907     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3908     MockRead("Proxy-Connection: keep-alive\r\n"),
3909     MockRead("Content-Length: 0\r\n\r\n"),
3910
3911     MockRead("HTTP/1.1 200 OK\r\n"),
3912     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3913     MockRead("Content-Length: 100\r\n\r\n"),
3914     MockRead(SYNCHRONOUS, OK),
3915   };
3916
3917   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3918                                  data_writes1, arraysize(data_writes1));
3919   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3920   SSLSocketDataProvider ssl(ASYNC, OK);
3921   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3922
3923   TestCompletionCallback callback1;
3924
3925   scoped_ptr<HttpTransaction> trans(
3926       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3927
3928   int rv = trans->Start(&request, callback1.callback(), log.bound());
3929   EXPECT_EQ(ERR_IO_PENDING, rv);
3930
3931   rv = callback1.WaitForResult();
3932   EXPECT_EQ(OK, rv);
3933
3934   LoadTimingInfo load_timing_info;
3935   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3936   TestLoadTimingNotReused(load_timing_info,
3937                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3938
3939   const HttpResponseInfo* response = trans->GetResponseInfo();
3940   ASSERT_TRUE(response != NULL);
3941   ASSERT_FALSE(response->headers.get() == NULL);
3942   EXPECT_EQ(407, response->headers->response_code());
3943   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3944   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3945
3946   TestCompletionCallback callback2;
3947
3948   rv = trans->RestartWithAuth(
3949       AuthCredentials(kFoo, kBar), callback2.callback());
3950   EXPECT_EQ(ERR_IO_PENDING, rv);
3951
3952   rv = callback2.WaitForResult();
3953   EXPECT_EQ(OK, rv);
3954
3955   load_timing_info = LoadTimingInfo();
3956   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3957   // Retrying with HTTP AUTH is considered to be reusing a socket.
3958   TestLoadTimingReused(load_timing_info);
3959
3960   response = trans->GetResponseInfo();
3961   ASSERT_TRUE(response != NULL);
3962
3963   EXPECT_TRUE(response->headers->IsKeepAlive());
3964   EXPECT_EQ(200, response->headers->response_code());
3965   EXPECT_EQ(100, response->headers->GetContentLength());
3966   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3967
3968   // The password prompt info should not be set.
3969   EXPECT_TRUE(response->auth_challenge.get() == NULL);
3970 }
3971
3972 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
3973     const MockRead& status, int expected_status) {
3974   HttpRequestInfo request;
3975   request.method = "GET";
3976   request.url = GURL("https://www.google.com/");
3977   request.load_flags = 0;
3978
3979   // Configure against proxy server "myproxy:70".
3980   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3981   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3982
3983   // Since we have proxy, should try to establish tunnel.
3984   MockWrite data_writes[] = {
3985     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
3986               "Host: www.google.com\r\n"
3987               "Proxy-Connection: keep-alive\r\n\r\n"),
3988   };
3989
3990   MockRead data_reads[] = {
3991     status,
3992     MockRead("Content-Length: 10\r\n\r\n"),
3993     // No response body because the test stops reading here.
3994     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
3995   };
3996
3997   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3998                                 data_writes, arraysize(data_writes));
3999   session_deps_.socket_factory->AddSocketDataProvider(&data);
4000
4001   TestCompletionCallback callback;
4002
4003   scoped_ptr<HttpTransaction> trans(
4004       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4005
4006   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4007   EXPECT_EQ(ERR_IO_PENDING, rv);
4008
4009   rv = callback.WaitForResult();
4010   EXPECT_EQ(expected_status, rv);
4011 }
4012
4013 void HttpNetworkTransactionTest::ConnectStatusHelper(
4014     const MockRead& status) {
4015   ConnectStatusHelperWithExpectedStatus(
4016       status, ERR_TUNNEL_CONNECTION_FAILED);
4017 }
4018
4019 TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
4020   ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4021 }
4022
4023 TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
4024   ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4025 }
4026
4027 TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
4028   ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4029 }
4030
4031 TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
4032   ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4033 }
4034
4035 TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
4036   ConnectStatusHelper(
4037       MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4038 }
4039
4040 TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
4041   ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4042 }
4043
4044 TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
4045   ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4046 }
4047
4048 TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
4049   ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4050 }
4051
4052 TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
4053   ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4054 }
4055
4056 TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
4057   ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4058 }
4059
4060 TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
4061   ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4062 }
4063
4064 TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
4065   ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4066 }
4067
4068 TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
4069   ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4070 }
4071
4072 TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
4073   ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4074 }
4075
4076 TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
4077   ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4078 }
4079
4080 TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
4081   ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4082 }
4083
4084 TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4085   ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4086 }
4087
4088 TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
4089   ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4090 }
4091
4092 TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
4093   ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4094 }
4095
4096 TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
4097   ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4098 }
4099
4100 TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
4101   ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4102 }
4103
4104 TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
4105   ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4106 }
4107
4108 TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
4109   ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4110 }
4111
4112 TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
4113   ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4114 }
4115
4116 TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
4117   ConnectStatusHelperWithExpectedStatus(
4118       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4119       ERR_PROXY_AUTH_UNSUPPORTED);
4120 }
4121
4122 TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
4123   ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4124 }
4125
4126 TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
4127   ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4128 }
4129
4130 TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
4131   ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4132 }
4133
4134 TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
4135   ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4136 }
4137
4138 TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
4139   ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4140 }
4141
4142 TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
4143   ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4144 }
4145
4146 TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
4147   ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4148 }
4149
4150 TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
4151   ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4152 }
4153
4154 TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
4155   ConnectStatusHelper(
4156       MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4157 }
4158
4159 TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
4160   ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4161 }
4162
4163 TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
4164   ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4165 }
4166
4167 TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
4168   ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4169 }
4170
4171 TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
4172   ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4173 }
4174
4175 TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
4176   ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4177 }
4178
4179 TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
4180   ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4181 }
4182
4183 TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
4184   ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4185 }
4186
4187 // Test the flow when both the proxy server AND origin server require
4188 // authentication. Again, this uses basic auth for both since that is
4189 // the simplest to mock.
4190 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
4191   HttpRequestInfo request;
4192   request.method = "GET";
4193   request.url = GURL("http://www.google.com/");
4194   request.load_flags = 0;
4195
4196   // Configure against proxy server "myproxy:70".
4197   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4198   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4199
4200   scoped_ptr<HttpTransaction> trans(
4201       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4202
4203   MockWrite data_writes1[] = {
4204     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4205               "Host: www.google.com\r\n"
4206               "Proxy-Connection: keep-alive\r\n\r\n"),
4207   };
4208
4209   MockRead data_reads1[] = {
4210     MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4211     // Give a couple authenticate options (only the middle one is actually
4212     // supported).
4213     MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
4214     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4215     MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4216     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4217     // Large content-length -- won't matter, as connection will be reset.
4218     MockRead("Content-Length: 10000\r\n\r\n"),
4219     MockRead(SYNCHRONOUS, ERR_FAILED),
4220   };
4221
4222   // After calling trans->RestartWithAuth() the first time, this is the
4223   // request we should be issuing -- the final header line contains the
4224   // proxy's credentials.
4225   MockWrite data_writes2[] = {
4226     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4227               "Host: www.google.com\r\n"
4228               "Proxy-Connection: keep-alive\r\n"
4229               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4230   };
4231
4232   // Now the proxy server lets the request pass through to origin server.
4233   // The origin server responds with a 401.
4234   MockRead data_reads2[] = {
4235     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4236     // Note: We are using the same realm-name as the proxy server. This is
4237     // completely valid, as realms are unique across hosts.
4238     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4239     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4240     MockRead("Content-Length: 2000\r\n\r\n"),
4241     MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
4242   };
4243
4244   // After calling trans->RestartWithAuth() the second time, we should send
4245   // the credentials for both the proxy and origin server.
4246   MockWrite data_writes3[] = {
4247     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4248               "Host: www.google.com\r\n"
4249               "Proxy-Connection: keep-alive\r\n"
4250               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4251               "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4252   };
4253
4254   // Lastly we get the desired content.
4255   MockRead data_reads3[] = {
4256     MockRead("HTTP/1.0 200 OK\r\n"),
4257     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4258     MockRead("Content-Length: 100\r\n\r\n"),
4259     MockRead(SYNCHRONOUS, OK),
4260   };
4261
4262   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4263                                  data_writes1, arraysize(data_writes1));
4264   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4265                                  data_writes2, arraysize(data_writes2));
4266   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4267                                  data_writes3, arraysize(data_writes3));
4268   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4269   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4270   session_deps_.socket_factory->AddSocketDataProvider(&data3);
4271
4272   TestCompletionCallback callback1;
4273
4274   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4275   EXPECT_EQ(ERR_IO_PENDING, rv);
4276
4277   rv = callback1.WaitForResult();
4278   EXPECT_EQ(OK, rv);
4279
4280   const HttpResponseInfo* response = trans->GetResponseInfo();
4281   ASSERT_TRUE(response != NULL);
4282   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
4283
4284   TestCompletionCallback callback2;
4285
4286   rv = trans->RestartWithAuth(
4287       AuthCredentials(kFoo, kBar), callback2.callback());
4288   EXPECT_EQ(ERR_IO_PENDING, rv);
4289
4290   rv = callback2.WaitForResult();
4291   EXPECT_EQ(OK, rv);
4292
4293   response = trans->GetResponseInfo();
4294   ASSERT_TRUE(response != NULL);
4295   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4296
4297   TestCompletionCallback callback3;
4298
4299   rv = trans->RestartWithAuth(
4300       AuthCredentials(kFoo2, kBar2), callback3.callback());
4301   EXPECT_EQ(ERR_IO_PENDING, rv);
4302
4303   rv = callback3.WaitForResult();
4304   EXPECT_EQ(OK, rv);
4305
4306   response = trans->GetResponseInfo();
4307   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4308   EXPECT_EQ(100, response->headers->GetContentLength());
4309 }
4310
4311 // For the NTLM implementation using SSPI, we skip the NTLM tests since we
4312 // can't hook into its internals to cause it to generate predictable NTLM
4313 // authorization headers.
4314 #if defined(NTLM_PORTABLE)
4315 // The NTLM authentication unit tests were generated by capturing the HTTP
4316 // requests and responses using Fiddler 2 and inspecting the generated random
4317 // bytes in the debugger.
4318
4319 // Enter the correct password and authenticate successfully.
4320 TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
4321   HttpRequestInfo request;
4322   request.method = "GET";
4323   request.url = GURL("http://172.22.68.17/kids/login.aspx");
4324
4325   // Ensure load is not disrupted by flags which suppress behaviour specific
4326   // to other auth schemes.
4327   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
4328
4329   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4330                                                     MockGetHostName);
4331   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4332
4333   MockWrite data_writes1[] = {
4334     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4335               "Host: 172.22.68.17\r\n"
4336               "Connection: keep-alive\r\n\r\n"),
4337   };
4338
4339   MockRead data_reads1[] = {
4340     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4341     // Negotiate and NTLM are often requested together.  However, we only want
4342     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4343     // the header that requests Negotiate for this test.
4344     MockRead("WWW-Authenticate: NTLM\r\n"),
4345     MockRead("Connection: close\r\n"),
4346     MockRead("Content-Length: 42\r\n"),
4347     MockRead("Content-Type: text/html\r\n\r\n"),
4348     // Missing content -- won't matter, as connection will be reset.
4349     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4350   };
4351
4352   MockWrite data_writes2[] = {
4353     // After restarting with a null identity, this is the
4354     // request we should be issuing -- the final header line contains a Type
4355     // 1 message.
4356     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4357               "Host: 172.22.68.17\r\n"
4358               "Connection: keep-alive\r\n"
4359               "Authorization: NTLM "
4360               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4361
4362     // After calling trans->RestartWithAuth(), we should send a Type 3 message
4363     // (the credentials for the origin server).  The second request continues
4364     // on the same connection.
4365     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4366               "Host: 172.22.68.17\r\n"
4367               "Connection: keep-alive\r\n"
4368               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4369               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4370               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4371               "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4372               "ahlhx5I=\r\n\r\n"),
4373   };
4374
4375   MockRead data_reads2[] = {
4376     // The origin server responds with a Type 2 message.
4377     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4378     MockRead("WWW-Authenticate: NTLM "
4379              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
4380              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4381              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4382              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4383              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4384              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4385              "BtAAAAAAA=\r\n"),
4386     MockRead("Content-Length: 42\r\n"),
4387     MockRead("Content-Type: text/html\r\n\r\n"),
4388     MockRead("You are not authorized to view this page\r\n"),
4389
4390     // Lastly we get the desired content.
4391     MockRead("HTTP/1.1 200 OK\r\n"),
4392     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4393     MockRead("Content-Length: 13\r\n\r\n"),
4394     MockRead("Please Login\r\n"),
4395     MockRead(SYNCHRONOUS, OK),
4396   };
4397
4398   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4399                                  data_writes1, arraysize(data_writes1));
4400   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4401                                  data_writes2, arraysize(data_writes2));
4402   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4403   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4404
4405   TestCompletionCallback callback1;
4406
4407   scoped_ptr<HttpTransaction> trans(
4408       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4409
4410   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4411   EXPECT_EQ(ERR_IO_PENDING, rv);
4412
4413   rv = callback1.WaitForResult();
4414   EXPECT_EQ(OK, rv);
4415
4416   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4417
4418   const HttpResponseInfo* response = trans->GetResponseInfo();
4419   ASSERT_FALSE(response == NULL);
4420   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
4421
4422   TestCompletionCallback callback2;
4423
4424   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
4425                               callback2.callback());
4426   EXPECT_EQ(ERR_IO_PENDING, rv);
4427
4428   rv = callback2.WaitForResult();
4429   EXPECT_EQ(OK, rv);
4430
4431   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4432
4433   response = trans->GetResponseInfo();
4434   ASSERT_TRUE(response != NULL);
4435   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4436
4437   TestCompletionCallback callback3;
4438
4439   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
4440   EXPECT_EQ(ERR_IO_PENDING, rv);
4441
4442   rv = callback3.WaitForResult();
4443   EXPECT_EQ(OK, rv);
4444
4445   response = trans->GetResponseInfo();
4446   ASSERT_TRUE(response != NULL);
4447   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4448   EXPECT_EQ(13, response->headers->GetContentLength());
4449 }
4450
4451 // Enter a wrong password, and then the correct one.
4452 TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
4453   HttpRequestInfo request;
4454   request.method = "GET";
4455   request.url = GURL("http://172.22.68.17/kids/login.aspx");
4456   request.load_flags = 0;
4457
4458   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4459                                                     MockGetHostName);
4460   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4461
4462   MockWrite data_writes1[] = {
4463     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4464               "Host: 172.22.68.17\r\n"
4465               "Connection: keep-alive\r\n\r\n"),
4466   };
4467
4468   MockRead data_reads1[] = {
4469     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4470     // Negotiate and NTLM are often requested together.  However, we only want
4471     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4472     // the header that requests Negotiate for this test.
4473     MockRead("WWW-Authenticate: NTLM\r\n"),
4474     MockRead("Connection: close\r\n"),
4475     MockRead("Content-Length: 42\r\n"),
4476     MockRead("Content-Type: text/html\r\n\r\n"),
4477     // Missing content -- won't matter, as connection will be reset.
4478     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4479   };
4480
4481   MockWrite data_writes2[] = {
4482     // After restarting with a null identity, this is the
4483     // request we should be issuing -- the final header line contains a Type
4484     // 1 message.
4485     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4486               "Host: 172.22.68.17\r\n"
4487               "Connection: keep-alive\r\n"
4488               "Authorization: NTLM "
4489               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4490
4491     // After calling trans->RestartWithAuth(), we should send a Type 3 message
4492     // (the credentials for the origin server).  The second request continues
4493     // on the same connection.
4494     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4495               "Host: 172.22.68.17\r\n"
4496               "Connection: keep-alive\r\n"
4497               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4498               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4499               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4500               "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4501               "4Ww7b7E=\r\n\r\n"),
4502   };
4503
4504   MockRead data_reads2[] = {
4505     // The origin server responds with a Type 2 message.
4506     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4507     MockRead("WWW-Authenticate: NTLM "
4508              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4509              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4510              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4511              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4512              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4513              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4514              "BtAAAAAAA=\r\n"),
4515     MockRead("Content-Length: 42\r\n"),
4516     MockRead("Content-Type: text/html\r\n\r\n"),
4517     MockRead("You are not authorized to view this page\r\n"),
4518
4519     // Wrong password.
4520     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4521     MockRead("WWW-Authenticate: NTLM\r\n"),
4522     MockRead("Connection: close\r\n"),
4523     MockRead("Content-Length: 42\r\n"),
4524     MockRead("Content-Type: text/html\r\n\r\n"),
4525     // Missing content -- won't matter, as connection will be reset.
4526     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4527   };
4528
4529   MockWrite data_writes3[] = {
4530     // After restarting with a null identity, this is the
4531     // request we should be issuing -- the final header line contains a Type
4532     // 1 message.
4533     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4534               "Host: 172.22.68.17\r\n"
4535               "Connection: keep-alive\r\n"
4536               "Authorization: NTLM "
4537               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4538
4539     // After calling trans->RestartWithAuth(), we should send a Type 3 message
4540     // (the credentials for the origin server).  The second request continues
4541     // on the same connection.
4542     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4543               "Host: 172.22.68.17\r\n"
4544               "Connection: keep-alive\r\n"
4545               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4546               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4547               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4548               "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4549               "+4MUm7c=\r\n\r\n"),
4550   };
4551
4552   MockRead data_reads3[] = {
4553     // The origin server responds with a Type 2 message.
4554     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4555     MockRead("WWW-Authenticate: NTLM "
4556              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4557              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4558              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4559              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4560              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4561              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4562              "BtAAAAAAA=\r\n"),
4563     MockRead("Content-Length: 42\r\n"),
4564     MockRead("Content-Type: text/html\r\n\r\n"),
4565     MockRead("You are not authorized to view this page\r\n"),
4566
4567     // Lastly we get the desired content.
4568     MockRead("HTTP/1.1 200 OK\r\n"),
4569     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4570     MockRead("Content-Length: 13\r\n\r\n"),
4571     MockRead("Please Login\r\n"),
4572     MockRead(SYNCHRONOUS, OK),
4573   };
4574
4575   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4576                                  data_writes1, arraysize(data_writes1));
4577   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4578                                  data_writes2, arraysize(data_writes2));
4579   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4580                                  data_writes3, arraysize(data_writes3));
4581   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4582   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4583   session_deps_.socket_factory->AddSocketDataProvider(&data3);
4584
4585   TestCompletionCallback callback1;
4586
4587   scoped_ptr<HttpTransaction> trans(
4588       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4589
4590   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4591   EXPECT_EQ(ERR_IO_PENDING, rv);
4592
4593   rv = callback1.WaitForResult();
4594   EXPECT_EQ(OK, rv);
4595
4596   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4597
4598   const HttpResponseInfo* response = trans->GetResponseInfo();
4599   ASSERT_TRUE(response != NULL);
4600   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
4601
4602   TestCompletionCallback callback2;
4603
4604   // Enter the wrong password.
4605   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
4606                               callback2.callback());
4607   EXPECT_EQ(ERR_IO_PENDING, rv);
4608
4609   rv = callback2.WaitForResult();
4610   EXPECT_EQ(OK, rv);
4611
4612   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4613   TestCompletionCallback callback3;
4614   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
4615   EXPECT_EQ(ERR_IO_PENDING, rv);
4616   rv = callback3.WaitForResult();
4617   EXPECT_EQ(OK, rv);
4618   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4619
4620   response = trans->GetResponseInfo();
4621   ASSERT_FALSE(response == NULL);
4622   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
4623
4624   TestCompletionCallback callback4;
4625
4626   // Now enter the right password.
4627   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
4628                               callback4.callback());
4629   EXPECT_EQ(ERR_IO_PENDING, rv);
4630
4631   rv = callback4.WaitForResult();
4632   EXPECT_EQ(OK, rv);
4633
4634   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4635
4636   TestCompletionCallback callback5;
4637
4638   // One more roundtrip
4639   rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
4640   EXPECT_EQ(ERR_IO_PENDING, rv);
4641
4642   rv = callback5.WaitForResult();
4643   EXPECT_EQ(OK, rv);
4644
4645   response = trans->GetResponseInfo();
4646   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4647   EXPECT_EQ(13, response->headers->GetContentLength());
4648 }
4649 #endif  // NTLM_PORTABLE
4650
4651 // Test reading a server response which has only headers, and no body.
4652 // After some maximum number of bytes is consumed, the transaction should
4653 // fail with ERR_RESPONSE_HEADERS_TOO_BIG.
4654 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
4655   HttpRequestInfo request;
4656   request.method = "GET";
4657   request.url = GURL("http://www.google.com/");
4658   request.load_flags = 0;
4659
4660   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4661   scoped_ptr<HttpTransaction> trans(
4662       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4663
4664   // Respond with 300 kb of headers (we should fail after 256 kb).
4665   std::string large_headers_string;
4666   FillLargeHeadersString(&large_headers_string, 300 * 1024);
4667
4668   MockRead data_reads[] = {
4669     MockRead("HTTP/1.0 200 OK\r\n"),
4670     MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
4671     MockRead("\r\nBODY"),
4672     MockRead(SYNCHRONOUS, OK),
4673   };
4674   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4675   session_deps_.socket_factory->AddSocketDataProvider(&data);
4676
4677   TestCompletionCallback callback;
4678
4679   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4680   EXPECT_EQ(ERR_IO_PENDING, rv);
4681
4682   rv = callback.WaitForResult();
4683   EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
4684
4685   const HttpResponseInfo* response = trans->GetResponseInfo();
4686   EXPECT_TRUE(response == NULL);
4687 }
4688
4689 // Make sure that we don't try to reuse a TCPClientSocket when failing to
4690 // establish tunnel.
4691 // http://code.google.com/p/chromium/issues/detail?id=3772
4692 TEST_P(HttpNetworkTransactionTest,
4693        DontRecycleTransportSocketForSSLTunnel) {
4694   HttpRequestInfo request;
4695   request.method = "GET";
4696   request.url = GURL("https://www.google.com/");
4697   request.load_flags = 0;
4698
4699   // Configure against proxy server "myproxy:70".
4700   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4701
4702   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4703
4704   scoped_ptr<HttpTransaction> trans(
4705       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4706
4707   // Since we have proxy, should try to establish tunnel.
4708   MockWrite data_writes1[] = {
4709     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
4710               "Host: www.google.com\r\n"
4711               "Proxy-Connection: keep-alive\r\n\r\n"),
4712   };
4713
4714   // The proxy responds to the connect with a 404, using a persistent
4715   // connection. Usually a proxy would return 501 (not implemented),
4716   // or 200 (tunnel established).
4717   MockRead data_reads1[] = {
4718     MockRead("HTTP/1.1 404 Not Found\r\n"),
4719     MockRead("Content-Length: 10\r\n\r\n"),
4720     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
4721   };
4722
4723   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4724                                  data_writes1, arraysize(data_writes1));
4725   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4726
4727   TestCompletionCallback callback1;
4728
4729   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4730   EXPECT_EQ(ERR_IO_PENDING, rv);
4731
4732   rv = callback1.WaitForResult();
4733   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
4734
4735   const HttpResponseInfo* response = trans->GetResponseInfo();
4736   EXPECT_TRUE(response == NULL);
4737
4738   // Empty the current queue.  This is necessary because idle sockets are
4739   // added to the connection pool asynchronously with a PostTask.
4740   base::MessageLoop::current()->RunUntilIdle();
4741
4742   // We now check to make sure the TCPClientSocket was not added back to
4743   // the pool.
4744   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4745   trans.reset();
4746   base::MessageLoop::current()->RunUntilIdle();
4747   // Make sure that the socket didn't get recycled after calling the destructor.
4748   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4749 }
4750
4751 // Make sure that we recycle a socket after reading all of the response body.
4752 TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
4753   HttpRequestInfo request;
4754   request.method = "GET";
4755   request.url = GURL("http://www.google.com/");
4756   request.load_flags = 0;
4757
4758   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4759
4760   scoped_ptr<HttpTransaction> trans(
4761       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4762
4763   MockRead data_reads[] = {
4764     // A part of the response body is received with the response headers.
4765     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4766     // The rest of the response body is received in two parts.
4767     MockRead("lo"),
4768     MockRead(" world"),
4769     MockRead("junk"),  // Should not be read!!
4770     MockRead(SYNCHRONOUS, OK),
4771   };
4772
4773   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4774   session_deps_.socket_factory->AddSocketDataProvider(&data);
4775
4776   TestCompletionCallback callback;
4777
4778   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4779   EXPECT_EQ(ERR_IO_PENDING, rv);
4780
4781   rv = callback.WaitForResult();
4782   EXPECT_EQ(OK, rv);
4783
4784   const HttpResponseInfo* response = trans->GetResponseInfo();
4785   ASSERT_TRUE(response != NULL);
4786
4787   EXPECT_TRUE(response->headers.get() != NULL);
4788   std::string status_line = response->headers->GetStatusLine();
4789   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4790
4791   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4792
4793   std::string response_data;
4794   rv = ReadTransaction(trans.get(), &response_data);
4795   EXPECT_EQ(OK, rv);
4796   EXPECT_EQ("hello world", response_data);
4797
4798   // Empty the current queue.  This is necessary because idle sockets are
4799   // added to the connection pool asynchronously with a PostTask.
4800   base::MessageLoop::current()->RunUntilIdle();
4801
4802   // We now check to make sure the socket was added back to the pool.
4803   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
4804 }
4805
4806 // Make sure that we recycle a SSL socket after reading all of the response
4807 // body.
4808 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
4809   HttpRequestInfo request;
4810   request.method = "GET";
4811   request.url = GURL("https://www.google.com/");
4812   request.load_flags = 0;
4813
4814   MockWrite data_writes[] = {
4815     MockWrite("GET / HTTP/1.1\r\n"
4816               "Host: www.google.com\r\n"
4817               "Connection: keep-alive\r\n\r\n"),
4818   };
4819
4820   MockRead data_reads[] = {
4821     MockRead("HTTP/1.1 200 OK\r\n"),
4822     MockRead("Content-Length: 11\r\n\r\n"),
4823     MockRead("hello world"),
4824     MockRead(SYNCHRONOUS, OK),
4825   };
4826
4827   SSLSocketDataProvider ssl(ASYNC, OK);
4828   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4829
4830   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4831                                 data_writes, arraysize(data_writes));
4832   session_deps_.socket_factory->AddSocketDataProvider(&data);
4833
4834   TestCompletionCallback callback;
4835
4836   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4837   scoped_ptr<HttpTransaction> trans(
4838       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4839
4840   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4841
4842   EXPECT_EQ(ERR_IO_PENDING, rv);
4843   EXPECT_EQ(OK, callback.WaitForResult());
4844
4845   const HttpResponseInfo* response = trans->GetResponseInfo();
4846   ASSERT_TRUE(response != NULL);
4847   ASSERT_TRUE(response->headers.get() != NULL);
4848   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4849
4850   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4851
4852   std::string response_data;
4853   rv = ReadTransaction(trans.get(), &response_data);
4854   EXPECT_EQ(OK, rv);
4855   EXPECT_EQ("hello world", response_data);
4856
4857   // Empty the current queue.  This is necessary because idle sockets are
4858   // added to the connection pool asynchronously with a PostTask.
4859   base::MessageLoop::current()->RunUntilIdle();
4860
4861   // We now check to make sure the socket was added back to the pool.
4862   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
4863 }
4864
4865 // Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
4866 // from the pool and make sure that we recover okay.
4867 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
4868   HttpRequestInfo request;
4869   request.method = "GET";
4870   request.url = GURL("https://www.google.com/");
4871   request.load_flags = 0;
4872
4873   MockWrite data_writes[] = {
4874     MockWrite("GET / HTTP/1.1\r\n"
4875               "Host: www.google.com\r\n"
4876               "Connection: keep-alive\r\n\r\n"),
4877     MockWrite("GET / HTTP/1.1\r\n"
4878               "Host: www.google.com\r\n"
4879               "Connection: keep-alive\r\n\r\n"),
4880   };
4881
4882   MockRead data_reads[] = {
4883     MockRead("HTTP/1.1 200 OK\r\n"),
4884     MockRead("Content-Length: 11\r\n\r\n"),
4885     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4886     MockRead("hello world"),
4887     MockRead(ASYNC, 0, 0)   // EOF
4888   };
4889
4890   SSLSocketDataProvider ssl(ASYNC, OK);
4891   SSLSocketDataProvider ssl2(ASYNC, OK);
4892   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4893   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
4894
4895   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4896                                 data_writes, arraysize(data_writes));
4897   StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4898                                 data_writes, arraysize(data_writes));
4899   session_deps_.socket_factory->AddSocketDataProvider(&data);
4900   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4901
4902   TestCompletionCallback callback;
4903
4904   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4905   scoped_ptr<HttpTransaction> trans(
4906       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4907
4908   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4909
4910   EXPECT_EQ(ERR_IO_PENDING, rv);
4911   EXPECT_EQ(OK, callback.WaitForResult());
4912
4913   const HttpResponseInfo* response = trans->GetResponseInfo();
4914   ASSERT_TRUE(response != NULL);
4915   ASSERT_TRUE(response->headers.get() != NULL);
4916   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4917
4918   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4919
4920   std::string response_data;
4921   rv = ReadTransaction(trans.get(), &response_data);
4922   EXPECT_EQ(OK, rv);
4923   EXPECT_EQ("hello world", response_data);
4924
4925   // Empty the current queue.  This is necessary because idle sockets are
4926   // added to the connection pool asynchronously with a PostTask.
4927   base::MessageLoop::current()->RunUntilIdle();
4928
4929   // We now check to make sure the socket was added back to the pool.
4930   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
4931
4932   // Now start the second transaction, which should reuse the previous socket.
4933
4934   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4935
4936   rv = trans->Start(&request, callback.callback(), BoundNetLog());
4937
4938   EXPECT_EQ(ERR_IO_PENDING, rv);
4939   EXPECT_EQ(OK, callback.WaitForResult());
4940
4941   response = trans->GetResponseInfo();
4942   ASSERT_TRUE(response != NULL);
4943   ASSERT_TRUE(response->headers.get() != NULL);
4944   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4945
4946   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4947
4948   rv = ReadTransaction(trans.get(), &response_data);
4949   EXPECT_EQ(OK, rv);
4950   EXPECT_EQ("hello world", response_data);
4951
4952   // Empty the current queue.  This is necessary because idle sockets are
4953   // added to the connection pool asynchronously with a PostTask.
4954   base::MessageLoop::current()->RunUntilIdle();
4955
4956   // We now check to make sure the socket was added back to the pool.
4957   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
4958 }
4959
4960 // Make sure that we recycle a socket after a zero-length response.
4961 // http://crbug.com/9880
4962 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
4963   HttpRequestInfo request;
4964   request.method = "GET";
4965   request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4966                      "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4967                      "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4968                      "rt=prt.2642,ol.2649,xjs.2951");
4969   request.load_flags = 0;
4970
4971   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4972
4973   scoped_ptr<HttpTransaction> trans(
4974       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4975
4976   MockRead data_reads[] = {
4977     MockRead("HTTP/1.1 204 No Content\r\n"
4978              "Content-Length: 0\r\n"
4979              "Content-Type: text/html\r\n\r\n"),
4980     MockRead("junk"),  // Should not be read!!
4981     MockRead(SYNCHRONOUS, OK),
4982   };
4983
4984   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4985   session_deps_.socket_factory->AddSocketDataProvider(&data);
4986
4987   TestCompletionCallback callback;
4988
4989   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4990   EXPECT_EQ(ERR_IO_PENDING, rv);
4991
4992   rv = callback.WaitForResult();
4993   EXPECT_EQ(OK, rv);
4994
4995   const HttpResponseInfo* response = trans->GetResponseInfo();
4996   ASSERT_TRUE(response != NULL);
4997
4998   EXPECT_TRUE(response->headers.get() != NULL);
4999   std::string status_line = response->headers->GetStatusLine();
5000   EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5001
5002   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
5003
5004   std::string response_data;
5005   rv = ReadTransaction(trans.get(), &response_data);
5006   EXPECT_EQ(OK, rv);
5007   EXPECT_EQ("", response_data);
5008
5009   // Empty the current queue.  This is necessary because idle sockets are
5010   // added to the connection pool asynchronously with a PostTask.
5011   base::MessageLoop::current()->RunUntilIdle();
5012
5013   // We now check to make sure the socket was added back to the pool.
5014   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
5015 }
5016
5017 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
5018   ScopedVector<UploadElementReader> element_readers;
5019   element_readers.push_back(new UploadBytesElementReader("foo", 3));
5020   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
5021
5022   HttpRequestInfo request[2];
5023   // Transaction 1: a GET request that succeeds.  The socket is recycled
5024   // after use.
5025   request[0].method = "GET";
5026   request[0].url = GURL("http://www.google.com/");
5027   request[0].load_flags = 0;
5028   // Transaction 2: a POST request.  Reuses the socket kept alive from
5029   // transaction 1.  The first attempts fails when writing the POST data.
5030   // This causes the transaction to retry with a new socket.  The second
5031   // attempt succeeds.
5032   request[1].method = "POST";
5033   request[1].url = GURL("http://www.google.com/login.cgi");
5034   request[1].upload_data_stream = &upload_data_stream;
5035   request[1].load_flags = 0;
5036
5037   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5038
5039   // The first socket is used for transaction 1 and the first attempt of
5040   // transaction 2.
5041
5042   // The response of transaction 1.
5043   MockRead data_reads1[] = {
5044     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5045     MockRead("hello world"),
5046     MockRead(SYNCHRONOUS, OK),
5047   };
5048   // The mock write results of transaction 1 and the first attempt of
5049   // transaction 2.
5050   MockWrite data_writes1[] = {
5051     MockWrite(SYNCHRONOUS, 64),  // GET
5052     MockWrite(SYNCHRONOUS, 93),  // POST
5053     MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
5054   };
5055   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5056                                  data_writes1, arraysize(data_writes1));
5057
5058   // The second socket is used for the second attempt of transaction 2.
5059
5060   // The response of transaction 2.
5061   MockRead data_reads2[] = {
5062     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5063     MockRead("welcome"),
5064     MockRead(SYNCHRONOUS, OK),
5065   };
5066   // The mock write results of the second attempt of transaction 2.
5067   MockWrite data_writes2[] = {
5068     MockWrite(SYNCHRONOUS, 93),  // POST
5069     MockWrite(SYNCHRONOUS, 3),  // POST data
5070   };
5071   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5072                                  data_writes2, arraysize(data_writes2));
5073
5074   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5075   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5076
5077   const char* kExpectedResponseData[] = {
5078     "hello world", "welcome"
5079   };
5080
5081   for (int i = 0; i < 2; ++i) {
5082     scoped_ptr<HttpTransaction> trans(
5083         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5084
5085     TestCompletionCallback callback;
5086
5087     int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
5088     EXPECT_EQ(ERR_IO_PENDING, rv);
5089
5090     rv = callback.WaitForResult();
5091     EXPECT_EQ(OK, rv);
5092
5093     const HttpResponseInfo* response = trans->GetResponseInfo();
5094     ASSERT_TRUE(response != NULL);
5095
5096     EXPECT_TRUE(response->headers.get() != NULL);
5097     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5098
5099     std::string response_data;
5100     rv = ReadTransaction(trans.get(), &response_data);
5101     EXPECT_EQ(OK, rv);
5102     EXPECT_EQ(kExpectedResponseData[i], response_data);
5103   }
5104 }
5105
5106 // Test the request-challenge-retry sequence for basic auth when there is
5107 // an identity in the URL. The request should be sent as normal, but when
5108 // it fails the identity from the URL is used to answer the challenge.
5109 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
5110   HttpRequestInfo request;
5111   request.method = "GET";
5112   request.url = GURL("http://foo:b@r@www.google.com/");
5113   request.load_flags = LOAD_NORMAL;
5114
5115   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5116   scoped_ptr<HttpTransaction> trans(
5117       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5118
5119   // The password contains an escaped character -- for this test to pass it
5120   // will need to be unescaped by HttpNetworkTransaction.
5121   EXPECT_EQ("b%40r", request.url.password());
5122
5123   MockWrite data_writes1[] = {
5124     MockWrite("GET / HTTP/1.1\r\n"
5125               "Host: www.google.com\r\n"
5126               "Connection: keep-alive\r\n\r\n"),
5127   };
5128
5129   MockRead data_reads1[] = {
5130     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5131     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5132     MockRead("Content-Length: 10\r\n\r\n"),
5133     MockRead(SYNCHRONOUS, ERR_FAILED),
5134   };
5135
5136   // After the challenge above, the transaction will be restarted using the
5137   // identity from the url (foo, b@r) to answer the challenge.
5138   MockWrite data_writes2[] = {
5139     MockWrite("GET / HTTP/1.1\r\n"
5140               "Host: www.google.com\r\n"
5141               "Connection: keep-alive\r\n"
5142               "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
5143   };
5144
5145   MockRead data_reads2[] = {
5146     MockRead("HTTP/1.0 200 OK\r\n"),
5147     MockRead("Content-Length: 100\r\n\r\n"),
5148     MockRead(SYNCHRONOUS, OK),
5149   };
5150
5151   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5152                                  data_writes1, arraysize(data_writes1));
5153   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5154                                  data_writes2, arraysize(data_writes2));
5155   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5156   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5157
5158   TestCompletionCallback callback1;
5159   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5160   EXPECT_EQ(ERR_IO_PENDING, rv);
5161   rv = callback1.WaitForResult();
5162   EXPECT_EQ(OK, rv);
5163   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5164
5165   TestCompletionCallback callback2;
5166   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5167   EXPECT_EQ(ERR_IO_PENDING, rv);
5168   rv = callback2.WaitForResult();
5169   EXPECT_EQ(OK, rv);
5170   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5171
5172   const HttpResponseInfo* response = trans->GetResponseInfo();
5173   ASSERT_TRUE(response != NULL);
5174
5175   // There is no challenge info, since the identity in URL worked.
5176   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5177
5178   EXPECT_EQ(100, response->headers->GetContentLength());
5179
5180   // Empty the current queue.
5181   base::MessageLoop::current()->RunUntilIdle();
5182 }
5183
5184 // Test the request-challenge-retry sequence for basic auth when there is an
5185 // incorrect identity in the URL. The identity from the URL should be used only
5186 // once.
5187 TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
5188   HttpRequestInfo request;
5189   request.method = "GET";
5190   // Note: the URL has a username:password in it.  The password "baz" is
5191   // wrong (should be "bar").
5192   request.url = GURL("http://foo:baz@www.google.com/");
5193
5194   request.load_flags = LOAD_NORMAL;
5195
5196   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5197   scoped_ptr<HttpTransaction> trans(
5198       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5199
5200   MockWrite data_writes1[] = {
5201     MockWrite("GET / HTTP/1.1\r\n"
5202               "Host: www.google.com\r\n"
5203               "Connection: keep-alive\r\n\r\n"),
5204   };
5205
5206   MockRead data_reads1[] = {
5207     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5208     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5209     MockRead("Content-Length: 10\r\n\r\n"),
5210     MockRead(SYNCHRONOUS, ERR_FAILED),
5211   };
5212
5213   // After the challenge above, the transaction will be restarted using the
5214   // identity from the url (foo, baz) to answer the challenge.
5215   MockWrite data_writes2[] = {
5216     MockWrite("GET / HTTP/1.1\r\n"
5217               "Host: www.google.com\r\n"
5218               "Connection: keep-alive\r\n"
5219               "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
5220   };
5221
5222   MockRead data_reads2[] = {
5223     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5224     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5225     MockRead("Content-Length: 10\r\n\r\n"),
5226     MockRead(SYNCHRONOUS, ERR_FAILED),
5227   };
5228
5229   // After the challenge above, the transaction will be restarted using the
5230   // identity supplied by the user (foo, bar) to answer the challenge.
5231   MockWrite data_writes3[] = {
5232     MockWrite("GET / HTTP/1.1\r\n"
5233               "Host: www.google.com\r\n"
5234               "Connection: keep-alive\r\n"
5235               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5236   };
5237
5238   MockRead data_reads3[] = {
5239     MockRead("HTTP/1.0 200 OK\r\n"),
5240     MockRead("Content-Length: 100\r\n\r\n"),
5241     MockRead(SYNCHRONOUS, OK),
5242   };
5243
5244   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5245                                  data_writes1, arraysize(data_writes1));
5246   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5247                                  data_writes2, arraysize(data_writes2));
5248   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5249                                  data_writes3, arraysize(data_writes3));
5250   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5251   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5252   session_deps_.socket_factory->AddSocketDataProvider(&data3);
5253
5254   TestCompletionCallback callback1;
5255
5256   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5257   EXPECT_EQ(ERR_IO_PENDING, rv);
5258
5259   rv = callback1.WaitForResult();
5260   EXPECT_EQ(OK, rv);
5261
5262   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5263   TestCompletionCallback callback2;
5264   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5265   EXPECT_EQ(ERR_IO_PENDING, rv);
5266   rv = callback2.WaitForResult();
5267   EXPECT_EQ(OK, rv);
5268   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5269
5270   const HttpResponseInfo* response = trans->GetResponseInfo();
5271   ASSERT_TRUE(response != NULL);
5272   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5273
5274   TestCompletionCallback callback3;
5275   rv = trans->RestartWithAuth(
5276       AuthCredentials(kFoo, kBar), callback3.callback());
5277   EXPECT_EQ(ERR_IO_PENDING, rv);
5278   rv = callback3.WaitForResult();
5279   EXPECT_EQ(OK, rv);
5280   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5281
5282   response = trans->GetResponseInfo();
5283   ASSERT_TRUE(response != NULL);
5284
5285   // There is no challenge info, since the identity worked.
5286   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5287
5288   EXPECT_EQ(100, response->headers->GetContentLength());
5289
5290   // Empty the current queue.
5291   base::MessageLoop::current()->RunUntilIdle();
5292 }
5293
5294
5295 // Test the request-challenge-retry sequence for basic auth when there is a
5296 // correct identity in the URL, but its use is being suppressed. The identity
5297 // from the URL should never be used.
5298 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5299   HttpRequestInfo request;
5300   request.method = "GET";
5301   request.url = GURL("http://foo:bar@www.google.com/");
5302   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5303
5304   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5305   scoped_ptr<HttpTransaction> trans(
5306       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5307
5308   MockWrite data_writes1[] = {
5309     MockWrite("GET / HTTP/1.1\r\n"
5310               "Host: www.google.com\r\n"
5311               "Connection: keep-alive\r\n\r\n"),
5312   };
5313
5314   MockRead data_reads1[] = {
5315     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5316     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5317     MockRead("Content-Length: 10\r\n\r\n"),
5318     MockRead(SYNCHRONOUS, ERR_FAILED),
5319   };
5320
5321   // After the challenge above, the transaction will be restarted using the
5322   // identity supplied by the user, not the one in the URL, to answer the
5323   // challenge.
5324   MockWrite data_writes3[] = {
5325     MockWrite("GET / HTTP/1.1\r\n"
5326               "Host: www.google.com\r\n"
5327               "Connection: keep-alive\r\n"
5328               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5329   };
5330
5331   MockRead data_reads3[] = {
5332     MockRead("HTTP/1.0 200 OK\r\n"),
5333     MockRead("Content-Length: 100\r\n\r\n"),
5334     MockRead(SYNCHRONOUS, OK),
5335   };
5336
5337   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5338                                  data_writes1, arraysize(data_writes1));
5339   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5340                                  data_writes3, arraysize(data_writes3));
5341   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5342   session_deps_.socket_factory->AddSocketDataProvider(&data3);
5343
5344   TestCompletionCallback callback1;
5345   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5346   EXPECT_EQ(ERR_IO_PENDING, rv);
5347   rv = callback1.WaitForResult();
5348   EXPECT_EQ(OK, rv);
5349   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5350
5351   const HttpResponseInfo* response = trans->GetResponseInfo();
5352   ASSERT_TRUE(response != NULL);
5353   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5354
5355   TestCompletionCallback callback3;
5356   rv = trans->RestartWithAuth(
5357       AuthCredentials(kFoo, kBar), callback3.callback());
5358   EXPECT_EQ(ERR_IO_PENDING, rv);
5359   rv = callback3.WaitForResult();
5360   EXPECT_EQ(OK, rv);
5361   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5362
5363   response = trans->GetResponseInfo();
5364   ASSERT_TRUE(response != NULL);
5365
5366   // There is no challenge info, since the identity worked.
5367   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5368   EXPECT_EQ(100, response->headers->GetContentLength());
5369
5370   // Empty the current queue.
5371   base::MessageLoop::current()->RunUntilIdle();
5372 }
5373
5374 // Test that previously tried username/passwords for a realm get re-used.
5375 TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
5376   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5377
5378   // Transaction 1: authenticate (foo, bar) on MyRealm1
5379   {
5380     HttpRequestInfo request;
5381     request.method = "GET";
5382     request.url = GURL("http://www.google.com/x/y/z");
5383     request.load_flags = 0;
5384
5385     scoped_ptr<HttpTransaction> trans(
5386         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5387
5388     MockWrite data_writes1[] = {
5389       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5390                 "Host: www.google.com\r\n"
5391                 "Connection: keep-alive\r\n\r\n"),
5392     };
5393
5394     MockRead data_reads1[] = {
5395       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5396       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5397       MockRead("Content-Length: 10000\r\n\r\n"),
5398       MockRead(SYNCHRONOUS, ERR_FAILED),
5399     };
5400
5401     // Resend with authorization (username=foo, password=bar)
5402     MockWrite data_writes2[] = {
5403       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5404                 "Host: www.google.com\r\n"
5405                 "Connection: keep-alive\r\n"
5406                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5407     };
5408
5409     // Sever accepts the authorization.
5410     MockRead data_reads2[] = {
5411       MockRead("HTTP/1.0 200 OK\r\n"),
5412       MockRead("Content-Length: 100\r\n\r\n"),
5413       MockRead(SYNCHRONOUS, OK),
5414     };
5415
5416     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5417                                    data_writes1, arraysize(data_writes1));
5418     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5419                                    data_writes2, arraysize(data_writes2));
5420     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5421     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5422
5423     TestCompletionCallback callback1;
5424
5425     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5426     EXPECT_EQ(ERR_IO_PENDING, rv);
5427
5428     rv = callback1.WaitForResult();
5429     EXPECT_EQ(OK, rv);
5430
5431     const HttpResponseInfo* response = trans->GetResponseInfo();
5432     ASSERT_TRUE(response != NULL);
5433     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5434
5435     TestCompletionCallback callback2;
5436
5437     rv = trans->RestartWithAuth(
5438         AuthCredentials(kFoo, kBar), callback2.callback());
5439     EXPECT_EQ(ERR_IO_PENDING, rv);
5440
5441     rv = callback2.WaitForResult();
5442     EXPECT_EQ(OK, rv);
5443
5444     response = trans->GetResponseInfo();
5445     ASSERT_TRUE(response != NULL);
5446     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5447     EXPECT_EQ(100, response->headers->GetContentLength());
5448   }
5449
5450   // ------------------------------------------------------------------------
5451
5452   // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5453   {
5454     HttpRequestInfo request;
5455     request.method = "GET";
5456     // Note that Transaction 1 was at /x/y/z, so this is in the same
5457     // protection space as MyRealm1.
5458     request.url = GURL("http://www.google.com/x/y/a/b");
5459     request.load_flags = 0;
5460
5461     scoped_ptr<HttpTransaction> trans(
5462         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5463
5464     MockWrite data_writes1[] = {
5465       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5466                 "Host: www.google.com\r\n"
5467                 "Connection: keep-alive\r\n"
5468                 // Send preemptive authorization for MyRealm1
5469                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5470     };
5471
5472     // The server didn't like the preemptive authorization, and
5473     // challenges us for a different realm (MyRealm2).
5474     MockRead data_reads1[] = {
5475       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5476       MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5477       MockRead("Content-Length: 10000\r\n\r\n"),
5478       MockRead(SYNCHRONOUS, ERR_FAILED),
5479     };
5480
5481     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5482     MockWrite data_writes2[] = {
5483       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5484                 "Host: www.google.com\r\n"
5485                 "Connection: keep-alive\r\n"
5486                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5487     };
5488
5489     // Sever accepts the authorization.
5490     MockRead data_reads2[] = {
5491       MockRead("HTTP/1.0 200 OK\r\n"),
5492       MockRead("Content-Length: 100\r\n\r\n"),
5493       MockRead(SYNCHRONOUS, OK),
5494     };
5495
5496     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5497                                    data_writes1, arraysize(data_writes1));
5498     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5499                                    data_writes2, arraysize(data_writes2));
5500     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5501     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5502
5503     TestCompletionCallback callback1;
5504
5505     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5506     EXPECT_EQ(ERR_IO_PENDING, rv);
5507
5508     rv = callback1.WaitForResult();
5509     EXPECT_EQ(OK, rv);
5510
5511     const HttpResponseInfo* response = trans->GetResponseInfo();
5512     ASSERT_TRUE(response != NULL);
5513     ASSERT_TRUE(response->auth_challenge.get());
5514     EXPECT_FALSE(response->auth_challenge->is_proxy);
5515     EXPECT_EQ("www.google.com:80",
5516               response->auth_challenge->challenger.ToString());
5517     EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5518     EXPECT_EQ("basic", response->auth_challenge->scheme);
5519
5520     TestCompletionCallback callback2;
5521
5522     rv = trans->RestartWithAuth(
5523         AuthCredentials(kFoo2, kBar2), callback2.callback());
5524     EXPECT_EQ(ERR_IO_PENDING, rv);
5525
5526     rv = callback2.WaitForResult();
5527     EXPECT_EQ(OK, rv);
5528
5529     response = trans->GetResponseInfo();
5530     ASSERT_TRUE(response != NULL);
5531     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5532     EXPECT_EQ(100, response->headers->GetContentLength());
5533   }
5534
5535   // ------------------------------------------------------------------------
5536
5537   // Transaction 3: Resend a request in MyRealm's protection space --
5538   // succeed with preemptive authorization.
5539   {
5540     HttpRequestInfo request;
5541     request.method = "GET";
5542     request.url = GURL("http://www.google.com/x/y/z2");
5543     request.load_flags = 0;
5544
5545     scoped_ptr<HttpTransaction> trans(
5546         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5547
5548     MockWrite data_writes1[] = {
5549       MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5550                 "Host: www.google.com\r\n"
5551                 "Connection: keep-alive\r\n"
5552                 // The authorization for MyRealm1 gets sent preemptively
5553                 // (since the url is in the same protection space)
5554                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5555     };
5556
5557     // Sever accepts the preemptive authorization
5558     MockRead data_reads1[] = {
5559       MockRead("HTTP/1.0 200 OK\r\n"),
5560       MockRead("Content-Length: 100\r\n\r\n"),
5561       MockRead(SYNCHRONOUS, OK),
5562     };
5563
5564     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5565                                    data_writes1, arraysize(data_writes1));
5566     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5567
5568     TestCompletionCallback callback1;
5569
5570     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5571     EXPECT_EQ(ERR_IO_PENDING, rv);
5572
5573     rv = callback1.WaitForResult();
5574     EXPECT_EQ(OK, rv);
5575
5576     const HttpResponseInfo* response = trans->GetResponseInfo();
5577     ASSERT_TRUE(response != NULL);
5578
5579     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5580     EXPECT_EQ(100, response->headers->GetContentLength());
5581   }
5582
5583   // ------------------------------------------------------------------------
5584
5585   // Transaction 4: request another URL in MyRealm (however the
5586   // url is not known to belong to the protection space, so no pre-auth).
5587   {
5588     HttpRequestInfo request;
5589     request.method = "GET";
5590     request.url = GURL("http://www.google.com/x/1");
5591     request.load_flags = 0;
5592
5593     scoped_ptr<HttpTransaction> trans(
5594         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5595
5596     MockWrite data_writes1[] = {
5597       MockWrite("GET /x/1 HTTP/1.1\r\n"
5598                 "Host: www.google.com\r\n"
5599                 "Connection: keep-alive\r\n\r\n"),
5600     };
5601
5602     MockRead data_reads1[] = {
5603       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5604       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5605       MockRead("Content-Length: 10000\r\n\r\n"),
5606       MockRead(SYNCHRONOUS, ERR_FAILED),
5607     };
5608
5609     // Resend with authorization from MyRealm's cache.
5610     MockWrite data_writes2[] = {
5611       MockWrite("GET /x/1 HTTP/1.1\r\n"
5612                 "Host: www.google.com\r\n"
5613                 "Connection: keep-alive\r\n"
5614                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5615     };
5616
5617     // Sever accepts the authorization.
5618     MockRead data_reads2[] = {
5619       MockRead("HTTP/1.0 200 OK\r\n"),
5620       MockRead("Content-Length: 100\r\n\r\n"),
5621       MockRead(SYNCHRONOUS, OK),
5622     };
5623
5624     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5625                                    data_writes1, arraysize(data_writes1));
5626     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5627                                    data_writes2, arraysize(data_writes2));
5628     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5629     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5630
5631     TestCompletionCallback callback1;
5632
5633     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5634     EXPECT_EQ(ERR_IO_PENDING, rv);
5635
5636     rv = callback1.WaitForResult();
5637     EXPECT_EQ(OK, rv);
5638
5639     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5640     TestCompletionCallback callback2;
5641     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5642     EXPECT_EQ(ERR_IO_PENDING, rv);
5643     rv = callback2.WaitForResult();
5644     EXPECT_EQ(OK, rv);
5645     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5646
5647     const HttpResponseInfo* response = trans->GetResponseInfo();
5648     ASSERT_TRUE(response != NULL);
5649     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5650     EXPECT_EQ(100, response->headers->GetContentLength());
5651   }
5652
5653   // ------------------------------------------------------------------------
5654
5655   // Transaction 5: request a URL in MyRealm, but the server rejects the
5656   // cached identity. Should invalidate and re-prompt.
5657   {
5658     HttpRequestInfo request;
5659     request.method = "GET";
5660     request.url = GURL("http://www.google.com/p/q/t");
5661     request.load_flags = 0;
5662
5663     scoped_ptr<HttpTransaction> trans(
5664         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5665
5666     MockWrite data_writes1[] = {
5667       MockWrite("GET /p/q/t HTTP/1.1\r\n"
5668                 "Host: www.google.com\r\n"
5669                 "Connection: keep-alive\r\n\r\n"),
5670     };
5671
5672     MockRead data_reads1[] = {
5673       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5674       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5675       MockRead("Content-Length: 10000\r\n\r\n"),
5676       MockRead(SYNCHRONOUS, ERR_FAILED),
5677     };
5678
5679     // Resend with authorization from cache for MyRealm.
5680     MockWrite data_writes2[] = {
5681       MockWrite("GET /p/q/t HTTP/1.1\r\n"
5682                 "Host: www.google.com\r\n"
5683                 "Connection: keep-alive\r\n"
5684                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5685     };
5686
5687     // Sever rejects the authorization.
5688     MockRead data_reads2[] = {
5689       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5690       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5691       MockRead("Content-Length: 10000\r\n\r\n"),
5692       MockRead(SYNCHRONOUS, ERR_FAILED),
5693     };
5694
5695     // At this point we should prompt for new credentials for MyRealm.
5696     // Restart with username=foo3, password=foo4.
5697     MockWrite data_writes3[] = {
5698       MockWrite("GET /p/q/t HTTP/1.1\r\n"
5699                 "Host: www.google.com\r\n"
5700                 "Connection: keep-alive\r\n"
5701                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5702     };
5703
5704     // Sever accepts the authorization.
5705     MockRead data_reads3[] = {
5706       MockRead("HTTP/1.0 200 OK\r\n"),
5707       MockRead("Content-Length: 100\r\n\r\n"),
5708       MockRead(SYNCHRONOUS, OK),
5709     };
5710
5711     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5712                                    data_writes1, arraysize(data_writes1));
5713     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5714                                    data_writes2, arraysize(data_writes2));
5715     StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5716                                    data_writes3, arraysize(data_writes3));
5717     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5718     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5719     session_deps_.socket_factory->AddSocketDataProvider(&data3);
5720
5721     TestCompletionCallback callback1;
5722
5723     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5724     EXPECT_EQ(ERR_IO_PENDING, rv);
5725
5726     rv = callback1.WaitForResult();
5727     EXPECT_EQ(OK, rv);
5728
5729     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5730     TestCompletionCallback callback2;
5731     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5732     EXPECT_EQ(ERR_IO_PENDING, rv);
5733     rv = callback2.WaitForResult();
5734     EXPECT_EQ(OK, rv);
5735     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5736
5737     const HttpResponseInfo* response = trans->GetResponseInfo();
5738     ASSERT_TRUE(response != NULL);
5739     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5740
5741     TestCompletionCallback callback3;
5742
5743     rv = trans->RestartWithAuth(
5744         AuthCredentials(kFoo3, kBar3), callback3.callback());
5745     EXPECT_EQ(ERR_IO_PENDING, rv);
5746
5747     rv = callback3.WaitForResult();
5748     EXPECT_EQ(OK, rv);
5749
5750     response = trans->GetResponseInfo();
5751     ASSERT_TRUE(response != NULL);
5752     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5753     EXPECT_EQ(100, response->headers->GetContentLength());
5754   }
5755 }
5756
5757 // Tests that nonce count increments when multiple auth attempts
5758 // are started with the same nonce.
5759 TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
5760   HttpAuthHandlerDigest::Factory* digest_factory =
5761       new HttpAuthHandlerDigest::Factory();
5762   HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5763       new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5764   digest_factory->set_nonce_generator(nonce_generator);
5765   session_deps_.http_auth_handler_factory.reset(digest_factory);
5766   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5767
5768   // Transaction 1: authenticate (foo, bar) on MyRealm1
5769   {
5770     HttpRequestInfo request;
5771     request.method = "GET";
5772     request.url = GURL("http://www.google.com/x/y/z");
5773     request.load_flags = 0;
5774
5775     scoped_ptr<HttpTransaction> trans(
5776         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5777
5778     MockWrite data_writes1[] = {
5779       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5780                 "Host: www.google.com\r\n"
5781                 "Connection: keep-alive\r\n\r\n"),
5782     };
5783
5784     MockRead data_reads1[] = {
5785       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5786       MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5787                "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
5788       MockRead(SYNCHRONOUS, OK),
5789     };
5790
5791     // Resend with authorization (username=foo, password=bar)
5792     MockWrite data_writes2[] = {
5793       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5794                 "Host: www.google.com\r\n"
5795                 "Connection: keep-alive\r\n"
5796                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5797                 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5798                 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5799                 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5800     };
5801
5802     // Sever accepts the authorization.
5803     MockRead data_reads2[] = {
5804       MockRead("HTTP/1.0 200 OK\r\n"),
5805       MockRead(SYNCHRONOUS, OK),
5806     };
5807
5808     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5809                                    data_writes1, arraysize(data_writes1));
5810     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5811                                    data_writes2, arraysize(data_writes2));
5812     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5813     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5814
5815     TestCompletionCallback callback1;
5816
5817     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5818     EXPECT_EQ(ERR_IO_PENDING, rv);
5819
5820     rv = callback1.WaitForResult();
5821     EXPECT_EQ(OK, rv);
5822
5823     const HttpResponseInfo* response = trans->GetResponseInfo();
5824     ASSERT_TRUE(response != NULL);
5825     EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
5826
5827     TestCompletionCallback callback2;
5828
5829     rv = trans->RestartWithAuth(
5830         AuthCredentials(kFoo, kBar), callback2.callback());
5831     EXPECT_EQ(ERR_IO_PENDING, rv);
5832
5833     rv = callback2.WaitForResult();
5834     EXPECT_EQ(OK, rv);
5835
5836     response = trans->GetResponseInfo();
5837     ASSERT_TRUE(response != NULL);
5838     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5839   }
5840
5841   // ------------------------------------------------------------------------
5842
5843   // Transaction 2: Request another resource in digestive's protection space.
5844   // This will preemptively add an Authorization header which should have an
5845   // "nc" value of 2 (as compared to 1 in the first use.
5846   {
5847     HttpRequestInfo request;
5848     request.method = "GET";
5849     // Note that Transaction 1 was at /x/y/z, so this is in the same
5850     // protection space as digest.
5851     request.url = GURL("http://www.google.com/x/y/a/b");
5852     request.load_flags = 0;
5853
5854     scoped_ptr<HttpTransaction> trans(
5855         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5856
5857     MockWrite data_writes1[] = {
5858       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5859                 "Host: www.google.com\r\n"
5860                 "Connection: keep-alive\r\n"
5861                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5862                 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5863                 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5864                 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5865     };
5866
5867     // Sever accepts the authorization.
5868     MockRead data_reads1[] = {
5869       MockRead("HTTP/1.0 200 OK\r\n"),
5870       MockRead("Content-Length: 100\r\n\r\n"),
5871       MockRead(SYNCHRONOUS, OK),
5872     };
5873
5874     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5875                                    data_writes1, arraysize(data_writes1));
5876     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5877
5878     TestCompletionCallback callback1;
5879
5880     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5881     EXPECT_EQ(ERR_IO_PENDING, rv);
5882
5883     rv = callback1.WaitForResult();
5884     EXPECT_EQ(OK, rv);
5885
5886     const HttpResponseInfo* response = trans->GetResponseInfo();
5887     ASSERT_TRUE(response != NULL);
5888     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5889   }
5890 }
5891
5892 // Test the ResetStateForRestart() private method.
5893 TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
5894   // Create a transaction (the dependencies aren't important).
5895   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5896   scoped_ptr<HttpNetworkTransaction> trans(
5897       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5898
5899   // Setup some state (which we expect ResetStateForRestart() will clear).
5900   trans->read_buf_ = new IOBuffer(15);
5901   trans->read_buf_len_ = 15;
5902   trans->request_headers_.SetHeader("Authorization", "NTLM");
5903
5904   // Setup state in response_
5905   HttpResponseInfo* response = &trans->response_;
5906   response->auth_challenge = new AuthChallengeInfo();
5907   response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
5908   response->response_time = base::Time::Now();
5909   response->was_cached = true;  // (Wouldn't ever actually be true...)
5910
5911   { // Setup state for response_.vary_data
5912     HttpRequestInfo request;
5913     std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5914     std::replace(temp.begin(), temp.end(), '\n', '\0');
5915     scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
5916     request.extra_headers.SetHeader("Foo", "1");
5917     request.extra_headers.SetHeader("bar", "23");
5918     EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
5919   }
5920
5921   // Cause the above state to be reset.
5922   trans->ResetStateForRestart();
5923
5924   // Verify that the state that needed to be reset, has been reset.
5925   EXPECT_TRUE(trans->read_buf_.get() == NULL);
5926   EXPECT_EQ(0, trans->read_buf_len_);
5927   EXPECT_TRUE(trans->request_headers_.IsEmpty());
5928   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5929   EXPECT_TRUE(response->headers.get() == NULL);
5930   EXPECT_FALSE(response->was_cached);
5931   EXPECT_EQ(0U, response->ssl_info.cert_status);
5932   EXPECT_FALSE(response->vary_data.is_valid());
5933 }
5934
5935 // Test HTTPS connections to a site with a bad certificate
5936 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
5937   HttpRequestInfo request;
5938   request.method = "GET";
5939   request.url = GURL("https://www.google.com/");
5940   request.load_flags = 0;
5941
5942   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5943   scoped_ptr<HttpTransaction> trans(
5944       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5945
5946   MockWrite data_writes[] = {
5947     MockWrite("GET / HTTP/1.1\r\n"
5948               "Host: www.google.com\r\n"
5949               "Connection: keep-alive\r\n\r\n"),
5950   };
5951
5952   MockRead data_reads[] = {
5953     MockRead("HTTP/1.0 200 OK\r\n"),
5954     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5955     MockRead("Content-Length: 100\r\n\r\n"),
5956     MockRead(SYNCHRONOUS, OK),
5957   };
5958
5959   StaticSocketDataProvider ssl_bad_certificate;
5960   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5961                                 data_writes, arraysize(data_writes));
5962   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5963   SSLSocketDataProvider ssl(ASYNC, OK);
5964
5965   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5966   session_deps_.socket_factory->AddSocketDataProvider(&data);
5967   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5968   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5969
5970   TestCompletionCallback callback;
5971
5972   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5973   EXPECT_EQ(ERR_IO_PENDING, rv);
5974
5975   rv = callback.WaitForResult();
5976   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5977
5978   rv = trans->RestartIgnoringLastError(callback.callback());
5979   EXPECT_EQ(ERR_IO_PENDING, rv);
5980
5981   rv = callback.WaitForResult();
5982   EXPECT_EQ(OK, rv);
5983
5984   const HttpResponseInfo* response = trans->GetResponseInfo();
5985
5986   ASSERT_TRUE(response != NULL);
5987   EXPECT_EQ(100, response->headers->GetContentLength());
5988 }
5989
5990 // Test HTTPS connections to a site with a bad certificate, going through a
5991 // proxy
5992 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
5993   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
5994
5995   HttpRequestInfo request;
5996   request.method = "GET";
5997   request.url = GURL("https://www.google.com/");
5998   request.load_flags = 0;
5999
6000   MockWrite proxy_writes[] = {
6001     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6002               "Host: www.google.com\r\n"
6003               "Proxy-Connection: keep-alive\r\n\r\n"),
6004   };
6005
6006   MockRead proxy_reads[] = {
6007     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6008     MockRead(SYNCHRONOUS, OK)
6009   };
6010
6011   MockWrite data_writes[] = {
6012     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6013               "Host: www.google.com\r\n"
6014               "Proxy-Connection: keep-alive\r\n\r\n"),
6015     MockWrite("GET / HTTP/1.1\r\n"
6016               "Host: www.google.com\r\n"
6017               "Connection: keep-alive\r\n\r\n"),
6018   };
6019
6020   MockRead data_reads[] = {
6021     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6022     MockRead("HTTP/1.0 200 OK\r\n"),
6023     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6024     MockRead("Content-Length: 100\r\n\r\n"),
6025     MockRead(SYNCHRONOUS, OK),
6026   };
6027
6028   StaticSocketDataProvider ssl_bad_certificate(
6029       proxy_reads, arraysize(proxy_reads),
6030       proxy_writes, arraysize(proxy_writes));
6031   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6032                                 data_writes, arraysize(data_writes));
6033   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6034   SSLSocketDataProvider ssl(ASYNC, OK);
6035
6036   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6037   session_deps_.socket_factory->AddSocketDataProvider(&data);
6038   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6039   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6040
6041   TestCompletionCallback callback;
6042
6043   for (int i = 0; i < 2; i++) {
6044     session_deps_.socket_factory->ResetNextMockIndexes();
6045
6046     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6047     scoped_ptr<HttpTransaction> trans(
6048         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6049
6050     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6051     EXPECT_EQ(ERR_IO_PENDING, rv);
6052
6053     rv = callback.WaitForResult();
6054     EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6055
6056     rv = trans->RestartIgnoringLastError(callback.callback());
6057     EXPECT_EQ(ERR_IO_PENDING, rv);
6058
6059     rv = callback.WaitForResult();
6060     EXPECT_EQ(OK, rv);
6061
6062     const HttpResponseInfo* response = trans->GetResponseInfo();
6063
6064     ASSERT_TRUE(response != NULL);
6065     EXPECT_EQ(100, response->headers->GetContentLength());
6066   }
6067 }
6068
6069
6070 // Test HTTPS connections to a site, going through an HTTPS proxy
6071 TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
6072   session_deps_.proxy_service.reset(
6073       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6074   CapturingNetLog net_log;
6075   session_deps_.net_log = &net_log;
6076
6077   HttpRequestInfo request;
6078   request.method = "GET";
6079   request.url = GURL("https://www.google.com/");
6080   request.load_flags = 0;
6081
6082   MockWrite data_writes[] = {
6083     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6084               "Host: www.google.com\r\n"
6085               "Proxy-Connection: keep-alive\r\n\r\n"),
6086     MockWrite("GET / HTTP/1.1\r\n"
6087               "Host: www.google.com\r\n"
6088               "Connection: keep-alive\r\n\r\n"),
6089   };
6090
6091   MockRead data_reads[] = {
6092     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6093     MockRead("HTTP/1.1 200 OK\r\n"),
6094     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6095     MockRead("Content-Length: 100\r\n\r\n"),
6096     MockRead(SYNCHRONOUS, OK),
6097   };
6098
6099   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6100                                 data_writes, arraysize(data_writes));
6101   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6102   SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
6103
6104   session_deps_.socket_factory->AddSocketDataProvider(&data);
6105   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6106   session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
6107
6108   TestCompletionCallback callback;
6109
6110   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6111   scoped_ptr<HttpTransaction> trans(
6112       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6113
6114   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6115   EXPECT_EQ(ERR_IO_PENDING, rv);
6116
6117   rv = callback.WaitForResult();
6118   EXPECT_EQ(OK, rv);
6119   const HttpResponseInfo* response = trans->GetResponseInfo();
6120
6121   ASSERT_TRUE(response != NULL);
6122
6123   EXPECT_TRUE(response->headers->IsKeepAlive());
6124   EXPECT_EQ(200, response->headers->response_code());
6125   EXPECT_EQ(100, response->headers->GetContentLength());
6126   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6127
6128   LoadTimingInfo load_timing_info;
6129   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6130   TestLoadTimingNotReusedWithPac(load_timing_info,
6131                                  CONNECT_TIMING_HAS_SSL_TIMES);
6132 }
6133
6134 // Test an HTTPS Proxy's ability to redirect a CONNECT request
6135 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
6136   session_deps_.proxy_service.reset(
6137       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6138   CapturingNetLog net_log;
6139   session_deps_.net_log = &net_log;
6140
6141   HttpRequestInfo request;
6142   request.method = "GET";
6143   request.url = GURL("https://www.google.com/");
6144   request.load_flags = 0;
6145
6146   MockWrite data_writes[] = {
6147     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6148               "Host: www.google.com\r\n"
6149               "Proxy-Connection: keep-alive\r\n\r\n"),
6150   };
6151
6152   MockRead data_reads[] = {
6153     MockRead("HTTP/1.1 302 Redirect\r\n"),
6154     MockRead("Location: http://login.example.com/\r\n"),
6155     MockRead("Content-Length: 0\r\n\r\n"),
6156     MockRead(SYNCHRONOUS, OK),
6157   };
6158
6159   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6160                                 data_writes, arraysize(data_writes));
6161   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6162
6163   session_deps_.socket_factory->AddSocketDataProvider(&data);
6164   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6165
6166   TestCompletionCallback callback;
6167
6168   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6169   scoped_ptr<HttpTransaction> trans(
6170       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6171
6172   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6173   EXPECT_EQ(ERR_IO_PENDING, rv);
6174
6175   rv = callback.WaitForResult();
6176   EXPECT_EQ(OK, rv);
6177   const HttpResponseInfo* response = trans->GetResponseInfo();
6178
6179   ASSERT_TRUE(response != NULL);
6180
6181   EXPECT_EQ(302, response->headers->response_code());
6182   std::string url;
6183   EXPECT_TRUE(response->headers->IsRedirect(&url));
6184   EXPECT_EQ("http://login.example.com/", url);
6185
6186   // In the case of redirects from proxies, HttpNetworkTransaction returns
6187   // timing for the proxy connection instead of the connection to the host,
6188   // and no send / receive times.
6189   // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6190   LoadTimingInfo load_timing_info;
6191   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6192
6193   EXPECT_FALSE(load_timing_info.socket_reused);
6194   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
6195
6196   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6197   EXPECT_LE(load_timing_info.proxy_resolve_start,
6198             load_timing_info.proxy_resolve_end);
6199   EXPECT_LE(load_timing_info.proxy_resolve_end,
6200             load_timing_info.connect_timing.connect_start);
6201   ExpectConnectTimingHasTimes(
6202       load_timing_info.connect_timing,
6203       CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6204
6205   EXPECT_TRUE(load_timing_info.send_start.is_null());
6206   EXPECT_TRUE(load_timing_info.send_end.is_null());
6207   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
6208 }
6209
6210 // Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
6211 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
6212   session_deps_.proxy_service.reset(
6213       ProxyService::CreateFixed("https://proxy:70"));
6214
6215   HttpRequestInfo request;
6216   request.method = "GET";
6217   request.url = GURL("https://www.google.com/");
6218   request.load_flags = 0;
6219
6220   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6221                                                              LOWEST));
6222   scoped_ptr<SpdyFrame> goaway(
6223       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
6224   MockWrite data_writes[] = {
6225     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6226     CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
6227   };
6228
6229   static const char* const kExtraHeaders[] = {
6230     "location",
6231     "http://login.example.com/",
6232   };
6233   scoped_ptr<SpdyFrame> resp(
6234       spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
6235                                  arraysize(kExtraHeaders)/2, 1));
6236   MockRead data_reads[] = {
6237     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6238     MockRead(ASYNC, 0, 2),  // EOF
6239   };
6240
6241   DelayedSocketData data(
6242       1,  // wait for one write to finish before reading.
6243       data_reads, arraysize(data_reads),
6244       data_writes, arraysize(data_writes));
6245   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6246   proxy_ssl.SetNextProto(GetParam());
6247
6248   session_deps_.socket_factory->AddSocketDataProvider(&data);
6249   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6250
6251   TestCompletionCallback callback;
6252
6253   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6254   scoped_ptr<HttpTransaction> trans(
6255       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6256
6257   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6258   EXPECT_EQ(ERR_IO_PENDING, rv);
6259
6260   rv = callback.WaitForResult();
6261   EXPECT_EQ(OK, rv);
6262   const HttpResponseInfo* response = trans->GetResponseInfo();
6263
6264   ASSERT_TRUE(response != NULL);
6265
6266   EXPECT_EQ(302, response->headers->response_code());
6267   std::string url;
6268   EXPECT_TRUE(response->headers->IsRedirect(&url));
6269   EXPECT_EQ("http://login.example.com/", url);
6270 }
6271
6272 // Test that an HTTPS proxy's response to a CONNECT request is filtered.
6273 TEST_P(HttpNetworkTransactionTest,
6274        ErrorResponseToHttpsConnectViaHttpsProxy) {
6275   session_deps_.proxy_service.reset(
6276       ProxyService::CreateFixed("https://proxy:70"));
6277
6278   HttpRequestInfo request;
6279   request.method = "GET";
6280   request.url = GURL("https://www.google.com/");
6281   request.load_flags = 0;
6282
6283   MockWrite data_writes[] = {
6284     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6285               "Host: www.google.com\r\n"
6286               "Proxy-Connection: keep-alive\r\n\r\n"),
6287   };
6288
6289   MockRead data_reads[] = {
6290     MockRead("HTTP/1.1 404 Not Found\r\n"),
6291     MockRead("Content-Length: 23\r\n\r\n"),
6292     MockRead("The host does not exist"),
6293     MockRead(SYNCHRONOUS, OK),
6294   };
6295
6296   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6297                                 data_writes, arraysize(data_writes));
6298   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6299
6300   session_deps_.socket_factory->AddSocketDataProvider(&data);
6301   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6302
6303   TestCompletionCallback callback;
6304
6305   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6306   scoped_ptr<HttpTransaction> trans(
6307       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6308
6309   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6310   EXPECT_EQ(ERR_IO_PENDING, rv);
6311
6312   rv = callback.WaitForResult();
6313   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
6314
6315   // TODO(ttuttle): Anything else to check here?
6316 }
6317
6318 // Test that a SPDY proxy's response to a CONNECT request is filtered.
6319 TEST_P(HttpNetworkTransactionTest,
6320        ErrorResponseToHttpsConnectViaSpdyProxy) {
6321   session_deps_.proxy_service.reset(
6322      ProxyService::CreateFixed("https://proxy:70"));
6323
6324   HttpRequestInfo request;
6325   request.method = "GET";
6326   request.url = GURL("https://www.google.com/");
6327   request.load_flags = 0;
6328
6329   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6330                                                              LOWEST));
6331   scoped_ptr<SpdyFrame> rst(
6332       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
6333   MockWrite data_writes[] = {
6334     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6335     CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
6336   };
6337
6338   static const char* const kExtraHeaders[] = {
6339     "location",
6340     "http://login.example.com/",
6341   };
6342   scoped_ptr<SpdyFrame> resp(
6343       spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
6344                                  arraysize(kExtraHeaders)/2, 1));
6345   scoped_ptr<SpdyFrame> body(
6346       spdy_util_.ConstructSpdyBodyFrame(
6347           1, "The host does not exist", 23, true));
6348   MockRead data_reads[] = {
6349     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6350     CreateMockRead(*body.get(), 2, SYNCHRONOUS),
6351     MockRead(ASYNC, 0, 4),  // EOF
6352   };
6353
6354   DelayedSocketData data(
6355       1,  // wait for one write to finish before reading.
6356       data_reads, arraysize(data_reads),
6357       data_writes, arraysize(data_writes));
6358   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6359   proxy_ssl.SetNextProto(GetParam());
6360
6361   session_deps_.socket_factory->AddSocketDataProvider(&data);
6362   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6363
6364   TestCompletionCallback callback;
6365
6366   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6367   scoped_ptr<HttpTransaction> trans(
6368       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6369
6370   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6371   EXPECT_EQ(ERR_IO_PENDING, rv);
6372
6373   rv = callback.WaitForResult();
6374   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
6375
6376   // TODO(ttuttle): Anything else to check here?
6377 }
6378
6379 // Test the request-challenge-retry sequence for basic auth, through
6380 // a SPDY proxy over a single SPDY session.
6381 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
6382   HttpRequestInfo request;
6383   request.method = "GET";
6384   request.url = GURL("https://www.google.com/");
6385   // when the no authentication data flag is set.
6386   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6387
6388   // Configure against https proxy server "myproxy:70".
6389   session_deps_.proxy_service.reset(
6390       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
6391   CapturingBoundNetLog log;
6392   session_deps_.net_log = log.bound().net_log();
6393   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6394
6395   // Since we have proxy, should try to establish tunnel.
6396   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6397                                                             LOWEST));
6398   scoped_ptr<SpdyFrame> rst(
6399       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
6400
6401   // After calling trans->RestartWithAuth(), this is the request we should
6402   // be issuing -- the final header line contains the credentials.
6403   const char* const kAuthCredentials[] = {
6404       "proxy-authorization", "Basic Zm9vOmJhcg==",
6405   };
6406   scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
6407       kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
6408   // fetch https://www.google.com/ via HTTP
6409   const char get[] = "GET / HTTP/1.1\r\n"
6410     "Host: www.google.com\r\n"
6411     "Connection: keep-alive\r\n\r\n";
6412   scoped_ptr<SpdyFrame> wrapped_get(
6413       spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
6414
6415   MockWrite spdy_writes[] = {
6416     CreateMockWrite(*req, 1, ASYNC),
6417     CreateMockWrite(*rst, 4, ASYNC),
6418     CreateMockWrite(*connect2, 5),
6419     CreateMockWrite(*wrapped_get, 8),
6420   };
6421
6422   // The proxy responds to the connect with a 407, using a persistent
6423   // connection.
6424   const char* const kAuthStatus = "407";
6425   const char* const kAuthChallenge[] = {
6426     "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6427   };
6428   scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6429       kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
6430
6431   scoped_ptr<SpdyFrame> conn_resp(
6432       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
6433   const char resp[] = "HTTP/1.1 200 OK\r\n"
6434       "Content-Length: 5\r\n\r\n";
6435
6436   scoped_ptr<SpdyFrame> wrapped_get_resp(
6437       spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
6438   scoped_ptr<SpdyFrame> wrapped_body(
6439       spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
6440   MockRead spdy_reads[] = {
6441     CreateMockRead(*conn_auth_resp, 2, ASYNC),
6442     CreateMockRead(*conn_resp, 6, ASYNC),
6443     CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6444     CreateMockRead(*wrapped_body, 10, ASYNC),
6445     MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
6446   };
6447
6448   OrderedSocketData spdy_data(
6449       spdy_reads, arraysize(spdy_reads),
6450       spdy_writes, arraysize(spdy_writes));
6451   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6452   // Negotiate SPDY to the proxy
6453   SSLSocketDataProvider proxy(ASYNC, OK);
6454   proxy.SetNextProto(GetParam());
6455   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
6456   // Vanilla SSL to the server
6457   SSLSocketDataProvider server(ASYNC, OK);
6458   session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
6459
6460   TestCompletionCallback callback1;
6461
6462   scoped_ptr<HttpTransaction> trans(
6463       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6464
6465   int rv = trans->Start(&request, callback1.callback(), log.bound());
6466   EXPECT_EQ(ERR_IO_PENDING, rv);
6467
6468   rv = callback1.WaitForResult();
6469   EXPECT_EQ(OK, rv);
6470   net::CapturingNetLog::CapturedEntryList entries;
6471   log.GetEntries(&entries);
6472   size_t pos = ExpectLogContainsSomewhere(
6473       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6474       NetLog::PHASE_NONE);
6475   ExpectLogContainsSomewhere(
6476       entries, pos,
6477       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6478       NetLog::PHASE_NONE);
6479
6480   const HttpResponseInfo* response = trans->GetResponseInfo();
6481   ASSERT_TRUE(response != NULL);
6482   ASSERT_FALSE(response->headers.get() == NULL);
6483   EXPECT_EQ(407, response->headers->response_code());
6484   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6485   EXPECT_TRUE(response->auth_challenge.get() != NULL);
6486   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6487
6488   TestCompletionCallback callback2;
6489
6490   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6491                               callback2.callback());
6492   EXPECT_EQ(ERR_IO_PENDING, rv);
6493
6494   rv = callback2.WaitForResult();
6495   EXPECT_EQ(OK, rv);
6496
6497   response = trans->GetResponseInfo();
6498   ASSERT_TRUE(response != NULL);
6499
6500   EXPECT_TRUE(response->headers->IsKeepAlive());
6501   EXPECT_EQ(200, response->headers->response_code());
6502   EXPECT_EQ(5, response->headers->GetContentLength());
6503   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6504
6505   // The password prompt info should not be set.
6506   EXPECT_TRUE(response->auth_challenge.get() == NULL);
6507
6508   LoadTimingInfo load_timing_info;
6509   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6510   TestLoadTimingNotReusedWithPac(load_timing_info,
6511                                  CONNECT_TIMING_HAS_SSL_TIMES);
6512
6513   trans.reset();
6514   session->CloseAllConnections();
6515 }
6516
6517 // Test that an explicitly trusted SPDY proxy can push a resource from an
6518 // origin that is different from that of its associated resource.
6519 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
6520   HttpRequestInfo request;
6521   HttpRequestInfo push_request;
6522
6523   request.method = "GET";
6524   request.url = GURL("http://www.google.com/");
6525   push_request.method = "GET";
6526   push_request.url = GURL("http://www.another-origin.com/foo.dat");
6527
6528   // Configure against https proxy server "myproxy:70".
6529   session_deps_.proxy_service.reset(
6530       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
6531   CapturingBoundNetLog log;
6532   session_deps_.net_log = log.bound().net_log();
6533
6534   // Enable cross-origin push.
6535   session_deps_.trusted_spdy_proxy = "myproxy:70";
6536
6537   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6538
6539   scoped_ptr<SpdyFrame> stream1_syn(
6540       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
6541
6542   MockWrite spdy_writes[] = {
6543     CreateMockWrite(*stream1_syn, 1, ASYNC),
6544   };
6545
6546   scoped_ptr<SpdyFrame>
6547       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
6548
6549   scoped_ptr<SpdyFrame>
6550       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
6551
6552   scoped_ptr<SpdyFrame>
6553       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
6554                                     0,
6555                                     2,
6556                                     1,
6557                                     "http://www.another-origin.com/foo.dat"));
6558   const char kPushedData[] = "pushed";
6559   scoped_ptr<SpdyFrame> stream2_body(
6560       spdy_util_.ConstructSpdyBodyFrame(
6561           2, kPushedData, strlen(kPushedData), true));
6562
6563   MockRead spdy_reads[] = {
6564     CreateMockRead(*stream1_reply, 2, ASYNC),
6565     CreateMockRead(*stream2_syn, 3, ASYNC),
6566     CreateMockRead(*stream1_body, 4, ASYNC),
6567     CreateMockRead(*stream2_body, 5, ASYNC),
6568     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
6569   };
6570
6571   OrderedSocketData spdy_data(
6572       spdy_reads, arraysize(spdy_reads),
6573       spdy_writes, arraysize(spdy_writes));
6574   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6575   // Negotiate SPDY to the proxy
6576   SSLSocketDataProvider proxy(ASYNC, OK);
6577   proxy.SetNextProto(GetParam());
6578   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
6579
6580   scoped_ptr<HttpTransaction> trans(
6581       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6582   TestCompletionCallback callback;
6583   int rv = trans->Start(&request, callback.callback(), log.bound());
6584   EXPECT_EQ(ERR_IO_PENDING, rv);
6585
6586   rv = callback.WaitForResult();
6587   EXPECT_EQ(OK, rv);
6588   const HttpResponseInfo* response = trans->GetResponseInfo();
6589
6590   scoped_ptr<HttpTransaction> push_trans(
6591       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6592   rv = push_trans->Start(&push_request, callback.callback(), log.bound());
6593   EXPECT_EQ(ERR_IO_PENDING, rv);
6594
6595   rv = callback.WaitForResult();
6596   EXPECT_EQ(OK, rv);
6597   const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6598
6599   ASSERT_TRUE(response != NULL);
6600   EXPECT_TRUE(response->headers->IsKeepAlive());
6601
6602   EXPECT_EQ(200, response->headers->response_code());
6603   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6604
6605   std::string response_data;
6606   rv = ReadTransaction(trans.get(), &response_data);
6607   EXPECT_EQ(OK, rv);
6608   EXPECT_EQ("hello!", response_data);
6609
6610   LoadTimingInfo load_timing_info;
6611   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6612   TestLoadTimingNotReusedWithPac(load_timing_info,
6613                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6614
6615   // Verify the pushed stream.
6616   EXPECT_TRUE(push_response->headers.get() != NULL);
6617   EXPECT_EQ(200, push_response->headers->response_code());
6618
6619   rv = ReadTransaction(push_trans.get(), &response_data);
6620   EXPECT_EQ(OK, rv);
6621   EXPECT_EQ("pushed", response_data);
6622
6623   LoadTimingInfo push_load_timing_info;
6624   EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6625   TestLoadTimingReusedWithPac(push_load_timing_info);
6626   // The transactions should share a socket ID, despite being for different
6627   // origins.
6628   EXPECT_EQ(load_timing_info.socket_log_id,
6629             push_load_timing_info.socket_log_id);
6630
6631   trans.reset();
6632   push_trans.reset();
6633   session->CloseAllConnections();
6634 }
6635
6636 // Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
6637 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
6638   HttpRequestInfo request;
6639
6640   request.method = "GET";
6641   request.url = GURL("http://www.google.com/");
6642
6643   // Configure against https proxy server "myproxy:70".
6644   session_deps_.proxy_service.reset(
6645       ProxyService::CreateFixed("https://myproxy:70"));
6646   CapturingBoundNetLog log;
6647   session_deps_.net_log = log.bound().net_log();
6648
6649   // Enable cross-origin push.
6650   session_deps_.trusted_spdy_proxy = "myproxy:70";
6651
6652   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6653
6654   scoped_ptr<SpdyFrame> stream1_syn(
6655       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
6656
6657   scoped_ptr<SpdyFrame> push_rst(
6658       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
6659
6660   MockWrite spdy_writes[] = {
6661     CreateMockWrite(*stream1_syn, 1, ASYNC),
6662     CreateMockWrite(*push_rst, 4),
6663   };
6664
6665   scoped_ptr<SpdyFrame>
6666       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
6667
6668   scoped_ptr<SpdyFrame>
6669       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
6670
6671   scoped_ptr<SpdyFrame>
6672       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
6673                                     0,
6674                                     2,
6675                                     1,
6676                                     "https://www.another-origin.com/foo.dat"));
6677
6678   MockRead spdy_reads[] = {
6679     CreateMockRead(*stream1_reply, 2, ASYNC),
6680     CreateMockRead(*stream2_syn, 3, ASYNC),
6681     CreateMockRead(*stream1_body, 5, ASYNC),
6682     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
6683   };
6684
6685   OrderedSocketData spdy_data(
6686       spdy_reads, arraysize(spdy_reads),
6687       spdy_writes, arraysize(spdy_writes));
6688   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6689   // Negotiate SPDY to the proxy
6690   SSLSocketDataProvider proxy(ASYNC, OK);
6691   proxy.SetNextProto(GetParam());
6692   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
6693
6694   scoped_ptr<HttpTransaction> trans(
6695       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6696   TestCompletionCallback callback;
6697   int rv = trans->Start(&request, callback.callback(), log.bound());
6698   EXPECT_EQ(ERR_IO_PENDING, rv);
6699
6700   rv = callback.WaitForResult();
6701   EXPECT_EQ(OK, rv);
6702   const HttpResponseInfo* response = trans->GetResponseInfo();
6703
6704   ASSERT_TRUE(response != NULL);
6705   EXPECT_TRUE(response->headers->IsKeepAlive());
6706
6707   EXPECT_EQ(200, response->headers->response_code());
6708   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6709
6710   std::string response_data;
6711   rv = ReadTransaction(trans.get(), &response_data);
6712   EXPECT_EQ(OK, rv);
6713   EXPECT_EQ("hello!", response_data);
6714
6715   trans.reset();
6716   session->CloseAllConnections();
6717 }
6718
6719 // Test HTTPS connections to a site with a bad certificate, going through an
6720 // HTTPS proxy
6721 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
6722   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
6723       "https://proxy:70"));
6724
6725   HttpRequestInfo request;
6726   request.method = "GET";
6727   request.url = GURL("https://www.google.com/");
6728   request.load_flags = 0;
6729
6730   // Attempt to fetch the URL from a server with a bad cert
6731   MockWrite bad_cert_writes[] = {
6732     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6733               "Host: www.google.com\r\n"
6734               "Proxy-Connection: keep-alive\r\n\r\n"),
6735   };
6736
6737   MockRead bad_cert_reads[] = {
6738     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6739     MockRead(SYNCHRONOUS, OK)
6740   };
6741
6742   // Attempt to fetch the URL with a good cert
6743   MockWrite good_data_writes[] = {
6744     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6745               "Host: www.google.com\r\n"
6746               "Proxy-Connection: keep-alive\r\n\r\n"),
6747     MockWrite("GET / HTTP/1.1\r\n"
6748               "Host: www.google.com\r\n"
6749               "Connection: keep-alive\r\n\r\n"),
6750   };
6751
6752   MockRead good_cert_reads[] = {
6753     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6754     MockRead("HTTP/1.0 200 OK\r\n"),
6755     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6756     MockRead("Content-Length: 100\r\n\r\n"),
6757     MockRead(SYNCHRONOUS, OK),
6758   };
6759
6760   StaticSocketDataProvider ssl_bad_certificate(
6761       bad_cert_reads, arraysize(bad_cert_reads),
6762       bad_cert_writes, arraysize(bad_cert_writes));
6763   StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6764                                 good_data_writes, arraysize(good_data_writes));
6765   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6766   SSLSocketDataProvider ssl(ASYNC, OK);
6767
6768   // SSL to the proxy, then CONNECT request, then SSL with bad certificate
6769   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6770   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6771   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6772
6773   // SSL to the proxy, then CONNECT request, then valid SSL certificate
6774   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6775   session_deps_.socket_factory->AddSocketDataProvider(&data);
6776   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6777
6778   TestCompletionCallback callback;
6779
6780   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6781   scoped_ptr<HttpTransaction> trans(
6782       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6783
6784   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6785   EXPECT_EQ(ERR_IO_PENDING, rv);
6786
6787   rv = callback.WaitForResult();
6788   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6789
6790   rv = trans->RestartIgnoringLastError(callback.callback());
6791   EXPECT_EQ(ERR_IO_PENDING, rv);
6792
6793   rv = callback.WaitForResult();
6794   EXPECT_EQ(OK, rv);
6795
6796   const HttpResponseInfo* response = trans->GetResponseInfo();
6797
6798   ASSERT_TRUE(response != NULL);
6799   EXPECT_EQ(100, response->headers->GetContentLength());
6800 }
6801
6802 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
6803   HttpRequestInfo request;
6804   request.method = "GET";
6805   request.url = GURL("http://www.google.com/");
6806   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6807                                   "Chromium Ultra Awesome X Edition");
6808
6809   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6810   scoped_ptr<HttpTransaction> trans(
6811       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6812
6813   MockWrite data_writes[] = {
6814     MockWrite("GET / HTTP/1.1\r\n"
6815               "Host: www.google.com\r\n"
6816               "Connection: keep-alive\r\n"
6817               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6818   };
6819
6820   // Lastly, the server responds with the actual content.
6821   MockRead data_reads[] = {
6822     MockRead("HTTP/1.0 200 OK\r\n"),
6823     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6824     MockRead("Content-Length: 100\r\n\r\n"),
6825     MockRead(SYNCHRONOUS, OK),
6826   };
6827
6828   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6829                                 data_writes, arraysize(data_writes));
6830   session_deps_.socket_factory->AddSocketDataProvider(&data);
6831
6832   TestCompletionCallback callback;
6833
6834   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6835   EXPECT_EQ(ERR_IO_PENDING, rv);
6836
6837   rv = callback.WaitForResult();
6838   EXPECT_EQ(OK, rv);
6839 }
6840
6841 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
6842   HttpRequestInfo request;
6843   request.method = "GET";
6844   request.url = GURL("https://www.google.com/");
6845   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6846                                   "Chromium Ultra Awesome X Edition");
6847
6848   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
6849   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6850   scoped_ptr<HttpTransaction> trans(
6851       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6852
6853   MockWrite data_writes[] = {
6854     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6855               "Host: www.google.com\r\n"
6856               "Proxy-Connection: keep-alive\r\n"
6857               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6858   };
6859   MockRead data_reads[] = {
6860     // Return an error, so the transaction stops here (this test isn't
6861     // interested in the rest).
6862     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6863     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6864     MockRead("Proxy-Connection: close\r\n\r\n"),
6865   };
6866
6867   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6868                                 data_writes, arraysize(data_writes));
6869   session_deps_.socket_factory->AddSocketDataProvider(&data);
6870
6871   TestCompletionCallback callback;
6872
6873   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6874   EXPECT_EQ(ERR_IO_PENDING, rv);
6875
6876   rv = callback.WaitForResult();
6877   EXPECT_EQ(OK, rv);
6878 }
6879
6880 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
6881   HttpRequestInfo request;
6882   request.method = "GET";
6883   request.url = GURL("http://www.google.com/");
6884   request.load_flags = 0;
6885   request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6886                                   "http://the.previous.site.com/");
6887
6888   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6889   scoped_ptr<HttpTransaction> trans(
6890       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6891
6892   MockWrite data_writes[] = {
6893     MockWrite("GET / HTTP/1.1\r\n"
6894               "Host: www.google.com\r\n"
6895               "Connection: keep-alive\r\n"
6896               "Referer: http://the.previous.site.com/\r\n\r\n"),
6897   };
6898
6899   // Lastly, the server responds with the actual content.
6900   MockRead data_reads[] = {
6901     MockRead("HTTP/1.0 200 OK\r\n"),
6902     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6903     MockRead("Content-Length: 100\r\n\r\n"),
6904     MockRead(SYNCHRONOUS, OK),
6905   };
6906
6907   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6908                                 data_writes, arraysize(data_writes));
6909   session_deps_.socket_factory->AddSocketDataProvider(&data);
6910
6911   TestCompletionCallback callback;
6912
6913   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6914   EXPECT_EQ(ERR_IO_PENDING, rv);
6915
6916   rv = callback.WaitForResult();
6917   EXPECT_EQ(OK, rv);
6918 }
6919
6920 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
6921   HttpRequestInfo request;
6922   request.method = "POST";
6923   request.url = GURL("http://www.google.com/");
6924
6925   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6926   scoped_ptr<HttpTransaction> trans(
6927       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6928
6929   MockWrite data_writes[] = {
6930     MockWrite("POST / HTTP/1.1\r\n"
6931               "Host: www.google.com\r\n"
6932               "Connection: keep-alive\r\n"
6933               "Content-Length: 0\r\n\r\n"),
6934   };
6935
6936   // Lastly, the server responds with the actual content.
6937   MockRead data_reads[] = {
6938     MockRead("HTTP/1.0 200 OK\r\n"),
6939     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6940     MockRead("Content-Length: 100\r\n\r\n"),
6941     MockRead(SYNCHRONOUS, OK),
6942   };
6943
6944   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6945                                 data_writes, arraysize(data_writes));
6946   session_deps_.socket_factory->AddSocketDataProvider(&data);
6947
6948   TestCompletionCallback callback;
6949
6950   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6951   EXPECT_EQ(ERR_IO_PENDING, rv);
6952
6953   rv = callback.WaitForResult();
6954   EXPECT_EQ(OK, rv);
6955 }
6956
6957 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
6958   HttpRequestInfo request;
6959   request.method = "PUT";
6960   request.url = GURL("http://www.google.com/");
6961
6962   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6963   scoped_ptr<HttpTransaction> trans(
6964       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6965
6966   MockWrite data_writes[] = {
6967     MockWrite("PUT / HTTP/1.1\r\n"
6968               "Host: www.google.com\r\n"
6969               "Connection: keep-alive\r\n"
6970               "Content-Length: 0\r\n\r\n"),
6971   };
6972
6973   // Lastly, the server responds with the actual content.
6974   MockRead data_reads[] = {
6975     MockRead("HTTP/1.0 200 OK\r\n"),
6976     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6977     MockRead("Content-Length: 100\r\n\r\n"),
6978     MockRead(SYNCHRONOUS, OK),
6979   };
6980
6981   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6982                                 data_writes, arraysize(data_writes));
6983   session_deps_.socket_factory->AddSocketDataProvider(&data);
6984
6985   TestCompletionCallback callback;
6986
6987   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6988   EXPECT_EQ(ERR_IO_PENDING, rv);
6989
6990   rv = callback.WaitForResult();
6991   EXPECT_EQ(OK, rv);
6992 }
6993
6994 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
6995   HttpRequestInfo request;
6996   request.method = "HEAD";
6997   request.url = GURL("http://www.google.com/");
6998
6999   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7000   scoped_ptr<HttpTransaction> trans(
7001       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7002
7003   MockWrite data_writes[] = {
7004     MockWrite("HEAD / HTTP/1.1\r\n"
7005               "Host: www.google.com\r\n"
7006               "Connection: keep-alive\r\n"
7007               "Content-Length: 0\r\n\r\n"),
7008   };
7009
7010   // Lastly, the server responds with the actual content.
7011   MockRead data_reads[] = {
7012     MockRead("HTTP/1.0 200 OK\r\n"),
7013     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7014     MockRead("Content-Length: 100\r\n\r\n"),
7015     MockRead(SYNCHRONOUS, OK),
7016   };
7017
7018   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7019                                 data_writes, arraysize(data_writes));
7020   session_deps_.socket_factory->AddSocketDataProvider(&data);
7021
7022   TestCompletionCallback callback;
7023
7024   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7025   EXPECT_EQ(ERR_IO_PENDING, rv);
7026
7027   rv = callback.WaitForResult();
7028   EXPECT_EQ(OK, rv);
7029 }
7030
7031 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
7032   HttpRequestInfo request;
7033   request.method = "GET";
7034   request.url = GURL("http://www.google.com/");
7035   request.load_flags = LOAD_BYPASS_CACHE;
7036
7037   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7038   scoped_ptr<HttpTransaction> trans(
7039       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7040
7041   MockWrite data_writes[] = {
7042     MockWrite("GET / HTTP/1.1\r\n"
7043               "Host: www.google.com\r\n"
7044               "Connection: keep-alive\r\n"
7045               "Pragma: no-cache\r\n"
7046               "Cache-Control: no-cache\r\n\r\n"),
7047   };
7048
7049   // Lastly, the server responds with the actual content.
7050   MockRead data_reads[] = {
7051     MockRead("HTTP/1.0 200 OK\r\n"),
7052     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7053     MockRead("Content-Length: 100\r\n\r\n"),
7054     MockRead(SYNCHRONOUS, OK),
7055   };
7056
7057   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7058                                 data_writes, arraysize(data_writes));
7059   session_deps_.socket_factory->AddSocketDataProvider(&data);
7060
7061   TestCompletionCallback callback;
7062
7063   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7064   EXPECT_EQ(ERR_IO_PENDING, rv);
7065
7066   rv = callback.WaitForResult();
7067   EXPECT_EQ(OK, rv);
7068 }
7069
7070 TEST_P(HttpNetworkTransactionTest,
7071        BuildRequest_CacheControlValidateCache) {
7072   HttpRequestInfo request;
7073   request.method = "GET";
7074   request.url = GURL("http://www.google.com/");
7075   request.load_flags = LOAD_VALIDATE_CACHE;
7076
7077   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7078   scoped_ptr<HttpTransaction> trans(
7079       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7080
7081   MockWrite data_writes[] = {
7082     MockWrite("GET / HTTP/1.1\r\n"
7083               "Host: www.google.com\r\n"
7084               "Connection: keep-alive\r\n"
7085               "Cache-Control: max-age=0\r\n\r\n"),
7086   };
7087
7088   // Lastly, the server responds with the actual content.
7089   MockRead data_reads[] = {
7090     MockRead("HTTP/1.0 200 OK\r\n"),
7091     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7092     MockRead("Content-Length: 100\r\n\r\n"),
7093     MockRead(SYNCHRONOUS, OK),
7094   };
7095
7096   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7097                                 data_writes, arraysize(data_writes));
7098   session_deps_.socket_factory->AddSocketDataProvider(&data);
7099
7100   TestCompletionCallback callback;
7101
7102   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7103   EXPECT_EQ(ERR_IO_PENDING, rv);
7104
7105   rv = callback.WaitForResult();
7106   EXPECT_EQ(OK, rv);
7107 }
7108
7109 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
7110   HttpRequestInfo request;
7111   request.method = "GET";
7112   request.url = GURL("http://www.google.com/");
7113   request.extra_headers.SetHeader("FooHeader", "Bar");
7114
7115   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7116   scoped_ptr<HttpTransaction> trans(
7117       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7118
7119   MockWrite data_writes[] = {
7120     MockWrite("GET / HTTP/1.1\r\n"
7121               "Host: www.google.com\r\n"
7122               "Connection: keep-alive\r\n"
7123               "FooHeader: Bar\r\n\r\n"),
7124   };
7125
7126   // Lastly, the server responds with the actual content.
7127   MockRead data_reads[] = {
7128     MockRead("HTTP/1.0 200 OK\r\n"),
7129     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7130     MockRead("Content-Length: 100\r\n\r\n"),
7131     MockRead(SYNCHRONOUS, OK),
7132   };
7133
7134   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7135                                 data_writes, arraysize(data_writes));
7136   session_deps_.socket_factory->AddSocketDataProvider(&data);
7137
7138   TestCompletionCallback callback;
7139
7140   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7141   EXPECT_EQ(ERR_IO_PENDING, rv);
7142
7143   rv = callback.WaitForResult();
7144   EXPECT_EQ(OK, rv);
7145 }
7146
7147 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
7148   HttpRequestInfo request;
7149   request.method = "GET";
7150   request.url = GURL("http://www.google.com/");
7151   request.extra_headers.SetHeader("referer", "www.foo.com");
7152   request.extra_headers.SetHeader("hEllo", "Kitty");
7153   request.extra_headers.SetHeader("FoO", "bar");
7154
7155   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7156   scoped_ptr<HttpTransaction> trans(
7157       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7158
7159   MockWrite data_writes[] = {
7160     MockWrite("GET / HTTP/1.1\r\n"
7161               "Host: www.google.com\r\n"
7162               "Connection: keep-alive\r\n"
7163               "referer: www.foo.com\r\n"
7164               "hEllo: Kitty\r\n"
7165               "FoO: bar\r\n\r\n"),
7166   };
7167
7168   // Lastly, the server responds with the actual content.
7169   MockRead data_reads[] = {
7170     MockRead("HTTP/1.0 200 OK\r\n"),
7171     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7172     MockRead("Content-Length: 100\r\n\r\n"),
7173     MockRead(SYNCHRONOUS, OK),
7174   };
7175
7176   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7177                                 data_writes, arraysize(data_writes));
7178   session_deps_.socket_factory->AddSocketDataProvider(&data);
7179
7180   TestCompletionCallback callback;
7181
7182   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7183   EXPECT_EQ(ERR_IO_PENDING, rv);
7184
7185   rv = callback.WaitForResult();
7186   EXPECT_EQ(OK, rv);
7187 }
7188
7189 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
7190   HttpRequestInfo request;
7191   request.method = "GET";
7192   request.url = GURL("http://www.google.com/");
7193   request.load_flags = 0;
7194
7195   session_deps_.proxy_service.reset(
7196       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7197   CapturingNetLog net_log;
7198   session_deps_.net_log = &net_log;
7199
7200   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7201   scoped_ptr<HttpTransaction> trans(
7202       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7203
7204   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7205   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7206
7207   MockWrite data_writes[] = {
7208     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7209     MockWrite("GET / HTTP/1.1\r\n"
7210               "Host: www.google.com\r\n"
7211               "Connection: keep-alive\r\n\r\n")
7212   };
7213
7214   MockRead data_reads[] = {
7215     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7216     MockRead("HTTP/1.0 200 OK\r\n"),
7217     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7218     MockRead("Payload"),
7219     MockRead(SYNCHRONOUS, OK)
7220   };
7221
7222   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7223                                 data_writes, arraysize(data_writes));
7224   session_deps_.socket_factory->AddSocketDataProvider(&data);
7225
7226   TestCompletionCallback callback;
7227
7228   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7229   EXPECT_EQ(ERR_IO_PENDING, rv);
7230
7231   rv = callback.WaitForResult();
7232   EXPECT_EQ(OK, rv);
7233
7234   const HttpResponseInfo* response = trans->GetResponseInfo();
7235   ASSERT_TRUE(response != NULL);
7236
7237   LoadTimingInfo load_timing_info;
7238   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7239   TestLoadTimingNotReusedWithPac(load_timing_info,
7240                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7241
7242   std::string response_text;
7243   rv = ReadTransaction(trans.get(), &response_text);
7244   EXPECT_EQ(OK, rv);
7245   EXPECT_EQ("Payload", response_text);
7246 }
7247
7248 TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
7249   HttpRequestInfo request;
7250   request.method = "GET";
7251   request.url = GURL("https://www.google.com/");
7252   request.load_flags = 0;
7253
7254   session_deps_.proxy_service.reset(
7255       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7256   CapturingNetLog net_log;
7257   session_deps_.net_log = &net_log;
7258
7259   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7260   scoped_ptr<HttpTransaction> trans(
7261       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7262
7263   unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7264   unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7265
7266   MockWrite data_writes[] = {
7267     MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7268               arraysize(write_buffer)),
7269     MockWrite("GET / HTTP/1.1\r\n"
7270               "Host: www.google.com\r\n"
7271               "Connection: keep-alive\r\n\r\n")
7272   };
7273
7274   MockRead data_reads[] = {
7275     MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7276              arraysize(read_buffer)),
7277     MockRead("HTTP/1.0 200 OK\r\n"),
7278     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7279     MockRead("Payload"),
7280     MockRead(SYNCHRONOUS, OK)
7281   };
7282
7283   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7284                                 data_writes, arraysize(data_writes));
7285   session_deps_.socket_factory->AddSocketDataProvider(&data);
7286
7287   SSLSocketDataProvider ssl(ASYNC, OK);
7288   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7289
7290   TestCompletionCallback callback;
7291
7292   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7293   EXPECT_EQ(ERR_IO_PENDING, rv);
7294
7295   rv = callback.WaitForResult();
7296   EXPECT_EQ(OK, rv);
7297
7298   LoadTimingInfo load_timing_info;
7299   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7300   TestLoadTimingNotReusedWithPac(load_timing_info,
7301                                  CONNECT_TIMING_HAS_SSL_TIMES);
7302
7303   const HttpResponseInfo* response = trans->GetResponseInfo();
7304   ASSERT_TRUE(response != NULL);
7305
7306   std::string response_text;
7307   rv = ReadTransaction(trans.get(), &response_text);
7308   EXPECT_EQ(OK, rv);
7309   EXPECT_EQ("Payload", response_text);
7310 }
7311
7312 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
7313   HttpRequestInfo request;
7314   request.method = "GET";
7315   request.url = GURL("http://www.google.com/");
7316   request.load_flags = 0;
7317
7318   session_deps_.proxy_service.reset(
7319       ProxyService::CreateFixed("socks4://myproxy:1080"));
7320   CapturingNetLog net_log;
7321   session_deps_.net_log = &net_log;
7322
7323   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7324   scoped_ptr<HttpTransaction> trans(
7325       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7326
7327   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7328   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7329
7330   MockWrite data_writes[] = {
7331     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7332     MockWrite("GET / HTTP/1.1\r\n"
7333               "Host: www.google.com\r\n"
7334               "Connection: keep-alive\r\n\r\n")
7335   };
7336
7337   MockRead data_reads[] = {
7338     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7339     MockRead("HTTP/1.0 200 OK\r\n"),
7340     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7341     MockRead("Payload"),
7342     MockRead(SYNCHRONOUS, OK)
7343   };
7344
7345   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7346                                 data_writes, arraysize(data_writes));
7347   session_deps_.socket_factory->AddSocketDataProvider(&data);
7348
7349   TestCompletionCallback callback;
7350
7351   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7352   EXPECT_EQ(ERR_IO_PENDING, rv);
7353
7354   rv = callback.WaitForResult();
7355   EXPECT_EQ(OK, rv);
7356
7357   const HttpResponseInfo* response = trans->GetResponseInfo();
7358   ASSERT_TRUE(response != NULL);
7359
7360   LoadTimingInfo load_timing_info;
7361   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7362   TestLoadTimingNotReused(load_timing_info,
7363                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7364
7365   std::string response_text;
7366   rv = ReadTransaction(trans.get(), &response_text);
7367   EXPECT_EQ(OK, rv);
7368   EXPECT_EQ("Payload", response_text);
7369 }
7370
7371 TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
7372   HttpRequestInfo request;
7373   request.method = "GET";
7374   request.url = GURL("http://www.google.com/");
7375   request.load_flags = 0;
7376
7377   session_deps_.proxy_service.reset(
7378       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7379   CapturingNetLog net_log;
7380   session_deps_.net_log = &net_log;
7381
7382   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7383   scoped_ptr<HttpTransaction> trans(
7384       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7385
7386   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7387   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
7388   const char kSOCKS5OkRequest[] = {
7389     0x05,  // Version
7390     0x01,  // Command (CONNECT)
7391     0x00,  // Reserved.
7392     0x03,  // Address type (DOMAINNAME).
7393     0x0E,  // Length of domain (14)
7394     // Domain string:
7395     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7396     0x00, 0x50,  // 16-bit port (80)
7397   };
7398   const char kSOCKS5OkResponse[] =
7399       { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7400
7401   MockWrite data_writes[] = {
7402     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7403     MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7404     MockWrite("GET / HTTP/1.1\r\n"
7405               "Host: www.google.com\r\n"
7406               "Connection: keep-alive\r\n\r\n")
7407   };
7408
7409   MockRead data_reads[] = {
7410     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7411     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
7412     MockRead("HTTP/1.0 200 OK\r\n"),
7413     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7414     MockRead("Payload"),
7415     MockRead(SYNCHRONOUS, OK)
7416   };
7417
7418   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7419                                 data_writes, arraysize(data_writes));
7420   session_deps_.socket_factory->AddSocketDataProvider(&data);
7421
7422   TestCompletionCallback callback;
7423
7424   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7425   EXPECT_EQ(ERR_IO_PENDING, rv);
7426
7427   rv = callback.WaitForResult();
7428   EXPECT_EQ(OK, rv);
7429
7430   const HttpResponseInfo* response = trans->GetResponseInfo();
7431   ASSERT_TRUE(response != NULL);
7432
7433   LoadTimingInfo load_timing_info;
7434   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7435   TestLoadTimingNotReusedWithPac(load_timing_info,
7436                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7437
7438   std::string response_text;
7439   rv = ReadTransaction(trans.get(), &response_text);
7440   EXPECT_EQ(OK, rv);
7441   EXPECT_EQ("Payload", response_text);
7442 }
7443
7444 TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
7445   HttpRequestInfo request;
7446   request.method = "GET";
7447   request.url = GURL("https://www.google.com/");
7448   request.load_flags = 0;
7449
7450   session_deps_.proxy_service.reset(
7451       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7452   CapturingNetLog net_log;
7453   session_deps_.net_log = &net_log;
7454
7455   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7456   scoped_ptr<HttpTransaction> trans(
7457       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7458
7459   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7460   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
7461   const unsigned char kSOCKS5OkRequest[] = {
7462     0x05,  // Version
7463     0x01,  // Command (CONNECT)
7464     0x00,  // Reserved.
7465     0x03,  // Address type (DOMAINNAME).
7466     0x0E,  // Length of domain (14)
7467     // Domain string:
7468     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7469     0x01, 0xBB,  // 16-bit port (443)
7470   };
7471
7472   const char kSOCKS5OkResponse[] =
7473       { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7474
7475   MockWrite data_writes[] = {
7476     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7477     MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7478               arraysize(kSOCKS5OkRequest)),
7479     MockWrite("GET / HTTP/1.1\r\n"
7480               "Host: www.google.com\r\n"
7481               "Connection: keep-alive\r\n\r\n")
7482   };
7483
7484   MockRead data_reads[] = {
7485     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7486     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
7487     MockRead("HTTP/1.0 200 OK\r\n"),
7488     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7489     MockRead("Payload"),
7490     MockRead(SYNCHRONOUS, OK)
7491   };
7492
7493   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7494                                 data_writes, arraysize(data_writes));
7495   session_deps_.socket_factory->AddSocketDataProvider(&data);
7496
7497   SSLSocketDataProvider ssl(ASYNC, OK);
7498   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7499
7500   TestCompletionCallback callback;
7501
7502   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7503   EXPECT_EQ(ERR_IO_PENDING, rv);
7504
7505   rv = callback.WaitForResult();
7506   EXPECT_EQ(OK, rv);
7507
7508   const HttpResponseInfo* response = trans->GetResponseInfo();
7509   ASSERT_TRUE(response != NULL);
7510
7511   LoadTimingInfo load_timing_info;
7512   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7513   TestLoadTimingNotReusedWithPac(load_timing_info,
7514                                  CONNECT_TIMING_HAS_SSL_TIMES);
7515
7516   std::string response_text;
7517   rv = ReadTransaction(trans.get(), &response_text);
7518   EXPECT_EQ(OK, rv);
7519   EXPECT_EQ("Payload", response_text);
7520 }
7521
7522 namespace {
7523
7524 // Tests that for connection endpoints the group names are correctly set.
7525
7526 struct GroupNameTest {
7527   std::string proxy_server;
7528   std::string url;
7529   std::string expected_group_name;
7530   bool ssl;
7531 };
7532
7533 scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
7534     NextProto next_proto,
7535     SpdySessionDependencies* session_deps_) {
7536   scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
7537
7538   base::WeakPtr<HttpServerProperties> http_server_properties =
7539       session->http_server_properties();
7540   http_server_properties->SetAlternateProtocol(
7541       HostPortPair("host.with.alternate", 80), 443,
7542       AlternateProtocolFromNextProto(next_proto), 1);
7543
7544   return session;
7545 }
7546
7547 int GroupNameTransactionHelper(
7548     const std::string& url,
7549     const scoped_refptr<HttpNetworkSession>& session) {
7550   HttpRequestInfo request;
7551   request.method = "GET";
7552   request.url = GURL(url);
7553   request.load_flags = 0;
7554
7555   scoped_ptr<HttpTransaction> trans(
7556       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7557
7558   TestCompletionCallback callback;
7559
7560   // We do not complete this request, the dtor will clean the transaction up.
7561   return trans->Start(&request, callback.callback(), BoundNetLog());
7562 }
7563
7564 }  // namespace
7565
7566 TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
7567   const GroupNameTest tests[] = {
7568     {
7569       "",  // unused
7570       "http://www.google.com/direct",
7571       "www.google.com:80",
7572       false,
7573     },
7574     {
7575       "",  // unused
7576       "http://[2001:1418:13:1::25]/direct",
7577       "[2001:1418:13:1::25]:80",
7578       false,
7579     },
7580
7581     // SSL Tests
7582     {
7583       "",  // unused
7584       "https://www.google.com/direct_ssl",
7585       "ssl/www.google.com:443",
7586       true,
7587     },
7588     {
7589       "",  // unused
7590       "https://[2001:1418:13:1::25]/direct",
7591       "ssl/[2001:1418:13:1::25]:443",
7592       true,
7593     },
7594     {
7595       "",  // unused
7596       "http://host.with.alternate/direct",
7597       "ssl/host.with.alternate:443",
7598       true,
7599     },
7600   };
7601
7602   session_deps_.use_alternate_protocols = true;
7603
7604   for (size_t i = 0; i < arraysize(tests); ++i) {
7605     session_deps_.proxy_service.reset(
7606         ProxyService::CreateFixed(tests[i].proxy_server));
7607     scoped_refptr<HttpNetworkSession> session(
7608         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
7609
7610     HttpNetworkSessionPeer peer(session);
7611     CaptureGroupNameTransportSocketPool* transport_conn_pool =
7612         new CaptureGroupNameTransportSocketPool(NULL, NULL);
7613     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
7614         new CaptureGroupNameSSLSocketPool(NULL, NULL);
7615     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7616         new MockClientSocketPoolManager);
7617     mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7618     mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
7619     peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
7620
7621     EXPECT_EQ(ERR_IO_PENDING,
7622               GroupNameTransactionHelper(tests[i].url, session));
7623     if (tests[i].ssl)
7624       EXPECT_EQ(tests[i].expected_group_name,
7625                 ssl_conn_pool->last_group_name_received());
7626     else
7627       EXPECT_EQ(tests[i].expected_group_name,
7628                 transport_conn_pool->last_group_name_received());
7629   }
7630
7631 }
7632
7633 TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
7634   const GroupNameTest tests[] = {
7635     {
7636       "http_proxy",
7637       "http://www.google.com/http_proxy_normal",
7638       "www.google.com:80",
7639       false,
7640     },
7641
7642     // SSL Tests
7643     {
7644       "http_proxy",
7645       "https://www.google.com/http_connect_ssl",
7646       "ssl/www.google.com:443",
7647       true,
7648     },
7649
7650     {
7651       "http_proxy",
7652       "http://host.with.alternate/direct",
7653       "ssl/host.with.alternate:443",
7654       true,
7655     },
7656
7657     {
7658       "http_proxy",
7659       "ftp://ftp.google.com/http_proxy_normal",
7660       "ftp/ftp.google.com:21",
7661       false,
7662     },
7663   };
7664
7665   session_deps_.use_alternate_protocols = true;
7666
7667   for (size_t i = 0; i < arraysize(tests); ++i) {
7668     session_deps_.proxy_service.reset(
7669         ProxyService::CreateFixed(tests[i].proxy_server));
7670     scoped_refptr<HttpNetworkSession> session(
7671         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
7672
7673     HttpNetworkSessionPeer peer(session);
7674
7675     HostPortPair proxy_host("http_proxy", 80);
7676     CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
7677         new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
7678     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
7679         new CaptureGroupNameSSLSocketPool(NULL, NULL);
7680
7681     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7682         new MockClientSocketPoolManager);
7683     mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7684     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7685     peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
7686
7687     EXPECT_EQ(ERR_IO_PENDING,
7688               GroupNameTransactionHelper(tests[i].url, session));
7689     if (tests[i].ssl)
7690       EXPECT_EQ(tests[i].expected_group_name,
7691                 ssl_conn_pool->last_group_name_received());
7692     else
7693       EXPECT_EQ(tests[i].expected_group_name,
7694                 http_proxy_pool->last_group_name_received());
7695   }
7696 }
7697
7698 TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
7699   const GroupNameTest tests[] = {
7700     {
7701       "socks4://socks_proxy:1080",
7702       "http://www.google.com/socks4_direct",
7703       "socks4/www.google.com:80",
7704       false,
7705     },
7706     {
7707       "socks5://socks_proxy:1080",
7708       "http://www.google.com/socks5_direct",
7709       "socks5/www.google.com:80",
7710       false,
7711     },
7712
7713     // SSL Tests
7714     {
7715       "socks4://socks_proxy:1080",
7716       "https://www.google.com/socks4_ssl",
7717       "socks4/ssl/www.google.com:443",
7718       true,
7719     },
7720     {
7721       "socks5://socks_proxy:1080",
7722       "https://www.google.com/socks5_ssl",
7723       "socks5/ssl/www.google.com:443",
7724       true,
7725     },
7726
7727     {
7728       "socks4://socks_proxy:1080",
7729       "http://host.with.alternate/direct",
7730       "socks4/ssl/host.with.alternate:443",
7731       true,
7732     },
7733   };
7734
7735   session_deps_.use_alternate_protocols = true;
7736
7737   for (size_t i = 0; i < arraysize(tests); ++i) {
7738     session_deps_.proxy_service.reset(
7739         ProxyService::CreateFixed(tests[i].proxy_server));
7740     scoped_refptr<HttpNetworkSession> session(
7741         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
7742
7743     HttpNetworkSessionPeer peer(session);
7744
7745     HostPortPair proxy_host("socks_proxy", 1080);
7746     CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
7747         new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
7748     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
7749         new CaptureGroupNameSSLSocketPool(NULL, NULL);
7750
7751     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7752         new MockClientSocketPoolManager);
7753     mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7754     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7755     peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
7756
7757     scoped_ptr<HttpTransaction> trans(
7758         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7759
7760     EXPECT_EQ(ERR_IO_PENDING,
7761               GroupNameTransactionHelper(tests[i].url, session));
7762     if (tests[i].ssl)
7763       EXPECT_EQ(tests[i].expected_group_name,
7764                 ssl_conn_pool->last_group_name_received());
7765     else
7766       EXPECT_EQ(tests[i].expected_group_name,
7767                 socks_conn_pool->last_group_name_received());
7768   }
7769 }
7770
7771 TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
7772   HttpRequestInfo request;
7773   request.method = "GET";
7774   request.url = GURL("http://www.google.com/");
7775
7776   session_deps_.proxy_service.reset(
7777       ProxyService::CreateFixed("myproxy:70;foobar:80"));
7778
7779   // This simulates failure resolving all hostnames; that means we will fail
7780   // connecting to both proxies (myproxy:70 and foobar:80).
7781   session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
7782
7783   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7784   scoped_ptr<HttpTransaction> trans(
7785       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7786
7787   TestCompletionCallback callback;
7788
7789   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7790   EXPECT_EQ(ERR_IO_PENDING, rv);
7791
7792   rv = callback.WaitForResult();
7793   EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
7794 }
7795
7796 // Base test to make sure that when the load flags for a request specify to
7797 // bypass the cache, the DNS cache is not used.
7798 void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
7799     int load_flags) {
7800   // Issue a request, asking to bypass the cache(s).
7801   HttpRequestInfo request;
7802   request.method = "GET";
7803   request.load_flags = load_flags;
7804   request.url = GURL("http://www.google.com/");
7805
7806   // Select a host resolver that does caching.
7807   session_deps_.host_resolver.reset(new MockCachingHostResolver);
7808
7809   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7810   scoped_ptr<HttpTransaction> trans(
7811       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7812
7813   // Warm up the host cache so it has an entry for "www.google.com".
7814   AddressList addrlist;
7815   TestCompletionCallback callback;
7816   int rv = session_deps_.host_resolver->Resolve(
7817       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7818       DEFAULT_PRIORITY,
7819       &addrlist,
7820       callback.callback(),
7821       NULL,
7822       BoundNetLog());
7823   EXPECT_EQ(ERR_IO_PENDING, rv);
7824   rv = callback.WaitForResult();
7825   EXPECT_EQ(OK, rv);
7826
7827   // Verify that it was added to host cache, by doing a subsequent async lookup
7828   // and confirming it completes synchronously.
7829   rv = session_deps_.host_resolver->Resolve(
7830       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7831       DEFAULT_PRIORITY,
7832       &addrlist,
7833       callback.callback(),
7834       NULL,
7835       BoundNetLog());
7836   ASSERT_EQ(OK, rv);
7837
7838   // Inject a failure the next time that "www.google.com" is resolved. This way
7839   // we can tell if the next lookup hit the cache, or the "network".
7840   // (cache --> success, "network" --> failure).
7841   session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
7842
7843   // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7844   // first read -- this won't be reached as the host resolution will fail first.
7845   MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
7846   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7847   session_deps_.socket_factory->AddSocketDataProvider(&data);
7848
7849   // Run the request.
7850   rv = trans->Start(&request, callback.callback(), BoundNetLog());
7851   ASSERT_EQ(ERR_IO_PENDING, rv);
7852   rv = callback.WaitForResult();
7853
7854   // If we bypassed the cache, we would have gotten a failure while resolving
7855   // "www.google.com".
7856   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7857 }
7858
7859 // There are multiple load flags that should trigger the host cache bypass.
7860 // Test each in isolation:
7861 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
7862   BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7863 }
7864
7865 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
7866   BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7867 }
7868
7869 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
7870   BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7871 }
7872
7873 // Make sure we can handle an error when writing the request.
7874 TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
7875   HttpRequestInfo request;
7876   request.method = "GET";
7877   request.url = GURL("http://www.foo.com/");
7878   request.load_flags = 0;
7879
7880   MockWrite write_failure[] = {
7881     MockWrite(ASYNC, ERR_CONNECTION_RESET),
7882   };
7883   StaticSocketDataProvider data(NULL, 0,
7884                                 write_failure, arraysize(write_failure));
7885   session_deps_.socket_factory->AddSocketDataProvider(&data);
7886   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7887
7888   TestCompletionCallback callback;
7889
7890   scoped_ptr<HttpTransaction> trans(
7891       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7892
7893   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7894   EXPECT_EQ(ERR_IO_PENDING, rv);
7895
7896   rv = callback.WaitForResult();
7897   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7898 }
7899
7900 // Check that a connection closed after the start of the headers finishes ok.
7901 TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
7902   HttpRequestInfo request;
7903   request.method = "GET";
7904   request.url = GURL("http://www.foo.com/");
7905   request.load_flags = 0;
7906
7907   MockRead data_reads[] = {
7908     MockRead("HTTP/1."),
7909     MockRead(SYNCHRONOUS, OK),
7910   };
7911
7912   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7913   session_deps_.socket_factory->AddSocketDataProvider(&data);
7914   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7915
7916   TestCompletionCallback callback;
7917
7918   scoped_ptr<HttpTransaction> trans(
7919       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7920
7921   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7922   EXPECT_EQ(ERR_IO_PENDING, rv);
7923
7924   rv = callback.WaitForResult();
7925   EXPECT_EQ(OK, rv);
7926
7927   const HttpResponseInfo* response = trans->GetResponseInfo();
7928   ASSERT_TRUE(response != NULL);
7929
7930   EXPECT_TRUE(response->headers.get() != NULL);
7931   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7932
7933   std::string response_data;
7934   rv = ReadTransaction(trans.get(), &response_data);
7935   EXPECT_EQ(OK, rv);
7936   EXPECT_EQ("", response_data);
7937 }
7938
7939 // Make sure that a dropped connection while draining the body for auth
7940 // restart does the right thing.
7941 TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
7942   HttpRequestInfo request;
7943   request.method = "GET";
7944   request.url = GURL("http://www.google.com/");
7945   request.load_flags = 0;
7946
7947   MockWrite data_writes1[] = {
7948     MockWrite("GET / HTTP/1.1\r\n"
7949               "Host: www.google.com\r\n"
7950               "Connection: keep-alive\r\n\r\n"),
7951   };
7952
7953   MockRead data_reads1[] = {
7954     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7955     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7956     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7957     MockRead("Content-Length: 14\r\n\r\n"),
7958     MockRead("Unauth"),
7959     MockRead(ASYNC, ERR_CONNECTION_RESET),
7960   };
7961
7962   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7963                                  data_writes1, arraysize(data_writes1));
7964   session_deps_.socket_factory->AddSocketDataProvider(&data1);
7965
7966   // After calling trans->RestartWithAuth(), this is the request we should
7967   // be issuing -- the final header line contains the credentials.
7968   MockWrite data_writes2[] = {
7969     MockWrite("GET / HTTP/1.1\r\n"
7970               "Host: www.google.com\r\n"
7971               "Connection: keep-alive\r\n"
7972               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7973   };
7974
7975   // Lastly, the server responds with the actual content.
7976   MockRead data_reads2[] = {
7977     MockRead("HTTP/1.1 200 OK\r\n"),
7978     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7979     MockRead("Content-Length: 100\r\n\r\n"),
7980     MockRead(SYNCHRONOUS, OK),
7981   };
7982
7983   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7984                                  data_writes2, arraysize(data_writes2));
7985   session_deps_.socket_factory->AddSocketDataProvider(&data2);
7986   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7987
7988   TestCompletionCallback callback1;
7989
7990   scoped_ptr<HttpTransaction> trans(
7991       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7992
7993   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
7994   EXPECT_EQ(ERR_IO_PENDING, rv);
7995
7996   rv = callback1.WaitForResult();
7997   EXPECT_EQ(OK, rv);
7998
7999   const HttpResponseInfo* response = trans->GetResponseInfo();
8000   ASSERT_TRUE(response != NULL);
8001   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8002
8003   TestCompletionCallback callback2;
8004
8005   rv = trans->RestartWithAuth(
8006       AuthCredentials(kFoo, kBar), callback2.callback());
8007   EXPECT_EQ(ERR_IO_PENDING, rv);
8008
8009   rv = callback2.WaitForResult();
8010   EXPECT_EQ(OK, rv);
8011
8012   response = trans->GetResponseInfo();
8013   ASSERT_TRUE(response != NULL);
8014   EXPECT_TRUE(response->auth_challenge.get() == NULL);
8015   EXPECT_EQ(100, response->headers->GetContentLength());
8016 }
8017
8018 // Test HTTPS connections going through a proxy that sends extra data.
8019 TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
8020   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
8021
8022   HttpRequestInfo request;
8023   request.method = "GET";
8024   request.url = GURL("https://www.google.com/");
8025   request.load_flags = 0;
8026
8027   MockRead proxy_reads[] = {
8028     MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
8029     MockRead(SYNCHRONOUS, OK)
8030   };
8031
8032   StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
8033   SSLSocketDataProvider ssl(ASYNC, OK);
8034
8035   session_deps_.socket_factory->AddSocketDataProvider(&data);
8036   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8037
8038   TestCompletionCallback callback;
8039
8040   session_deps_.socket_factory->ResetNextMockIndexes();
8041
8042   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8043   scoped_ptr<HttpTransaction> trans(
8044       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8045
8046   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8047   EXPECT_EQ(ERR_IO_PENDING, rv);
8048
8049   rv = callback.WaitForResult();
8050   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8051 }
8052
8053 TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
8054   HttpRequestInfo request;
8055   request.method = "GET";
8056   request.url = GURL("http://www.google.com/");
8057   request.load_flags = 0;
8058
8059   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8060   scoped_ptr<HttpTransaction> trans(
8061       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8062
8063   MockRead data_reads[] = {
8064     MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
8065     MockRead(SYNCHRONOUS, OK),
8066   };
8067
8068   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8069   session_deps_.socket_factory->AddSocketDataProvider(&data);
8070
8071   TestCompletionCallback callback;
8072
8073   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8074   EXPECT_EQ(ERR_IO_PENDING, rv);
8075
8076   EXPECT_EQ(OK, callback.WaitForResult());
8077
8078   const HttpResponseInfo* response = trans->GetResponseInfo();
8079   ASSERT_TRUE(response != NULL);
8080
8081   EXPECT_TRUE(response->headers.get() != NULL);
8082   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8083
8084   std::string response_data;
8085   rv = ReadTransaction(trans.get(), &response_data);
8086   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
8087 }
8088
8089 TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
8090   base::FilePath temp_file_path;
8091   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
8092   const uint64 kFakeSize = 100000;  // file is actually blank
8093   UploadFileElementReader::ScopedOverridingContentLengthForTests
8094       overriding_content_length(kFakeSize);
8095
8096   ScopedVector<UploadElementReader> element_readers;
8097   element_readers.push_back(
8098       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8099                                   temp_file_path,
8100                                   0,
8101                                   kuint64max,
8102                                   base::Time()));
8103   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
8104
8105   HttpRequestInfo request;
8106   request.method = "POST";
8107   request.url = GURL("http://www.google.com/upload");
8108   request.upload_data_stream = &upload_data_stream;
8109   request.load_flags = 0;
8110
8111   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8112   scoped_ptr<HttpTransaction> trans(
8113       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8114
8115   MockRead data_reads[] = {
8116     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8117     MockRead("hello world"),
8118     MockRead(SYNCHRONOUS, OK),
8119   };
8120   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8121   session_deps_.socket_factory->AddSocketDataProvider(&data);
8122
8123   TestCompletionCallback callback;
8124
8125   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8126   EXPECT_EQ(ERR_IO_PENDING, rv);
8127
8128   rv = callback.WaitForResult();
8129   EXPECT_EQ(OK, rv);
8130
8131   const HttpResponseInfo* response = trans->GetResponseInfo();
8132   ASSERT_TRUE(response != NULL);
8133
8134   EXPECT_TRUE(response->headers.get() != NULL);
8135   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8136
8137   std::string response_data;
8138   rv = ReadTransaction(trans.get(), &response_data);
8139   EXPECT_EQ(OK, rv);
8140   EXPECT_EQ("hello world", response_data);
8141
8142   base::DeleteFile(temp_file_path, false);
8143 }
8144
8145 TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
8146   base::FilePath temp_file;
8147   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
8148   std::string temp_file_content("Unreadable file.");
8149   ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
8150                                    temp_file_content.length()));
8151   ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
8152
8153   ScopedVector<UploadElementReader> element_readers;
8154   element_readers.push_back(
8155       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8156                                   temp_file,
8157                                   0,
8158                                   kuint64max,
8159                                   base::Time()));
8160   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
8161
8162   HttpRequestInfo request;
8163   request.method = "POST";
8164   request.url = GURL("http://www.google.com/upload");
8165   request.upload_data_stream = &upload_data_stream;
8166   request.load_flags = 0;
8167
8168   // If we try to upload an unreadable file, the transaction should fail.
8169   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8170   scoped_ptr<HttpTransaction> trans(
8171       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8172
8173   StaticSocketDataProvider data(NULL, 0, NULL, 0);
8174   session_deps_.socket_factory->AddSocketDataProvider(&data);
8175
8176   TestCompletionCallback callback;
8177
8178   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8179   EXPECT_EQ(ERR_IO_PENDING, rv);
8180
8181   rv = callback.WaitForResult();
8182   EXPECT_EQ(ERR_ACCESS_DENIED, rv);
8183
8184   const HttpResponseInfo* response = trans->GetResponseInfo();
8185   EXPECT_FALSE(response);
8186
8187   base::DeleteFile(temp_file, false);
8188 }
8189
8190 TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8191   class FakeUploadElementReader : public UploadElementReader {
8192    public:
8193     FakeUploadElementReader() {}
8194     ~FakeUploadElementReader() override {}
8195
8196     const CompletionCallback& callback() const { return callback_; }
8197
8198     // UploadElementReader overrides:
8199     int Init(const CompletionCallback& callback) override {
8200       callback_ = callback;
8201       return ERR_IO_PENDING;
8202     }
8203     uint64 GetContentLength() const override { return 0; }
8204     uint64 BytesRemaining() const override { return 0; }
8205     int Read(IOBuffer* buf,
8206              int buf_length,
8207              const CompletionCallback& callback) override {
8208       return ERR_FAILED;
8209     }
8210
8211    private:
8212     CompletionCallback callback_;
8213   };
8214
8215   FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8216   ScopedVector<UploadElementReader> element_readers;
8217   element_readers.push_back(fake_reader);
8218   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
8219
8220   HttpRequestInfo request;
8221   request.method = "POST";
8222   request.url = GURL("http://www.google.com/upload");
8223   request.upload_data_stream = &upload_data_stream;
8224   request.load_flags = 0;
8225
8226   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8227   scoped_ptr<HttpTransaction> trans(
8228       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8229
8230   StaticSocketDataProvider data;
8231   session_deps_.socket_factory->AddSocketDataProvider(&data);
8232
8233   TestCompletionCallback callback;
8234   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8235   EXPECT_EQ(ERR_IO_PENDING, rv);
8236   base::MessageLoop::current()->RunUntilIdle();
8237
8238   // Transaction is pending on request body initialization.
8239   ASSERT_FALSE(fake_reader->callback().is_null());
8240
8241   // Return Init()'s result after the transaction gets destroyed.
8242   trans.reset();
8243   fake_reader->callback().Run(OK);  // Should not crash.
8244 }
8245
8246 // Tests that changes to Auth realms are treated like auth rejections.
8247 TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
8248
8249   HttpRequestInfo request;
8250   request.method = "GET";
8251   request.url = GURL("http://www.google.com/");
8252   request.load_flags = 0;
8253
8254   // First transaction will request a resource and receive a Basic challenge
8255   // with realm="first_realm".
8256   MockWrite data_writes1[] = {
8257     MockWrite("GET / HTTP/1.1\r\n"
8258               "Host: www.google.com\r\n"
8259               "Connection: keep-alive\r\n"
8260               "\r\n"),
8261   };
8262   MockRead data_reads1[] = {
8263     MockRead("HTTP/1.1 401 Unauthorized\r\n"
8264              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8265              "\r\n"),
8266   };
8267
8268   // After calling trans->RestartWithAuth(), provide an Authentication header
8269   // for first_realm. The server will reject and provide a challenge with
8270   // second_realm.
8271   MockWrite data_writes2[] = {
8272     MockWrite("GET / HTTP/1.1\r\n"
8273               "Host: www.google.com\r\n"
8274               "Connection: keep-alive\r\n"
8275               "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8276               "\r\n"),
8277   };
8278   MockRead data_reads2[] = {
8279     MockRead("HTTP/1.1 401 Unauthorized\r\n"
8280              "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8281              "\r\n"),
8282   };
8283
8284   // This again fails, and goes back to first_realm. Make sure that the
8285   // entry is removed from cache.
8286   MockWrite data_writes3[] = {
8287     MockWrite("GET / HTTP/1.1\r\n"
8288               "Host: www.google.com\r\n"
8289               "Connection: keep-alive\r\n"
8290               "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8291               "\r\n"),
8292   };
8293   MockRead data_reads3[] = {
8294     MockRead("HTTP/1.1 401 Unauthorized\r\n"
8295              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8296              "\r\n"),
8297   };
8298
8299   // Try one last time (with the correct password) and get the resource.
8300   MockWrite data_writes4[] = {
8301     MockWrite("GET / HTTP/1.1\r\n"
8302               "Host: www.google.com\r\n"
8303               "Connection: keep-alive\r\n"
8304               "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8305               "\r\n"),
8306   };
8307   MockRead data_reads4[] = {
8308     MockRead("HTTP/1.1 200 OK\r\n"
8309              "Content-Type: text/html; charset=iso-8859-1\r\n"
8310              "Content-Length: 5\r\n"
8311              "\r\n"
8312              "hello"),
8313   };
8314
8315   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8316                                  data_writes1, arraysize(data_writes1));
8317   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8318                                  data_writes2, arraysize(data_writes2));
8319   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8320                                  data_writes3, arraysize(data_writes3));
8321   StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8322                                  data_writes4, arraysize(data_writes4));
8323   session_deps_.socket_factory->AddSocketDataProvider(&data1);
8324   session_deps_.socket_factory->AddSocketDataProvider(&data2);
8325   session_deps_.socket_factory->AddSocketDataProvider(&data3);
8326   session_deps_.socket_factory->AddSocketDataProvider(&data4);
8327
8328   TestCompletionCallback callback1;
8329
8330   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8331   scoped_ptr<HttpTransaction> trans(
8332       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8333
8334   // Issue the first request with Authorize headers. There should be a
8335   // password prompt for first_realm waiting to be filled in after the
8336   // transaction completes.
8337   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
8338   EXPECT_EQ(ERR_IO_PENDING, rv);
8339   rv = callback1.WaitForResult();
8340   EXPECT_EQ(OK, rv);
8341   const HttpResponseInfo* response = trans->GetResponseInfo();
8342   ASSERT_TRUE(response != NULL);
8343   const AuthChallengeInfo* challenge = response->auth_challenge.get();
8344   ASSERT_FALSE(challenge == NULL);
8345   EXPECT_FALSE(challenge->is_proxy);
8346   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8347   EXPECT_EQ("first_realm", challenge->realm);
8348   EXPECT_EQ("basic", challenge->scheme);
8349
8350   // Issue the second request with an incorrect password. There should be a
8351   // password prompt for second_realm waiting to be filled in after the
8352   // transaction completes.
8353   TestCompletionCallback callback2;
8354   rv = trans->RestartWithAuth(
8355       AuthCredentials(kFirst, kBaz), callback2.callback());
8356   EXPECT_EQ(ERR_IO_PENDING, rv);
8357   rv = callback2.WaitForResult();
8358   EXPECT_EQ(OK, rv);
8359   response = trans->GetResponseInfo();
8360   ASSERT_TRUE(response != NULL);
8361   challenge = response->auth_challenge.get();
8362   ASSERT_FALSE(challenge == NULL);
8363   EXPECT_FALSE(challenge->is_proxy);
8364   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8365   EXPECT_EQ("second_realm", challenge->realm);
8366   EXPECT_EQ("basic", challenge->scheme);
8367
8368   // Issue the third request with another incorrect password. There should be
8369   // a password prompt for first_realm waiting to be filled in. If the password
8370   // prompt is not present, it indicates that the HttpAuthCacheEntry for
8371   // first_realm was not correctly removed.
8372   TestCompletionCallback callback3;
8373   rv = trans->RestartWithAuth(
8374       AuthCredentials(kSecond, kFou), callback3.callback());
8375   EXPECT_EQ(ERR_IO_PENDING, rv);
8376   rv = callback3.WaitForResult();
8377   EXPECT_EQ(OK, rv);
8378   response = trans->GetResponseInfo();
8379   ASSERT_TRUE(response != NULL);
8380   challenge = response->auth_challenge.get();
8381   ASSERT_FALSE(challenge == NULL);
8382   EXPECT_FALSE(challenge->is_proxy);
8383   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8384   EXPECT_EQ("first_realm", challenge->realm);
8385   EXPECT_EQ("basic", challenge->scheme);
8386
8387   // Issue the fourth request with the correct password and username.
8388   TestCompletionCallback callback4;
8389   rv = trans->RestartWithAuth(
8390       AuthCredentials(kFirst, kBar), callback4.callback());
8391   EXPECT_EQ(ERR_IO_PENDING, rv);
8392   rv = callback4.WaitForResult();
8393   EXPECT_EQ(OK, rv);
8394   response = trans->GetResponseInfo();
8395   ASSERT_TRUE(response != NULL);
8396   EXPECT_TRUE(response->auth_challenge.get() == NULL);
8397 }
8398
8399 TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
8400   session_deps_.next_protos = SpdyNextProtos();
8401   session_deps_.use_alternate_protocols = true;
8402
8403   std::string alternate_protocol_http_header =
8404       GetAlternateProtocolHttpHeader();
8405
8406   MockRead data_reads[] = {
8407     MockRead("HTTP/1.1 200 OK\r\n"),
8408     MockRead(alternate_protocol_http_header.c_str()),
8409     MockRead("hello world"),
8410     MockRead(SYNCHRONOUS, OK),
8411   };
8412
8413   HttpRequestInfo request;
8414   request.method = "GET";
8415   request.url = GURL("http://www.google.com/");
8416   request.load_flags = 0;
8417
8418   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8419
8420   session_deps_.socket_factory->AddSocketDataProvider(&data);
8421
8422   TestCompletionCallback callback;
8423
8424   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8425   scoped_ptr<HttpTransaction> trans(
8426       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8427
8428   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8429   EXPECT_EQ(ERR_IO_PENDING, rv);
8430
8431   HostPortPair http_host_port_pair("www.google.com", 80);
8432   HttpServerProperties& http_server_properties =
8433       *session->http_server_properties();
8434   EXPECT_FALSE(
8435       http_server_properties.HasAlternateProtocol(http_host_port_pair));
8436
8437   EXPECT_EQ(OK, callback.WaitForResult());
8438
8439   const HttpResponseInfo* response = trans->GetResponseInfo();
8440   ASSERT_TRUE(response != NULL);
8441   ASSERT_TRUE(response->headers.get() != NULL);
8442   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8443   EXPECT_FALSE(response->was_fetched_via_spdy);
8444   EXPECT_FALSE(response->was_npn_negotiated);
8445
8446   std::string response_data;
8447   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8448   EXPECT_EQ("hello world", response_data);
8449
8450   ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8451   const AlternateProtocolInfo alternate =
8452       http_server_properties.GetAlternateProtocol(http_host_port_pair);
8453   AlternateProtocolInfo expected_alternate(
8454       443, AlternateProtocolFromNextProto(GetParam()), 1);
8455   EXPECT_TRUE(expected_alternate.Equals(alternate));
8456 }
8457
8458 TEST_P(HttpNetworkTransactionTest,
8459        MarkBrokenAlternateProtocolAndFallback) {
8460   session_deps_.use_alternate_protocols = true;
8461
8462   HttpRequestInfo request;
8463   request.method = "GET";
8464   request.url = GURL("http://www.google.com/");
8465   request.load_flags = 0;
8466
8467   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8468   StaticSocketDataProvider first_data;
8469   first_data.set_connect_data(mock_connect);
8470   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8471
8472   MockRead data_reads[] = {
8473     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8474     MockRead("hello world"),
8475     MockRead(ASYNC, OK),
8476   };
8477   StaticSocketDataProvider second_data(
8478       data_reads, arraysize(data_reads), NULL, 0);
8479   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8480
8481   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8482
8483   base::WeakPtr<HttpServerProperties> http_server_properties =
8484       session->http_server_properties();
8485   // Port must be < 1024, or the header will be ignored (since initial port was
8486   // port 80 (another restricted port).
8487   http_server_properties->SetAlternateProtocol(
8488       HostPortPair::FromURL(request.url),
8489       666 /* port is ignored by MockConnect anyway */,
8490       AlternateProtocolFromNextProto(GetParam()), 1);
8491
8492   scoped_ptr<HttpTransaction> trans(
8493       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8494   TestCompletionCallback callback;
8495
8496   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8497   EXPECT_EQ(ERR_IO_PENDING, rv);
8498   EXPECT_EQ(OK, callback.WaitForResult());
8499
8500   const HttpResponseInfo* response = trans->GetResponseInfo();
8501   ASSERT_TRUE(response != NULL);
8502   ASSERT_TRUE(response->headers.get() != NULL);
8503   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8504
8505   std::string response_data;
8506   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8507   EXPECT_EQ("hello world", response_data);
8508
8509   ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
8510       HostPortPair::FromURL(request.url)));
8511   const AlternateProtocolInfo alternate =
8512       http_server_properties->GetAlternateProtocol(
8513           HostPortPair::FromURL(request.url));
8514   EXPECT_TRUE(alternate.is_broken);
8515 }
8516
8517 TEST_P(HttpNetworkTransactionTest,
8518        AlternateProtocolPortRestrictedBlocked) {
8519   // Ensure that we're not allowed to redirect traffic via an alternate
8520   // protocol to an unrestricted (port >= 1024) when the original traffic was
8521   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8522   // other cases.
8523   session_deps_.use_alternate_protocols = true;
8524
8525   HttpRequestInfo restricted_port_request;
8526   restricted_port_request.method = "GET";
8527   restricted_port_request.url = GURL("http://www.google.com:1023/");
8528   restricted_port_request.load_flags = 0;
8529
8530   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8531   StaticSocketDataProvider first_data;
8532   first_data.set_connect_data(mock_connect);
8533   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8534
8535   MockRead data_reads[] = {
8536     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8537     MockRead("hello world"),
8538     MockRead(ASYNC, OK),
8539   };
8540   StaticSocketDataProvider second_data(
8541       data_reads, arraysize(data_reads), NULL, 0);
8542   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8543
8544   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8545
8546   base::WeakPtr<HttpServerProperties> http_server_properties =
8547       session->http_server_properties();
8548   const int kUnrestrictedAlternatePort = 1024;
8549   http_server_properties->SetAlternateProtocol(
8550       HostPortPair::FromURL(restricted_port_request.url),
8551       kUnrestrictedAlternatePort,
8552       AlternateProtocolFromNextProto(GetParam()), 1);
8553
8554   scoped_ptr<HttpTransaction> trans(
8555       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8556   TestCompletionCallback callback;
8557
8558   int rv = trans->Start(
8559       &restricted_port_request,
8560       callback.callback(), BoundNetLog());
8561   EXPECT_EQ(ERR_IO_PENDING, rv);
8562   // Invalid change to unrestricted port should fail.
8563   EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
8564 }
8565
8566 TEST_P(HttpNetworkTransactionTest,
8567        AlternateProtocolPortRestrictedPermitted) {
8568   // Ensure that we're allowed to redirect traffic via an alternate
8569   // protocol to an unrestricted (port >= 1024) when the original traffic was
8570   // on a restricted port (port < 1024) if we set
8571   // enable_user_alternate_protocol_ports.
8572
8573   session_deps_.use_alternate_protocols = true;
8574   session_deps_.enable_user_alternate_protocol_ports = true;
8575
8576   HttpRequestInfo restricted_port_request;
8577   restricted_port_request.method = "GET";
8578   restricted_port_request.url = GURL("http://www.google.com:1023/");
8579   restricted_port_request.load_flags = 0;
8580
8581   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8582   StaticSocketDataProvider first_data;
8583   first_data.set_connect_data(mock_connect);
8584   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8585
8586   MockRead data_reads[] = {
8587     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8588     MockRead("hello world"),
8589     MockRead(ASYNC, OK),
8590   };
8591   StaticSocketDataProvider second_data(
8592       data_reads, arraysize(data_reads), NULL, 0);
8593   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8594
8595   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8596
8597   base::WeakPtr<HttpServerProperties> http_server_properties =
8598       session->http_server_properties();
8599   const int kUnrestrictedAlternatePort = 1024;
8600   http_server_properties->SetAlternateProtocol(
8601       HostPortPair::FromURL(restricted_port_request.url),
8602       kUnrestrictedAlternatePort,
8603       AlternateProtocolFromNextProto(GetParam()), 1);
8604
8605   scoped_ptr<HttpTransaction> trans(
8606       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8607   TestCompletionCallback callback;
8608
8609   EXPECT_EQ(ERR_IO_PENDING, trans->Start(
8610       &restricted_port_request,
8611       callback.callback(), BoundNetLog()));
8612   // Change to unrestricted port should succeed.
8613   EXPECT_EQ(OK, callback.WaitForResult());
8614 }
8615
8616 TEST_P(HttpNetworkTransactionTest,
8617        AlternateProtocolPortRestrictedAllowed) {
8618   // Ensure that we're not allowed to redirect traffic via an alternate
8619   // protocol to an unrestricted (port >= 1024) when the original traffic was
8620   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8621   // other cases.
8622   session_deps_.use_alternate_protocols = true;
8623
8624   HttpRequestInfo restricted_port_request;
8625   restricted_port_request.method = "GET";
8626   restricted_port_request.url = GURL("http://www.google.com:1023/");
8627   restricted_port_request.load_flags = 0;
8628
8629   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8630   StaticSocketDataProvider first_data;
8631   first_data.set_connect_data(mock_connect);
8632   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8633
8634   MockRead data_reads[] = {
8635     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8636     MockRead("hello world"),
8637     MockRead(ASYNC, OK),
8638   };
8639   StaticSocketDataProvider second_data(
8640       data_reads, arraysize(data_reads), NULL, 0);
8641   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8642
8643   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8644
8645   base::WeakPtr<HttpServerProperties> http_server_properties =
8646       session->http_server_properties();
8647   const int kRestrictedAlternatePort = 80;
8648   http_server_properties->SetAlternateProtocol(
8649       HostPortPair::FromURL(restricted_port_request.url),
8650       kRestrictedAlternatePort,
8651       AlternateProtocolFromNextProto(GetParam()), 1);
8652
8653   scoped_ptr<HttpTransaction> trans(
8654       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8655   TestCompletionCallback callback;
8656
8657   int rv = trans->Start(
8658       &restricted_port_request,
8659       callback.callback(), BoundNetLog());
8660   EXPECT_EQ(ERR_IO_PENDING, rv);
8661   // Valid change to restricted port should pass.
8662   EXPECT_EQ(OK, callback.WaitForResult());
8663 }
8664
8665 TEST_P(HttpNetworkTransactionTest,
8666        AlternateProtocolPortUnrestrictedAllowed1) {
8667   // Ensure that we're not allowed to redirect traffic via an alternate
8668   // protocol to an unrestricted (port >= 1024) when the original traffic was
8669   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8670   // other cases.
8671   session_deps_.use_alternate_protocols = true;
8672
8673   HttpRequestInfo unrestricted_port_request;
8674   unrestricted_port_request.method = "GET";
8675   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8676   unrestricted_port_request.load_flags = 0;
8677
8678   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8679   StaticSocketDataProvider first_data;
8680   first_data.set_connect_data(mock_connect);
8681   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8682
8683   MockRead data_reads[] = {
8684     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8685     MockRead("hello world"),
8686     MockRead(ASYNC, OK),
8687   };
8688   StaticSocketDataProvider second_data(
8689       data_reads, arraysize(data_reads), NULL, 0);
8690   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8691
8692   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8693
8694   base::WeakPtr<HttpServerProperties> http_server_properties =
8695       session->http_server_properties();
8696   const int kRestrictedAlternatePort = 80;
8697   http_server_properties->SetAlternateProtocol(
8698       HostPortPair::FromURL(unrestricted_port_request.url),
8699       kRestrictedAlternatePort,
8700       AlternateProtocolFromNextProto(GetParam()), 1);
8701
8702   scoped_ptr<HttpTransaction> trans(
8703       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8704   TestCompletionCallback callback;
8705
8706   int rv = trans->Start(
8707       &unrestricted_port_request, callback.callback(), BoundNetLog());
8708   EXPECT_EQ(ERR_IO_PENDING, rv);
8709   // Valid change to restricted port should pass.
8710   EXPECT_EQ(OK, callback.WaitForResult());
8711 }
8712
8713 TEST_P(HttpNetworkTransactionTest,
8714        AlternateProtocolPortUnrestrictedAllowed2) {
8715   // Ensure that we're not allowed to redirect traffic via an alternate
8716   // protocol to an unrestricted (port >= 1024) when the original traffic was
8717   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8718   // other cases.
8719   session_deps_.use_alternate_protocols = true;
8720
8721   HttpRequestInfo unrestricted_port_request;
8722   unrestricted_port_request.method = "GET";
8723   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8724   unrestricted_port_request.load_flags = 0;
8725
8726   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8727   StaticSocketDataProvider first_data;
8728   first_data.set_connect_data(mock_connect);
8729   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8730
8731   MockRead data_reads[] = {
8732     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8733     MockRead("hello world"),
8734     MockRead(ASYNC, OK),
8735   };
8736   StaticSocketDataProvider second_data(
8737       data_reads, arraysize(data_reads), NULL, 0);
8738   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8739
8740   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8741
8742   base::WeakPtr<HttpServerProperties> http_server_properties =
8743       session->http_server_properties();
8744   const int kUnrestrictedAlternatePort = 1024;
8745   http_server_properties->SetAlternateProtocol(
8746       HostPortPair::FromURL(unrestricted_port_request.url),
8747       kUnrestrictedAlternatePort,
8748       AlternateProtocolFromNextProto(GetParam()), 1);
8749
8750   scoped_ptr<HttpTransaction> trans(
8751       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8752   TestCompletionCallback callback;
8753
8754   int rv = trans->Start(
8755       &unrestricted_port_request, callback.callback(), BoundNetLog());
8756   EXPECT_EQ(ERR_IO_PENDING, rv);
8757   // Valid change to an unrestricted port should pass.
8758   EXPECT_EQ(OK, callback.WaitForResult());
8759 }
8760
8761 TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
8762   // Ensure that we're not allowed to redirect traffic via an alternate
8763   // protocol to an unsafe port, and that we resume the second
8764   // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8765   session_deps_.use_alternate_protocols = true;
8766
8767   HttpRequestInfo request;
8768   request.method = "GET";
8769   request.url = GURL("http://www.google.com/");
8770   request.load_flags = 0;
8771
8772   // The alternate protocol request will error out before we attempt to connect,
8773   // so only the standard HTTP request will try to connect.
8774   MockRead data_reads[] = {
8775     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8776     MockRead("hello world"),
8777     MockRead(ASYNC, OK),
8778   };
8779   StaticSocketDataProvider data(
8780       data_reads, arraysize(data_reads), NULL, 0);
8781   session_deps_.socket_factory->AddSocketDataProvider(&data);
8782
8783   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8784
8785   base::WeakPtr<HttpServerProperties> http_server_properties =
8786       session->http_server_properties();
8787   const int kUnsafePort = 7;
8788   http_server_properties->SetAlternateProtocol(
8789       HostPortPair::FromURL(request.url),
8790       kUnsafePort,
8791       AlternateProtocolFromNextProto(GetParam()), 1);
8792
8793   scoped_ptr<HttpTransaction> trans(
8794       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8795   TestCompletionCallback callback;
8796
8797   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8798   EXPECT_EQ(ERR_IO_PENDING, rv);
8799   // The HTTP request should succeed.
8800   EXPECT_EQ(OK, callback.WaitForResult());
8801
8802   // Disable alternate protocol before the asserts.
8803  // HttpStreamFactory::set_use_alternate_protocols(false);
8804
8805   const HttpResponseInfo* response = trans->GetResponseInfo();
8806   ASSERT_TRUE(response != NULL);
8807   ASSERT_TRUE(response->headers.get() != NULL);
8808   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8809
8810   std::string response_data;
8811   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8812   EXPECT_EQ("hello world", response_data);
8813 }
8814
8815 TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
8816   session_deps_.use_alternate_protocols = true;
8817   session_deps_.next_protos = SpdyNextProtos();
8818
8819   HttpRequestInfo request;
8820   request.method = "GET";
8821   request.url = GURL("http://www.google.com/");
8822   request.load_flags = 0;
8823
8824   std::string alternate_protocol_http_header =
8825       GetAlternateProtocolHttpHeader();
8826
8827   MockRead data_reads[] = {
8828     MockRead("HTTP/1.1 200 OK\r\n"),
8829     MockRead(alternate_protocol_http_header.c_str()),
8830     MockRead("hello world"),
8831     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8832     MockRead(ASYNC, OK)
8833   };
8834
8835   StaticSocketDataProvider first_transaction(
8836       data_reads, arraysize(data_reads), NULL, 0);
8837   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
8838
8839   SSLSocketDataProvider ssl(ASYNC, OK);
8840   ssl.SetNextProto(GetParam());
8841   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8842
8843   scoped_ptr<SpdyFrame> req(
8844       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8845   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
8846
8847   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8848   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
8849   MockRead spdy_reads[] = {
8850     CreateMockRead(*resp),
8851     CreateMockRead(*data),
8852     MockRead(ASYNC, 0, 0),
8853   };
8854
8855   DelayedSocketData spdy_data(
8856       1,  // wait for one write to finish before reading.
8857       spdy_reads, arraysize(spdy_reads),
8858       spdy_writes, arraysize(spdy_writes));
8859   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8860
8861   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
8862   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8863       NULL, 0, NULL, 0);
8864   hanging_non_alternate_protocol_socket.set_connect_data(
8865       never_finishing_connect);
8866   session_deps_.socket_factory->AddSocketDataProvider(
8867       &hanging_non_alternate_protocol_socket);
8868
8869   TestCompletionCallback callback;
8870
8871   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8872   scoped_ptr<HttpTransaction> trans(
8873       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8874
8875   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8876   EXPECT_EQ(ERR_IO_PENDING, rv);
8877   EXPECT_EQ(OK, callback.WaitForResult());
8878
8879   const HttpResponseInfo* response = trans->GetResponseInfo();
8880   ASSERT_TRUE(response != NULL);
8881   ASSERT_TRUE(response->headers.get() != NULL);
8882   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8883
8884   std::string response_data;
8885   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8886   EXPECT_EQ("hello world", response_data);
8887
8888   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8889
8890   rv = trans->Start(&request, callback.callback(), BoundNetLog());
8891   EXPECT_EQ(ERR_IO_PENDING, rv);
8892   EXPECT_EQ(OK, callback.WaitForResult());
8893
8894   response = trans->GetResponseInfo();
8895   ASSERT_TRUE(response != NULL);
8896   ASSERT_TRUE(response->headers.get() != NULL);
8897   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8898   EXPECT_TRUE(response->was_fetched_via_spdy);
8899   EXPECT_TRUE(response->was_npn_negotiated);
8900
8901   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8902   EXPECT_EQ("hello!", response_data);
8903 }
8904
8905 TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
8906   session_deps_.use_alternate_protocols = true;
8907   session_deps_.next_protos = SpdyNextProtos();
8908
8909   HttpRequestInfo request;
8910   request.method = "GET";
8911   request.url = GURL("http://www.google.com/");
8912   request.load_flags = 0;
8913
8914   std::string alternate_protocol_http_header =
8915       GetAlternateProtocolHttpHeader();
8916
8917   MockRead data_reads[] = {
8918     MockRead("HTTP/1.1 200 OK\r\n"),
8919     MockRead(alternate_protocol_http_header.c_str()),
8920     MockRead("hello world"),
8921     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8922     MockRead(ASYNC, OK),
8923   };
8924
8925   StaticSocketDataProvider first_transaction(
8926       data_reads, arraysize(data_reads), NULL, 0);
8927   // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
8928   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
8929
8930   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
8931   StaticSocketDataProvider hanging_socket(
8932       NULL, 0, NULL, 0);
8933   hanging_socket.set_connect_data(never_finishing_connect);
8934   // Socket 2 and 3 are the hanging Alternate-Protocol and
8935   // non-Alternate-Protocol jobs from the 2nd transaction.
8936   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8937   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8938
8939   SSLSocketDataProvider ssl(ASYNC, OK);
8940   ssl.SetNextProto(GetParam());
8941   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8942
8943   scoped_ptr<SpdyFrame> req1(
8944       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8945   scoped_ptr<SpdyFrame> req2(
8946       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
8947   MockWrite spdy_writes[] = {
8948     CreateMockWrite(*req1),
8949     CreateMockWrite(*req2),
8950   };
8951   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8952   scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8953   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8954   scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
8955   MockRead spdy_reads[] = {
8956     CreateMockRead(*resp1),
8957     CreateMockRead(*data1),
8958     CreateMockRead(*resp2),
8959     CreateMockRead(*data2),
8960     MockRead(ASYNC, 0, 0),
8961   };
8962
8963   DelayedSocketData spdy_data(
8964       2,  // wait for writes to finish before reading.
8965       spdy_reads, arraysize(spdy_reads),
8966       spdy_writes, arraysize(spdy_writes));
8967   // Socket 4 is the successful Alternate-Protocol for transaction 3.
8968   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8969
8970   // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
8971   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8972
8973   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8974   TestCompletionCallback callback1;
8975   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
8976
8977   int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
8978   EXPECT_EQ(ERR_IO_PENDING, rv);
8979   EXPECT_EQ(OK, callback1.WaitForResult());
8980
8981   const HttpResponseInfo* response = trans1.GetResponseInfo();
8982   ASSERT_TRUE(response != NULL);
8983   ASSERT_TRUE(response->headers.get() != NULL);
8984   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8985
8986   std::string response_data;
8987   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8988   EXPECT_EQ("hello world", response_data);
8989
8990   TestCompletionCallback callback2;
8991   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
8992   rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
8993   EXPECT_EQ(ERR_IO_PENDING, rv);
8994
8995   TestCompletionCallback callback3;
8996   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
8997   rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
8998   EXPECT_EQ(ERR_IO_PENDING, rv);
8999
9000   EXPECT_EQ(OK, callback2.WaitForResult());
9001   EXPECT_EQ(OK, callback3.WaitForResult());
9002
9003   response = trans2.GetResponseInfo();
9004   ASSERT_TRUE(response != NULL);
9005   ASSERT_TRUE(response->headers.get() != NULL);
9006   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9007   EXPECT_TRUE(response->was_fetched_via_spdy);
9008   EXPECT_TRUE(response->was_npn_negotiated);
9009   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9010   EXPECT_EQ("hello!", response_data);
9011
9012   response = trans3.GetResponseInfo();
9013   ASSERT_TRUE(response != NULL);
9014   ASSERT_TRUE(response->headers.get() != NULL);
9015   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9016   EXPECT_TRUE(response->was_fetched_via_spdy);
9017   EXPECT_TRUE(response->was_npn_negotiated);
9018   ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9019   EXPECT_EQ("hello!", response_data);
9020 }
9021
9022 TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
9023   session_deps_.use_alternate_protocols = true;
9024   session_deps_.next_protos = SpdyNextProtos();
9025
9026   HttpRequestInfo request;
9027   request.method = "GET";
9028   request.url = GURL("http://www.google.com/");
9029   request.load_flags = 0;
9030
9031   std::string alternate_protocol_http_header =
9032       GetAlternateProtocolHttpHeader();
9033
9034   MockRead data_reads[] = {
9035     MockRead("HTTP/1.1 200 OK\r\n"),
9036     MockRead(alternate_protocol_http_header.c_str()),
9037     MockRead("hello world"),
9038     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9039     MockRead(ASYNC, OK),
9040   };
9041
9042   StaticSocketDataProvider first_transaction(
9043       data_reads, arraysize(data_reads), NULL, 0);
9044   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
9045
9046   SSLSocketDataProvider ssl(ASYNC, OK);
9047   ssl.SetNextProto(GetParam());
9048   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9049
9050   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
9051   StaticSocketDataProvider hanging_alternate_protocol_socket(
9052       NULL, 0, NULL, 0);
9053   hanging_alternate_protocol_socket.set_connect_data(
9054       never_finishing_connect);
9055   session_deps_.socket_factory->AddSocketDataProvider(
9056       &hanging_alternate_protocol_socket);
9057
9058   // 2nd request is just a copy of the first one, over HTTP again.
9059   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
9060
9061   TestCompletionCallback callback;
9062
9063   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9064   scoped_ptr<HttpTransaction> trans(
9065       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9066
9067   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9068   EXPECT_EQ(ERR_IO_PENDING, rv);
9069   EXPECT_EQ(OK, callback.WaitForResult());
9070
9071   const HttpResponseInfo* response = trans->GetResponseInfo();
9072   ASSERT_TRUE(response != NULL);
9073   ASSERT_TRUE(response->headers.get() != NULL);
9074   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9075
9076   std::string response_data;
9077   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9078   EXPECT_EQ("hello world", response_data);
9079
9080   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9081
9082   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9083   EXPECT_EQ(ERR_IO_PENDING, rv);
9084   EXPECT_EQ(OK, callback.WaitForResult());
9085
9086   response = trans->GetResponseInfo();
9087   ASSERT_TRUE(response != NULL);
9088   ASSERT_TRUE(response->headers.get() != NULL);
9089   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9090   EXPECT_FALSE(response->was_fetched_via_spdy);
9091   EXPECT_FALSE(response->was_npn_negotiated);
9092
9093   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9094   EXPECT_EQ("hello world", response_data);
9095 }
9096
9097 class CapturingProxyResolver : public ProxyResolver {
9098  public:
9099   CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
9100   ~CapturingProxyResolver() override {}
9101
9102   int GetProxyForURL(const GURL& url,
9103                      ProxyInfo* results,
9104                      const CompletionCallback& callback,
9105                      RequestHandle* request,
9106                      const BoundNetLog& net_log) override {
9107     ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9108                              HostPortPair("myproxy", 80));
9109     results->UseProxyServer(proxy_server);
9110     resolved_.push_back(url);
9111     return OK;
9112   }
9113
9114   void CancelRequest(RequestHandle request) override { NOTREACHED(); }
9115
9116   LoadState GetLoadState(RequestHandle request) const override {
9117     NOTREACHED();
9118     return LOAD_STATE_IDLE;
9119   }
9120
9121   void CancelSetPacScript() override { NOTREACHED(); }
9122
9123   int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
9124                    const CompletionCallback& /*callback*/) override {
9125     return OK;
9126   }
9127
9128   const std::vector<GURL>& resolved() const { return resolved_; }
9129
9130  private:
9131   std::vector<GURL> resolved_;
9132
9133   DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9134 };
9135
9136 TEST_P(HttpNetworkTransactionTest,
9137        UseAlternateProtocolForTunneledNpnSpdy) {
9138   session_deps_.use_alternate_protocols = true;
9139   session_deps_.next_protos = SpdyNextProtos();
9140
9141   ProxyConfig proxy_config;
9142   proxy_config.set_auto_detect(true);
9143   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
9144
9145   CapturingProxyResolver* capturing_proxy_resolver =
9146       new CapturingProxyResolver();
9147   session_deps_.proxy_service.reset(new ProxyService(
9148       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
9149       NULL));
9150   CapturingNetLog net_log;
9151   session_deps_.net_log = &net_log;
9152
9153   HttpRequestInfo request;
9154   request.method = "GET";
9155   request.url = GURL("http://www.google.com/");
9156   request.load_flags = 0;
9157
9158   std::string alternate_protocol_http_header =
9159       GetAlternateProtocolHttpHeader();
9160
9161   MockRead data_reads[] = {
9162     MockRead("HTTP/1.1 200 OK\r\n"),
9163     MockRead(alternate_protocol_http_header.c_str()),
9164     MockRead("hello world"),
9165     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9166     MockRead(ASYNC, OK),
9167   };
9168
9169   StaticSocketDataProvider first_transaction(
9170       data_reads, arraysize(data_reads), NULL, 0);
9171   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
9172
9173   SSLSocketDataProvider ssl(ASYNC, OK);
9174   ssl.SetNextProto(GetParam());
9175   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9176
9177   scoped_ptr<SpdyFrame> req(
9178       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9179   MockWrite spdy_writes[] = {
9180     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9181               "Host: www.google.com\r\n"
9182               "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
9183     CreateMockWrite(*req),                              // 3
9184   };
9185
9186   const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9187
9188   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9189   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
9190   MockRead spdy_reads[] = {
9191     MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
9192     CreateMockRead(*resp.get(), 4),  // 2, 4
9193     CreateMockRead(*data.get(), 4),  // 5
9194     MockRead(ASYNC, 0, 0, 4),  // 6
9195   };
9196
9197   OrderedSocketData spdy_data(
9198       spdy_reads, arraysize(spdy_reads),
9199       spdy_writes, arraysize(spdy_writes));
9200   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9201
9202   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
9203   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9204       NULL, 0, NULL, 0);
9205   hanging_non_alternate_protocol_socket.set_connect_data(
9206       never_finishing_connect);
9207   session_deps_.socket_factory->AddSocketDataProvider(
9208       &hanging_non_alternate_protocol_socket);
9209
9210   TestCompletionCallback callback;
9211
9212   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9213   scoped_ptr<HttpTransaction> trans(
9214       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9215
9216   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9217   EXPECT_EQ(ERR_IO_PENDING, rv);
9218   EXPECT_EQ(OK, callback.WaitForResult());
9219
9220   const HttpResponseInfo* response = trans->GetResponseInfo();
9221   ASSERT_TRUE(response != NULL);
9222   ASSERT_TRUE(response->headers.get() != NULL);
9223   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9224   EXPECT_FALSE(response->was_fetched_via_spdy);
9225   EXPECT_FALSE(response->was_npn_negotiated);
9226
9227   std::string response_data;
9228   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9229   EXPECT_EQ("hello world", response_data);
9230
9231   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9232
9233   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9234   EXPECT_EQ(ERR_IO_PENDING, rv);
9235   EXPECT_EQ(OK, callback.WaitForResult());
9236
9237   response = trans->GetResponseInfo();
9238   ASSERT_TRUE(response != NULL);
9239   ASSERT_TRUE(response->headers.get() != NULL);
9240   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9241   EXPECT_TRUE(response->was_fetched_via_spdy);
9242   EXPECT_TRUE(response->was_npn_negotiated);
9243
9244   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9245   EXPECT_EQ("hello!", response_data);
9246   ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
9247   EXPECT_EQ("http://www.google.com/",
9248             capturing_proxy_resolver->resolved()[0].spec());
9249   EXPECT_EQ("https://www.google.com/",
9250             capturing_proxy_resolver->resolved()[1].spec());
9251
9252   LoadTimingInfo load_timing_info;
9253   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9254   TestLoadTimingNotReusedWithPac(load_timing_info,
9255                                  CONNECT_TIMING_HAS_SSL_TIMES);
9256 }
9257
9258 TEST_P(HttpNetworkTransactionTest,
9259        UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
9260   session_deps_.use_alternate_protocols = true;
9261   session_deps_.next_protos = SpdyNextProtos();
9262
9263   HttpRequestInfo request;
9264   request.method = "GET";
9265   request.url = GURL("http://www.google.com/");
9266   request.load_flags = 0;
9267
9268   std::string alternate_protocol_http_header =
9269       GetAlternateProtocolHttpHeader();
9270
9271   MockRead data_reads[] = {
9272     MockRead("HTTP/1.1 200 OK\r\n"),
9273     MockRead(alternate_protocol_http_header.c_str()),
9274     MockRead("hello world"),
9275     MockRead(ASYNC, OK),
9276   };
9277
9278   StaticSocketDataProvider first_transaction(
9279       data_reads, arraysize(data_reads), NULL, 0);
9280   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
9281
9282   SSLSocketDataProvider ssl(ASYNC, OK);
9283   ssl.SetNextProto(GetParam());
9284   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9285
9286   scoped_ptr<SpdyFrame> req(
9287       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9288   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
9289
9290   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9291   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
9292   MockRead spdy_reads[] = {
9293     CreateMockRead(*resp),
9294     CreateMockRead(*data),
9295     MockRead(ASYNC, 0, 0),
9296   };
9297
9298   DelayedSocketData spdy_data(
9299       1,  // wait for one write to finish before reading.
9300       spdy_reads, arraysize(spdy_reads),
9301       spdy_writes, arraysize(spdy_writes));
9302   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9303
9304   TestCompletionCallback callback;
9305
9306   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9307
9308   scoped_ptr<HttpTransaction> trans(
9309       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9310
9311   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9312   EXPECT_EQ(ERR_IO_PENDING, rv);
9313   EXPECT_EQ(OK, callback.WaitForResult());
9314
9315   const HttpResponseInfo* response = trans->GetResponseInfo();
9316   ASSERT_TRUE(response != NULL);
9317   ASSERT_TRUE(response->headers.get() != NULL);
9318   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9319
9320   std::string response_data;
9321   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9322   EXPECT_EQ("hello world", response_data);
9323
9324   // Set up an initial SpdySession in the pool to reuse.
9325   HostPortPair host_port_pair("www.google.com", 443);
9326   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
9327                      PRIVACY_MODE_DISABLED);
9328   base::WeakPtr<SpdySession> spdy_session =
9329       CreateSecureSpdySession(session, key, BoundNetLog());
9330
9331   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9332
9333   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9334   EXPECT_EQ(ERR_IO_PENDING, rv);
9335   EXPECT_EQ(OK, callback.WaitForResult());
9336
9337   response = trans->GetResponseInfo();
9338   ASSERT_TRUE(response != NULL);
9339   ASSERT_TRUE(response->headers.get() != NULL);
9340   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9341   EXPECT_TRUE(response->was_fetched_via_spdy);
9342   EXPECT_TRUE(response->was_npn_negotiated);
9343
9344   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9345   EXPECT_EQ("hello!", response_data);
9346 }
9347
9348 // GenerateAuthToken is a mighty big test.
9349 // It tests all permutation of GenerateAuthToken behavior:
9350 //   - Synchronous and Asynchronous completion.
9351 //   - OK or error on completion.
9352 //   - Direct connection, non-authenticating proxy, and authenticating proxy.
9353 //   - HTTP or HTTPS backend (to include proxy tunneling).
9354 //   - Non-authenticating and authenticating backend.
9355 //
9356 // In all, there are 44 reasonable permuations (for example, if there are
9357 // problems generating an auth token for an authenticating proxy, we don't
9358 // need to test all permutations of the backend server).
9359 //
9360 // The test proceeds by going over each of the configuration cases, and
9361 // potentially running up to three rounds in each of the tests. The TestConfig
9362 // specifies both the configuration for the test as well as the expectations
9363 // for the results.
9364 TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
9365   static const char kServer[] = "http://www.example.com";
9366   static const char kSecureServer[] = "https://www.example.com";
9367   static const char kProxy[] = "myproxy:70";
9368   const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9369
9370   enum AuthTiming {
9371     AUTH_NONE,
9372     AUTH_SYNC,
9373     AUTH_ASYNC,
9374   };
9375
9376   const MockWrite kGet(
9377       "GET / HTTP/1.1\r\n"
9378       "Host: www.example.com\r\n"
9379       "Connection: keep-alive\r\n\r\n");
9380   const MockWrite kGetProxy(
9381       "GET http://www.example.com/ HTTP/1.1\r\n"
9382       "Host: www.example.com\r\n"
9383       "Proxy-Connection: keep-alive\r\n\r\n");
9384   const MockWrite kGetAuth(
9385       "GET / HTTP/1.1\r\n"
9386       "Host: www.example.com\r\n"
9387       "Connection: keep-alive\r\n"
9388       "Authorization: auth_token\r\n\r\n");
9389   const MockWrite kGetProxyAuth(
9390       "GET http://www.example.com/ HTTP/1.1\r\n"
9391       "Host: www.example.com\r\n"
9392       "Proxy-Connection: keep-alive\r\n"
9393       "Proxy-Authorization: auth_token\r\n\r\n");
9394   const MockWrite kGetAuthThroughProxy(
9395       "GET http://www.example.com/ HTTP/1.1\r\n"
9396       "Host: www.example.com\r\n"
9397       "Proxy-Connection: keep-alive\r\n"
9398       "Authorization: auth_token\r\n\r\n");
9399   const MockWrite kGetAuthWithProxyAuth(
9400       "GET http://www.example.com/ HTTP/1.1\r\n"
9401       "Host: www.example.com\r\n"
9402       "Proxy-Connection: keep-alive\r\n"
9403       "Proxy-Authorization: auth_token\r\n"
9404       "Authorization: auth_token\r\n\r\n");
9405   const MockWrite kConnect(
9406       "CONNECT www.example.com:443 HTTP/1.1\r\n"
9407       "Host: www.example.com\r\n"
9408       "Proxy-Connection: keep-alive\r\n\r\n");
9409   const MockWrite kConnectProxyAuth(
9410       "CONNECT www.example.com:443 HTTP/1.1\r\n"
9411       "Host: www.example.com\r\n"
9412       "Proxy-Connection: keep-alive\r\n"
9413       "Proxy-Authorization: auth_token\r\n\r\n");
9414
9415   const MockRead kSuccess(
9416       "HTTP/1.1 200 OK\r\n"
9417       "Content-Type: text/html; charset=iso-8859-1\r\n"
9418       "Content-Length: 3\r\n\r\n"
9419       "Yes");
9420   const MockRead kFailure(
9421       "Should not be called.");
9422   const MockRead kServerChallenge(
9423       "HTTP/1.1 401 Unauthorized\r\n"
9424       "WWW-Authenticate: Mock realm=server\r\n"
9425       "Content-Type: text/html; charset=iso-8859-1\r\n"
9426       "Content-Length: 14\r\n\r\n"
9427       "Unauthorized\r\n");
9428   const MockRead kProxyChallenge(
9429       "HTTP/1.1 407 Unauthorized\r\n"
9430       "Proxy-Authenticate: Mock realm=proxy\r\n"
9431       "Proxy-Connection: close\r\n"
9432       "Content-Type: text/html; charset=iso-8859-1\r\n"
9433       "Content-Length: 14\r\n\r\n"
9434       "Unauthorized\r\n");
9435   const MockRead kProxyConnected(
9436       "HTTP/1.1 200 Connection Established\r\n\r\n");
9437
9438   // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9439   // no constructors, but the C++ compiler on Windows warns about
9440   // unspecified data in compound literals. So, moved to using constructors,
9441   // and TestRound's created with the default constructor should not be used.
9442   struct TestRound {
9443     TestRound()
9444         : expected_rv(ERR_UNEXPECTED),
9445           extra_write(NULL),
9446           extra_read(NULL) {
9447     }
9448     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9449               int expected_rv_arg)
9450         : write(write_arg),
9451           read(read_arg),
9452           expected_rv(expected_rv_arg),
9453           extra_write(NULL),
9454           extra_read(NULL) {
9455     }
9456     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9457               int expected_rv_arg, const MockWrite* extra_write_arg,
9458               const MockRead* extra_read_arg)
9459         : write(write_arg),
9460           read(read_arg),
9461           expected_rv(expected_rv_arg),
9462           extra_write(extra_write_arg),
9463           extra_read(extra_read_arg) {
9464     }
9465     MockWrite write;
9466     MockRead read;
9467     int expected_rv;
9468     const MockWrite* extra_write;
9469     const MockRead* extra_read;
9470   };
9471
9472   static const int kNoSSL = 500;
9473
9474   struct TestConfig {
9475     const char* proxy_url;
9476     AuthTiming proxy_auth_timing;
9477     int proxy_auth_rv;
9478     const char* server_url;
9479     AuthTiming server_auth_timing;
9480     int server_auth_rv;
9481     int num_auth_rounds;
9482     int first_ssl_round;
9483     TestRound rounds[3];
9484   } test_configs[] = {
9485     // Non-authenticating HTTP server with a direct connection.
9486     { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9487       { TestRound(kGet, kSuccess, OK)}},
9488     // Authenticating HTTP server with a direct connection.
9489     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9490       { TestRound(kGet, kServerChallenge, OK),
9491         TestRound(kGetAuth, kSuccess, OK)}},
9492     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9493       { TestRound(kGet, kServerChallenge, OK),
9494         TestRound(kGetAuth, kFailure, kAuthErr)}},
9495     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9496       { TestRound(kGet, kServerChallenge, OK),
9497         TestRound(kGetAuth, kSuccess, OK)}},
9498     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9499       { TestRound(kGet, kServerChallenge, OK),
9500         TestRound(kGetAuth, kFailure, kAuthErr)}},
9501     // Non-authenticating HTTP server through a non-authenticating proxy.
9502     { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9503       { TestRound(kGetProxy, kSuccess, OK)}},
9504     // Authenticating HTTP server through a non-authenticating proxy.
9505     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9506       { TestRound(kGetProxy, kServerChallenge, OK),
9507         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9508     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9509       { TestRound(kGetProxy, kServerChallenge, OK),
9510         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9511     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9512       { TestRound(kGetProxy, kServerChallenge, OK),
9513         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9514     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9515       { TestRound(kGetProxy, kServerChallenge, OK),
9516         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9517     // Non-authenticating HTTP server through an authenticating proxy.
9518     { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9519       { TestRound(kGetProxy, kProxyChallenge, OK),
9520         TestRound(kGetProxyAuth, kSuccess, OK)}},
9521     { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9522       { TestRound(kGetProxy, kProxyChallenge, OK),
9523         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9524     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9525       { TestRound(kGetProxy, kProxyChallenge, OK),
9526         TestRound(kGetProxyAuth, kSuccess, OK)}},
9527     { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9528       { TestRound(kGetProxy, kProxyChallenge, OK),
9529         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9530     // Authenticating HTTP server through an authenticating proxy.
9531     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9532       { TestRound(kGetProxy, kProxyChallenge, OK),
9533         TestRound(kGetProxyAuth, kServerChallenge, OK),
9534         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9535     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9536       { TestRound(kGetProxy, kProxyChallenge, OK),
9537         TestRound(kGetProxyAuth, kServerChallenge, OK),
9538         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9539     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9540       { TestRound(kGetProxy, kProxyChallenge, OK),
9541         TestRound(kGetProxyAuth, kServerChallenge, OK),
9542         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9543     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9544       { TestRound(kGetProxy, kProxyChallenge, OK),
9545         TestRound(kGetProxyAuth, kServerChallenge, OK),
9546         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9547     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9548       { TestRound(kGetProxy, kProxyChallenge, OK),
9549         TestRound(kGetProxyAuth, kServerChallenge, OK),
9550         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9551     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9552       { TestRound(kGetProxy, kProxyChallenge, OK),
9553         TestRound(kGetProxyAuth, kServerChallenge, OK),
9554         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9555     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9556       { TestRound(kGetProxy, kProxyChallenge, OK),
9557         TestRound(kGetProxyAuth, kServerChallenge, OK),
9558         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9559     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9560       { TestRound(kGetProxy, kProxyChallenge, OK),
9561         TestRound(kGetProxyAuth, kServerChallenge, OK),
9562         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9563     // Non-authenticating HTTPS server with a direct connection.
9564     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9565       { TestRound(kGet, kSuccess, OK)}},
9566     // Authenticating HTTPS server with a direct connection.
9567     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9568       { TestRound(kGet, kServerChallenge, OK),
9569         TestRound(kGetAuth, kSuccess, OK)}},
9570     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9571       { TestRound(kGet, kServerChallenge, OK),
9572         TestRound(kGetAuth, kFailure, kAuthErr)}},
9573     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9574       { TestRound(kGet, kServerChallenge, OK),
9575         TestRound(kGetAuth, kSuccess, OK)}},
9576     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9577       { TestRound(kGet, kServerChallenge, OK),
9578         TestRound(kGetAuth, kFailure, kAuthErr)}},
9579     // Non-authenticating HTTPS server with a non-authenticating proxy.
9580     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9581       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9582     // Authenticating HTTPS server through a non-authenticating proxy.
9583     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9584       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9585         TestRound(kGetAuth, kSuccess, OK)}},
9586     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9587       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9588         TestRound(kGetAuth, kFailure, kAuthErr)}},
9589     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9590       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9591         TestRound(kGetAuth, kSuccess, OK)}},
9592     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9593       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9594         TestRound(kGetAuth, kFailure, kAuthErr)}},
9595     // Non-Authenticating HTTPS server through an authenticating proxy.
9596     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9597       { TestRound(kConnect, kProxyChallenge, OK),
9598         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9599     { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9600       { TestRound(kConnect, kProxyChallenge, OK),
9601         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9602     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9603       { TestRound(kConnect, kProxyChallenge, OK),
9604         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9605     { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9606       { TestRound(kConnect, kProxyChallenge, OK),
9607         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9608     // Authenticating HTTPS server through an authenticating proxy.
9609     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9610       { TestRound(kConnect, kProxyChallenge, OK),
9611         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9612                   &kGet, &kServerChallenge),
9613         TestRound(kGetAuth, kSuccess, OK)}},
9614     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9615       { TestRound(kConnect, kProxyChallenge, OK),
9616         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9617                   &kGet, &kServerChallenge),
9618         TestRound(kGetAuth, kFailure, kAuthErr)}},
9619     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9620       { TestRound(kConnect, kProxyChallenge, OK),
9621         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9622                   &kGet, &kServerChallenge),
9623         TestRound(kGetAuth, kSuccess, OK)}},
9624     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9625       { TestRound(kConnect, kProxyChallenge, OK),
9626         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9627                   &kGet, &kServerChallenge),
9628         TestRound(kGetAuth, kFailure, kAuthErr)}},
9629     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9630       { TestRound(kConnect, kProxyChallenge, OK),
9631         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9632                   &kGet, &kServerChallenge),
9633         TestRound(kGetAuth, kSuccess, OK)}},
9634     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9635       { TestRound(kConnect, kProxyChallenge, OK),
9636         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9637                   &kGet, &kServerChallenge),
9638         TestRound(kGetAuth, kFailure, kAuthErr)}},
9639     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9640       { TestRound(kConnect, kProxyChallenge, OK),
9641         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9642                   &kGet, &kServerChallenge),
9643         TestRound(kGetAuth, kSuccess, OK)}},
9644     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9645       { TestRound(kConnect, kProxyChallenge, OK),
9646         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9647                   &kGet, &kServerChallenge),
9648         TestRound(kGetAuth, kFailure, kAuthErr)}},
9649   };
9650
9651   for (size_t i = 0; i < arraysize(test_configs); ++i) {
9652     HttpAuthHandlerMock::Factory* auth_factory(
9653         new HttpAuthHandlerMock::Factory());
9654     session_deps_.http_auth_handler_factory.reset(auth_factory);
9655     const TestConfig& test_config = test_configs[i];
9656
9657     // Set up authentication handlers as necessary.
9658     if (test_config.proxy_auth_timing != AUTH_NONE) {
9659       for (int n = 0; n < 2; n++) {
9660         HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9661         std::string auth_challenge = "Mock realm=proxy";
9662         GURL origin(test_config.proxy_url);
9663         HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9664                                              auth_challenge.end());
9665         auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9666                                         origin, BoundNetLog());
9667         auth_handler->SetGenerateExpectation(
9668             test_config.proxy_auth_timing == AUTH_ASYNC,
9669             test_config.proxy_auth_rv);
9670         auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9671       }
9672     }
9673     if (test_config.server_auth_timing != AUTH_NONE) {
9674       HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9675       std::string auth_challenge = "Mock realm=server";
9676       GURL origin(test_config.server_url);
9677       HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9678                                            auth_challenge.end());
9679       auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9680                                       origin, BoundNetLog());
9681       auth_handler->SetGenerateExpectation(
9682           test_config.server_auth_timing == AUTH_ASYNC,
9683           test_config.server_auth_rv);
9684       auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
9685     }
9686     if (test_config.proxy_url) {
9687       session_deps_.proxy_service.reset(
9688           ProxyService::CreateFixed(test_config.proxy_url));
9689     } else {
9690       session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9691     }
9692
9693     HttpRequestInfo request;
9694     request.method = "GET";
9695     request.url = GURL(test_config.server_url);
9696     request.load_flags = 0;
9697
9698     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9699     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9700
9701     for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9702       const TestRound& read_write_round = test_config.rounds[round];
9703
9704       // Set up expected reads and writes.
9705       MockRead reads[2];
9706       reads[0] = read_write_round.read;
9707       size_t length_reads = 1;
9708       if (read_write_round.extra_read) {
9709         reads[1] = *read_write_round.extra_read;
9710         length_reads = 2;
9711       }
9712
9713       MockWrite writes[2];
9714       writes[0] = read_write_round.write;
9715       size_t length_writes = 1;
9716       if (read_write_round.extra_write) {
9717         writes[1] = *read_write_round.extra_write;
9718         length_writes = 2;
9719       }
9720       StaticSocketDataProvider data_provider(
9721           reads, length_reads, writes, length_writes);
9722       session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
9723
9724       // Add an SSL sequence if necessary.
9725       SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
9726       if (round >= test_config.first_ssl_round)
9727         session_deps_.socket_factory->AddSSLSocketDataProvider(
9728             &ssl_socket_data_provider);
9729
9730       // Start or restart the transaction.
9731       TestCompletionCallback callback;
9732       int rv;
9733       if (round == 0) {
9734         rv = trans.Start(&request, callback.callback(), BoundNetLog());
9735       } else {
9736         rv = trans.RestartWithAuth(
9737             AuthCredentials(kFoo, kBar), callback.callback());
9738       }
9739       if (rv == ERR_IO_PENDING)
9740         rv = callback.WaitForResult();
9741
9742       // Compare results with expected data.
9743       EXPECT_EQ(read_write_round.expected_rv, rv);
9744       const HttpResponseInfo* response = trans.GetResponseInfo();
9745       if (read_write_round.expected_rv == OK) {
9746         ASSERT_TRUE(response != NULL);
9747       } else {
9748         EXPECT_TRUE(response == NULL);
9749         EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9750         continue;
9751       }
9752       if (round + 1 < test_config.num_auth_rounds) {
9753         EXPECT_FALSE(response->auth_challenge.get() == NULL);
9754       } else {
9755         EXPECT_TRUE(response->auth_challenge.get() == NULL);
9756       }
9757     }
9758   }
9759 }
9760
9761 TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
9762   // Do multi-round authentication and make sure it works correctly.
9763   HttpAuthHandlerMock::Factory* auth_factory(
9764       new HttpAuthHandlerMock::Factory());
9765   session_deps_.http_auth_handler_factory.reset(auth_factory);
9766   session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9767   session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9768   session_deps_.host_resolver->set_synchronous_mode(true);
9769
9770   HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9771   auth_handler->set_connection_based(true);
9772   std::string auth_challenge = "Mock realm=server";
9773   GURL origin("http://www.example.com");
9774   HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9775                                        auth_challenge.end());
9776   auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9777                                   origin, BoundNetLog());
9778   auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
9779
9780   int rv = OK;
9781   const HttpResponseInfo* response = NULL;
9782   HttpRequestInfo request;
9783   request.method = "GET";
9784   request.url = origin;
9785   request.load_flags = 0;
9786
9787   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9788
9789   // Use a TCP Socket Pool with only one connection per group. This is used
9790   // to validate that the TCP socket is not released to the pool between
9791   // each round of multi-round authentication.
9792   HttpNetworkSessionPeer session_peer(session);
9793   ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9794   TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
9795       50,  // Max sockets for pool
9796       1,   // Max sockets per group
9797       &transport_pool_histograms,
9798       session_deps_.host_resolver.get(),
9799       session_deps_.socket_factory.get(),
9800       session_deps_.net_log);
9801   scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9802       new MockClientSocketPoolManager);
9803   mock_pool_manager->SetTransportSocketPool(transport_pool);
9804   session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
9805
9806   scoped_ptr<HttpTransaction> trans(
9807       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9808   TestCompletionCallback callback;
9809
9810   const MockWrite kGet(
9811       "GET / HTTP/1.1\r\n"
9812       "Host: www.example.com\r\n"
9813       "Connection: keep-alive\r\n\r\n");
9814   const MockWrite kGetAuth(
9815       "GET / HTTP/1.1\r\n"
9816       "Host: www.example.com\r\n"
9817       "Connection: keep-alive\r\n"
9818       "Authorization: auth_token\r\n\r\n");
9819
9820   const MockRead kServerChallenge(
9821       "HTTP/1.1 401 Unauthorized\r\n"
9822       "WWW-Authenticate: Mock realm=server\r\n"
9823       "Content-Type: text/html; charset=iso-8859-1\r\n"
9824       "Content-Length: 14\r\n\r\n"
9825       "Unauthorized\r\n");
9826   const MockRead kSuccess(
9827       "HTTP/1.1 200 OK\r\n"
9828       "Content-Type: text/html; charset=iso-8859-1\r\n"
9829       "Content-Length: 3\r\n\r\n"
9830       "Yes");
9831
9832   MockWrite writes[] = {
9833     // First round
9834     kGet,
9835     // Second round
9836     kGetAuth,
9837     // Third round
9838     kGetAuth,
9839     // Fourth round
9840     kGetAuth,
9841     // Competing request
9842     kGet,
9843   };
9844   MockRead reads[] = {
9845     // First round
9846     kServerChallenge,
9847     // Second round
9848     kServerChallenge,
9849     // Third round
9850     kServerChallenge,
9851     // Fourth round
9852     kSuccess,
9853     // Competing response
9854     kSuccess,
9855   };
9856   StaticSocketDataProvider data_provider(reads, arraysize(reads),
9857                                          writes, arraysize(writes));
9858   session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
9859
9860   const char* const kSocketGroup = "www.example.com:80";
9861
9862   // First round of authentication.
9863   auth_handler->SetGenerateExpectation(false, OK);
9864   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9865   if (rv == ERR_IO_PENDING)
9866     rv = callback.WaitForResult();
9867   EXPECT_EQ(OK, rv);
9868   response = trans->GetResponseInfo();
9869   ASSERT_TRUE(response != NULL);
9870   EXPECT_FALSE(response->auth_challenge.get() == NULL);
9871   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9872
9873   // In between rounds, another request comes in for the same domain.
9874   // It should not be able to grab the TCP socket that trans has already
9875   // claimed.
9876   scoped_ptr<HttpTransaction> trans_compete(
9877       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9878   TestCompletionCallback callback_compete;
9879   rv = trans_compete->Start(
9880       &request, callback_compete.callback(), BoundNetLog());
9881   EXPECT_EQ(ERR_IO_PENDING, rv);
9882   // callback_compete.WaitForResult at this point would stall forever,
9883   // since the HttpNetworkTransaction does not release the request back to
9884   // the pool until after authentication completes.
9885
9886   // Second round of authentication.
9887   auth_handler->SetGenerateExpectation(false, OK);
9888   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
9889   if (rv == ERR_IO_PENDING)
9890     rv = callback.WaitForResult();
9891   EXPECT_EQ(OK, rv);
9892   response = trans->GetResponseInfo();
9893   ASSERT_TRUE(response != NULL);
9894   EXPECT_TRUE(response->auth_challenge.get() == NULL);
9895   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9896
9897   // Third round of authentication.
9898   auth_handler->SetGenerateExpectation(false, OK);
9899   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
9900   if (rv == ERR_IO_PENDING)
9901     rv = callback.WaitForResult();
9902   EXPECT_EQ(OK, rv);
9903   response = trans->GetResponseInfo();
9904   ASSERT_TRUE(response != NULL);
9905   EXPECT_TRUE(response->auth_challenge.get() == NULL);
9906   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9907
9908   // Fourth round of authentication, which completes successfully.
9909   auth_handler->SetGenerateExpectation(false, OK);
9910   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
9911   if (rv == ERR_IO_PENDING)
9912     rv = callback.WaitForResult();
9913   EXPECT_EQ(OK, rv);
9914   response = trans->GetResponseInfo();
9915   ASSERT_TRUE(response != NULL);
9916   EXPECT_TRUE(response->auth_challenge.get() == NULL);
9917   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9918
9919   // Read the body since the fourth round was successful. This will also
9920   // release the socket back to the pool.
9921   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
9922   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
9923   if (rv == ERR_IO_PENDING)
9924     rv = callback.WaitForResult();
9925   EXPECT_EQ(3, rv);
9926   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
9927   EXPECT_EQ(0, rv);
9928   // There are still 0 idle sockets, since the trans_compete transaction
9929   // will be handed it immediately after trans releases it to the group.
9930   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9931
9932   // The competing request can now finish. Wait for the headers and then
9933   // read the body.
9934   rv = callback_compete.WaitForResult();
9935   EXPECT_EQ(OK, rv);
9936   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
9937   if (rv == ERR_IO_PENDING)
9938     rv = callback.WaitForResult();
9939   EXPECT_EQ(3, rv);
9940   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
9941   EXPECT_EQ(0, rv);
9942
9943   // Finally, the socket is released to the group.
9944   EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9945 }
9946
9947 // This tests the case that a request is issued via http instead of spdy after
9948 // npn is negotiated.
9949 TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
9950   session_deps_.use_alternate_protocols = true;
9951   NextProtoVector next_protos;
9952   next_protos.push_back(kProtoHTTP11);
9953   session_deps_.next_protos = next_protos;
9954
9955   HttpRequestInfo request;
9956   request.method = "GET";
9957   request.url = GURL("https://www.google.com/");
9958   request.load_flags = 0;
9959
9960   MockWrite data_writes[] = {
9961     MockWrite("GET / HTTP/1.1\r\n"
9962               "Host: www.google.com\r\n"
9963               "Connection: keep-alive\r\n\r\n"),
9964   };
9965
9966   std::string alternate_protocol_http_header =
9967       GetAlternateProtocolHttpHeader();
9968
9969   MockRead data_reads[] = {
9970     MockRead("HTTP/1.1 200 OK\r\n"),
9971     MockRead(alternate_protocol_http_header.c_str()),
9972     MockRead("hello world"),
9973     MockRead(SYNCHRONOUS, OK),
9974   };
9975
9976   SSLSocketDataProvider ssl(ASYNC, OK);
9977   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9978   ssl.next_proto = "http/1.1";
9979   ssl.protocol_negotiated = kProtoHTTP11;
9980
9981   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9982
9983   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9984                                 data_writes, arraysize(data_writes));
9985   session_deps_.socket_factory->AddSocketDataProvider(&data);
9986
9987   TestCompletionCallback callback;
9988
9989   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9990   scoped_ptr<HttpTransaction> trans(
9991       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9992
9993   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9994
9995   EXPECT_EQ(ERR_IO_PENDING, rv);
9996   EXPECT_EQ(OK, callback.WaitForResult());
9997
9998   const HttpResponseInfo* response = trans->GetResponseInfo();
9999   ASSERT_TRUE(response != NULL);
10000   ASSERT_TRUE(response->headers.get() != NULL);
10001   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10002
10003   std::string response_data;
10004   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10005   EXPECT_EQ("hello world", response_data);
10006
10007   EXPECT_FALSE(response->was_fetched_via_spdy);
10008   EXPECT_TRUE(response->was_npn_negotiated);
10009 }
10010
10011 TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
10012   // Simulate the SSL handshake completing with an NPN negotiation
10013   // followed by an immediate server closing of the socket.
10014   // Fix crash:  http://crbug.com/46369
10015   session_deps_.use_alternate_protocols = true;
10016   session_deps_.next_protos = SpdyNextProtos();
10017
10018   HttpRequestInfo request;
10019   request.method = "GET";
10020   request.url = GURL("https://www.google.com/");
10021   request.load_flags = 0;
10022
10023   SSLSocketDataProvider ssl(ASYNC, OK);
10024   ssl.SetNextProto(GetParam());
10025   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10026
10027   scoped_ptr<SpdyFrame> req(
10028       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
10029   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10030
10031   MockRead spdy_reads[] = {
10032     MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
10033   };
10034
10035   DelayedSocketData spdy_data(
10036       0,  // don't wait in this case, immediate hangup.
10037       spdy_reads, arraysize(spdy_reads),
10038       spdy_writes, arraysize(spdy_writes));
10039   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10040
10041   TestCompletionCallback callback;
10042
10043   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10044   scoped_ptr<HttpTransaction> trans(
10045       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10046
10047   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10048   EXPECT_EQ(ERR_IO_PENDING, rv);
10049   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
10050 }
10051
10052 // A subclass of HttpAuthHandlerMock that records the request URL when
10053 // it gets it. This is needed since the auth handler may get destroyed
10054 // before we get a chance to query it.
10055 class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10056  public:
10057   explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10058
10059   ~UrlRecordingHttpAuthHandlerMock() override {}
10060
10061  protected:
10062   int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10063                             const HttpRequestInfo* request,
10064                             const CompletionCallback& callback,
10065                             std::string* auth_token) override {
10066     *url_ = request->url;
10067     return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10068         credentials, request, callback, auth_token);
10069   }
10070
10071  private:
10072   GURL* url_;
10073 };
10074
10075 TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
10076   // This test ensures that the URL passed into the proxy is upgraded
10077   // to https when doing an Alternate Protocol upgrade.
10078   session_deps_.use_alternate_protocols = true;
10079   session_deps_.next_protos = SpdyNextProtos();
10080
10081   session_deps_.proxy_service.reset(
10082       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10083   CapturingNetLog net_log;
10084   session_deps_.net_log = &net_log;
10085   GURL request_url;
10086   {
10087     HttpAuthHandlerMock::Factory* auth_factory =
10088         new HttpAuthHandlerMock::Factory();
10089     UrlRecordingHttpAuthHandlerMock* auth_handler =
10090         new UrlRecordingHttpAuthHandlerMock(&request_url);
10091     auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10092     auth_factory->set_do_init_from_challenge(true);
10093     session_deps_.http_auth_handler_factory.reset(auth_factory);
10094   }
10095
10096   HttpRequestInfo request;
10097   request.method = "GET";
10098   request.url = GURL("http://www.google.com");
10099   request.load_flags = 0;
10100
10101   // First round goes unauthenticated through the proxy.
10102   MockWrite data_writes_1[] = {
10103     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10104               "Host: www.google.com\r\n"
10105               "Proxy-Connection: keep-alive\r\n"
10106               "\r\n"),
10107   };
10108   MockRead data_reads_1[] = {
10109     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10110     MockRead("HTTP/1.1 200 OK\r\n"
10111              "Alternate-Protocol: 443:npn-spdy/2\r\n"
10112              "Proxy-Connection: close\r\n"
10113              "\r\n"),
10114   };
10115   StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10116                                   data_writes_1, arraysize(data_writes_1));
10117
10118   // Second round tries to tunnel to www.google.com due to the
10119   // Alternate-Protocol announcement in the first round. It fails due
10120   // to a proxy authentication challenge.
10121   // After the failure, a tunnel is established to www.google.com using
10122   // Proxy-Authorization headers. There is then a SPDY request round.
10123   //
10124   // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10125   // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10126   // does a Disconnect and Connect on the same socket, rather than trying
10127   // to obtain a new one.
10128   //
10129   // NOTE: Originally, the proxy response to the second CONNECT request
10130   // simply returned another 407 so the unit test could skip the SSL connection
10131   // establishment and SPDY framing issues. Alas, the
10132   // retry-http-when-alternate-protocol fails logic kicks in, which was more
10133   // complicated to set up expectations for than the SPDY session.
10134
10135   scoped_ptr<SpdyFrame> req(
10136       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
10137   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10138   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
10139
10140   MockWrite data_writes_2[] = {
10141     // First connection attempt without Proxy-Authorization.
10142     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10143               "Host: www.google.com\r\n"
10144               "Proxy-Connection: keep-alive\r\n"
10145               "\r\n"),
10146
10147     // Second connection attempt with Proxy-Authorization.
10148     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10149               "Host: www.google.com\r\n"
10150               "Proxy-Connection: keep-alive\r\n"
10151               "Proxy-Authorization: auth_token\r\n"
10152               "\r\n"),
10153
10154     // SPDY request
10155     CreateMockWrite(*req),
10156   };
10157   const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10158                                          "Proxy-Authenticate: Mock\r\n"
10159                                          "Proxy-Connection: close\r\n"
10160                                          "\r\n");
10161   const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10162   MockRead data_reads_2[] = {
10163     // First connection attempt fails
10164     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
10165     MockRead(ASYNC, kRejectConnectResponse,
10166              arraysize(kRejectConnectResponse) - 1, 1),
10167
10168     // Second connection attempt passes
10169     MockRead(ASYNC, kAcceptConnectResponse,
10170              arraysize(kAcceptConnectResponse) -1, 4),
10171
10172     // SPDY response
10173     CreateMockRead(*resp.get(), 6),
10174     CreateMockRead(*data.get(), 6),
10175     MockRead(ASYNC, 0, 0, 6),
10176   };
10177   OrderedSocketData data_2(
10178       data_reads_2, arraysize(data_reads_2),
10179       data_writes_2, arraysize(data_writes_2));
10180
10181   SSLSocketDataProvider ssl(ASYNC, OK);
10182   ssl.SetNextProto(GetParam());
10183
10184   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
10185   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10186       NULL, 0, NULL, 0);
10187   hanging_non_alternate_protocol_socket.set_connect_data(
10188       never_finishing_connect);
10189
10190   session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10191   session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10192   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10193   session_deps_.socket_factory->AddSocketDataProvider(
10194       &hanging_non_alternate_protocol_socket);
10195   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10196
10197   // First round should work and provide the Alternate-Protocol state.
10198   TestCompletionCallback callback_1;
10199   scoped_ptr<HttpTransaction> trans_1(
10200       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10201   int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
10202   EXPECT_EQ(ERR_IO_PENDING, rv);
10203   EXPECT_EQ(OK, callback_1.WaitForResult());
10204
10205   // Second round should attempt a tunnel connect and get an auth challenge.
10206   TestCompletionCallback callback_2;
10207   scoped_ptr<HttpTransaction> trans_2(
10208       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10209   rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
10210   EXPECT_EQ(ERR_IO_PENDING, rv);
10211   EXPECT_EQ(OK, callback_2.WaitForResult());
10212   const HttpResponseInfo* response = trans_2->GetResponseInfo();
10213   ASSERT_TRUE(response != NULL);
10214   ASSERT_FALSE(response->auth_challenge.get() == NULL);
10215
10216   // Restart with auth. Tunnel should work and response received.
10217   TestCompletionCallback callback_3;
10218   rv = trans_2->RestartWithAuth(
10219       AuthCredentials(kFoo, kBar), callback_3.callback());
10220   EXPECT_EQ(ERR_IO_PENDING, rv);
10221   EXPECT_EQ(OK, callback_3.WaitForResult());
10222
10223   // After all that work, these two lines (or actually, just the scheme) are
10224   // what this test is all about. Make sure it happens correctly.
10225   EXPECT_EQ("https", request_url.scheme());
10226   EXPECT_EQ("www.google.com", request_url.host());
10227
10228   LoadTimingInfo load_timing_info;
10229   EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10230   TestLoadTimingNotReusedWithPac(load_timing_info,
10231                                  CONNECT_TIMING_HAS_SSL_TIMES);
10232 }
10233
10234 // Test that if we cancel the transaction as the connection is completing, that
10235 // everything tears down correctly.
10236 TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
10237   // Setup everything about the connection to complete synchronously, so that
10238   // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10239   // for is the callback from the HttpStreamRequest.
10240   // Then cancel the transaction.
10241   // Verify that we don't crash.
10242   MockConnect mock_connect(SYNCHRONOUS, OK);
10243   MockRead data_reads[] = {
10244     MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10245     MockRead(SYNCHRONOUS, "hello world"),
10246     MockRead(SYNCHRONOUS, OK),
10247   };
10248
10249   HttpRequestInfo request;
10250   request.method = "GET";
10251   request.url = GURL("http://www.google.com/");
10252   request.load_flags = 0;
10253
10254   session_deps_.host_resolver->set_synchronous_mode(true);
10255   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10256   scoped_ptr<HttpTransaction> trans(
10257       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10258
10259   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10260   data.set_connect_data(mock_connect);
10261   session_deps_.socket_factory->AddSocketDataProvider(&data);
10262
10263   TestCompletionCallback callback;
10264
10265   CapturingBoundNetLog log;
10266   int rv = trans->Start(&request, callback.callback(), log.bound());
10267   EXPECT_EQ(ERR_IO_PENDING, rv);
10268   trans.reset();  // Cancel the transaction here.
10269
10270   base::MessageLoop::current()->RunUntilIdle();
10271 }
10272
10273 // Test that if a transaction is cancelled after receiving the headers, the
10274 // stream is drained properly and added back to the socket pool.  The main
10275 // purpose of this test is to make sure that an HttpStreamParser can be read
10276 // from after the HttpNetworkTransaction and the objects it owns have been
10277 // deleted.
10278 // See http://crbug.com/368418
10279 TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10280   MockRead data_reads[] = {
10281     MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10282     MockRead(ASYNC, "Content-Length: 2\r\n"),
10283     MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10284     MockRead(ASYNC, "1"),
10285     // 2 async reads are necessary to trigger a ReadResponseBody call after the
10286     // HttpNetworkTransaction has been deleted.
10287     MockRead(ASYNC, "2"),
10288     MockRead(SYNCHRONOUS, ERR_IO_PENDING),  // Should never read this.
10289   };
10290   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10291   session_deps_.socket_factory->AddSocketDataProvider(&data);
10292
10293   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10294
10295   {
10296     HttpRequestInfo request;
10297     request.method = "GET";
10298     request.url = GURL("http://www.google.com/");
10299     request.load_flags = 0;
10300
10301     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10302     TestCompletionCallback callback;
10303
10304     int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10305     EXPECT_EQ(ERR_IO_PENDING, rv);
10306     callback.WaitForResult();
10307
10308     const HttpResponseInfo* response = trans.GetResponseInfo();
10309     ASSERT_TRUE(response != NULL);
10310     EXPECT_TRUE(response->headers.get() != NULL);
10311     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10312
10313     // The transaction and HttpRequestInfo are deleted.
10314   }
10315
10316   // Let the HttpResponseBodyDrainer drain the socket.
10317   base::MessageLoop::current()->RunUntilIdle();
10318
10319   // Socket should now be idle, waiting to be reused.
10320   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
10321 }
10322
10323 // Test a basic GET request through a proxy.
10324 TEST_P(HttpNetworkTransactionTest, ProxyGet) {
10325   session_deps_.proxy_service.reset(
10326       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10327   CapturingBoundNetLog log;
10328   session_deps_.net_log = log.bound().net_log();
10329   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10330
10331   HttpRequestInfo request;
10332   request.method = "GET";
10333   request.url = GURL("http://www.google.com/");
10334
10335   MockWrite data_writes1[] = {
10336     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10337               "Host: www.google.com\r\n"
10338               "Proxy-Connection: keep-alive\r\n\r\n"),
10339   };
10340
10341   MockRead data_reads1[] = {
10342     MockRead("HTTP/1.1 200 OK\r\n"),
10343     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10344     MockRead("Content-Length: 100\r\n\r\n"),
10345     MockRead(SYNCHRONOUS, OK),
10346   };
10347
10348   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10349                                  data_writes1, arraysize(data_writes1));
10350   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10351
10352   TestCompletionCallback callback1;
10353
10354   scoped_ptr<HttpTransaction> trans(
10355       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10356   BeforeProxyHeadersSentHandler proxy_headers_handler;
10357   trans->SetBeforeProxyHeadersSentCallback(
10358       base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10359                  base::Unretained(&proxy_headers_handler)));
10360
10361   int rv = trans->Start(&request, callback1.callback(), log.bound());
10362   EXPECT_EQ(ERR_IO_PENDING, rv);
10363
10364   rv = callback1.WaitForResult();
10365   EXPECT_EQ(OK, rv);
10366
10367   const HttpResponseInfo* response = trans->GetResponseInfo();
10368   ASSERT_TRUE(response != NULL);
10369
10370   EXPECT_TRUE(response->headers->IsKeepAlive());
10371   EXPECT_EQ(200, response->headers->response_code());
10372   EXPECT_EQ(100, response->headers->GetContentLength());
10373   EXPECT_TRUE(response->was_fetched_via_proxy);
10374   EXPECT_TRUE(
10375       response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
10376   EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10377   EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
10378   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10379
10380   LoadTimingInfo load_timing_info;
10381   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10382   TestLoadTimingNotReusedWithPac(load_timing_info,
10383                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10384 }
10385
10386 // Test a basic HTTPS GET request through a proxy.
10387 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
10388   session_deps_.proxy_service.reset(
10389       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10390   CapturingBoundNetLog log;
10391   session_deps_.net_log = log.bound().net_log();
10392   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10393
10394   HttpRequestInfo request;
10395   request.method = "GET";
10396   request.url = GURL("https://www.google.com/");
10397
10398   // Since we have proxy, should try to establish tunnel.
10399   MockWrite data_writes1[] = {
10400     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10401               "Host: www.google.com\r\n"
10402               "Proxy-Connection: keep-alive\r\n\r\n"),
10403
10404     MockWrite("GET / HTTP/1.1\r\n"
10405               "Host: www.google.com\r\n"
10406               "Connection: keep-alive\r\n\r\n"),
10407   };
10408
10409   MockRead data_reads1[] = {
10410     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10411
10412     MockRead("HTTP/1.1 200 OK\r\n"),
10413     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10414     MockRead("Content-Length: 100\r\n\r\n"),
10415     MockRead(SYNCHRONOUS, OK),
10416   };
10417
10418   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10419                                  data_writes1, arraysize(data_writes1));
10420   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10421   SSLSocketDataProvider ssl(ASYNC, OK);
10422   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10423
10424   TestCompletionCallback callback1;
10425
10426   scoped_ptr<HttpTransaction> trans(
10427       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10428
10429   int rv = trans->Start(&request, callback1.callback(), log.bound());
10430   EXPECT_EQ(ERR_IO_PENDING, rv);
10431
10432   rv = callback1.WaitForResult();
10433   EXPECT_EQ(OK, rv);
10434   net::CapturingNetLog::CapturedEntryList entries;
10435   log.GetEntries(&entries);
10436   size_t pos = ExpectLogContainsSomewhere(
10437       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10438       NetLog::PHASE_NONE);
10439   ExpectLogContainsSomewhere(
10440       entries, pos,
10441       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10442       NetLog::PHASE_NONE);
10443
10444   const HttpResponseInfo* response = trans->GetResponseInfo();
10445   ASSERT_TRUE(response != NULL);
10446
10447   EXPECT_TRUE(response->headers->IsKeepAlive());
10448   EXPECT_EQ(200, response->headers->response_code());
10449   EXPECT_EQ(100, response->headers->GetContentLength());
10450   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10451   EXPECT_TRUE(response->was_fetched_via_proxy);
10452   EXPECT_TRUE(
10453       response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
10454
10455   LoadTimingInfo load_timing_info;
10456   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10457   TestLoadTimingNotReusedWithPac(load_timing_info,
10458                                  CONNECT_TIMING_HAS_SSL_TIMES);
10459 }
10460
10461 // Test a basic HTTPS GET request through a proxy, but the server hangs up
10462 // while establishing the tunnel.
10463 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
10464   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
10465   CapturingBoundNetLog log;
10466   session_deps_.net_log = log.bound().net_log();
10467   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10468
10469   HttpRequestInfo request;
10470   request.method = "GET";
10471   request.url = GURL("https://www.google.com/");
10472
10473   // Since we have proxy, should try to establish tunnel.
10474   MockWrite data_writes1[] = {
10475     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10476               "Host: www.google.com\r\n"
10477               "Proxy-Connection: keep-alive\r\n\r\n"),
10478
10479     MockWrite("GET / HTTP/1.1\r\n"
10480               "Host: www.google.com\r\n"
10481               "Connection: keep-alive\r\n\r\n"),
10482   };
10483
10484   MockRead data_reads1[] = {
10485     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10486     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10487     MockRead(ASYNC, 0, 0),  // EOF
10488   };
10489
10490   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10491                                  data_writes1, arraysize(data_writes1));
10492   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10493   SSLSocketDataProvider ssl(ASYNC, OK);
10494   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10495
10496   TestCompletionCallback callback1;
10497
10498   scoped_ptr<HttpTransaction> trans(
10499       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10500
10501   int rv = trans->Start(&request, callback1.callback(), log.bound());
10502   EXPECT_EQ(ERR_IO_PENDING, rv);
10503
10504   rv = callback1.WaitForResult();
10505   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
10506   net::CapturingNetLog::CapturedEntryList entries;
10507   log.GetEntries(&entries);
10508   size_t pos = ExpectLogContainsSomewhere(
10509       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10510       NetLog::PHASE_NONE);
10511   ExpectLogContainsSomewhere(
10512       entries, pos,
10513       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10514       NetLog::PHASE_NONE);
10515 }
10516
10517 // Test for crbug.com/55424.
10518 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
10519   scoped_ptr<SpdyFrame> req(
10520       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10521   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10522
10523   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10524   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
10525   MockRead spdy_reads[] = {
10526     CreateMockRead(*resp),
10527     CreateMockRead(*data),
10528     MockRead(ASYNC, 0, 0),
10529   };
10530
10531   DelayedSocketData spdy_data(
10532       1,  // wait for one write to finish before reading.
10533       spdy_reads, arraysize(spdy_reads),
10534       spdy_writes, arraysize(spdy_writes));
10535   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10536
10537   SSLSocketDataProvider ssl(ASYNC, OK);
10538   ssl.SetNextProto(GetParam());
10539   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10540
10541   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10542
10543   // Set up an initial SpdySession in the pool to reuse.
10544   HostPortPair host_port_pair("www.google.com", 443);
10545   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10546                      PRIVACY_MODE_DISABLED);
10547   base::WeakPtr<SpdySession> spdy_session =
10548       CreateInsecureSpdySession(session, key, BoundNetLog());
10549
10550   HttpRequestInfo request;
10551   request.method = "GET";
10552   request.url = GURL("https://www.google.com/");
10553   request.load_flags = 0;
10554
10555   // This is the important line that marks this as a preconnect.
10556   request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10557
10558   scoped_ptr<HttpTransaction> trans(
10559       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10560
10561   TestCompletionCallback callback;
10562   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10563   EXPECT_EQ(ERR_IO_PENDING, rv);
10564   EXPECT_EQ(OK, callback.WaitForResult());
10565 }
10566
10567 // Given a net error, cause that error to be returned from the first Write()
10568 // call and verify that the HttpTransaction fails with that error.
10569 void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
10570     int error, IoMode mode) {
10571   net::HttpRequestInfo request_info;
10572   request_info.url = GURL("https://www.example.com/");
10573   request_info.method = "GET";
10574   request_info.load_flags = net::LOAD_NORMAL;
10575
10576   SSLSocketDataProvider ssl_data(mode, OK);
10577   net::MockWrite data_writes[] = {
10578     net::MockWrite(mode, error),
10579   };
10580   net::StaticSocketDataProvider data(NULL, 0,
10581                                      data_writes, arraysize(data_writes));
10582   session_deps_.socket_factory->AddSocketDataProvider(&data);
10583   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
10584
10585   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10586   scoped_ptr<HttpTransaction> trans(
10587       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10588
10589   TestCompletionCallback callback;
10590   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
10591   if (rv == net::ERR_IO_PENDING)
10592     rv = callback.WaitForResult();
10593   ASSERT_EQ(error, rv);
10594 }
10595
10596 TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
10597   // Just check a grab bag of cert errors.
10598   static const int kErrors[] = {
10599     ERR_CERT_COMMON_NAME_INVALID,
10600     ERR_CERT_AUTHORITY_INVALID,
10601     ERR_CERT_DATE_INVALID,
10602   };
10603   for (size_t i = 0; i < arraysize(kErrors); i++) {
10604     CheckErrorIsPassedBack(kErrors[i], ASYNC);
10605     CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
10606   }
10607 }
10608
10609 // Ensure that a client certificate is removed from the SSL client auth
10610 // cache when:
10611 //  1) No proxy is involved.
10612 //  2) TLS False Start is disabled.
10613 //  3) The initial TLS handshake requests a client certificate.
10614 //  4) The client supplies an invalid/unacceptable certificate.
10615 TEST_P(HttpNetworkTransactionTest,
10616        ClientAuthCertCache_Direct_NoFalseStart) {
10617   net::HttpRequestInfo request_info;
10618   request_info.url = GURL("https://www.example.com/");
10619   request_info.method = "GET";
10620   request_info.load_flags = net::LOAD_NORMAL;
10621
10622   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10623   cert_request->host_and_port = HostPortPair("www.example.com", 443);
10624
10625   // [ssl_]data1 contains the data for the first SSL handshake. When a
10626   // CertificateRequest is received for the first time, the handshake will
10627   // be aborted to allow the caller to provide a certificate.
10628   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
10629   ssl_data1.cert_request_info = cert_request.get();
10630   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
10631   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10632   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10633
10634   // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10635   // False Start is not being used, the result of the SSL handshake will be
10636   // returned as part of the SSLClientSocket::Connect() call. This test
10637   // matches the result of a server sending a handshake_failure alert,
10638   // rather than a Finished message, because it requires a client
10639   // certificate and none was supplied.
10640   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10641   ssl_data2.cert_request_info = cert_request.get();
10642   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
10643   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10644   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10645
10646   // [ssl_]data3 contains the data for the third SSL handshake. When a
10647   // connection to a server fails during an SSL handshake,
10648   // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10649   // connection was attempted with TLSv1.1. This is transparent to the caller
10650   // of the HttpNetworkTransaction. Because this test failure is due to
10651   // requiring a client certificate, this fallback handshake should also
10652   // fail.
10653   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10654   ssl_data3.cert_request_info = cert_request.get();
10655   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
10656   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10657   session_deps_.socket_factory->AddSocketDataProvider(&data3);
10658
10659   // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10660   // connection to a server fails during an SSL handshake,
10661   // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10662   // connection was attempted with TLSv1. This is transparent to the caller
10663   // of the HttpNetworkTransaction. Because this test failure is due to
10664   // requiring a client certificate, this fallback handshake should also
10665   // fail.
10666   SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10667   ssl_data4.cert_request_info = cert_request.get();
10668   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
10669   net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
10670   session_deps_.socket_factory->AddSocketDataProvider(&data4);
10671
10672   // Need one more if TLSv1.2 is enabled.
10673   SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10674   ssl_data5.cert_request_info = cert_request.get();
10675   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10676   net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10677   session_deps_.socket_factory->AddSocketDataProvider(&data5);
10678
10679   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10680   scoped_ptr<HttpTransaction> trans(
10681       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10682
10683   // Begin the SSL handshake with the peer. This consumes ssl_data1.
10684   TestCompletionCallback callback;
10685   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
10686   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10687
10688   // Complete the SSL handshake, which should abort due to requiring a
10689   // client certificate.
10690   rv = callback.WaitForResult();
10691   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10692
10693   // Indicate that no certificate should be supplied. From the perspective
10694   // of SSLClientCertCache, NULL is just as meaningful as a real
10695   // certificate, so this is the same as supply a
10696   // legitimate-but-unacceptable certificate.
10697   rv = trans->RestartWithCertificate(NULL, callback.callback());
10698   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10699
10700   // Ensure the certificate was added to the client auth cache before
10701   // allowing the connection to continue restarting.
10702   scoped_refptr<X509Certificate> client_cert;
10703   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10704       HostPortPair("www.example.com", 443), &client_cert));
10705   ASSERT_EQ(NULL, client_cert.get());
10706
10707   // Restart the handshake. This will consume ssl_data2, which fails, and
10708   // then consume ssl_data3 and ssl_data4, both of which should also fail.
10709   // The result code is checked against what ssl_data4 should return.
10710   rv = callback.WaitForResult();
10711   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10712
10713   // Ensure that the client certificate is removed from the cache on a
10714   // handshake failure.
10715   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10716       HostPortPair("www.example.com", 443), &client_cert));
10717 }
10718
10719 // Ensure that a client certificate is removed from the SSL client auth
10720 // cache when:
10721 //  1) No proxy is involved.
10722 //  2) TLS False Start is enabled.
10723 //  3) The initial TLS handshake requests a client certificate.
10724 //  4) The client supplies an invalid/unacceptable certificate.
10725 TEST_P(HttpNetworkTransactionTest,
10726        ClientAuthCertCache_Direct_FalseStart) {
10727   net::HttpRequestInfo request_info;
10728   request_info.url = GURL("https://www.example.com/");
10729   request_info.method = "GET";
10730   request_info.load_flags = net::LOAD_NORMAL;
10731
10732   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10733   cert_request->host_and_port = HostPortPair("www.example.com", 443);
10734
10735   // When TLS False Start is used, SSLClientSocket::Connect() calls will
10736   // return successfully after reading up to the peer's Certificate message.
10737   // This is to allow the caller to call SSLClientSocket::Write(), which can
10738   // enqueue application data to be sent in the same packet as the
10739   // ChangeCipherSpec and Finished messages.
10740   // The actual handshake will be finished when SSLClientSocket::Read() is
10741   // called, which expects to process the peer's ChangeCipherSpec and
10742   // Finished messages. If there was an error negotiating with the peer,
10743   // such as due to the peer requiring a client certificate when none was
10744   // supplied, the alert sent by the peer won't be processed until Read() is
10745   // called.
10746
10747   // Like the non-False Start case, when a client certificate is requested by
10748   // the peer, the handshake is aborted during the Connect() call.
10749   // [ssl_]data1 represents the initial SSL handshake with the peer.
10750   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
10751   ssl_data1.cert_request_info = cert_request.get();
10752   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
10753   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10754   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10755
10756   // When a client certificate is supplied, Connect() will not be aborted
10757   // when the peer requests the certificate. Instead, the handshake will
10758   // artificially succeed, allowing the caller to write the HTTP request to
10759   // the socket. The handshake messages are not processed until Read() is
10760   // called, which then detects that the handshake was aborted, due to the
10761   // peer sending a handshake_failure because it requires a client
10762   // certificate.
10763   SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
10764   ssl_data2.cert_request_info = cert_request.get();
10765   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
10766   net::MockRead data2_reads[] = {
10767     net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
10768   };
10769   net::StaticSocketDataProvider data2(
10770       data2_reads, arraysize(data2_reads), NULL, 0);
10771   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10772
10773   // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
10774   // the data for the SSL handshake once the TLSv1.1 connection falls back to
10775   // TLSv1. It has the same behaviour as [ssl_]data2.
10776   SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
10777   ssl_data3.cert_request_info = cert_request.get();
10778   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
10779   net::StaticSocketDataProvider data3(
10780       data2_reads, arraysize(data2_reads), NULL, 0);
10781   session_deps_.socket_factory->AddSocketDataProvider(&data3);
10782
10783   // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10784   // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10785   SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10786   ssl_data4.cert_request_info = cert_request.get();
10787   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
10788   net::StaticSocketDataProvider data4(
10789       data2_reads, arraysize(data2_reads), NULL, 0);
10790   session_deps_.socket_factory->AddSocketDataProvider(&data4);
10791
10792   // Need one more if TLSv1.2 is enabled.
10793   SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10794   ssl_data5.cert_request_info = cert_request.get();
10795   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10796   net::StaticSocketDataProvider data5(
10797       data2_reads, arraysize(data2_reads), NULL, 0);
10798   session_deps_.socket_factory->AddSocketDataProvider(&data5);
10799
10800   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10801   scoped_ptr<HttpTransaction> trans(
10802       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10803
10804   // Begin the initial SSL handshake.
10805   TestCompletionCallback callback;
10806   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
10807   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10808
10809   // Complete the SSL handshake, which should abort due to requiring a
10810   // client certificate.
10811   rv = callback.WaitForResult();
10812   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10813
10814   // Indicate that no certificate should be supplied. From the perspective
10815   // of SSLClientCertCache, NULL is just as meaningful as a real
10816   // certificate, so this is the same as supply a
10817   // legitimate-but-unacceptable certificate.
10818   rv = trans->RestartWithCertificate(NULL, callback.callback());
10819   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10820
10821   // Ensure the certificate was added to the client auth cache before
10822   // allowing the connection to continue restarting.
10823   scoped_refptr<X509Certificate> client_cert;
10824   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10825       HostPortPair("www.example.com", 443), &client_cert));
10826   ASSERT_EQ(NULL, client_cert.get());
10827
10828   // Restart the handshake. This will consume ssl_data2, which fails, and
10829   // then consume ssl_data3 and ssl_data4, both of which should also fail.
10830   // The result code is checked against what ssl_data4 should return.
10831   rv = callback.WaitForResult();
10832   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10833
10834   // Ensure that the client certificate is removed from the cache on a
10835   // handshake failure.
10836   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10837       HostPortPair("www.example.com", 443), &client_cert));
10838 }
10839
10840 // Ensure that a client certificate is removed from the SSL client auth
10841 // cache when:
10842 //  1) An HTTPS proxy is involved.
10843 //  3) The HTTPS proxy requests a client certificate.
10844 //  4) The client supplies an invalid/unacceptable certificate for the
10845 //     proxy.
10846 // The test is repeated twice, first for connecting to an HTTPS endpoint,
10847 // then for connecting to an HTTP endpoint.
10848 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
10849   session_deps_.proxy_service.reset(
10850       ProxyService::CreateFixed("https://proxy:70"));
10851   CapturingBoundNetLog log;
10852   session_deps_.net_log = log.bound().net_log();
10853
10854   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10855   cert_request->host_and_port = HostPortPair("proxy", 70);
10856
10857   // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10858   // [ssl_]data[1-3]. Rather than represending the endpoint
10859   // (www.example.com:443), they represent failures with the HTTPS proxy
10860   // (proxy:70).
10861   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
10862   ssl_data1.cert_request_info = cert_request.get();
10863   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
10864   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10865   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10866
10867   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10868   ssl_data2.cert_request_info = cert_request.get();
10869   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
10870   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10871   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10872
10873   // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10874 #if 0
10875   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10876   ssl_data3.cert_request_info = cert_request.get();
10877   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
10878   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10879   session_deps_.socket_factory->AddSocketDataProvider(&data3);
10880 #endif
10881
10882   net::HttpRequestInfo requests[2];
10883   requests[0].url = GURL("https://www.example.com/");
10884   requests[0].method = "GET";
10885   requests[0].load_flags = net::LOAD_NORMAL;
10886
10887   requests[1].url = GURL("http://www.example.com/");
10888   requests[1].method = "GET";
10889   requests[1].load_flags = net::LOAD_NORMAL;
10890
10891   for (size_t i = 0; i < arraysize(requests); ++i) {
10892     session_deps_.socket_factory->ResetNextMockIndexes();
10893     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10894     scoped_ptr<HttpNetworkTransaction> trans(
10895         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10896
10897     // Begin the SSL handshake with the proxy.
10898     TestCompletionCallback callback;
10899     int rv = trans->Start(
10900         &requests[i], callback.callback(), net::BoundNetLog());
10901     ASSERT_EQ(net::ERR_IO_PENDING, rv);
10902
10903     // Complete the SSL handshake, which should abort due to requiring a
10904     // client certificate.
10905     rv = callback.WaitForResult();
10906     ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10907
10908     // Indicate that no certificate should be supplied. From the perspective
10909     // of SSLClientCertCache, NULL is just as meaningful as a real
10910     // certificate, so this is the same as supply a
10911     // legitimate-but-unacceptable certificate.
10912     rv = trans->RestartWithCertificate(NULL, callback.callback());
10913     ASSERT_EQ(net::ERR_IO_PENDING, rv);
10914
10915     // Ensure the certificate was added to the client auth cache before
10916     // allowing the connection to continue restarting.
10917     scoped_refptr<X509Certificate> client_cert;
10918     ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10919         HostPortPair("proxy", 70), &client_cert));
10920     ASSERT_EQ(NULL, client_cert.get());
10921     // Ensure the certificate was NOT cached for the endpoint. This only
10922     // applies to HTTPS requests, but is fine to check for HTTP requests.
10923     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10924         HostPortPair("www.example.com", 443), &client_cert));
10925
10926     // Restart the handshake. This will consume ssl_data2, which fails, and
10927     // then consume ssl_data3, which should also fail. The result code is
10928     // checked against what ssl_data3 should return.
10929     rv = callback.WaitForResult();
10930     ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10931
10932     // Now that the new handshake has failed, ensure that the client
10933     // certificate was removed from the client auth cache.
10934     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10935         HostPortPair("proxy", 70), &client_cert));
10936     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10937         HostPortPair("www.example.com", 443), &client_cert));
10938   }
10939 }
10940
10941 // Unlike TEST/TEST_F, which are macros that expand to further macros,
10942 // TEST_P is a macro that expands directly to code that stringizes the
10943 // arguments. As a result, macros passed as parameters (such as prefix
10944 // or test_case_name) will not be expanded by the preprocessor. To
10945 // work around this, indirect the macro for TEST_P, so that the
10946 // pre-processor will expand macros such as MAYBE_test_name before
10947 // instantiating the test.
10948 #define WRAPPED_TEST_P(test_case_name, test_name) \
10949   TEST_P(test_case_name, test_name)
10950
10951 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
10952 #if defined(OS_WIN)
10953 #define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10954 #else
10955 #define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10956 #endif
10957 WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
10958   session_deps_.use_alternate_protocols = true;
10959   session_deps_.next_protos = SpdyNextProtos();
10960
10961   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
10962   session_deps_.host_resolver.reset(new MockCachingHostResolver());
10963   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10964   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10965   pool_peer.DisableDomainAuthenticationVerification();
10966
10967   SSLSocketDataProvider ssl(ASYNC, OK);
10968   ssl.SetNextProto(GetParam());
10969   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10970
10971   scoped_ptr<SpdyFrame> host1_req(
10972       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10973   scoped_ptr<SpdyFrame> host2_req(
10974       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
10975   MockWrite spdy_writes[] = {
10976     CreateMockWrite(*host1_req, 1),
10977     CreateMockWrite(*host2_req, 4),
10978   };
10979   scoped_ptr<SpdyFrame> host1_resp(
10980       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10981   scoped_ptr<SpdyFrame> host1_resp_body(
10982       spdy_util_.ConstructSpdyBodyFrame(1, true));
10983   scoped_ptr<SpdyFrame> host2_resp(
10984       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10985   scoped_ptr<SpdyFrame> host2_resp_body(
10986       spdy_util_.ConstructSpdyBodyFrame(3, true));
10987   MockRead spdy_reads[] = {
10988     CreateMockRead(*host1_resp, 2),
10989     CreateMockRead(*host1_resp_body, 3),
10990     CreateMockRead(*host2_resp, 5),
10991     CreateMockRead(*host2_resp_body, 6),
10992     MockRead(ASYNC, 0, 7),
10993   };
10994
10995   IPAddressNumber ip;
10996   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10997   IPEndPoint peer_addr = IPEndPoint(ip, 443);
10998   MockConnect connect(ASYNC, OK, peer_addr);
10999   OrderedSocketData spdy_data(
11000       connect,
11001       spdy_reads, arraysize(spdy_reads),
11002       spdy_writes, arraysize(spdy_writes));
11003   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11004
11005   TestCompletionCallback callback;
11006   HttpRequestInfo request1;
11007   request1.method = "GET";
11008   request1.url = GURL("https://www.google.com/");
11009   request1.load_flags = 0;
11010   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
11011
11012   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11013   EXPECT_EQ(ERR_IO_PENDING, rv);
11014   EXPECT_EQ(OK, callback.WaitForResult());
11015
11016   const HttpResponseInfo* response = trans1.GetResponseInfo();
11017   ASSERT_TRUE(response != NULL);
11018   ASSERT_TRUE(response->headers.get() != NULL);
11019   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11020
11021   std::string response_data;
11022   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11023   EXPECT_EQ("hello!", response_data);
11024
11025   // Preload www.gmail.com into HostCache.
11026   HostPortPair host_port("www.gmail.com", 443);
11027   HostResolver::RequestInfo resolve_info(host_port);
11028   AddressList ignored;
11029   rv = session_deps_.host_resolver->Resolve(resolve_info,
11030                                             DEFAULT_PRIORITY,
11031                                             &ignored,
11032                                             callback.callback(),
11033                                             NULL,
11034                                             BoundNetLog());
11035   EXPECT_EQ(ERR_IO_PENDING, rv);
11036   rv = callback.WaitForResult();
11037   EXPECT_EQ(OK, rv);
11038
11039   HttpRequestInfo request2;
11040   request2.method = "GET";
11041   request2.url = GURL("https://www.gmail.com/");
11042   request2.load_flags = 0;
11043   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
11044
11045   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11046   EXPECT_EQ(ERR_IO_PENDING, rv);
11047   EXPECT_EQ(OK, callback.WaitForResult());
11048
11049   response = trans2.GetResponseInfo();
11050   ASSERT_TRUE(response != NULL);
11051   ASSERT_TRUE(response->headers.get() != NULL);
11052   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11053   EXPECT_TRUE(response->was_fetched_via_spdy);
11054   EXPECT_TRUE(response->was_npn_negotiated);
11055   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11056   EXPECT_EQ("hello!", response_data);
11057 }
11058 #undef MAYBE_UseIPConnectionPooling
11059
11060 TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
11061   session_deps_.use_alternate_protocols = true;
11062   session_deps_.next_protos = SpdyNextProtos();
11063
11064   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
11065   session_deps_.host_resolver.reset(new MockCachingHostResolver());
11066   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11067   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11068   pool_peer.DisableDomainAuthenticationVerification();
11069
11070   SSLSocketDataProvider ssl(ASYNC, OK);
11071   ssl.SetNextProto(GetParam());
11072   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11073
11074   scoped_ptr<SpdyFrame> host1_req(
11075       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11076   scoped_ptr<SpdyFrame> host2_req(
11077       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
11078   MockWrite spdy_writes[] = {
11079     CreateMockWrite(*host1_req, 1),
11080     CreateMockWrite(*host2_req, 4),
11081   };
11082   scoped_ptr<SpdyFrame> host1_resp(
11083       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11084   scoped_ptr<SpdyFrame> host1_resp_body(
11085       spdy_util_.ConstructSpdyBodyFrame(1, true));
11086   scoped_ptr<SpdyFrame> host2_resp(
11087       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11088   scoped_ptr<SpdyFrame> host2_resp_body(
11089       spdy_util_.ConstructSpdyBodyFrame(3, true));
11090   MockRead spdy_reads[] = {
11091     CreateMockRead(*host1_resp, 2),
11092     CreateMockRead(*host1_resp_body, 3),
11093     CreateMockRead(*host2_resp, 5),
11094     CreateMockRead(*host2_resp_body, 6),
11095     MockRead(ASYNC, 0, 7),
11096   };
11097
11098   IPAddressNumber ip;
11099   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11100   IPEndPoint peer_addr = IPEndPoint(ip, 443);
11101   MockConnect connect(ASYNC, OK, peer_addr);
11102   OrderedSocketData spdy_data(
11103       connect,
11104       spdy_reads, arraysize(spdy_reads),
11105       spdy_writes, arraysize(spdy_writes));
11106   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11107
11108   TestCompletionCallback callback;
11109   HttpRequestInfo request1;
11110   request1.method = "GET";
11111   request1.url = GURL("https://www.google.com/");
11112   request1.load_flags = 0;
11113   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
11114
11115   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11116   EXPECT_EQ(ERR_IO_PENDING, rv);
11117   EXPECT_EQ(OK, callback.WaitForResult());
11118
11119   const HttpResponseInfo* response = trans1.GetResponseInfo();
11120   ASSERT_TRUE(response != NULL);
11121   ASSERT_TRUE(response->headers.get() != NULL);
11122   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11123
11124   std::string response_data;
11125   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11126   EXPECT_EQ("hello!", response_data);
11127
11128   HttpRequestInfo request2;
11129   request2.method = "GET";
11130   request2.url = GURL("https://www.gmail.com/");
11131   request2.load_flags = 0;
11132   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
11133
11134   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11135   EXPECT_EQ(ERR_IO_PENDING, rv);
11136   EXPECT_EQ(OK, callback.WaitForResult());
11137
11138   response = trans2.GetResponseInfo();
11139   ASSERT_TRUE(response != NULL);
11140   ASSERT_TRUE(response->headers.get() != NULL);
11141   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11142   EXPECT_TRUE(response->was_fetched_via_spdy);
11143   EXPECT_TRUE(response->was_npn_negotiated);
11144   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11145   EXPECT_EQ("hello!", response_data);
11146 }
11147
11148 class OneTimeCachingHostResolver : public net::HostResolver {
11149  public:
11150   explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11151       : host_port_(host_port) {}
11152   ~OneTimeCachingHostResolver() override {}
11153
11154   RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11155
11156   // HostResolver methods:
11157   int Resolve(const RequestInfo& info,
11158               RequestPriority priority,
11159               AddressList* addresses,
11160               const CompletionCallback& callback,
11161               RequestHandle* out_req,
11162               const BoundNetLog& net_log) override {
11163     return host_resolver_.Resolve(
11164         info, priority, addresses, callback, out_req, net_log);
11165   }
11166
11167   int ResolveFromCache(const RequestInfo& info,
11168                        AddressList* addresses,
11169                        const BoundNetLog& net_log) override {
11170     int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11171     if (rv == OK && info.host_port_pair().Equals(host_port_))
11172       host_resolver_.GetHostCache()->clear();
11173     return rv;
11174   }
11175
11176   void CancelRequest(RequestHandle req) override {
11177     host_resolver_.CancelRequest(req);
11178   }
11179
11180   MockCachingHostResolver* GetMockHostResolver() {
11181     return &host_resolver_;
11182   }
11183
11184  private:
11185   MockCachingHostResolver host_resolver_;
11186   const HostPortPair host_port_;
11187 };
11188
11189 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
11190 #if defined(OS_WIN)
11191 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11192     DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
11193 #else
11194 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11195     UseIPConnectionPoolingWithHostCacheExpiration
11196 #endif
11197 WRAPPED_TEST_P(HttpNetworkTransactionTest,
11198                MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
11199 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11200 // prefix doesn't work with parametrized tests).
11201 #if defined(OS_WIN)
11202   return;
11203 #else
11204   session_deps_.use_alternate_protocols = true;
11205   session_deps_.next_protos = SpdyNextProtos();
11206
11207   // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
11208   OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
11209   HttpNetworkSession::Params params =
11210       SpdySessionDependencies::CreateSessionParams(&session_deps_);
11211   params.host_resolver = &host_resolver;
11212   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11213   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11214   pool_peer.DisableDomainAuthenticationVerification();
11215
11216   SSLSocketDataProvider ssl(ASYNC, OK);
11217   ssl.SetNextProto(GetParam());
11218   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11219
11220   scoped_ptr<SpdyFrame> host1_req(
11221       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11222   scoped_ptr<SpdyFrame> host2_req(
11223       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
11224   MockWrite spdy_writes[] = {
11225     CreateMockWrite(*host1_req, 1),
11226     CreateMockWrite(*host2_req, 4),
11227   };
11228   scoped_ptr<SpdyFrame> host1_resp(
11229       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11230   scoped_ptr<SpdyFrame> host1_resp_body(
11231       spdy_util_.ConstructSpdyBodyFrame(1, true));
11232   scoped_ptr<SpdyFrame> host2_resp(
11233       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11234   scoped_ptr<SpdyFrame> host2_resp_body(
11235       spdy_util_.ConstructSpdyBodyFrame(3, true));
11236   MockRead spdy_reads[] = {
11237     CreateMockRead(*host1_resp, 2),
11238     CreateMockRead(*host1_resp_body, 3),
11239     CreateMockRead(*host2_resp, 5),
11240     CreateMockRead(*host2_resp_body, 6),
11241     MockRead(ASYNC, 0, 7),
11242   };
11243
11244   IPAddressNumber ip;
11245   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11246   IPEndPoint peer_addr = IPEndPoint(ip, 443);
11247   MockConnect connect(ASYNC, OK, peer_addr);
11248   OrderedSocketData spdy_data(
11249       connect,
11250       spdy_reads, arraysize(spdy_reads),
11251       spdy_writes, arraysize(spdy_writes));
11252   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11253
11254   TestCompletionCallback callback;
11255   HttpRequestInfo request1;
11256   request1.method = "GET";
11257   request1.url = GURL("https://www.google.com/");
11258   request1.load_flags = 0;
11259   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
11260
11261   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11262   EXPECT_EQ(ERR_IO_PENDING, rv);
11263   EXPECT_EQ(OK, callback.WaitForResult());
11264
11265   const HttpResponseInfo* response = trans1.GetResponseInfo();
11266   ASSERT_TRUE(response != NULL);
11267   ASSERT_TRUE(response->headers.get() != NULL);
11268   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11269
11270   std::string response_data;
11271   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11272   EXPECT_EQ("hello!", response_data);
11273
11274   // Preload cache entries into HostCache.
11275   HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
11276   AddressList ignored;
11277   rv = host_resolver.Resolve(resolve_info,
11278                              DEFAULT_PRIORITY,
11279                              &ignored,
11280                              callback.callback(),
11281                              NULL,
11282                              BoundNetLog());
11283   EXPECT_EQ(ERR_IO_PENDING, rv);
11284   rv = callback.WaitForResult();
11285   EXPECT_EQ(OK, rv);
11286
11287   HttpRequestInfo request2;
11288   request2.method = "GET";
11289   request2.url = GURL("https://www.gmail.com/");
11290   request2.load_flags = 0;
11291   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
11292
11293   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11294   EXPECT_EQ(ERR_IO_PENDING, rv);
11295   EXPECT_EQ(OK, callback.WaitForResult());
11296
11297   response = trans2.GetResponseInfo();
11298   ASSERT_TRUE(response != NULL);
11299   ASSERT_TRUE(response->headers.get() != NULL);
11300   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11301   EXPECT_TRUE(response->was_fetched_via_spdy);
11302   EXPECT_TRUE(response->was_npn_negotiated);
11303   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11304   EXPECT_EQ("hello!", response_data);
11305 #endif
11306 }
11307 #undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
11308
11309 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
11310   const std::string https_url = "https://www.google.com/";
11311   const std::string http_url = "http://www.google.com:443/";
11312
11313   // SPDY GET for HTTPS URL
11314   scoped_ptr<SpdyFrame> req1(
11315       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
11316
11317   MockWrite writes1[] = {
11318     CreateMockWrite(*req1, 0),
11319   };
11320
11321   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11322   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11323   MockRead reads1[] = {
11324     CreateMockRead(*resp1, 1),
11325     CreateMockRead(*body1, 2),
11326     MockRead(ASYNC, ERR_IO_PENDING, 3)
11327   };
11328
11329   DelayedSocketData data1(
11330       1, reads1, arraysize(reads1),
11331       writes1, arraysize(writes1));
11332   MockConnect connect_data1(ASYNC, OK);
11333   data1.set_connect_data(connect_data1);
11334
11335   // HTTP GET for the HTTP URL
11336   MockWrite writes2[] = {
11337     MockWrite(ASYNC, 4,
11338               "GET / HTTP/1.1\r\n"
11339               "Host: www.google.com:443\r\n"
11340               "Connection: keep-alive\r\n\r\n"),
11341   };
11342
11343   MockRead reads2[] = {
11344     MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11345     MockRead(ASYNC, 6, "hello"),
11346     MockRead(ASYNC, 7, OK),
11347   };
11348
11349   DelayedSocketData data2(
11350       1, reads2, arraysize(reads2),
11351       writes2, arraysize(writes2));
11352
11353   SSLSocketDataProvider ssl(ASYNC, OK);
11354   ssl.SetNextProto(GetParam());
11355   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11356   session_deps_.socket_factory->AddSocketDataProvider(&data1);
11357   session_deps_.socket_factory->AddSocketDataProvider(&data2);
11358
11359   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11360
11361   // Start the first transaction to set up the SpdySession
11362   HttpRequestInfo request1;
11363   request1.method = "GET";
11364   request1.url = GURL(https_url);
11365   request1.load_flags = 0;
11366   HttpNetworkTransaction trans1(LOWEST, session.get());
11367   TestCompletionCallback callback1;
11368   EXPECT_EQ(ERR_IO_PENDING,
11369             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11370   base::MessageLoop::current()->RunUntilIdle();
11371
11372   EXPECT_EQ(OK, callback1.WaitForResult());
11373   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11374
11375   // Now, start the HTTP request
11376   HttpRequestInfo request2;
11377   request2.method = "GET";
11378   request2.url = GURL(http_url);
11379   request2.load_flags = 0;
11380   HttpNetworkTransaction trans2(MEDIUM, session.get());
11381   TestCompletionCallback callback2;
11382   EXPECT_EQ(ERR_IO_PENDING,
11383             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11384   base::MessageLoop::current()->RunUntilIdle();
11385
11386   EXPECT_EQ(OK, callback2.WaitForResult());
11387   EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11388 }
11389
11390 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
11391   const std::string https_url = "https://www.google.com/";
11392   const std::string http_url = "http://www.google.com:443/";
11393
11394   // SPDY GET for HTTPS URL (through CONNECT tunnel)
11395   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
11396                                                                 LOWEST));
11397   scoped_ptr<SpdyFrame> req1(
11398       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
11399   scoped_ptr<SpdyFrame> wrapped_req1(
11400       spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
11401
11402   // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
11403   SpdyHeaderBlock req2_block;
11404   req2_block[spdy_util_.GetMethodKey()] = "GET";
11405   req2_block[spdy_util_.GetPathKey()] =
11406       spdy_util_.is_spdy2() ? http_url.c_str() : "/";
11407   req2_block[spdy_util_.GetHostKey()] = "www.google.com:443";
11408   req2_block[spdy_util_.GetSchemeKey()] = "http";
11409   spdy_util_.MaybeAddVersionHeader(&req2_block);
11410   scoped_ptr<SpdyFrame> req2(
11411       spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
11412
11413   MockWrite writes1[] = {
11414     CreateMockWrite(*connect, 0),
11415     CreateMockWrite(*wrapped_req1, 2),
11416     CreateMockWrite(*req2, 5),
11417   };
11418
11419   scoped_ptr<SpdyFrame> conn_resp(
11420       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11421   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11422   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11423   scoped_ptr<SpdyFrame> wrapped_resp1(
11424       spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11425   scoped_ptr<SpdyFrame> wrapped_body1(
11426       spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11427   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11428   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
11429   MockRead reads1[] = {
11430     CreateMockRead(*conn_resp, 1),
11431     CreateMockRead(*wrapped_resp1, 3),
11432     CreateMockRead(*wrapped_body1, 4),
11433     CreateMockRead(*resp2, 6),
11434     CreateMockRead(*body2, 7),
11435     MockRead(ASYNC, ERR_IO_PENDING, 8)
11436   };
11437
11438   DeterministicSocketData data1(reads1, arraysize(reads1),
11439                                 writes1, arraysize(writes1));
11440   MockConnect connect_data1(ASYNC, OK);
11441   data1.set_connect_data(connect_data1);
11442
11443   session_deps_.proxy_service.reset(
11444       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11445   CapturingNetLog log;
11446   session_deps_.net_log = &log;
11447   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
11448   ssl1.SetNextProto(GetParam());
11449   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11450   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
11451   ssl2.SetNextProto(GetParam());
11452   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11453   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
11454
11455   scoped_refptr<HttpNetworkSession> session(
11456       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11457
11458   // Start the first transaction to set up the SpdySession
11459   HttpRequestInfo request1;
11460   request1.method = "GET";
11461   request1.url = GURL(https_url);
11462   request1.load_flags = 0;
11463   HttpNetworkTransaction trans1(LOWEST, session.get());
11464   TestCompletionCallback callback1;
11465   EXPECT_EQ(ERR_IO_PENDING,
11466             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11467   base::MessageLoop::current()->RunUntilIdle();
11468   data1.RunFor(4);
11469
11470   EXPECT_EQ(OK, callback1.WaitForResult());
11471   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11472
11473   LoadTimingInfo load_timing_info1;
11474   EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11475   TestLoadTimingNotReusedWithPac(load_timing_info1,
11476                                  CONNECT_TIMING_HAS_SSL_TIMES);
11477
11478   // Now, start the HTTP request
11479   HttpRequestInfo request2;
11480   request2.method = "GET";
11481   request2.url = GURL(http_url);
11482   request2.load_flags = 0;
11483   HttpNetworkTransaction trans2(MEDIUM, session.get());
11484   TestCompletionCallback callback2;
11485   EXPECT_EQ(ERR_IO_PENDING,
11486             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11487   base::MessageLoop::current()->RunUntilIdle();
11488   data1.RunFor(3);
11489
11490   EXPECT_EQ(OK, callback2.WaitForResult());
11491   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11492
11493   LoadTimingInfo load_timing_info2;
11494   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11495   // The established SPDY sessions is considered reused by the HTTP request.
11496   TestLoadTimingReusedWithPac(load_timing_info2);
11497   // HTTP requests over a SPDY session should have a different connection
11498   // socket_log_id than requests over a tunnel.
11499   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
11500 }
11501
11502 TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
11503   session_deps_.force_spdy_always = true;
11504   const std::string https_url = "https://www.google.com/";
11505   const std::string http_url = "http://www.google.com:443/";
11506
11507   // SPDY GET for HTTPS URL
11508   scoped_ptr<SpdyFrame> req1(
11509       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
11510   // SPDY GET for the HTTP URL
11511   scoped_ptr<SpdyFrame> req2(
11512       spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
11513
11514   MockWrite writes[] = {
11515     CreateMockWrite(*req1, 1),
11516     CreateMockWrite(*req2, 4),
11517   };
11518
11519   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11520   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11521   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11522   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
11523   MockRead reads[] = {
11524     CreateMockRead(*resp1, 2),
11525     CreateMockRead(*body1, 3),
11526     CreateMockRead(*resp2, 5),
11527     CreateMockRead(*body2, 6),
11528     MockRead(ASYNC, ERR_IO_PENDING, 7)
11529   };
11530
11531   OrderedSocketData data(reads, arraysize(reads),
11532                          writes, arraysize(writes));
11533
11534   SSLSocketDataProvider ssl(ASYNC, OK);
11535   ssl.SetNextProto(GetParam());
11536   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11537   session_deps_.socket_factory->AddSocketDataProvider(&data);
11538
11539   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11540
11541   // Start the first transaction to set up the SpdySession
11542   HttpRequestInfo request1;
11543   request1.method = "GET";
11544   request1.url = GURL(https_url);
11545   request1.load_flags = 0;
11546   HttpNetworkTransaction trans1(LOWEST, session.get());
11547   TestCompletionCallback callback1;
11548   EXPECT_EQ(ERR_IO_PENDING,
11549             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11550   base::MessageLoop::current()->RunUntilIdle();
11551
11552   EXPECT_EQ(OK, callback1.WaitForResult());
11553   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11554
11555   // Now, start the HTTP request
11556   HttpRequestInfo request2;
11557   request2.method = "GET";
11558   request2.url = GURL(http_url);
11559   request2.load_flags = 0;
11560   HttpNetworkTransaction trans2(MEDIUM, session.get());
11561   TestCompletionCallback callback2;
11562   EXPECT_EQ(ERR_IO_PENDING,
11563             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11564   base::MessageLoop::current()->RunUntilIdle();
11565
11566   EXPECT_EQ(OK, callback2.WaitForResult());
11567   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11568 }
11569
11570 // Test that in the case where we have a SPDY session to a SPDY proxy
11571 // that we do not pool other origins that resolve to the same IP when
11572 // the certificate does not match the new origin.
11573 // http://crbug.com/134690
11574 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
11575   const std::string url1 = "http://www.google.com/";
11576   const std::string url2 = "https://mail.google.com/";
11577   const std::string ip_addr = "1.2.3.4";
11578
11579   // SPDY GET for HTTP URL (through SPDY proxy)
11580   scoped_ptr<SpdyHeaderBlock> headers(
11581       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
11582   scoped_ptr<SpdyFrame> req1(
11583       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
11584
11585   MockWrite writes1[] = {
11586     CreateMockWrite(*req1, 0),
11587   };
11588
11589   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11590   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11591   MockRead reads1[] = {
11592     CreateMockRead(*resp1, 1),
11593     CreateMockRead(*body1, 2),
11594     MockRead(ASYNC, OK, 3) // EOF
11595   };
11596
11597   scoped_ptr<DeterministicSocketData> data1(
11598       new DeterministicSocketData(reads1, arraysize(reads1),
11599                                   writes1, arraysize(writes1)));
11600   IPAddressNumber ip;
11601   ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11602   IPEndPoint peer_addr = IPEndPoint(ip, 443);
11603   MockConnect connect_data1(ASYNC, OK, peer_addr);
11604   data1->set_connect_data(connect_data1);
11605
11606   // SPDY GET for HTTPS URL (direct)
11607   scoped_ptr<SpdyFrame> req2(
11608       spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
11609
11610   MockWrite writes2[] = {
11611     CreateMockWrite(*req2, 0),
11612   };
11613
11614   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11615   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11616   MockRead reads2[] = {
11617     CreateMockRead(*resp2, 1),
11618     CreateMockRead(*body2, 2),
11619     MockRead(ASYNC, OK, 3) // EOF
11620   };
11621
11622   scoped_ptr<DeterministicSocketData> data2(
11623       new DeterministicSocketData(reads2, arraysize(reads2),
11624                                   writes2, arraysize(writes2)));
11625   MockConnect connect_data2(ASYNC, OK);
11626   data2->set_connect_data(connect_data2);
11627
11628   // Set up a proxy config that sends HTTP requests to a proxy, and
11629   // all others direct.
11630   ProxyConfig proxy_config;
11631   proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11632   CapturingProxyResolver* capturing_proxy_resolver =
11633       new CapturingProxyResolver();
11634   session_deps_.proxy_service.reset(new ProxyService(
11635       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11636       NULL));
11637
11638   // Load a valid cert.  Note, that this does not need to
11639   // be valid for proxy because the MockSSLClientSocket does
11640   // not actually verify it.  But SpdySession will use this
11641   // to see if it is valid for the new origin
11642   base::FilePath certs_dir = GetTestCertsDirectory();
11643   scoped_refptr<X509Certificate> server_cert(
11644       ImportCertFromFile(certs_dir, "ok_cert.pem"));
11645   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
11646
11647   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
11648   ssl1.SetNextProto(GetParam());
11649   ssl1.cert = server_cert;
11650   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11651   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11652       data1.get());
11653
11654   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
11655   ssl2.SetNextProto(GetParam());
11656   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11657   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11658       data2.get());
11659
11660   session_deps_.host_resolver.reset(new MockCachingHostResolver());
11661   session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11662   session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
11663
11664   scoped_refptr<HttpNetworkSession> session(
11665       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11666
11667   // Start the first transaction to set up the SpdySession
11668   HttpRequestInfo request1;
11669   request1.method = "GET";
11670   request1.url = GURL(url1);
11671   request1.load_flags = 0;
11672   HttpNetworkTransaction trans1(LOWEST, session.get());
11673   TestCompletionCallback callback1;
11674   ASSERT_EQ(ERR_IO_PENDING,
11675             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11676   data1->RunFor(3);
11677
11678   ASSERT_TRUE(callback1.have_result());
11679   EXPECT_EQ(OK, callback1.WaitForResult());
11680   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11681
11682   // Now, start the HTTP request
11683   HttpRequestInfo request2;
11684   request2.method = "GET";
11685   request2.url = GURL(url2);
11686   request2.load_flags = 0;
11687   HttpNetworkTransaction trans2(MEDIUM, session.get());
11688   TestCompletionCallback callback2;
11689   EXPECT_EQ(ERR_IO_PENDING,
11690             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11691   base::MessageLoop::current()->RunUntilIdle();
11692   data2->RunFor(3);
11693
11694   ASSERT_TRUE(callback2.have_result());
11695   EXPECT_EQ(OK, callback2.WaitForResult());
11696   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11697 }
11698
11699 // Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11700 // error) in SPDY session, removes the socket from pool and closes the SPDY
11701 // session. Verify that new url's from the same HttpNetworkSession (and a new
11702 // SpdySession) do work. http://crbug.com/224701
11703 TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
11704   const std::string https_url = "https://www.google.com/";
11705
11706   MockRead reads1[] = {
11707     MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11708   };
11709
11710   scoped_ptr<DeterministicSocketData> data1(
11711       new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11712   data1->SetStop(1);
11713
11714   scoped_ptr<SpdyFrame> req2(
11715       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
11716   MockWrite writes2[] = {
11717     CreateMockWrite(*req2, 0),
11718   };
11719
11720   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11721   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11722   MockRead reads2[] = {
11723     CreateMockRead(*resp2, 1),
11724     CreateMockRead(*body2, 2),
11725     MockRead(ASYNC, OK, 3)  // EOF
11726   };
11727
11728   scoped_ptr<DeterministicSocketData> data2(
11729       new DeterministicSocketData(reads2, arraysize(reads2),
11730                                   writes2, arraysize(writes2)));
11731
11732   SSLSocketDataProvider ssl1(ASYNC, OK);
11733   ssl1.SetNextProto(GetParam());
11734   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11735   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11736       data1.get());
11737
11738   SSLSocketDataProvider ssl2(ASYNC, OK);
11739   ssl2.SetNextProto(GetParam());
11740   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11741   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11742       data2.get());
11743
11744   scoped_refptr<HttpNetworkSession> session(
11745       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11746
11747   // Start the first transaction to set up the SpdySession and verify that
11748   // connection was closed.
11749   HttpRequestInfo request1;
11750   request1.method = "GET";
11751   request1.url = GURL(https_url);
11752   request1.load_flags = 0;
11753   HttpNetworkTransaction trans1(MEDIUM, session.get());
11754   TestCompletionCallback callback1;
11755   EXPECT_EQ(ERR_IO_PENDING,
11756             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11757   base::MessageLoop::current()->RunUntilIdle();
11758   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11759
11760   // Now, start the second request and make sure it succeeds.
11761   HttpRequestInfo request2;
11762   request2.method = "GET";
11763   request2.url = GURL(https_url);
11764   request2.load_flags = 0;
11765   HttpNetworkTransaction trans2(MEDIUM, session.get());
11766   TestCompletionCallback callback2;
11767   EXPECT_EQ(ERR_IO_PENDING,
11768             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11769   base::MessageLoop::current()->RunUntilIdle();
11770   data2->RunFor(3);
11771
11772   ASSERT_TRUE(callback2.have_result());
11773   EXPECT_EQ(OK, callback2.WaitForResult());
11774   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11775 }
11776
11777 TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
11778   session_deps_.next_protos = SpdyNextProtos();
11779   ClientSocketPoolManager::set_max_sockets_per_group(
11780       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11781   ClientSocketPoolManager::set_max_sockets_per_pool(
11782       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11783
11784   // Use two different hosts with different IPs so they don't get pooled.
11785   session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11786   session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11787   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11788
11789   SSLSocketDataProvider ssl1(ASYNC, OK);
11790   ssl1.SetNextProto(GetParam());
11791   SSLSocketDataProvider ssl2(ASYNC, OK);
11792   ssl2.SetNextProto(GetParam());
11793   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11794   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11795
11796   scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
11797       "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11798   MockWrite spdy1_writes[] = {
11799     CreateMockWrite(*host1_req, 1),
11800   };
11801   scoped_ptr<SpdyFrame> host1_resp(
11802       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11803   scoped_ptr<SpdyFrame> host1_resp_body(
11804       spdy_util_.ConstructSpdyBodyFrame(1, true));
11805   MockRead spdy1_reads[] = {
11806     CreateMockRead(*host1_resp, 2),
11807     CreateMockRead(*host1_resp_body, 3),
11808     MockRead(ASYNC, ERR_IO_PENDING, 4),
11809   };
11810
11811   scoped_ptr<OrderedSocketData> spdy1_data(
11812       new OrderedSocketData(
11813           spdy1_reads, arraysize(spdy1_reads),
11814           spdy1_writes, arraysize(spdy1_writes)));
11815   session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11816
11817   scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
11818       "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11819   MockWrite spdy2_writes[] = {
11820     CreateMockWrite(*host2_req, 1),
11821   };
11822   scoped_ptr<SpdyFrame> host2_resp(
11823       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11824   scoped_ptr<SpdyFrame> host2_resp_body(
11825       spdy_util_.ConstructSpdyBodyFrame(1, true));
11826   MockRead spdy2_reads[] = {
11827     CreateMockRead(*host2_resp, 2),
11828     CreateMockRead(*host2_resp_body, 3),
11829     MockRead(ASYNC, ERR_IO_PENDING, 4),
11830   };
11831
11832   scoped_ptr<OrderedSocketData> spdy2_data(
11833       new OrderedSocketData(
11834           spdy2_reads, arraysize(spdy2_reads),
11835           spdy2_writes, arraysize(spdy2_writes)));
11836   session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11837
11838   MockWrite http_write[] = {
11839     MockWrite("GET / HTTP/1.1\r\n"
11840               "Host: www.a.com\r\n"
11841               "Connection: keep-alive\r\n\r\n"),
11842   };
11843
11844   MockRead http_read[] = {
11845     MockRead("HTTP/1.1 200 OK\r\n"),
11846     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11847     MockRead("Content-Length: 6\r\n\r\n"),
11848     MockRead("hello!"),
11849   };
11850   StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11851                                      http_write, arraysize(http_write));
11852   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11853
11854   HostPortPair host_port_pair_a("www.a.com", 443);
11855   SpdySessionKey spdy_session_key_a(
11856       host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11857   EXPECT_FALSE(
11858       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11859
11860   TestCompletionCallback callback;
11861   HttpRequestInfo request1;
11862   request1.method = "GET";
11863   request1.url = GURL("https://www.a.com/");
11864   request1.load_flags = 0;
11865   scoped_ptr<HttpNetworkTransaction> trans(
11866       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11867
11868   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11869   EXPECT_EQ(ERR_IO_PENDING, rv);
11870   EXPECT_EQ(OK, callback.WaitForResult());
11871
11872   const HttpResponseInfo* response = trans->GetResponseInfo();
11873   ASSERT_TRUE(response != NULL);
11874   ASSERT_TRUE(response->headers.get() != NULL);
11875   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11876   EXPECT_TRUE(response->was_fetched_via_spdy);
11877   EXPECT_TRUE(response->was_npn_negotiated);
11878
11879   std::string response_data;
11880   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11881   EXPECT_EQ("hello!", response_data);
11882   trans.reset();
11883   EXPECT_TRUE(
11884       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11885
11886   HostPortPair host_port_pair_b("www.b.com", 443);
11887   SpdySessionKey spdy_session_key_b(
11888       host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11889   EXPECT_FALSE(
11890       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11891   HttpRequestInfo request2;
11892   request2.method = "GET";
11893   request2.url = GURL("https://www.b.com/");
11894   request2.load_flags = 0;
11895   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11896
11897   rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11898   EXPECT_EQ(ERR_IO_PENDING, rv);
11899   EXPECT_EQ(OK, callback.WaitForResult());
11900
11901   response = trans->GetResponseInfo();
11902   ASSERT_TRUE(response != NULL);
11903   ASSERT_TRUE(response->headers.get() != NULL);
11904   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11905   EXPECT_TRUE(response->was_fetched_via_spdy);
11906   EXPECT_TRUE(response->was_npn_negotiated);
11907   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11908   EXPECT_EQ("hello!", response_data);
11909   EXPECT_FALSE(
11910       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11911   EXPECT_TRUE(
11912       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11913
11914   HostPortPair host_port_pair_a1("www.a.com", 80);
11915   SpdySessionKey spdy_session_key_a1(
11916       host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11917   EXPECT_FALSE(
11918       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
11919   HttpRequestInfo request3;
11920   request3.method = "GET";
11921   request3.url = GURL("http://www.a.com/");
11922   request3.load_flags = 0;
11923   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11924
11925   rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11926   EXPECT_EQ(ERR_IO_PENDING, rv);
11927   EXPECT_EQ(OK, callback.WaitForResult());
11928
11929   response = trans->GetResponseInfo();
11930   ASSERT_TRUE(response != NULL);
11931   ASSERT_TRUE(response->headers.get() != NULL);
11932   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11933   EXPECT_FALSE(response->was_fetched_via_spdy);
11934   EXPECT_FALSE(response->was_npn_negotiated);
11935   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11936   EXPECT_EQ("hello!", response_data);
11937   EXPECT_FALSE(
11938       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11939   EXPECT_FALSE(
11940       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11941 }
11942
11943 TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11944   HttpRequestInfo request;
11945   request.method = "GET";
11946   request.url = GURL("http://www.google.com/");
11947   request.load_flags = 0;
11948
11949   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11950   scoped_ptr<HttpTransaction> trans(
11951       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11952
11953   MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11954   StaticSocketDataProvider data;
11955   data.set_connect_data(mock_connect);
11956   session_deps_.socket_factory->AddSocketDataProvider(&data);
11957
11958   TestCompletionCallback callback;
11959
11960   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11961   EXPECT_EQ(ERR_IO_PENDING, rv);
11962
11963   rv = callback.WaitForResult();
11964   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11965
11966   EXPECT_EQ(NULL, trans->GetResponseInfo());
11967
11968   // We don't care whether this succeeds or fails, but it shouldn't crash.
11969   HttpRequestHeaders request_headers;
11970   trans->GetFullRequestHeaders(&request_headers);
11971 }
11972
11973 TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11974   HttpRequestInfo request;
11975   request.method = "GET";
11976   request.url = GURL("http://www.google.com/");
11977   request.load_flags = 0;
11978
11979   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11980   scoped_ptr<HttpTransaction> trans(
11981       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11982
11983   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11984   StaticSocketDataProvider data;
11985   data.set_connect_data(mock_connect);
11986   session_deps_.socket_factory->AddSocketDataProvider(&data);
11987
11988   TestCompletionCallback callback;
11989
11990   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11991   EXPECT_EQ(ERR_IO_PENDING, rv);
11992
11993   rv = callback.WaitForResult();
11994   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11995
11996   EXPECT_EQ(NULL, trans->GetResponseInfo());
11997
11998   // We don't care whether this succeeds or fails, but it shouldn't crash.
11999   HttpRequestHeaders request_headers;
12000   trans->GetFullRequestHeaders(&request_headers);
12001 }
12002
12003 TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12004   HttpRequestInfo request;
12005   request.method = "GET";
12006   request.url = GURL("http://www.google.com/");
12007   request.load_flags = 0;
12008
12009   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12010   scoped_ptr<HttpTransaction> trans(
12011       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12012
12013   MockWrite data_writes[] = {
12014     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12015   };
12016   MockRead data_reads[] = {
12017     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
12018   };
12019
12020   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12021                                 data_writes, arraysize(data_writes));
12022   session_deps_.socket_factory->AddSocketDataProvider(&data);
12023
12024   TestCompletionCallback callback;
12025
12026   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12027   EXPECT_EQ(ERR_IO_PENDING, rv);
12028
12029   rv = callback.WaitForResult();
12030   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12031
12032   EXPECT_EQ(NULL, trans->GetResponseInfo());
12033
12034   HttpRequestHeaders request_headers;
12035   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12036   EXPECT_TRUE(request_headers.HasHeader("Host"));
12037 }
12038
12039 TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12040   HttpRequestInfo request;
12041   request.method = "GET";
12042   request.url = GURL("http://www.google.com/");
12043   request.load_flags = 0;
12044
12045   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12046   scoped_ptr<HttpTransaction> trans(
12047       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12048
12049   MockWrite data_writes[] = {
12050     MockWrite(ASYNC, ERR_CONNECTION_RESET),
12051   };
12052   MockRead data_reads[] = {
12053     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
12054   };
12055
12056   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12057                                 data_writes, arraysize(data_writes));
12058   session_deps_.socket_factory->AddSocketDataProvider(&data);
12059
12060   TestCompletionCallback callback;
12061
12062   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12063   EXPECT_EQ(ERR_IO_PENDING, rv);
12064
12065   rv = callback.WaitForResult();
12066   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12067
12068   EXPECT_EQ(NULL, trans->GetResponseInfo());
12069
12070   HttpRequestHeaders request_headers;
12071   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12072   EXPECT_TRUE(request_headers.HasHeader("Host"));
12073 }
12074
12075 TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12076   HttpRequestInfo request;
12077   request.method = "GET";
12078   request.url = GURL("http://www.google.com/");
12079   request.load_flags = 0;
12080
12081   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12082   scoped_ptr<HttpTransaction> trans(
12083       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12084
12085   MockWrite data_writes[] = {
12086     MockWrite("GET / HTTP/1.1\r\n"
12087               "Host: www.google.com\r\n"
12088               "Connection: keep-alive\r\n\r\n"),
12089   };
12090   MockRead data_reads[] = {
12091     MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12092   };
12093
12094   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12095                                 data_writes, arraysize(data_writes));
12096   session_deps_.socket_factory->AddSocketDataProvider(&data);
12097
12098   TestCompletionCallback callback;
12099
12100   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12101   EXPECT_EQ(ERR_IO_PENDING, rv);
12102
12103   rv = callback.WaitForResult();
12104   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12105
12106   EXPECT_EQ(NULL, trans->GetResponseInfo());
12107
12108   HttpRequestHeaders request_headers;
12109   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12110   EXPECT_TRUE(request_headers.HasHeader("Host"));
12111 }
12112
12113 TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12114   HttpRequestInfo request;
12115   request.method = "GET";
12116   request.url = GURL("http://www.google.com/");
12117   request.load_flags = 0;
12118
12119   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12120   scoped_ptr<HttpTransaction> trans(
12121       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12122
12123   MockWrite data_writes[] = {
12124     MockWrite("GET / HTTP/1.1\r\n"
12125               "Host: www.google.com\r\n"
12126               "Connection: keep-alive\r\n\r\n"),
12127   };
12128   MockRead data_reads[] = {
12129     MockRead(ASYNC, ERR_CONNECTION_RESET),
12130   };
12131
12132   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12133                                 data_writes, arraysize(data_writes));
12134   session_deps_.socket_factory->AddSocketDataProvider(&data);
12135
12136   TestCompletionCallback callback;
12137
12138   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12139   EXPECT_EQ(ERR_IO_PENDING, rv);
12140
12141   rv = callback.WaitForResult();
12142   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12143
12144   EXPECT_EQ(NULL, trans->GetResponseInfo());
12145
12146   HttpRequestHeaders request_headers;
12147   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12148   EXPECT_TRUE(request_headers.HasHeader("Host"));
12149 }
12150
12151 TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12152   HttpRequestInfo request;
12153   request.method = "GET";
12154   request.url = GURL("http://www.google.com/");
12155   request.load_flags = 0;
12156   request.extra_headers.SetHeader("X-Foo", "bar");
12157
12158   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12159   scoped_ptr<HttpTransaction> trans(
12160       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12161
12162   MockWrite data_writes[] = {
12163     MockWrite("GET / HTTP/1.1\r\n"
12164               "Host: www.google.com\r\n"
12165               "Connection: keep-alive\r\n"
12166               "X-Foo: bar\r\n\r\n"),
12167   };
12168   MockRead data_reads[] = {
12169     MockRead("HTTP/1.1 200 OK\r\n"
12170              "Content-Length: 5\r\n\r\n"
12171              "hello"),
12172     MockRead(ASYNC, ERR_UNEXPECTED),
12173   };
12174
12175   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12176                                 data_writes, arraysize(data_writes));
12177   session_deps_.socket_factory->AddSocketDataProvider(&data);
12178
12179   TestCompletionCallback callback;
12180
12181   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12182   EXPECT_EQ(ERR_IO_PENDING, rv);
12183
12184   rv = callback.WaitForResult();
12185   EXPECT_EQ(OK, rv);
12186
12187   HttpRequestHeaders request_headers;
12188   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12189   std::string foo;
12190   EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12191   EXPECT_EQ("bar", foo);
12192 }
12193
12194 namespace {
12195
12196 // Fake HttpStream that simply records calls to SetPriority().
12197 class FakeStream : public HttpStream,
12198                    public base::SupportsWeakPtr<FakeStream> {
12199  public:
12200   explicit FakeStream(RequestPriority priority) : priority_(priority) {}
12201   ~FakeStream() override {}
12202
12203   RequestPriority priority() const { return priority_; }
12204
12205   int InitializeStream(const HttpRequestInfo* request_info,
12206                        RequestPriority priority,
12207                        const BoundNetLog& net_log,
12208                        const CompletionCallback& callback) override {
12209     return ERR_IO_PENDING;
12210   }
12211
12212   int SendRequest(const HttpRequestHeaders& request_headers,
12213                   HttpResponseInfo* response,
12214                   const CompletionCallback& callback) override {
12215     ADD_FAILURE();
12216     return ERR_UNEXPECTED;
12217   }
12218
12219   int ReadResponseHeaders(const CompletionCallback& callback) override {
12220     ADD_FAILURE();
12221     return ERR_UNEXPECTED;
12222   }
12223
12224   int ReadResponseBody(IOBuffer* buf,
12225                        int buf_len,
12226                        const CompletionCallback& callback) override {
12227     ADD_FAILURE();
12228     return ERR_UNEXPECTED;
12229   }
12230
12231   void Close(bool not_reusable) override {}
12232
12233   bool IsResponseBodyComplete() const override {
12234     ADD_FAILURE();
12235     return false;
12236   }
12237
12238   bool CanFindEndOfResponse() const override { return false; }
12239
12240   bool IsConnectionReused() const override {
12241     ADD_FAILURE();
12242     return false;
12243   }
12244
12245   void SetConnectionReused() override { ADD_FAILURE(); }
12246
12247   bool IsConnectionReusable() const override {
12248     ADD_FAILURE();
12249     return false;
12250   }
12251
12252   int64 GetTotalReceivedBytes() const override {
12253     ADD_FAILURE();
12254     return 0;
12255   }
12256
12257   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
12258     ADD_FAILURE();
12259     return false;
12260   }
12261
12262   void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
12263
12264   void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
12265     ADD_FAILURE();
12266   }
12267
12268   bool IsSpdyHttpStream() const override {
12269     ADD_FAILURE();
12270     return false;
12271   }
12272
12273   void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
12274
12275   void SetPriority(RequestPriority priority) override { priority_ = priority; }
12276
12277   UploadProgress GetUploadProgress() const override { return UploadProgress(); }
12278
12279   HttpStream* RenewStreamForAuth() override { return NULL; }
12280
12281  private:
12282   RequestPriority priority_;
12283
12284   DISALLOW_COPY_AND_ASSIGN(FakeStream);
12285 };
12286
12287 // Fake HttpStreamRequest that simply records calls to SetPriority()
12288 // and vends FakeStreams with its current priority.
12289 class FakeStreamRequest : public HttpStreamRequest,
12290                           public base::SupportsWeakPtr<FakeStreamRequest> {
12291  public:
12292   FakeStreamRequest(RequestPriority priority,
12293                     HttpStreamRequest::Delegate* delegate)
12294       : priority_(priority),
12295         delegate_(delegate),
12296         websocket_stream_create_helper_(NULL) {}
12297
12298   FakeStreamRequest(RequestPriority priority,
12299                     HttpStreamRequest::Delegate* delegate,
12300                     WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12301       : priority_(priority),
12302         delegate_(delegate),
12303         websocket_stream_create_helper_(create_helper) {}
12304
12305   ~FakeStreamRequest() override {}
12306
12307   RequestPriority priority() const { return priority_; }
12308
12309   const WebSocketHandshakeStreamBase::CreateHelper*
12310   websocket_stream_create_helper() const {
12311     return websocket_stream_create_helper_;
12312   }
12313
12314   // Create a new FakeStream and pass it to the request's
12315   // delegate. Returns a weak pointer to the FakeStream.
12316   base::WeakPtr<FakeStream> FinishStreamRequest() {
12317     FakeStream* fake_stream = new FakeStream(priority_);
12318     // Do this before calling OnStreamReady() as OnStreamReady() may
12319     // immediately delete |fake_stream|.
12320     base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12321     delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12322     return weak_stream;
12323   }
12324
12325   int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
12326     ADD_FAILURE();
12327     return ERR_UNEXPECTED;
12328   }
12329
12330   LoadState GetLoadState() const override {
12331     ADD_FAILURE();
12332     return LoadState();
12333   }
12334
12335   void SetPriority(RequestPriority priority) override { priority_ = priority; }
12336
12337   bool was_npn_negotiated() const override { return false; }
12338
12339   NextProto protocol_negotiated() const override { return kProtoUnknown; }
12340
12341   bool using_spdy() const override { return false; }
12342
12343  private:
12344   RequestPriority priority_;
12345   HttpStreamRequest::Delegate* const delegate_;
12346   WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
12347
12348   DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12349 };
12350
12351 // Fake HttpStreamFactory that vends FakeStreamRequests.
12352 class FakeStreamFactory : public HttpStreamFactory {
12353  public:
12354   FakeStreamFactory() {}
12355   ~FakeStreamFactory() override {}
12356
12357   // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12358   // RequestStream() (which may be NULL if it was destroyed already).
12359   base::WeakPtr<FakeStreamRequest> last_stream_request() {
12360     return last_stream_request_;
12361   }
12362
12363   HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
12364                                    RequestPriority priority,
12365                                    const SSLConfig& server_ssl_config,
12366                                    const SSLConfig& proxy_ssl_config,
12367                                    HttpStreamRequest::Delegate* delegate,
12368                                    const BoundNetLog& net_log) override {
12369     FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
12370     last_stream_request_ = fake_request->AsWeakPtr();
12371     return fake_request;
12372   }
12373
12374   HttpStreamRequest* RequestWebSocketHandshakeStream(
12375       const HttpRequestInfo& info,
12376       RequestPriority priority,
12377       const SSLConfig& server_ssl_config,
12378       const SSLConfig& proxy_ssl_config,
12379       HttpStreamRequest::Delegate* delegate,
12380       WebSocketHandshakeStreamBase::CreateHelper* create_helper,
12381       const BoundNetLog& net_log) override {
12382     FakeStreamRequest* fake_request =
12383         new FakeStreamRequest(priority, delegate, create_helper);
12384     last_stream_request_ = fake_request->AsWeakPtr();
12385     return fake_request;
12386   }
12387
12388   void PreconnectStreams(int num_streams,
12389                          const HttpRequestInfo& info,
12390                          RequestPriority priority,
12391                          const SSLConfig& server_ssl_config,
12392                          const SSLConfig& proxy_ssl_config) override {
12393     ADD_FAILURE();
12394   }
12395
12396   const HostMappingRules* GetHostMappingRules() const override {
12397     ADD_FAILURE();
12398     return NULL;
12399   }
12400
12401  private:
12402   base::WeakPtr<FakeStreamRequest> last_stream_request_;
12403
12404   DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12405 };
12406
12407 // TODO(yhirano): Split this class out into a net/websockets file, if it is
12408 // worth doing.
12409 class FakeWebSocketStreamCreateHelper :
12410       public WebSocketHandshakeStreamBase::CreateHelper {
12411  public:
12412   WebSocketHandshakeStreamBase* CreateBasicStream(
12413       scoped_ptr<ClientSocketHandle> connection,
12414       bool using_proxy) override {
12415     NOTREACHED();
12416     return NULL;
12417   }
12418
12419   WebSocketHandshakeStreamBase* CreateSpdyStream(
12420       const base::WeakPtr<SpdySession>& session,
12421       bool use_relative_url) override {
12422     NOTREACHED();
12423     return NULL;
12424   };
12425
12426   ~FakeWebSocketStreamCreateHelper() override {}
12427
12428   virtual scoped_ptr<WebSocketStream> Upgrade() {
12429     NOTREACHED();
12430     return scoped_ptr<WebSocketStream>();
12431   }
12432 };
12433
12434 }  // namespace
12435
12436 // Make sure that HttpNetworkTransaction passes on its priority to its
12437 // stream request on start.
12438 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12439   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12440   HttpNetworkSessionPeer peer(session);
12441   FakeStreamFactory* fake_factory = new FakeStreamFactory();
12442   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
12443
12444   HttpNetworkTransaction trans(LOW, session.get());
12445
12446   ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12447
12448   HttpRequestInfo request;
12449   TestCompletionCallback callback;
12450   EXPECT_EQ(ERR_IO_PENDING,
12451             trans.Start(&request, callback.callback(), BoundNetLog()));
12452
12453   base::WeakPtr<FakeStreamRequest> fake_request =
12454       fake_factory->last_stream_request();
12455   ASSERT_TRUE(fake_request != NULL);
12456   EXPECT_EQ(LOW, fake_request->priority());
12457 }
12458
12459 // Make sure that HttpNetworkTransaction passes on its priority
12460 // updates to its stream request.
12461 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12462   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12463   HttpNetworkSessionPeer peer(session);
12464   FakeStreamFactory* fake_factory = new FakeStreamFactory();
12465   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
12466
12467   HttpNetworkTransaction trans(LOW, session.get());
12468
12469   HttpRequestInfo request;
12470   TestCompletionCallback callback;
12471   EXPECT_EQ(ERR_IO_PENDING,
12472             trans.Start(&request, callback.callback(), BoundNetLog()));
12473
12474   base::WeakPtr<FakeStreamRequest> fake_request =
12475       fake_factory->last_stream_request();
12476   ASSERT_TRUE(fake_request != NULL);
12477   EXPECT_EQ(LOW, fake_request->priority());
12478
12479   trans.SetPriority(LOWEST);
12480   ASSERT_TRUE(fake_request != NULL);
12481   EXPECT_EQ(LOWEST, fake_request->priority());
12482 }
12483
12484 // Make sure that HttpNetworkTransaction passes on its priority
12485 // updates to its stream.
12486 TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12487   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12488   HttpNetworkSessionPeer peer(session);
12489   FakeStreamFactory* fake_factory = new FakeStreamFactory();
12490   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
12491
12492   HttpNetworkTransaction trans(LOW, session.get());
12493
12494   HttpRequestInfo request;
12495   TestCompletionCallback callback;
12496   EXPECT_EQ(ERR_IO_PENDING,
12497             trans.Start(&request, callback.callback(), BoundNetLog()));
12498
12499   base::WeakPtr<FakeStreamRequest> fake_request =
12500       fake_factory->last_stream_request();
12501   ASSERT_TRUE(fake_request != NULL);
12502   base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12503   ASSERT_TRUE(fake_stream != NULL);
12504   EXPECT_EQ(LOW, fake_stream->priority());
12505
12506   trans.SetPriority(LOWEST);
12507   EXPECT_EQ(LOWEST, fake_stream->priority());
12508 }
12509
12510 TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12511   // The same logic needs to be tested for both ws: and wss: schemes, but this
12512   // test is already parameterised on NextProto, so it uses a loop to verify
12513   // that the different schemes work.
12514   std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12515   for (size_t i = 0; i < arraysize(test_cases); ++i) {
12516     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12517     HttpNetworkSessionPeer peer(session);
12518     FakeStreamFactory* fake_factory = new FakeStreamFactory();
12519     FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
12520     peer.SetHttpStreamFactoryForWebSocket(
12521         scoped_ptr<HttpStreamFactory>(fake_factory));
12522
12523     HttpNetworkTransaction trans(LOW, session.get());
12524     trans.SetWebSocketHandshakeStreamCreateHelper(
12525         &websocket_stream_create_helper);
12526
12527     HttpRequestInfo request;
12528     TestCompletionCallback callback;
12529     request.method = "GET";
12530     request.url = GURL(test_cases[i]);
12531
12532     EXPECT_EQ(ERR_IO_PENDING,
12533               trans.Start(&request, callback.callback(), BoundNetLog()));
12534
12535     base::WeakPtr<FakeStreamRequest> fake_request =
12536         fake_factory->last_stream_request();
12537     ASSERT_TRUE(fake_request != NULL);
12538     EXPECT_EQ(&websocket_stream_create_helper,
12539               fake_request->websocket_stream_create_helper());
12540   }
12541 }
12542
12543 // Tests that when a used socket is returned to the SSL socket pool, it's closed
12544 // if the transport socket pool is stalled on the global socket limit.
12545 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12546   ClientSocketPoolManager::set_max_sockets_per_group(
12547       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12548   ClientSocketPoolManager::set_max_sockets_per_pool(
12549       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12550
12551   // Set up SSL request.
12552
12553   HttpRequestInfo ssl_request;
12554   ssl_request.method = "GET";
12555   ssl_request.url = GURL("https://www.google.com/");
12556
12557   MockWrite ssl_writes[] = {
12558     MockWrite("GET / HTTP/1.1\r\n"
12559               "Host: www.google.com\r\n"
12560               "Connection: keep-alive\r\n\r\n"),
12561   };
12562   MockRead ssl_reads[] = {
12563     MockRead("HTTP/1.1 200 OK\r\n"),
12564     MockRead("Content-Length: 11\r\n\r\n"),
12565     MockRead("hello world"),
12566     MockRead(SYNCHRONOUS, OK),
12567   };
12568   StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12569                                     ssl_writes, arraysize(ssl_writes));
12570   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12571
12572   SSLSocketDataProvider ssl(ASYNC, OK);
12573   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12574
12575   // Set up HTTP request.
12576
12577   HttpRequestInfo http_request;
12578   http_request.method = "GET";
12579   http_request.url = GURL("http://www.google.com/");
12580
12581   MockWrite http_writes[] = {
12582     MockWrite("GET / HTTP/1.1\r\n"
12583               "Host: www.google.com\r\n"
12584               "Connection: keep-alive\r\n\r\n"),
12585   };
12586   MockRead http_reads[] = {
12587     MockRead("HTTP/1.1 200 OK\r\n"),
12588     MockRead("Content-Length: 7\r\n\r\n"),
12589     MockRead("falafel"),
12590     MockRead(SYNCHRONOUS, OK),
12591   };
12592   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12593                                      http_writes, arraysize(http_writes));
12594   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12595
12596   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12597
12598   // Start the SSL request.
12599   TestCompletionCallback ssl_callback;
12600   scoped_ptr<HttpTransaction> ssl_trans(
12601       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12602   ASSERT_EQ(ERR_IO_PENDING,
12603             ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12604             BoundNetLog()));
12605
12606   // Start the HTTP request.  Pool should stall.
12607   TestCompletionCallback http_callback;
12608   scoped_ptr<HttpTransaction> http_trans(
12609       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12610   ASSERT_EQ(ERR_IO_PENDING,
12611             http_trans->Start(&http_request, http_callback.callback(),
12612                               BoundNetLog()));
12613   EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
12614
12615   // Wait for response from SSL request.
12616   ASSERT_EQ(OK, ssl_callback.WaitForResult());
12617   std::string response_data;
12618   ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12619   EXPECT_EQ("hello world", response_data);
12620
12621   // The SSL socket should automatically be closed, so the HTTP request can
12622   // start.
12623   EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
12624   ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
12625
12626   // The HTTP request can now complete.
12627   ASSERT_EQ(OK, http_callback.WaitForResult());
12628   ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12629   EXPECT_EQ("falafel", response_data);
12630
12631   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12632 }
12633
12634 // Tests that when a SSL connection is established but there's no corresponding
12635 // request that needs it, the new socket is closed if the transport socket pool
12636 // is stalled on the global socket limit.
12637 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12638   ClientSocketPoolManager::set_max_sockets_per_group(
12639       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12640   ClientSocketPoolManager::set_max_sockets_per_pool(
12641       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12642
12643   // Set up an ssl request.
12644
12645   HttpRequestInfo ssl_request;
12646   ssl_request.method = "GET";
12647   ssl_request.url = GURL("https://www.foopy.com/");
12648
12649   // No data will be sent on the SSL socket.
12650   StaticSocketDataProvider ssl_data;
12651   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12652
12653   SSLSocketDataProvider ssl(ASYNC, OK);
12654   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12655
12656   // Set up HTTP request.
12657
12658   HttpRequestInfo http_request;
12659   http_request.method = "GET";
12660   http_request.url = GURL("http://www.google.com/");
12661
12662   MockWrite http_writes[] = {
12663     MockWrite("GET / HTTP/1.1\r\n"
12664               "Host: www.google.com\r\n"
12665               "Connection: keep-alive\r\n\r\n"),
12666   };
12667   MockRead http_reads[] = {
12668     MockRead("HTTP/1.1 200 OK\r\n"),
12669     MockRead("Content-Length: 7\r\n\r\n"),
12670     MockRead("falafel"),
12671     MockRead(SYNCHRONOUS, OK),
12672   };
12673   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12674                                      http_writes, arraysize(http_writes));
12675   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12676
12677   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12678
12679   // Preconnect an SSL socket.  A preconnect is needed because connect jobs are
12680   // cancelled when a normal transaction is cancelled.
12681   net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12682   net::SSLConfig ssl_config;
12683   session->ssl_config_service()->GetSSLConfig(&ssl_config);
12684   http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12685                                          ssl_config, ssl_config);
12686   EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
12687
12688   // Start the HTTP request.  Pool should stall.
12689   TestCompletionCallback http_callback;
12690   scoped_ptr<HttpTransaction> http_trans(
12691       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12692   ASSERT_EQ(ERR_IO_PENDING,
12693             http_trans->Start(&http_request, http_callback.callback(),
12694                               BoundNetLog()));
12695   EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
12696
12697   // The SSL connection will automatically be closed once the connection is
12698   // established, to let the HTTP request start.
12699   ASSERT_EQ(OK, http_callback.WaitForResult());
12700   std::string response_data;
12701   ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12702   EXPECT_EQ("falafel", response_data);
12703
12704   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
12705 }
12706
12707 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
12708   ScopedVector<UploadElementReader> element_readers;
12709   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12710   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
12711
12712   HttpRequestInfo request;
12713   request.method = "POST";
12714   request.url = GURL("http://www.foo.com/");
12715   request.upload_data_stream = &upload_data_stream;
12716   request.load_flags = 0;
12717
12718   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12719   scoped_ptr<HttpTransaction> trans(
12720       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12721   // Send headers successfully, but get an error while sending the body.
12722   MockWrite data_writes[] = {
12723     MockWrite("POST / HTTP/1.1\r\n"
12724               "Host: www.foo.com\r\n"
12725               "Connection: keep-alive\r\n"
12726               "Content-Length: 3\r\n\r\n"),
12727     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12728   };
12729
12730   MockRead data_reads[] = {
12731     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12732     MockRead("hello world"),
12733     MockRead(SYNCHRONOUS, OK),
12734   };
12735   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12736                                 arraysize(data_writes));
12737   session_deps_.socket_factory->AddSocketDataProvider(&data);
12738
12739   TestCompletionCallback callback;
12740
12741   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12742   EXPECT_EQ(ERR_IO_PENDING, rv);
12743
12744   rv = callback.WaitForResult();
12745   EXPECT_EQ(OK, rv);
12746
12747   const HttpResponseInfo* response = trans->GetResponseInfo();
12748   ASSERT_TRUE(response != NULL);
12749
12750   EXPECT_TRUE(response->headers.get() != NULL);
12751   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12752
12753   std::string response_data;
12754   rv = ReadTransaction(trans.get(), &response_data);
12755   EXPECT_EQ(OK, rv);
12756   EXPECT_EQ("hello world", response_data);
12757 }
12758
12759 // This test makes sure the retry logic doesn't trigger when reading an error
12760 // response from a server that rejected a POST with a CONNECTION_RESET.
12761 TEST_P(HttpNetworkTransactionTest,
12762        PostReadsErrorResponseAfterResetOnReusedSocket) {
12763   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12764   MockWrite data_writes[] = {
12765     MockWrite("GET / HTTP/1.1\r\n"
12766               "Host: www.foo.com\r\n"
12767               "Connection: keep-alive\r\n\r\n"),
12768     MockWrite("POST / HTTP/1.1\r\n"
12769               "Host: www.foo.com\r\n"
12770               "Connection: keep-alive\r\n"
12771               "Content-Length: 3\r\n\r\n"),
12772     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12773   };
12774
12775   MockRead data_reads[] = {
12776     MockRead("HTTP/1.1 200 Peachy\r\n"
12777              "Content-Length: 14\r\n\r\n"),
12778     MockRead("first response"),
12779     MockRead("HTTP/1.1 400 Not OK\r\n"
12780              "Content-Length: 15\r\n\r\n"),
12781     MockRead("second response"),
12782     MockRead(SYNCHRONOUS, OK),
12783   };
12784   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12785                                 arraysize(data_writes));
12786   session_deps_.socket_factory->AddSocketDataProvider(&data);
12787
12788   TestCompletionCallback callback;
12789   HttpRequestInfo request1;
12790   request1.method = "GET";
12791   request1.url = GURL("http://www.foo.com/");
12792   request1.load_flags = 0;
12793
12794   scoped_ptr<HttpTransaction> trans1(
12795       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12796   int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
12797   EXPECT_EQ(ERR_IO_PENDING, rv);
12798
12799   rv = callback.WaitForResult();
12800   EXPECT_EQ(OK, rv);
12801
12802   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12803   ASSERT_TRUE(response1 != NULL);
12804
12805   EXPECT_TRUE(response1->headers.get() != NULL);
12806   EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
12807
12808   std::string response_data1;
12809   rv = ReadTransaction(trans1.get(), &response_data1);
12810   EXPECT_EQ(OK, rv);
12811   EXPECT_EQ("first response", response_data1);
12812   // Delete the transaction to release the socket back into the socket pool.
12813   trans1.reset();
12814
12815   ScopedVector<UploadElementReader> element_readers;
12816   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12817   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
12818
12819   HttpRequestInfo request2;
12820   request2.method = "POST";
12821   request2.url = GURL("http://www.foo.com/");
12822   request2.upload_data_stream = &upload_data_stream;
12823   request2.load_flags = 0;
12824
12825   scoped_ptr<HttpTransaction> trans2(
12826       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12827   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
12828   EXPECT_EQ(ERR_IO_PENDING, rv);
12829
12830   rv = callback.WaitForResult();
12831   EXPECT_EQ(OK, rv);
12832
12833   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
12834   ASSERT_TRUE(response2 != NULL);
12835
12836   EXPECT_TRUE(response2->headers.get() != NULL);
12837   EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
12838
12839   std::string response_data2;
12840   rv = ReadTransaction(trans2.get(), &response_data2);
12841   EXPECT_EQ(OK, rv);
12842   EXPECT_EQ("second response", response_data2);
12843 }
12844
12845 TEST_P(HttpNetworkTransactionTest,
12846        PostReadsErrorResponseAfterResetPartialBodySent) {
12847   ScopedVector<UploadElementReader> element_readers;
12848   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12849   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
12850
12851   HttpRequestInfo request;
12852   request.method = "POST";
12853   request.url = GURL("http://www.foo.com/");
12854   request.upload_data_stream = &upload_data_stream;
12855   request.load_flags = 0;
12856
12857   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12858   scoped_ptr<HttpTransaction> trans(
12859       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12860   // Send headers successfully, but get an error while sending the body.
12861   MockWrite data_writes[] = {
12862     MockWrite("POST / HTTP/1.1\r\n"
12863               "Host: www.foo.com\r\n"
12864               "Connection: keep-alive\r\n"
12865               "Content-Length: 3\r\n\r\n"
12866               "fo"),
12867     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12868   };
12869
12870   MockRead data_reads[] = {
12871     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12872     MockRead("hello world"),
12873     MockRead(SYNCHRONOUS, OK),
12874   };
12875   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12876                                 arraysize(data_writes));
12877   session_deps_.socket_factory->AddSocketDataProvider(&data);
12878
12879   TestCompletionCallback callback;
12880
12881   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12882   EXPECT_EQ(ERR_IO_PENDING, rv);
12883
12884   rv = callback.WaitForResult();
12885   EXPECT_EQ(OK, rv);
12886
12887   const HttpResponseInfo* response = trans->GetResponseInfo();
12888   ASSERT_TRUE(response != NULL);
12889
12890   EXPECT_TRUE(response->headers.get() != NULL);
12891   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12892
12893   std::string response_data;
12894   rv = ReadTransaction(trans.get(), &response_data);
12895   EXPECT_EQ(OK, rv);
12896   EXPECT_EQ("hello world", response_data);
12897 }
12898
12899 // This tests the more common case than the previous test, where headers and
12900 // body are not merged into a single request.
12901 TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
12902   ScopedVector<UploadElementReader> element_readers;
12903   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12904   ChunkedUploadDataStream upload_data_stream(0);
12905
12906   HttpRequestInfo request;
12907   request.method = "POST";
12908   request.url = GURL("http://www.foo.com/");
12909   request.upload_data_stream = &upload_data_stream;
12910   request.load_flags = 0;
12911
12912   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12913   scoped_ptr<HttpTransaction> trans(
12914       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12915   // Send headers successfully, but get an error while sending the body.
12916   MockWrite data_writes[] = {
12917     MockWrite("POST / HTTP/1.1\r\n"
12918               "Host: www.foo.com\r\n"
12919               "Connection: keep-alive\r\n"
12920               "Transfer-Encoding: chunked\r\n\r\n"),
12921     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12922   };
12923
12924   MockRead data_reads[] = {
12925     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12926     MockRead("hello world"),
12927     MockRead(SYNCHRONOUS, OK),
12928   };
12929   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12930                                 arraysize(data_writes));
12931   session_deps_.socket_factory->AddSocketDataProvider(&data);
12932
12933   TestCompletionCallback callback;
12934
12935   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12936   EXPECT_EQ(ERR_IO_PENDING, rv);
12937   // Make sure the headers are sent before adding a chunk.  This ensures that
12938   // they can't be merged with the body in a single send.  Not currently
12939   // necessary since a chunked body is never merged with headers, but this makes
12940   // the test more future proof.
12941   base::RunLoop().RunUntilIdle();
12942
12943   upload_data_stream.AppendData("last chunk", 10, true);
12944
12945   rv = callback.WaitForResult();
12946   EXPECT_EQ(OK, rv);
12947
12948   const HttpResponseInfo* response = trans->GetResponseInfo();
12949   ASSERT_TRUE(response != NULL);
12950
12951   EXPECT_TRUE(response->headers.get() != NULL);
12952   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12953
12954   std::string response_data;
12955   rv = ReadTransaction(trans.get(), &response_data);
12956   EXPECT_EQ(OK, rv);
12957   EXPECT_EQ("hello world", response_data);
12958 }
12959
12960 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
12961   ScopedVector<UploadElementReader> element_readers;
12962   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12963   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
12964
12965   HttpRequestInfo request;
12966   request.method = "POST";
12967   request.url = GURL("http://www.foo.com/");
12968   request.upload_data_stream = &upload_data_stream;
12969   request.load_flags = 0;
12970
12971   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12972   scoped_ptr<HttpTransaction> trans(
12973       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12974
12975   MockWrite data_writes[] = {
12976     MockWrite("POST / HTTP/1.1\r\n"
12977               "Host: www.foo.com\r\n"
12978               "Connection: keep-alive\r\n"
12979               "Content-Length: 3\r\n\r\n"),
12980     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12981   };
12982
12983   MockRead data_reads[] = {
12984     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
12985     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12986     MockRead("hello world"),
12987     MockRead(SYNCHRONOUS, OK),
12988   };
12989   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12990                                 arraysize(data_writes));
12991   session_deps_.socket_factory->AddSocketDataProvider(&data);
12992
12993   TestCompletionCallback callback;
12994
12995   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12996   EXPECT_EQ(ERR_IO_PENDING, rv);
12997
12998   rv = callback.WaitForResult();
12999   EXPECT_EQ(OK, rv);
13000
13001   const HttpResponseInfo* response = trans->GetResponseInfo();
13002   ASSERT_TRUE(response != NULL);
13003
13004   EXPECT_TRUE(response->headers.get() != NULL);
13005   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13006
13007   std::string response_data;
13008   rv = ReadTransaction(trans.get(), &response_data);
13009   EXPECT_EQ(OK, rv);
13010   EXPECT_EQ("hello world", response_data);
13011 }
13012
13013 TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13014   ScopedVector<UploadElementReader> element_readers;
13015   element_readers.push_back(new UploadBytesElementReader("foo", 3));
13016   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
13017
13018   HttpRequestInfo request;
13019   request.method = "POST";
13020   request.url = GURL("http://www.foo.com/");
13021   request.upload_data_stream = &upload_data_stream;
13022   request.load_flags = 0;
13023
13024   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13025   scoped_ptr<HttpTransaction> trans(
13026       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13027   // Send headers successfully, but get an error while sending the body.
13028   MockWrite data_writes[] = {
13029     MockWrite("POST / HTTP/1.1\r\n"
13030               "Host: www.foo.com\r\n"
13031               "Connection: keep-alive\r\n"
13032               "Content-Length: 3\r\n\r\n"),
13033     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13034   };
13035
13036   MockRead data_reads[] = {
13037     MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13038     MockRead("hello world"),
13039     MockRead(SYNCHRONOUS, OK),
13040   };
13041   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13042                                 arraysize(data_writes));
13043   session_deps_.socket_factory->AddSocketDataProvider(&data);
13044
13045   TestCompletionCallback callback;
13046
13047   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13048   EXPECT_EQ(ERR_IO_PENDING, rv);
13049
13050   rv = callback.WaitForResult();
13051   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13052
13053   const HttpResponseInfo* response = trans->GetResponseInfo();
13054   EXPECT_TRUE(response == NULL);
13055 }
13056
13057 TEST_P(HttpNetworkTransactionTest,
13058        PostIgnoresNonErrorResponseAfterResetAnd100) {
13059   ScopedVector<UploadElementReader> element_readers;
13060   element_readers.push_back(new UploadBytesElementReader("foo", 3));
13061   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
13062
13063   HttpRequestInfo request;
13064   request.method = "POST";
13065   request.url = GURL("http://www.foo.com/");
13066   request.upload_data_stream = &upload_data_stream;
13067   request.load_flags = 0;
13068
13069   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13070   scoped_ptr<HttpTransaction> trans(
13071       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13072   // Send headers successfully, but get an error while sending the body.
13073   MockWrite data_writes[] = {
13074     MockWrite("POST / HTTP/1.1\r\n"
13075               "Host: www.foo.com\r\n"
13076               "Connection: keep-alive\r\n"
13077               "Content-Length: 3\r\n\r\n"),
13078     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13079   };
13080
13081   MockRead data_reads[] = {
13082     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13083     MockRead("HTTP/1.0 302 Redirect\r\n"),
13084     MockRead("Location: http://somewhere-else.com/\r\n"),
13085     MockRead("Content-Length: 0\r\n\r\n"),
13086     MockRead(SYNCHRONOUS, OK),
13087   };
13088   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13089                                 arraysize(data_writes));
13090   session_deps_.socket_factory->AddSocketDataProvider(&data);
13091
13092   TestCompletionCallback callback;
13093
13094   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13095   EXPECT_EQ(ERR_IO_PENDING, rv);
13096
13097   rv = callback.WaitForResult();
13098   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13099
13100   const HttpResponseInfo* response = trans->GetResponseInfo();
13101   EXPECT_TRUE(response == NULL);
13102 }
13103
13104 TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13105   ScopedVector<UploadElementReader> element_readers;
13106   element_readers.push_back(new UploadBytesElementReader("foo", 3));
13107   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
13108
13109   HttpRequestInfo request;
13110   request.method = "POST";
13111   request.url = GURL("http://www.foo.com/");
13112   request.upload_data_stream = &upload_data_stream;
13113   request.load_flags = 0;
13114
13115   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13116   scoped_ptr<HttpTransaction> trans(
13117       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13118   // Send headers successfully, but get an error while sending the body.
13119   MockWrite data_writes[] = {
13120     MockWrite("POST / HTTP/1.1\r\n"
13121               "Host: www.foo.com\r\n"
13122               "Connection: keep-alive\r\n"
13123               "Content-Length: 3\r\n\r\n"),
13124     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13125   };
13126
13127   MockRead data_reads[] = {
13128     MockRead("HTTP 0.9 rocks!"),
13129     MockRead(SYNCHRONOUS, OK),
13130   };
13131   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13132                                 arraysize(data_writes));
13133   session_deps_.socket_factory->AddSocketDataProvider(&data);
13134
13135   TestCompletionCallback callback;
13136
13137   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13138   EXPECT_EQ(ERR_IO_PENDING, rv);
13139
13140   rv = callback.WaitForResult();
13141   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13142
13143   const HttpResponseInfo* response = trans->GetResponseInfo();
13144   EXPECT_TRUE(response == NULL);
13145 }
13146
13147 TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13148   ScopedVector<UploadElementReader> element_readers;
13149   element_readers.push_back(new UploadBytesElementReader("foo", 3));
13150   ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
13151
13152   HttpRequestInfo request;
13153   request.method = "POST";
13154   request.url = GURL("http://www.foo.com/");
13155   request.upload_data_stream = &upload_data_stream;
13156   request.load_flags = 0;
13157
13158   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13159   scoped_ptr<HttpTransaction> trans(
13160       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13161   // Send headers successfully, but get an error while sending the body.
13162   MockWrite data_writes[] = {
13163     MockWrite("POST / HTTP/1.1\r\n"
13164               "Host: www.foo.com\r\n"
13165               "Connection: keep-alive\r\n"
13166               "Content-Length: 3\r\n\r\n"),
13167     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13168   };
13169
13170   MockRead data_reads[] = {
13171     MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13172     MockRead(SYNCHRONOUS, OK),
13173   };
13174   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13175                                 arraysize(data_writes));
13176   session_deps_.socket_factory->AddSocketDataProvider(&data);
13177
13178   TestCompletionCallback callback;
13179
13180   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13181   EXPECT_EQ(ERR_IO_PENDING, rv);
13182
13183   rv = callback.WaitForResult();
13184   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13185
13186   const HttpResponseInfo* response = trans->GetResponseInfo();
13187   EXPECT_TRUE(response == NULL);
13188 }
13189
13190 }  // namespace net