Upstream version 9.38.198.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/file_util.h"
15 #include "base/files/file_path.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/completion_callback.h"
26 #include "net/base/load_timing_info.h"
27 #include "net/base/load_timing_info_test_util.h"
28 #include "net/base/net_log.h"
29 #include "net/base/net_log_unittest.h"
30 #include "net/base/request_priority.h"
31 #include "net/base/test_completion_callback.h"
32 #include "net/base/test_data_directory.h"
33 #include "net/base/upload_bytes_element_reader.h"
34 #include "net/base/upload_data_stream.h"
35 #include "net/base/upload_file_element_reader.h"
36 #include "net/cert/mock_cert_verifier.h"
37 #include "net/dns/host_cache.h"
38 #include "net/dns/mock_host_resolver.h"
39 #include "net/http/http_auth_challenge_tokenizer.h"
40 #include "net/http/http_auth_handler_digest.h"
41 #include "net/http/http_auth_handler_mock.h"
42 #include "net/http/http_auth_handler_ntlm.h"
43 #include "net/http/http_basic_stream.h"
44 #include "net/http/http_network_session.h"
45 #include "net/http/http_network_session_peer.h"
46 #include "net/http/http_server_properties_impl.h"
47 #include "net/http/http_stream.h"
48 #include "net/http/http_stream_factory.h"
49 #include "net/http/http_transaction_test_util.h"
50 #include "net/proxy/proxy_config_service_fixed.h"
51 #include "net/proxy/proxy_info.h"
52 #include "net/proxy/proxy_resolver.h"
53 #include "net/proxy/proxy_service.h"
54 #include "net/socket/client_socket_factory.h"
55 #include "net/socket/client_socket_pool_manager.h"
56 #include "net/socket/mock_client_socket_pool_manager.h"
57 #include "net/socket/next_proto.h"
58 #include "net/socket/socket_test_util.h"
59 #include "net/socket/ssl_client_socket.h"
60 #include "net/spdy/spdy_framer.h"
61 #include "net/spdy/spdy_session.h"
62 #include "net/spdy/spdy_session_pool.h"
63 #include "net/spdy/spdy_test_util_common.h"
64 #include "net/ssl/ssl_cert_request_info.h"
65 #include "net/ssl/ssl_config_service.h"
66 #include "net/ssl/ssl_config_service_defaults.h"
67 #include "net/ssl/ssl_info.h"
68 #include "net/test/cert_test_util.h"
69 #include "net/websockets/websocket_handshake_stream_base.h"
70 #include "testing/gtest/include/gtest/gtest.h"
71 #include "testing/platform_test.h"
72 #include "url/gurl.h"
73
74 using base::ASCIIToUTF16;
75
76 //-----------------------------------------------------------------------------
77
78 namespace {
79
80 const base::string16 kBar(ASCIIToUTF16("bar"));
81 const base::string16 kBar2(ASCIIToUTF16("bar2"));
82 const base::string16 kBar3(ASCIIToUTF16("bar3"));
83 const base::string16 kBaz(ASCIIToUTF16("baz"));
84 const base::string16 kFirst(ASCIIToUTF16("first"));
85 const base::string16 kFoo(ASCIIToUTF16("foo"));
86 const base::string16 kFoo2(ASCIIToUTF16("foo2"));
87 const base::string16 kFoo3(ASCIIToUTF16("foo3"));
88 const base::string16 kFou(ASCIIToUTF16("fou"));
89 const base::string16 kSecond(ASCIIToUTF16("second"));
90 const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
91 const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
92
93 int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
94   return session->GetTransportSocketPool(
95       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
96 }
97
98 int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
99   return session->GetSSLSocketPool(
100       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
101 }
102
103 bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
104   return session->GetTransportSocketPool(
105       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
106 }
107
108 // Takes in a Value created from a NetLogHttpResponseParameter, and returns
109 // a JSONified list of headers as a single string.  Uses single quotes instead
110 // of double quotes for easier comparison.  Returns false on failure.
111 bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
112   if (!params)
113     return false;
114   base::ListValue* header_list;
115   if (!params->GetList("headers", &header_list))
116     return false;
117   std::string double_quote_headers;
118   base::JSONWriter::Write(header_list, &double_quote_headers);
119   base::ReplaceChars(double_quote_headers, "\"", "'", headers);
120   return true;
121 }
122
123 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is
124 // used.
125 void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
126   EXPECT_TRUE(load_timing_info.socket_reused);
127   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
128
129   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
130   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
131
132   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
133   EXPECT_FALSE(load_timing_info.send_start.is_null());
134
135   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
136
137   // Set at a higher level.
138   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
139   EXPECT_TRUE(load_timing_info.request_start.is_null());
140   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
141 }
142
143 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is
144 // used.
145 void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
146                              int connect_timing_flags) {
147   EXPECT_FALSE(load_timing_info.socket_reused);
148   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
149
150   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
151   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
152
153   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
154                                    connect_timing_flags);
155   EXPECT_LE(load_timing_info.connect_timing.connect_end,
156             load_timing_info.send_start);
157
158   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
159
160   // Set at a higher level.
161   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
162   EXPECT_TRUE(load_timing_info.request_start.is_null());
163   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
164 }
165
166 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is
167 // used.
168 void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
169   EXPECT_TRUE(load_timing_info.socket_reused);
170   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
171
172   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
173
174   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
175   EXPECT_LE(load_timing_info.proxy_resolve_start,
176             load_timing_info.proxy_resolve_end);
177   EXPECT_LE(load_timing_info.proxy_resolve_end,
178             load_timing_info.send_start);
179   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
180
181   // Set at a higher level.
182   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
183   EXPECT_TRUE(load_timing_info.request_start.is_null());
184   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
185 }
186
187 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is
188 // used.
189 void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
190                                     int connect_timing_flags) {
191   EXPECT_FALSE(load_timing_info.socket_reused);
192   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
193
194   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
195   EXPECT_LE(load_timing_info.proxy_resolve_start,
196             load_timing_info.proxy_resolve_end);
197   EXPECT_LE(load_timing_info.proxy_resolve_end,
198             load_timing_info.connect_timing.connect_start);
199   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
200                                    connect_timing_flags);
201   EXPECT_LE(load_timing_info.connect_timing.connect_end,
202             load_timing_info.send_start);
203
204   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
205
206   // Set at a higher level.
207   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
208   EXPECT_TRUE(load_timing_info.request_start.is_null());
209   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
210 }
211
212 }  // namespace
213
214 namespace net {
215
216 namespace {
217
218 HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
219   return SpdySessionDependencies::SpdyCreateSession(session_deps);
220 }
221
222 }  // namespace
223
224 class HttpNetworkTransactionTest
225     : public PlatformTest,
226       public ::testing::WithParamInterface<NextProto> {
227  public:
228   virtual ~HttpNetworkTransactionTest() {
229     // Important to restore the per-pool limit first, since the pool limit must
230     // always be greater than group limit, and the tests reduce both limits.
231     ClientSocketPoolManager::set_max_sockets_per_pool(
232         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
233     ClientSocketPoolManager::set_max_sockets_per_group(
234         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
235   }
236
237  protected:
238   HttpNetworkTransactionTest()
239       : spdy_util_(GetParam()),
240         session_deps_(GetParam()),
241         old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
242             HttpNetworkSession::NORMAL_SOCKET_POOL)),
243         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
244             HttpNetworkSession::NORMAL_SOCKET_POOL)) {
245   }
246
247   struct SimpleGetHelperResult {
248     int rv;
249     std::string status_line;
250     std::string response_data;
251     int64 totalReceivedBytes;
252     LoadTimingInfo load_timing_info;
253   };
254
255   virtual void SetUp() {
256     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
257     base::MessageLoop::current()->RunUntilIdle();
258   }
259
260   virtual void TearDown() {
261     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
262     base::MessageLoop::current()->RunUntilIdle();
263     // Empty the current queue.
264     base::MessageLoop::current()->RunUntilIdle();
265     PlatformTest::TearDown();
266     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
267     base::MessageLoop::current()->RunUntilIdle();
268   }
269
270   // This is the expected return from a current server advertising SPDY.
271   std::string GetAlternateProtocolHttpHeader() {
272     return
273         std::string("Alternate-Protocol: 443:") +
274         AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
275         "\r\n\r\n";
276   }
277
278   // Either |write_failure| specifies a write failure or |read_failure|
279   // specifies a read failure when using a reused socket.  In either case, the
280   // failure should cause the network transaction to resend the request, and the
281   // other argument should be NULL.
282   void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
283                                             const MockRead* read_failure);
284
285   // Either |write_failure| specifies a write failure or |read_failure|
286   // specifies a read failure when using a reused socket.  In either case, the
287   // failure should cause the network transaction to resend the request, and the
288   // other argument should be NULL.
289   void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
290                                         const MockRead* read_failure,
291                                         bool use_spdy);
292
293   SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
294                                                size_t data_count) {
295     SimpleGetHelperResult out;
296
297     HttpRequestInfo request;
298     request.method = "GET";
299     request.url = GURL("http://www.google.com/");
300     request.load_flags = 0;
301
302     CapturingBoundNetLog log;
303     session_deps_.net_log = log.bound().net_log();
304     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
305     scoped_ptr<HttpTransaction> trans(
306         new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
307
308     for (size_t i = 0; i < data_count; ++i) {
309       session_deps_.socket_factory->AddSocketDataProvider(data[i]);
310     }
311
312     TestCompletionCallback callback;
313
314     EXPECT_TRUE(log.bound().IsLogging());
315     int rv = trans->Start(&request, callback.callback(), log.bound());
316     EXPECT_EQ(ERR_IO_PENDING, rv);
317
318     out.rv = callback.WaitForResult();
319
320     // Even in the failure cases that use this function, connections are always
321     // successfully established before the error.
322     EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
323     TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
324
325     if (out.rv != OK)
326       return out;
327
328     const HttpResponseInfo* response = trans->GetResponseInfo();
329     // Can't use ASSERT_* inside helper functions like this, so
330     // return an error.
331     if (response == NULL || response->headers.get() == NULL) {
332       out.rv = ERR_UNEXPECTED;
333       return out;
334     }
335     out.status_line = response->headers->GetStatusLine();
336
337     EXPECT_EQ("127.0.0.1", response->socket_address.host());
338     EXPECT_EQ(80, response->socket_address.port());
339
340     rv = ReadTransaction(trans.get(), &out.response_data);
341     EXPECT_EQ(OK, rv);
342
343     net::CapturingNetLog::CapturedEntryList entries;
344     log.GetEntries(&entries);
345     size_t pos = ExpectLogContainsSomewhere(
346         entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
347         NetLog::PHASE_NONE);
348     ExpectLogContainsSomewhere(
349         entries, pos,
350         NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
351         NetLog::PHASE_NONE);
352
353     std::string line;
354     EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
355     EXPECT_EQ("GET / HTTP/1.1\r\n", line);
356
357     HttpRequestHeaders request_headers;
358     EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
359     std::string value;
360     EXPECT_TRUE(request_headers.GetHeader("Host", &value));
361     EXPECT_EQ("www.google.com", value);
362     EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
363     EXPECT_EQ("keep-alive", value);
364
365     std::string response_headers;
366     EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
367     EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
368               response_headers);
369
370     out.totalReceivedBytes = trans->GetTotalReceivedBytes();
371     return out;
372   }
373
374   SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
375                                         size_t reads_count) {
376     StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
377     StaticSocketDataProvider* data[] = { &reads };
378     return SimpleGetHelperForData(data, 1);
379   }
380
381   int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
382     int64 size = 0;
383     for (size_t i = 0; i < reads_count; ++i)
384       size += data_reads[i].data_len;
385     return size;
386   }
387
388   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
389                                              int expected_status);
390
391   void ConnectStatusHelper(const MockRead& status);
392
393   void BypassHostCacheOnRefreshHelper(int load_flags);
394
395   void CheckErrorIsPassedBack(int error, IoMode mode);
396
397   SpdyTestUtil spdy_util_;
398   SpdySessionDependencies session_deps_;
399
400   // Original socket limits.  Some tests set these.  Safest to always restore
401   // them once each test has been run.
402   int old_max_group_sockets_;
403   int old_max_pool_sockets_;
404 };
405
406 INSTANTIATE_TEST_CASE_P(
407     NextProto,
408     HttpNetworkTransactionTest,
409     testing::Values(kProtoDeprecatedSPDY2,
410                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
411
412 namespace {
413
414 class BeforeNetworkStartHandler {
415  public:
416   explicit BeforeNetworkStartHandler(bool defer)
417       : defer_on_before_network_start_(defer),
418         observed_before_network_start_(false) {}
419
420   void OnBeforeNetworkStart(bool* defer) {
421     *defer = defer_on_before_network_start_;
422     observed_before_network_start_ = true;
423   }
424
425   bool observed_before_network_start() const {
426     return observed_before_network_start_;
427   }
428
429  private:
430   const bool defer_on_before_network_start_;
431   bool observed_before_network_start_;
432
433   DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
434 };
435
436 class BeforeProxyHeadersSentHandler {
437  public:
438   BeforeProxyHeadersSentHandler()
439       : observed_before_proxy_headers_sent_(false) {}
440
441   void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
442                                 HttpRequestHeaders* request_headers) {
443     observed_before_proxy_headers_sent_ = true;
444     observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
445   }
446
447   bool observed_before_proxy_headers_sent() const {
448     return observed_before_proxy_headers_sent_;
449   }
450
451   std::string observed_proxy_server_uri() const {
452     return observed_proxy_server_uri_;
453   }
454
455  private:
456   bool observed_before_proxy_headers_sent_;
457   std::string observed_proxy_server_uri_;
458
459   DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
460 };
461
462 // Fill |str| with a long header list that consumes >= |size| bytes.
463 void FillLargeHeadersString(std::string* str, int size) {
464   const char* row =
465       "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
466   const int sizeof_row = strlen(row);
467   const int num_rows = static_cast<int>(
468       ceil(static_cast<float>(size) / sizeof_row));
469   const int sizeof_data = num_rows * sizeof_row;
470   DCHECK(sizeof_data >= size);
471   str->reserve(sizeof_data);
472
473   for (int i = 0; i < num_rows; ++i)
474     str->append(row, sizeof_row);
475 }
476
477 // Alternative functions that eliminate randomness and dependency on the local
478 // host name so that the generated NTLM messages are reproducible.
479 void MockGenerateRandom1(uint8* output, size_t n) {
480   static const uint8 bytes[] = {
481     0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
482   };
483   static size_t current_byte = 0;
484   for (size_t i = 0; i < n; ++i) {
485     output[i] = bytes[current_byte++];
486     current_byte %= arraysize(bytes);
487   }
488 }
489
490 void MockGenerateRandom2(uint8* output, size_t n) {
491   static const uint8 bytes[] = {
492     0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
493     0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
494   };
495   static size_t current_byte = 0;
496   for (size_t i = 0; i < n; ++i) {
497     output[i] = bytes[current_byte++];
498     current_byte %= arraysize(bytes);
499   }
500 }
501
502 std::string MockGetHostName() {
503   return "WTC-WIN7";
504 }
505
506 template<typename ParentPool>
507 class CaptureGroupNameSocketPool : public ParentPool {
508  public:
509   CaptureGroupNameSocketPool(HostResolver* host_resolver,
510                              CertVerifier* cert_verifier);
511
512   const std::string last_group_name_received() const {
513     return last_group_name_;
514   }
515
516   virtual int RequestSocket(const std::string& group_name,
517                             const void* socket_params,
518                             RequestPriority priority,
519                             ClientSocketHandle* handle,
520                             const CompletionCallback& callback,
521                             const BoundNetLog& net_log) {
522     last_group_name_ = group_name;
523     return ERR_IO_PENDING;
524   }
525   virtual void CancelRequest(const std::string& group_name,
526                              ClientSocketHandle* handle) {}
527   virtual void ReleaseSocket(const std::string& group_name,
528                              scoped_ptr<StreamSocket> socket,
529                              int id) {}
530   virtual void CloseIdleSockets() {}
531   virtual int IdleSocketCount() const {
532     return 0;
533   }
534   virtual int IdleSocketCountInGroup(const std::string& group_name) const {
535     return 0;
536   }
537   virtual LoadState GetLoadState(const std::string& group_name,
538                                  const ClientSocketHandle* handle) const {
539     return LOAD_STATE_IDLE;
540   }
541   virtual base::TimeDelta ConnectionTimeout() const {
542     return base::TimeDelta();
543   }
544
545  private:
546   std::string last_group_name_;
547 };
548
549 typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
550 CaptureGroupNameTransportSocketPool;
551 typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
552 CaptureGroupNameHttpProxySocketPool;
553 typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
554 CaptureGroupNameSOCKSSocketPool;
555 typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
556 CaptureGroupNameSSLSocketPool;
557
558 template<typename ParentPool>
559 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
560     HostResolver* host_resolver,
561     CertVerifier* /* cert_verifier */)
562     : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
563
564 template<>
565 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
566     HostResolver* host_resolver,
567     CertVerifier* /* cert_verifier */)
568     : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
569
570 template <>
571 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
572     HostResolver* host_resolver,
573     CertVerifier* cert_verifier)
574     : SSLClientSocketPool(0,
575                           0,
576                           NULL,
577                           host_resolver,
578                           cert_verifier,
579                           NULL,
580                           NULL,
581                           NULL,
582                           std::string(),
583                           NULL,
584                           NULL,
585                           NULL,
586                           NULL,
587                           NULL,
588                           false,
589                           NULL) {
590 }
591
592 //-----------------------------------------------------------------------------
593
594 // Helper functions for validating that AuthChallengeInfo's are correctly
595 // configured for common cases.
596 bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
597   if (!auth_challenge)
598     return false;
599   EXPECT_FALSE(auth_challenge->is_proxy);
600   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
601   EXPECT_EQ("MyRealm1", auth_challenge->realm);
602   EXPECT_EQ("basic", auth_challenge->scheme);
603   return true;
604 }
605
606 bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
607   if (!auth_challenge)
608     return false;
609   EXPECT_TRUE(auth_challenge->is_proxy);
610   EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
611   EXPECT_EQ("MyRealm1", auth_challenge->realm);
612   EXPECT_EQ("basic", auth_challenge->scheme);
613   return true;
614 }
615
616 bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
617   if (!auth_challenge)
618     return false;
619   EXPECT_FALSE(auth_challenge->is_proxy);
620   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
621   EXPECT_EQ("digestive", auth_challenge->realm);
622   EXPECT_EQ("digest", auth_challenge->scheme);
623   return true;
624 }
625
626 bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
627   if (!auth_challenge)
628     return false;
629   EXPECT_FALSE(auth_challenge->is_proxy);
630   EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
631   EXPECT_EQ(std::string(), auth_challenge->realm);
632   EXPECT_EQ("ntlm", auth_challenge->scheme);
633   return true;
634 }
635
636 }  // namespace
637
638 TEST_P(HttpNetworkTransactionTest, Basic) {
639   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
640   scoped_ptr<HttpTransaction> trans(
641       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
642 }
643
644 TEST_P(HttpNetworkTransactionTest, SimpleGET) {
645   MockRead data_reads[] = {
646     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
647     MockRead("hello world"),
648     MockRead(SYNCHRONOUS, OK),
649   };
650   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
651                                               arraysize(data_reads));
652   EXPECT_EQ(OK, out.rv);
653   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
654   EXPECT_EQ("hello world", out.response_data);
655   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
656   EXPECT_EQ(reads_size, out.totalReceivedBytes);
657 }
658
659 // Response with no status line.
660 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
661   MockRead data_reads[] = {
662     MockRead("hello world"),
663     MockRead(SYNCHRONOUS, OK),
664   };
665   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
666                                               arraysize(data_reads));
667   EXPECT_EQ(OK, out.rv);
668   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
669   EXPECT_EQ("hello world", out.response_data);
670   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
671   EXPECT_EQ(reads_size, out.totalReceivedBytes);
672 }
673
674 // Allow up to 4 bytes of junk to precede status line.
675 TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
676   MockRead data_reads[] = {
677     MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
678     MockRead(SYNCHRONOUS, OK),
679   };
680   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
681                                               arraysize(data_reads));
682   EXPECT_EQ(OK, out.rv);
683   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
684   EXPECT_EQ("DATA", out.response_data);
685   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
686   EXPECT_EQ(reads_size, out.totalReceivedBytes);
687 }
688
689 // Allow up to 4 bytes of junk to precede status line.
690 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
691   MockRead data_reads[] = {
692     MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
693     MockRead(SYNCHRONOUS, OK),
694   };
695   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
696                                               arraysize(data_reads));
697   EXPECT_EQ(OK, out.rv);
698   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
699   EXPECT_EQ("DATA", out.response_data);
700   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
701   EXPECT_EQ(reads_size, out.totalReceivedBytes);
702 }
703
704 // Beyond 4 bytes of slop and it should fail to find a status line.
705 TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
706   MockRead data_reads[] = {
707     MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
708     MockRead(SYNCHRONOUS, OK),
709   };
710   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
711                                               arraysize(data_reads));
712   EXPECT_EQ(OK, out.rv);
713   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
714   EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
715   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
716   EXPECT_EQ(reads_size, out.totalReceivedBytes);
717 }
718
719 // Same as StatusLineJunk4Bytes, except the read chunks are smaller.
720 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
721   MockRead data_reads[] = {
722     MockRead("\n"),
723     MockRead("\n"),
724     MockRead("Q"),
725     MockRead("J"),
726     MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
727     MockRead(SYNCHRONOUS, OK),
728   };
729   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
730                                               arraysize(data_reads));
731   EXPECT_EQ(OK, out.rv);
732   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
733   EXPECT_EQ("DATA", out.response_data);
734   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
735   EXPECT_EQ(reads_size, out.totalReceivedBytes);
736 }
737
738 // Close the connection before enough bytes to have a status line.
739 TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
740   MockRead data_reads[] = {
741     MockRead("HTT"),
742     MockRead(SYNCHRONOUS, OK),
743   };
744   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
745                                               arraysize(data_reads));
746   EXPECT_EQ(OK, out.rv);
747   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
748   EXPECT_EQ("HTT", out.response_data);
749   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
750   EXPECT_EQ(reads_size, out.totalReceivedBytes);
751 }
752
753 // Simulate a 204 response, lacking a Content-Length header, sent over a
754 // persistent connection.  The response should still terminate since a 204
755 // cannot have a response body.
756 TEST_P(HttpNetworkTransactionTest, StopsReading204) {
757   char junk[] = "junk";
758   MockRead data_reads[] = {
759     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
760     MockRead(junk),  // Should not be read!!
761     MockRead(SYNCHRONOUS, OK),
762   };
763   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
764                                               arraysize(data_reads));
765   EXPECT_EQ(OK, out.rv);
766   EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
767   EXPECT_EQ("", out.response_data);
768   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
769   int64 response_size = reads_size - strlen(junk);
770   EXPECT_EQ(response_size, out.totalReceivedBytes);
771 }
772
773 // A simple request using chunked encoding with some extra data after.
774 TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
775   std::string final_chunk = "0\r\n\r\n";
776   std::string extra_data = "HTTP/1.1 200 OK\r\n";
777   std::string last_read = final_chunk + extra_data;
778   MockRead data_reads[] = {
779     MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
780     MockRead("5\r\nHello\r\n"),
781     MockRead("1\r\n"),
782     MockRead(" \r\n"),
783     MockRead("5\r\nworld\r\n"),
784     MockRead(last_read.data()),
785     MockRead(SYNCHRONOUS, OK),
786   };
787   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
788                                               arraysize(data_reads));
789   EXPECT_EQ(OK, out.rv);
790   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
791   EXPECT_EQ("Hello world", out.response_data);
792   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
793   int64 response_size = reads_size - extra_data.size();
794   EXPECT_EQ(response_size, out.totalReceivedBytes);
795 }
796
797 // Next tests deal with http://crbug.com/56344.
798
799 TEST_P(HttpNetworkTransactionTest,
800        MultipleContentLengthHeadersNoTransferEncoding) {
801   MockRead data_reads[] = {
802     MockRead("HTTP/1.1 200 OK\r\n"),
803     MockRead("Content-Length: 10\r\n"),
804     MockRead("Content-Length: 5\r\n\r\n"),
805   };
806   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
807                                               arraysize(data_reads));
808   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
809 }
810
811 TEST_P(HttpNetworkTransactionTest,
812        DuplicateContentLengthHeadersNoTransferEncoding) {
813   MockRead data_reads[] = {
814     MockRead("HTTP/1.1 200 OK\r\n"),
815     MockRead("Content-Length: 5\r\n"),
816     MockRead("Content-Length: 5\r\n\r\n"),
817     MockRead("Hello"),
818   };
819   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
820                                               arraysize(data_reads));
821   EXPECT_EQ(OK, out.rv);
822   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
823   EXPECT_EQ("Hello", out.response_data);
824 }
825
826 TEST_P(HttpNetworkTransactionTest,
827        ComplexContentLengthHeadersNoTransferEncoding) {
828   // More than 2 dupes.
829   {
830     MockRead data_reads[] = {
831       MockRead("HTTP/1.1 200 OK\r\n"),
832       MockRead("Content-Length: 5\r\n"),
833       MockRead("Content-Length: 5\r\n"),
834       MockRead("Content-Length: 5\r\n\r\n"),
835       MockRead("Hello"),
836     };
837     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
838                                                 arraysize(data_reads));
839     EXPECT_EQ(OK, out.rv);
840     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
841     EXPECT_EQ("Hello", out.response_data);
842   }
843   // HTTP/1.0
844   {
845     MockRead data_reads[] = {
846       MockRead("HTTP/1.0 200 OK\r\n"),
847       MockRead("Content-Length: 5\r\n"),
848       MockRead("Content-Length: 5\r\n"),
849       MockRead("Content-Length: 5\r\n\r\n"),
850       MockRead("Hello"),
851     };
852     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
853                                                 arraysize(data_reads));
854     EXPECT_EQ(OK, out.rv);
855     EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
856     EXPECT_EQ("Hello", out.response_data);
857   }
858   // 2 dupes and one mismatched.
859   {
860     MockRead data_reads[] = {
861       MockRead("HTTP/1.1 200 OK\r\n"),
862       MockRead("Content-Length: 10\r\n"),
863       MockRead("Content-Length: 10\r\n"),
864       MockRead("Content-Length: 5\r\n\r\n"),
865     };
866     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
867                                                 arraysize(data_reads));
868     EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
869   }
870 }
871
872 TEST_P(HttpNetworkTransactionTest,
873        MultipleContentLengthHeadersTransferEncoding) {
874   MockRead data_reads[] = {
875     MockRead("HTTP/1.1 200 OK\r\n"),
876     MockRead("Content-Length: 666\r\n"),
877     MockRead("Content-Length: 1337\r\n"),
878     MockRead("Transfer-Encoding: chunked\r\n\r\n"),
879     MockRead("5\r\nHello\r\n"),
880     MockRead("1\r\n"),
881     MockRead(" \r\n"),
882     MockRead("5\r\nworld\r\n"),
883     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
884     MockRead(SYNCHRONOUS, OK),
885   };
886   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
887                                               arraysize(data_reads));
888   EXPECT_EQ(OK, out.rv);
889   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
890   EXPECT_EQ("Hello world", out.response_data);
891 }
892
893 // Next tests deal with http://crbug.com/98895.
894
895 // Checks that a single Content-Disposition header results in no error.
896 TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
897   MockRead data_reads[] = {
898     MockRead("HTTP/1.1 200 OK\r\n"),
899     MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
900     MockRead("Content-Length: 5\r\n\r\n"),
901     MockRead("Hello"),
902   };
903   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
904                                               arraysize(data_reads));
905   EXPECT_EQ(OK, out.rv);
906   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
907   EXPECT_EQ("Hello", out.response_data);
908 }
909
910 // Checks that two identical Content-Disposition headers result in no error.
911 TEST_P(HttpNetworkTransactionTest,
912        TwoIdenticalContentDispositionHeaders) {
913   MockRead data_reads[] = {
914     MockRead("HTTP/1.1 200 OK\r\n"),
915     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
916     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
917     MockRead("Content-Length: 5\r\n\r\n"),
918     MockRead("Hello"),
919   };
920   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
921                                               arraysize(data_reads));
922   EXPECT_EQ(OK, out.rv);
923   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
924   EXPECT_EQ("Hello", out.response_data);
925 }
926
927 // Checks that two distinct Content-Disposition headers result in an error.
928 TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
929   MockRead data_reads[] = {
930     MockRead("HTTP/1.1 200 OK\r\n"),
931     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
932     MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
933     MockRead("Content-Length: 5\r\n\r\n"),
934     MockRead("Hello"),
935   };
936   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
937                                               arraysize(data_reads));
938   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
939 }
940
941 // Checks that two identical Location headers result in no error.
942 // Also tests Location header behavior.
943 TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
944   MockRead data_reads[] = {
945     MockRead("HTTP/1.1 302 Redirect\r\n"),
946     MockRead("Location: http://good.com/\r\n"),
947     MockRead("Location: http://good.com/\r\n"),
948     MockRead("Content-Length: 0\r\n\r\n"),
949     MockRead(SYNCHRONOUS, OK),
950   };
951
952   HttpRequestInfo request;
953   request.method = "GET";
954   request.url = GURL("http://redirect.com/");
955   request.load_flags = 0;
956
957   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
958   scoped_ptr<HttpTransaction> trans(
959       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
960
961   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
962   session_deps_.socket_factory->AddSocketDataProvider(&data);
963
964   TestCompletionCallback callback;
965
966   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
967   EXPECT_EQ(ERR_IO_PENDING, rv);
968
969   EXPECT_EQ(OK, callback.WaitForResult());
970
971   const HttpResponseInfo* response = trans->GetResponseInfo();
972   ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
973   EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
974   std::string url;
975   EXPECT_TRUE(response->headers->IsRedirect(&url));
976   EXPECT_EQ("http://good.com/", url);
977   EXPECT_TRUE(response->proxy_server.IsEmpty());
978 }
979
980 // Checks that two distinct Location headers result in an error.
981 TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
982   MockRead data_reads[] = {
983     MockRead("HTTP/1.1 302 Redirect\r\n"),
984     MockRead("Location: http://good.com/\r\n"),
985     MockRead("Location: http://evil.com/\r\n"),
986     MockRead("Content-Length: 0\r\n\r\n"),
987     MockRead(SYNCHRONOUS, OK),
988   };
989   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
990                                               arraysize(data_reads));
991   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
992 }
993
994 // Do a request using the HEAD method. Verify that we don't try to read the
995 // message body (since HEAD has none).
996 TEST_P(HttpNetworkTransactionTest, Head) {
997   HttpRequestInfo request;
998   request.method = "HEAD";
999   request.url = GURL("http://www.google.com/");
1000   request.load_flags = 0;
1001
1002   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1003   scoped_ptr<HttpTransaction> trans(
1004       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1005   BeforeProxyHeadersSentHandler proxy_headers_handler;
1006   trans->SetBeforeProxyHeadersSentCallback(
1007       base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1008                  base::Unretained(&proxy_headers_handler)));
1009
1010   MockWrite data_writes1[] = {
1011     MockWrite("HEAD / HTTP/1.1\r\n"
1012               "Host: www.google.com\r\n"
1013               "Connection: keep-alive\r\n"
1014               "Content-Length: 0\r\n\r\n"),
1015   };
1016   MockRead data_reads1[] = {
1017     MockRead("HTTP/1.1 404 Not Found\r\n"),
1018     MockRead("Server: Blah\r\n"),
1019     MockRead("Content-Length: 1234\r\n\r\n"),
1020
1021     // No response body because the test stops reading here.
1022     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
1023   };
1024
1025   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1026                                  data_writes1, arraysize(data_writes1));
1027   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1028
1029   TestCompletionCallback callback1;
1030
1031   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
1032   EXPECT_EQ(ERR_IO_PENDING, rv);
1033
1034   rv = callback1.WaitForResult();
1035   EXPECT_EQ(OK, rv);
1036
1037   const HttpResponseInfo* response = trans->GetResponseInfo();
1038   ASSERT_TRUE(response != NULL);
1039
1040   // Check that the headers got parsed.
1041   EXPECT_TRUE(response->headers.get() != NULL);
1042   EXPECT_EQ(1234, response->headers->GetContentLength());
1043   EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
1044   EXPECT_TRUE(response->proxy_server.IsEmpty());
1045   EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
1046
1047   std::string server_header;
1048   void* iter = NULL;
1049   bool has_server_header = response->headers->EnumerateHeader(
1050       &iter, "Server", &server_header);
1051   EXPECT_TRUE(has_server_header);
1052   EXPECT_EQ("Blah", server_header);
1053
1054   // Reading should give EOF right away, since there is no message body
1055   // (despite non-zero content-length).
1056   std::string response_data;
1057   rv = ReadTransaction(trans.get(), &response_data);
1058   EXPECT_EQ(OK, rv);
1059   EXPECT_EQ("", response_data);
1060 }
1061
1062 TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
1063   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1064
1065   MockRead data_reads[] = {
1066     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1067     MockRead("hello"),
1068     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1069     MockRead("world"),
1070     MockRead(SYNCHRONOUS, OK),
1071   };
1072   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1073   session_deps_.socket_factory->AddSocketDataProvider(&data);
1074
1075   const char* const kExpectedResponseData[] = {
1076     "hello", "world"
1077   };
1078
1079   for (int i = 0; i < 2; ++i) {
1080     HttpRequestInfo request;
1081     request.method = "GET";
1082     request.url = GURL("http://www.google.com/");
1083     request.load_flags = 0;
1084
1085     scoped_ptr<HttpTransaction> trans(
1086         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1087
1088     TestCompletionCallback callback;
1089
1090     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1091     EXPECT_EQ(ERR_IO_PENDING, rv);
1092
1093     rv = callback.WaitForResult();
1094     EXPECT_EQ(OK, rv);
1095
1096     const HttpResponseInfo* response = trans->GetResponseInfo();
1097     ASSERT_TRUE(response != NULL);
1098
1099     EXPECT_TRUE(response->headers.get() != NULL);
1100     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1101     EXPECT_TRUE(response->proxy_server.IsEmpty());
1102
1103     std::string response_data;
1104     rv = ReadTransaction(trans.get(), &response_data);
1105     EXPECT_EQ(OK, rv);
1106     EXPECT_EQ(kExpectedResponseData[i], response_data);
1107   }
1108 }
1109
1110 TEST_P(HttpNetworkTransactionTest, Ignores100) {
1111   ScopedVector<UploadElementReader> element_readers;
1112   element_readers.push_back(new UploadBytesElementReader("foo", 3));
1113   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
1114
1115   HttpRequestInfo request;
1116   request.method = "POST";
1117   request.url = GURL("http://www.foo.com/");
1118   request.upload_data_stream = &upload_data_stream;
1119   request.load_flags = 0;
1120
1121   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1122   scoped_ptr<HttpTransaction> trans(
1123       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1124
1125   MockRead data_reads[] = {
1126     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1127     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1128     MockRead("hello world"),
1129     MockRead(SYNCHRONOUS, OK),
1130   };
1131   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1132   session_deps_.socket_factory->AddSocketDataProvider(&data);
1133
1134   TestCompletionCallback callback;
1135
1136   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1137   EXPECT_EQ(ERR_IO_PENDING, rv);
1138
1139   rv = callback.WaitForResult();
1140   EXPECT_EQ(OK, rv);
1141
1142   const HttpResponseInfo* response = trans->GetResponseInfo();
1143   ASSERT_TRUE(response != NULL);
1144
1145   EXPECT_TRUE(response->headers.get() != NULL);
1146   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
1147
1148   std::string response_data;
1149   rv = ReadTransaction(trans.get(), &response_data);
1150   EXPECT_EQ(OK, rv);
1151   EXPECT_EQ("hello world", response_data);
1152 }
1153
1154 // This test is almost the same as Ignores100 above, but the response contains
1155 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
1156 // HTTP/1.1 and the two status headers are read in one read.
1157 TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
1158   HttpRequestInfo request;
1159   request.method = "GET";
1160   request.url = GURL("http://www.foo.com/");
1161   request.load_flags = 0;
1162
1163   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1164   scoped_ptr<HttpTransaction> trans(
1165       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1166
1167   MockRead data_reads[] = {
1168     MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1169              "HTTP/1.1 200 OK\r\n\r\n"),
1170     MockRead("hello world"),
1171     MockRead(SYNCHRONOUS, OK),
1172   };
1173   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1174   session_deps_.socket_factory->AddSocketDataProvider(&data);
1175
1176   TestCompletionCallback callback;
1177
1178   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1179   EXPECT_EQ(ERR_IO_PENDING, rv);
1180
1181   rv = callback.WaitForResult();
1182   EXPECT_EQ(OK, rv);
1183
1184   const HttpResponseInfo* response = trans->GetResponseInfo();
1185   ASSERT_TRUE(response != NULL);
1186
1187   EXPECT_TRUE(response->headers.get() != NULL);
1188   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1189
1190   std::string response_data;
1191   rv = ReadTransaction(trans.get(), &response_data);
1192   EXPECT_EQ(OK, rv);
1193   EXPECT_EQ("hello world", response_data);
1194 }
1195
1196 TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
1197   HttpRequestInfo request;
1198   request.method = "POST";
1199   request.url = GURL("http://www.foo.com/");
1200   request.load_flags = 0;
1201
1202   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1203   scoped_ptr<HttpTransaction> trans(
1204       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1205
1206   MockRead data_reads[] = {
1207     MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1208     MockRead(ASYNC, 0),
1209   };
1210   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1211   session_deps_.socket_factory->AddSocketDataProvider(&data);
1212
1213   TestCompletionCallback callback;
1214
1215   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1216   EXPECT_EQ(ERR_IO_PENDING, rv);
1217
1218   rv = callback.WaitForResult();
1219   EXPECT_EQ(OK, rv);
1220
1221   std::string response_data;
1222   rv = ReadTransaction(trans.get(), &response_data);
1223   EXPECT_EQ(OK, rv);
1224   EXPECT_EQ("", response_data);
1225 }
1226
1227 TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
1228   HttpRequestInfo request;
1229   request.method = "POST";
1230   request.url = GURL("http://www.foo.com/");
1231   request.load_flags = 0;
1232
1233   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1234   scoped_ptr<HttpTransaction> trans(
1235       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1236
1237
1238   MockRead data_reads[] = {
1239     MockRead(ASYNC, 0),
1240   };
1241   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1242   session_deps_.socket_factory->AddSocketDataProvider(&data);
1243
1244   TestCompletionCallback callback;
1245
1246   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1247   EXPECT_EQ(ERR_IO_PENDING, rv);
1248
1249   rv = callback.WaitForResult();
1250   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1251 }
1252
1253 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
1254     const MockWrite* write_failure,
1255     const MockRead* read_failure) {
1256   HttpRequestInfo request;
1257   request.method = "GET";
1258   request.url = GURL("http://www.foo.com/");
1259   request.load_flags = 0;
1260
1261   CapturingNetLog net_log;
1262   session_deps_.net_log = &net_log;
1263   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1264
1265   // Written data for successfully sending both requests.
1266   MockWrite data1_writes[] = {
1267     MockWrite("GET / HTTP/1.1\r\n"
1268               "Host: www.foo.com\r\n"
1269               "Connection: keep-alive\r\n\r\n"),
1270     MockWrite("GET / HTTP/1.1\r\n"
1271               "Host: www.foo.com\r\n"
1272               "Connection: keep-alive\r\n\r\n")
1273   };
1274
1275   // Read results for the first request.
1276   MockRead data1_reads[] = {
1277     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1278     MockRead("hello"),
1279     MockRead(ASYNC, OK),
1280   };
1281
1282   if (write_failure) {
1283     ASSERT_FALSE(read_failure);
1284     data1_writes[1] = *write_failure;
1285   } else {
1286     ASSERT_TRUE(read_failure);
1287     data1_reads[2] = *read_failure;
1288   }
1289
1290   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1291                                  data1_writes, arraysize(data1_writes));
1292   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1293
1294   MockRead data2_reads[] = {
1295     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1296     MockRead("world"),
1297     MockRead(ASYNC, OK),
1298   };
1299   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1300   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1301
1302   const char* kExpectedResponseData[] = {
1303     "hello", "world"
1304   };
1305
1306   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
1307   for (int i = 0; i < 2; ++i) {
1308     TestCompletionCallback callback;
1309
1310     scoped_ptr<HttpTransaction> trans(
1311         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1312
1313     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1314     EXPECT_EQ(ERR_IO_PENDING, rv);
1315
1316     rv = callback.WaitForResult();
1317     EXPECT_EQ(OK, rv);
1318
1319     LoadTimingInfo load_timing_info;
1320     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1321     TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1322     if (i == 0) {
1323       first_socket_log_id = load_timing_info.socket_log_id;
1324     } else {
1325       // The second request should be using a new socket.
1326       EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1327     }
1328
1329     const HttpResponseInfo* response = trans->GetResponseInfo();
1330     ASSERT_TRUE(response != NULL);
1331
1332     EXPECT_TRUE(response->headers.get() != NULL);
1333     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1334
1335     std::string response_data;
1336     rv = ReadTransaction(trans.get(), &response_data);
1337     EXPECT_EQ(OK, rv);
1338     EXPECT_EQ(kExpectedResponseData[i], response_data);
1339   }
1340 }
1341
1342 void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1343     const MockWrite* write_failure,
1344     const MockRead* read_failure,
1345     bool use_spdy) {
1346   HttpRequestInfo request;
1347   request.method = "GET";
1348   request.url = GURL("https://www.foo.com/");
1349   request.load_flags = 0;
1350
1351   CapturingNetLog net_log;
1352   session_deps_.net_log = &net_log;
1353   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1354
1355   SSLSocketDataProvider ssl1(ASYNC, OK);
1356   SSLSocketDataProvider ssl2(ASYNC, OK);
1357   if (use_spdy) {
1358     ssl1.SetNextProto(GetParam());
1359     ssl2.SetNextProto(GetParam());
1360   }
1361   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1362   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
1363
1364   // SPDY versions of the request and response.
1365   scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1366       request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1367   scoped_ptr<SpdyFrame> spdy_response(
1368       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1369   scoped_ptr<SpdyFrame> spdy_data(
1370       spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
1371
1372   // HTTP/1.1 versions of the request and response.
1373   const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1374       "Host: www.foo.com\r\n"
1375       "Connection: keep-alive\r\n\r\n";
1376   const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1377   const char kHttpData[] = "hello";
1378
1379   std::vector<MockRead> data1_reads;
1380   std::vector<MockWrite> data1_writes;
1381   if (write_failure) {
1382     ASSERT_FALSE(read_failure);
1383     data1_writes.push_back(*write_failure);
1384     data1_reads.push_back(MockRead(ASYNC, OK));
1385   } else {
1386     ASSERT_TRUE(read_failure);
1387     if (use_spdy) {
1388       data1_writes.push_back(CreateMockWrite(*spdy_request));
1389     } else {
1390       data1_writes.push_back(MockWrite(kHttpRequest));
1391     }
1392     data1_reads.push_back(*read_failure);
1393   }
1394
1395   StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1396                                  &data1_writes[0], data1_writes.size());
1397   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1398
1399   std::vector<MockRead> data2_reads;
1400   std::vector<MockWrite> data2_writes;
1401
1402   if (use_spdy) {
1403     data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1404
1405     data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1406     data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1407     data2_reads.push_back(MockRead(ASYNC, OK, 3));
1408   } else {
1409     data2_writes.push_back(
1410         MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1411
1412     data2_reads.push_back(
1413         MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1414     data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1415     data2_reads.push_back(MockRead(ASYNC, OK, 3));
1416   }
1417   OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1418                           &data2_writes[0], data2_writes.size());
1419   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1420
1421   // Preconnect a socket.
1422   net::SSLConfig ssl_config;
1423   session->ssl_config_service()->GetSSLConfig(&ssl_config);
1424   session->GetNextProtos(&ssl_config.next_protos);
1425   session->http_stream_factory()->PreconnectStreams(
1426       1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1427   // Wait for the preconnect to complete.
1428   // TODO(davidben): Some way to wait for an idle socket count might be handy.
1429   base::RunLoop().RunUntilIdle();
1430   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
1431
1432   // Make the request.
1433   TestCompletionCallback callback;
1434
1435   scoped_ptr<HttpTransaction> trans(
1436       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1437
1438   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1439   EXPECT_EQ(ERR_IO_PENDING, rv);
1440
1441   rv = callback.WaitForResult();
1442   EXPECT_EQ(OK, rv);
1443
1444   LoadTimingInfo load_timing_info;
1445   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1446   TestLoadTimingNotReused(
1447       load_timing_info,
1448       CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
1449
1450   const HttpResponseInfo* response = trans->GetResponseInfo();
1451   ASSERT_TRUE(response != NULL);
1452
1453   EXPECT_TRUE(response->headers.get() != NULL);
1454   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1455
1456   std::string response_data;
1457   rv = ReadTransaction(trans.get(), &response_data);
1458   EXPECT_EQ(OK, rv);
1459   EXPECT_EQ(kHttpData, response_data);
1460 }
1461
1462 TEST_P(HttpNetworkTransactionTest,
1463        KeepAliveConnectionNotConnectedOnWrite) {
1464   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1465   KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1466 }
1467
1468 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
1469   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1470   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1471 }
1472
1473 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
1474   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1475   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1476 }
1477
1478 // Make sure that on a 408 response (Request Timeout), the request is retried,
1479 // if the socket was a reused keep alive socket.
1480 TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1481   MockRead read_failure(SYNCHRONOUS,
1482                         "HTTP/1.1 408 Request Timeout\r\n"
1483                         "Connection: Keep-Alive\r\n"
1484                         "Content-Length: 6\r\n\r\n"
1485                         "Pickle");
1486   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1487 }
1488
1489 TEST_P(HttpNetworkTransactionTest,
1490        PreconnectErrorNotConnectedOnWrite) {
1491   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1492   PreconnectErrorResendRequestTest(&write_failure, NULL, false);
1493 }
1494
1495 TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1496   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1497   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1498 }
1499
1500 TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1501   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1502   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1503 }
1504
1505 TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1506   MockRead read_failure(ASYNC, OK);  // EOF
1507   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1508 }
1509
1510 // Make sure that on a 408 response (Request Timeout), the request is retried,
1511 // if the socket was a preconnected (UNUSED_IDLE) socket.
1512 TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1513   MockRead read_failure(SYNCHRONOUS,
1514                         "HTTP/1.1 408 Request Timeout\r\n"
1515                         "Connection: Keep-Alive\r\n"
1516                         "Content-Length: 6\r\n\r\n"
1517                         "Pickle");
1518   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1519   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1520 }
1521
1522 TEST_P(HttpNetworkTransactionTest,
1523        SpdyPreconnectErrorNotConnectedOnWrite) {
1524   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1525   PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1526 }
1527
1528 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1529   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1530   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1531 }
1532
1533 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1534   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1535   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1536 }
1537
1538 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1539   MockRead read_failure(ASYNC, OK);  // EOF
1540   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1541 }
1542
1543 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
1544   HttpRequestInfo request;
1545   request.method = "GET";
1546   request.url = GURL("http://www.google.com/");
1547   request.load_flags = 0;
1548
1549   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1550   scoped_ptr<HttpTransaction> trans(
1551       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1552
1553   MockRead data_reads[] = {
1554     MockRead(ASYNC, ERR_CONNECTION_RESET),
1555     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
1556     MockRead("hello world"),
1557     MockRead(SYNCHRONOUS, OK),
1558   };
1559   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1560   session_deps_.socket_factory->AddSocketDataProvider(&data);
1561
1562   TestCompletionCallback callback;
1563
1564   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1565   EXPECT_EQ(ERR_IO_PENDING, rv);
1566
1567   rv = callback.WaitForResult();
1568   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1569
1570   const HttpResponseInfo* response = trans->GetResponseInfo();
1571   EXPECT_TRUE(response == NULL);
1572 }
1573
1574 // What do various browsers do when the server closes a non-keepalive
1575 // connection without sending any response header or body?
1576 //
1577 // IE7: error page
1578 // Safari 3.1.2 (Windows): error page
1579 // Firefox 3.0.1: blank page
1580 // Opera 9.52: after five attempts, blank page
1581 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1582 // Us: error page (EMPTY_RESPONSE)
1583 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
1584   MockRead data_reads[] = {
1585     MockRead(SYNCHRONOUS, OK),  // EOF
1586     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
1587     MockRead("hello world"),
1588     MockRead(SYNCHRONOUS, OK),
1589   };
1590   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1591                                               arraysize(data_reads));
1592   EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
1593 }
1594
1595 // Test that network access can be deferred and resumed.
1596 TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1597   HttpRequestInfo request;
1598   request.method = "GET";
1599   request.url = GURL("http://www.google.com/");
1600   request.load_flags = 0;
1601
1602   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1603   scoped_ptr<HttpTransaction> trans(
1604       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1605
1606   // Defer on OnBeforeNetworkStart.
1607   BeforeNetworkStartHandler net_start_handler(true);  // defer
1608   trans->SetBeforeNetworkStartCallback(
1609       base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1610                  base::Unretained(&net_start_handler)));
1611
1612   MockRead data_reads[] = {
1613     MockRead("HTTP/1.0 200 OK\r\n"),
1614     MockRead("Content-Length: 5\r\n\r\n"),
1615     MockRead("hello"),
1616     MockRead(SYNCHRONOUS, 0),
1617   };
1618   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1619   session_deps_.socket_factory->AddSocketDataProvider(&data);
1620
1621   TestCompletionCallback callback;
1622
1623   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1624   EXPECT_EQ(ERR_IO_PENDING, rv);
1625   base::MessageLoop::current()->RunUntilIdle();
1626
1627   // Should have deferred for network start.
1628   EXPECT_TRUE(net_start_handler.observed_before_network_start());
1629   EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1630   EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1631
1632   trans->ResumeNetworkStart();
1633   rv = callback.WaitForResult();
1634   EXPECT_EQ(OK, rv);
1635   EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1636
1637   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1638   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1639   if (rv == ERR_IO_PENDING)
1640     rv = callback.WaitForResult();
1641   EXPECT_EQ(5, rv);
1642   trans.reset();
1643 }
1644
1645 // Test that network use can be deferred and canceled.
1646 TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1647   HttpRequestInfo request;
1648   request.method = "GET";
1649   request.url = GURL("http://www.google.com/");
1650   request.load_flags = 0;
1651
1652   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1653   scoped_ptr<HttpTransaction> trans(
1654       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1655
1656   // Defer on OnBeforeNetworkStart.
1657   BeforeNetworkStartHandler net_start_handler(true);  // defer
1658   trans->SetBeforeNetworkStartCallback(
1659       base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1660                  base::Unretained(&net_start_handler)));
1661
1662   TestCompletionCallback callback;
1663
1664   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1665   EXPECT_EQ(ERR_IO_PENDING, rv);
1666   base::MessageLoop::current()->RunUntilIdle();
1667
1668   // Should have deferred for network start.
1669   EXPECT_TRUE(net_start_handler.observed_before_network_start());
1670   EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1671   EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1672 }
1673
1674 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1675 // tests. There was a bug causing HttpNetworkTransaction to hang in the
1676 // destructor in such situations.
1677 // See http://crbug.com/154712 and http://crbug.com/156609.
1678 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
1679   HttpRequestInfo request;
1680   request.method = "GET";
1681   request.url = GURL("http://www.google.com/");
1682   request.load_flags = 0;
1683
1684   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1685   scoped_ptr<HttpTransaction> trans(
1686       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1687
1688   MockRead data_reads[] = {
1689     MockRead("HTTP/1.0 200 OK\r\n"),
1690     MockRead("Connection: keep-alive\r\n"),
1691     MockRead("Content-Length: 100\r\n\r\n"),
1692     MockRead("hello"),
1693     MockRead(SYNCHRONOUS, 0),
1694   };
1695   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1696   session_deps_.socket_factory->AddSocketDataProvider(&data);
1697
1698   TestCompletionCallback callback;
1699
1700   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1701   EXPECT_EQ(ERR_IO_PENDING, rv);
1702
1703   rv = callback.WaitForResult();
1704   EXPECT_EQ(OK, rv);
1705
1706   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1707   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1708   if (rv == ERR_IO_PENDING)
1709     rv = callback.WaitForResult();
1710   EXPECT_EQ(5, rv);
1711   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1712   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1713
1714   trans.reset();
1715   base::MessageLoop::current()->RunUntilIdle();
1716   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1717 }
1718
1719 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
1720   HttpRequestInfo request;
1721   request.method = "GET";
1722   request.url = GURL("http://www.google.com/");
1723   request.load_flags = 0;
1724
1725   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1726   scoped_ptr<HttpTransaction> trans(
1727       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1728
1729   MockRead data_reads[] = {
1730     MockRead("HTTP/1.0 200 OK\r\n"),
1731     MockRead("Connection: keep-alive\r\n"),
1732     MockRead("Content-Length: 100\r\n\r\n"),
1733     MockRead(SYNCHRONOUS, 0),
1734   };
1735   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1736   session_deps_.socket_factory->AddSocketDataProvider(&data);
1737
1738   TestCompletionCallback callback;
1739
1740   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1741   EXPECT_EQ(ERR_IO_PENDING, rv);
1742
1743   rv = callback.WaitForResult();
1744   EXPECT_EQ(OK, rv);
1745
1746   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1747   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1748   if (rv == ERR_IO_PENDING)
1749     rv = callback.WaitForResult();
1750   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1751
1752   trans.reset();
1753   base::MessageLoop::current()->RunUntilIdle();
1754   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1755 }
1756
1757 // Test that we correctly reuse a keep-alive connection after not explicitly
1758 // reading the body.
1759 TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
1760   HttpRequestInfo request;
1761   request.method = "GET";
1762   request.url = GURL("http://www.foo.com/");
1763   request.load_flags = 0;
1764
1765   CapturingNetLog net_log;
1766   session_deps_.net_log = &net_log;
1767   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1768
1769   // Note that because all these reads happen in the same
1770   // StaticSocketDataProvider, it shows that the same socket is being reused for
1771   // all transactions.
1772   MockRead data1_reads[] = {
1773     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1774     MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
1775     MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
1776     MockRead("HTTP/1.1 302 Found\r\n"
1777              "Content-Length: 0\r\n\r\n"),
1778     MockRead("HTTP/1.1 302 Found\r\n"
1779              "Content-Length: 5\r\n\r\n"
1780              "hello"),
1781     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1782              "Content-Length: 0\r\n\r\n"),
1783     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1784              "Content-Length: 5\r\n\r\n"
1785              "hello"),
1786     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1787     MockRead("hello"),
1788   };
1789   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
1790   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1791
1792   MockRead data2_reads[] = {
1793     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
1794   };
1795   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1796   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1797
1798   const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1799   std::string response_lines[kNumUnreadBodies];
1800
1801   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
1802   for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
1803     TestCompletionCallback callback;
1804
1805     scoped_ptr<HttpTransaction> trans(
1806         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1807
1808     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1809     EXPECT_EQ(ERR_IO_PENDING, rv);
1810
1811     rv = callback.WaitForResult();
1812     EXPECT_EQ(OK, rv);
1813
1814     LoadTimingInfo load_timing_info;
1815     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1816     if (i == 0) {
1817       TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1818       first_socket_log_id = load_timing_info.socket_log_id;
1819     } else {
1820       TestLoadTimingReused(load_timing_info);
1821       EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1822     }
1823
1824     const HttpResponseInfo* response = trans->GetResponseInfo();
1825     ASSERT_TRUE(response != NULL);
1826
1827     ASSERT_TRUE(response->headers.get() != NULL);
1828     response_lines[i] = response->headers->GetStatusLine();
1829
1830     // We intentionally don't read the response bodies.
1831   }
1832
1833   const char* const kStatusLines[] = {
1834     "HTTP/1.1 204 No Content",
1835     "HTTP/1.1 205 Reset Content",
1836     "HTTP/1.1 304 Not Modified",
1837     "HTTP/1.1 302 Found",
1838     "HTTP/1.1 302 Found",
1839     "HTTP/1.1 301 Moved Permanently",
1840     "HTTP/1.1 301 Moved Permanently",
1841   };
1842
1843   COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1844                  forgot_to_update_kStatusLines);
1845
1846   for (int i = 0; i < kNumUnreadBodies; ++i)
1847     EXPECT_EQ(kStatusLines[i], response_lines[i]);
1848
1849   TestCompletionCallback callback;
1850   scoped_ptr<HttpTransaction> trans(
1851       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1852   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1853   EXPECT_EQ(ERR_IO_PENDING, rv);
1854   rv = callback.WaitForResult();
1855   EXPECT_EQ(OK, rv);
1856   const HttpResponseInfo* response = trans->GetResponseInfo();
1857   ASSERT_TRUE(response != NULL);
1858   ASSERT_TRUE(response->headers.get() != NULL);
1859   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1860   std::string response_data;
1861   rv = ReadTransaction(trans.get(), &response_data);
1862   EXPECT_EQ(OK, rv);
1863   EXPECT_EQ("hello", response_data);
1864 }
1865
1866 // Test the request-challenge-retry sequence for basic auth.
1867 // (basic auth is the easiest to mock, because it has no randomness).
1868 TEST_P(HttpNetworkTransactionTest, BasicAuth) {
1869   HttpRequestInfo request;
1870   request.method = "GET";
1871   request.url = GURL("http://www.google.com/");
1872   request.load_flags = 0;
1873
1874   CapturingNetLog log;
1875   session_deps_.net_log = &log;
1876   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1877   scoped_ptr<HttpTransaction> trans(
1878       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1879
1880   MockWrite data_writes1[] = {
1881     MockWrite("GET / HTTP/1.1\r\n"
1882               "Host: www.google.com\r\n"
1883               "Connection: keep-alive\r\n\r\n"),
1884   };
1885
1886   MockRead data_reads1[] = {
1887     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1888     // Give a couple authenticate options (only the middle one is actually
1889     // supported).
1890     MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
1891     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1892     MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1893     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1894     // Large content-length -- won't matter, as connection will be reset.
1895     MockRead("Content-Length: 10000\r\n\r\n"),
1896     MockRead(SYNCHRONOUS, ERR_FAILED),
1897   };
1898
1899   // After calling trans->RestartWithAuth(), this is the request we should
1900   // be issuing -- the final header line contains the credentials.
1901   MockWrite data_writes2[] = {
1902     MockWrite("GET / HTTP/1.1\r\n"
1903               "Host: www.google.com\r\n"
1904               "Connection: keep-alive\r\n"
1905               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1906   };
1907
1908   // Lastly, the server responds with the actual content.
1909   MockRead data_reads2[] = {
1910     MockRead("HTTP/1.0 200 OK\r\n"),
1911     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1912     MockRead("Content-Length: 100\r\n\r\n"),
1913     MockRead(SYNCHRONOUS, OK),
1914   };
1915
1916   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1917                                  data_writes1, arraysize(data_writes1));
1918   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1919                                  data_writes2, arraysize(data_writes2));
1920   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1921   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1922
1923   TestCompletionCallback callback1;
1924
1925   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
1926   EXPECT_EQ(ERR_IO_PENDING, rv);
1927
1928   rv = callback1.WaitForResult();
1929   EXPECT_EQ(OK, rv);
1930
1931   LoadTimingInfo load_timing_info1;
1932   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1933   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1934
1935   int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1936   EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1937
1938   const HttpResponseInfo* response = trans->GetResponseInfo();
1939   ASSERT_TRUE(response != NULL);
1940   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
1941
1942   TestCompletionCallback callback2;
1943
1944   rv = trans->RestartWithAuth(
1945       AuthCredentials(kFoo, kBar), callback2.callback());
1946   EXPECT_EQ(ERR_IO_PENDING, rv);
1947
1948   rv = callback2.WaitForResult();
1949   EXPECT_EQ(OK, rv);
1950
1951   LoadTimingInfo load_timing_info2;
1952   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1953   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1954   // The load timing after restart should have a new socket ID, and times after
1955   // those of the first load timing.
1956   EXPECT_LE(load_timing_info1.receive_headers_end,
1957             load_timing_info2.connect_timing.connect_start);
1958   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1959
1960   int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1961   EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1962
1963   response = trans->GetResponseInfo();
1964   ASSERT_TRUE(response != NULL);
1965   EXPECT_TRUE(response->auth_challenge.get() == NULL);
1966   EXPECT_EQ(100, response->headers->GetContentLength());
1967 }
1968
1969 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
1970   HttpRequestInfo request;
1971   request.method = "GET";
1972   request.url = GURL("http://www.google.com/");
1973   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1974
1975   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1976   scoped_ptr<HttpTransaction> trans(
1977       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1978
1979   MockWrite data_writes[] = {
1980     MockWrite("GET / HTTP/1.1\r\n"
1981               "Host: www.google.com\r\n"
1982               "Connection: keep-alive\r\n\r\n"),
1983   };
1984
1985   MockRead data_reads[] = {
1986     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1987     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1988     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1989     // Large content-length -- won't matter, as connection will be reset.
1990     MockRead("Content-Length: 10000\r\n\r\n"),
1991     MockRead(SYNCHRONOUS, ERR_FAILED),
1992   };
1993
1994   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1995                                 data_writes, arraysize(data_writes));
1996   session_deps_.socket_factory->AddSocketDataProvider(&data);
1997   TestCompletionCallback callback;
1998
1999   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2000   EXPECT_EQ(ERR_IO_PENDING, rv);
2001
2002   rv = callback.WaitForResult();
2003   EXPECT_EQ(0, rv);
2004
2005   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2006   EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2007
2008   const HttpResponseInfo* response = trans->GetResponseInfo();
2009   ASSERT_TRUE(response != NULL);
2010   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2011 }
2012
2013 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2014 // connection.
2015 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
2016   HttpRequestInfo request;
2017   request.method = "GET";
2018   request.url = GURL("http://www.google.com/");
2019   request.load_flags = 0;
2020
2021   CapturingNetLog log;
2022   session_deps_.net_log = &log;
2023   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2024
2025   MockWrite data_writes1[] = {
2026     MockWrite("GET / HTTP/1.1\r\n"
2027               "Host: www.google.com\r\n"
2028               "Connection: keep-alive\r\n\r\n"),
2029
2030     // After calling trans->RestartWithAuth(), this is the request we should
2031     // be issuing -- the final header line contains the credentials.
2032     MockWrite("GET / HTTP/1.1\r\n"
2033               "Host: www.google.com\r\n"
2034               "Connection: keep-alive\r\n"
2035               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2036   };
2037
2038   MockRead data_reads1[] = {
2039     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2040     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2041     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2042     MockRead("Content-Length: 14\r\n\r\n"),
2043     MockRead("Unauthorized\r\n"),
2044
2045     // Lastly, the server responds with the actual content.
2046     MockRead("HTTP/1.1 200 OK\r\n"),
2047     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2048     MockRead("Content-Length: 5\r\n\r\n"),
2049     MockRead("Hello"),
2050   };
2051
2052   // If there is a regression where we disconnect a Keep-Alive
2053   // connection during an auth roundtrip, we'll end up reading this.
2054   MockRead data_reads2[] = {
2055     MockRead(SYNCHRONOUS, ERR_FAILED),
2056   };
2057
2058   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2059                                  data_writes1, arraysize(data_writes1));
2060   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2061                                  NULL, 0);
2062   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2063   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2064
2065   TestCompletionCallback callback1;
2066
2067   scoped_ptr<HttpTransaction> trans(
2068       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2069   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2070   EXPECT_EQ(ERR_IO_PENDING, rv);
2071
2072   rv = callback1.WaitForResult();
2073   EXPECT_EQ(OK, rv);
2074
2075   LoadTimingInfo load_timing_info1;
2076   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2077   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2078
2079   const HttpResponseInfo* response = trans->GetResponseInfo();
2080   ASSERT_TRUE(response != NULL);
2081   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2082
2083   TestCompletionCallback callback2;
2084
2085   rv = trans->RestartWithAuth(
2086       AuthCredentials(kFoo, kBar), callback2.callback());
2087   EXPECT_EQ(ERR_IO_PENDING, rv);
2088
2089   rv = callback2.WaitForResult();
2090   EXPECT_EQ(OK, rv);
2091
2092   LoadTimingInfo load_timing_info2;
2093   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2094   TestLoadTimingReused(load_timing_info2);
2095   // The load timing after restart should have the same socket ID, and times
2096   // those of the first load timing.
2097   EXPECT_LE(load_timing_info1.receive_headers_end,
2098             load_timing_info2.send_start);
2099   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2100
2101   response = trans->GetResponseInfo();
2102   ASSERT_TRUE(response != NULL);
2103   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2104   EXPECT_EQ(5, response->headers->GetContentLength());
2105
2106   std::string response_data;
2107   rv = ReadTransaction(trans.get(), &response_data);
2108   EXPECT_EQ(OK, rv);
2109   int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2110   EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2111 }
2112
2113 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2114 // connection and with no response body to drain.
2115 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
2116   HttpRequestInfo request;
2117   request.method = "GET";
2118   request.url = GURL("http://www.google.com/");
2119   request.load_flags = 0;
2120
2121   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2122
2123   MockWrite data_writes1[] = {
2124     MockWrite("GET / HTTP/1.1\r\n"
2125               "Host: www.google.com\r\n"
2126               "Connection: keep-alive\r\n\r\n"),
2127
2128     // After calling trans->RestartWithAuth(), this is the request we should
2129     // be issuing -- the final header line contains the credentials.
2130     MockWrite("GET / HTTP/1.1\r\n"
2131               "Host: www.google.com\r\n"
2132               "Connection: keep-alive\r\n"
2133               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2134   };
2135
2136   MockRead data_reads1[] = {
2137     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2138     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2139     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
2140
2141     // Lastly, the server responds with the actual content.
2142     MockRead("HTTP/1.1 200 OK\r\n"),
2143     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2144     MockRead("Content-Length: 5\r\n\r\n"),
2145     MockRead("hello"),
2146   };
2147
2148   // An incorrect reconnect would cause this to be read.
2149   MockRead data_reads2[] = {
2150     MockRead(SYNCHRONOUS, ERR_FAILED),
2151   };
2152
2153   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2154                                  data_writes1, arraysize(data_writes1));
2155   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2156                                  NULL, 0);
2157   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2158   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2159
2160   TestCompletionCallback callback1;
2161
2162   scoped_ptr<HttpTransaction> trans(
2163       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2164   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2165   EXPECT_EQ(ERR_IO_PENDING, rv);
2166
2167   rv = callback1.WaitForResult();
2168   EXPECT_EQ(OK, rv);
2169
2170   const HttpResponseInfo* response = trans->GetResponseInfo();
2171   ASSERT_TRUE(response != NULL);
2172   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2173
2174   TestCompletionCallback callback2;
2175
2176   rv = trans->RestartWithAuth(
2177       AuthCredentials(kFoo, kBar), callback2.callback());
2178   EXPECT_EQ(ERR_IO_PENDING, rv);
2179
2180   rv = callback2.WaitForResult();
2181   EXPECT_EQ(OK, rv);
2182
2183   response = trans->GetResponseInfo();
2184   ASSERT_TRUE(response != NULL);
2185   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2186   EXPECT_EQ(5, response->headers->GetContentLength());
2187 }
2188
2189 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2190 // connection and with a large response body to drain.
2191 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
2192   HttpRequestInfo request;
2193   request.method = "GET";
2194   request.url = GURL("http://www.google.com/");
2195   request.load_flags = 0;
2196
2197   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2198
2199   MockWrite data_writes1[] = {
2200     MockWrite("GET / HTTP/1.1\r\n"
2201               "Host: www.google.com\r\n"
2202               "Connection: keep-alive\r\n\r\n"),
2203
2204     // After calling trans->RestartWithAuth(), this is the request we should
2205     // be issuing -- the final header line contains the credentials.
2206     MockWrite("GET / HTTP/1.1\r\n"
2207               "Host: www.google.com\r\n"
2208               "Connection: keep-alive\r\n"
2209               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2210   };
2211
2212   // Respond with 5 kb of response body.
2213   std::string large_body_string("Unauthorized");
2214   large_body_string.append(5 * 1024, ' ');
2215   large_body_string.append("\r\n");
2216
2217   MockRead data_reads1[] = {
2218     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2219     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2220     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2221     // 5134 = 12 + 5 * 1024 + 2
2222     MockRead("Content-Length: 5134\r\n\r\n"),
2223     MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
2224
2225     // Lastly, the server responds with the actual content.
2226     MockRead("HTTP/1.1 200 OK\r\n"),
2227     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2228     MockRead("Content-Length: 5\r\n\r\n"),
2229     MockRead("hello"),
2230   };
2231
2232   // An incorrect reconnect would cause this to be read.
2233   MockRead data_reads2[] = {
2234     MockRead(SYNCHRONOUS, ERR_FAILED),
2235   };
2236
2237   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2238                                  data_writes1, arraysize(data_writes1));
2239   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2240                                  NULL, 0);
2241   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2242   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2243
2244   TestCompletionCallback callback1;
2245
2246   scoped_ptr<HttpTransaction> trans(
2247       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2248   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2249   EXPECT_EQ(ERR_IO_PENDING, rv);
2250
2251   rv = callback1.WaitForResult();
2252   EXPECT_EQ(OK, rv);
2253
2254   const HttpResponseInfo* response = trans->GetResponseInfo();
2255   ASSERT_TRUE(response != NULL);
2256   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2257
2258   TestCompletionCallback callback2;
2259
2260   rv = trans->RestartWithAuth(
2261       AuthCredentials(kFoo, kBar), callback2.callback());
2262   EXPECT_EQ(ERR_IO_PENDING, rv);
2263
2264   rv = callback2.WaitForResult();
2265   EXPECT_EQ(OK, rv);
2266
2267   response = trans->GetResponseInfo();
2268   ASSERT_TRUE(response != NULL);
2269   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2270   EXPECT_EQ(5, response->headers->GetContentLength());
2271 }
2272
2273 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2274 // connection, but the server gets impatient and closes the connection.
2275 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
2276   HttpRequestInfo request;
2277   request.method = "GET";
2278   request.url = GURL("http://www.google.com/");
2279   request.load_flags = 0;
2280
2281   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2282
2283   MockWrite data_writes1[] = {
2284     MockWrite("GET / HTTP/1.1\r\n"
2285               "Host: www.google.com\r\n"
2286               "Connection: keep-alive\r\n\r\n"),
2287     // This simulates the seemingly successful write to a closed connection
2288     // if the bug is not fixed.
2289     MockWrite("GET / HTTP/1.1\r\n"
2290               "Host: www.google.com\r\n"
2291               "Connection: keep-alive\r\n"
2292               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2293   };
2294
2295   MockRead data_reads1[] = {
2296     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2297     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2298     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2299     MockRead("Content-Length: 14\r\n\r\n"),
2300     // Tell MockTCPClientSocket to simulate the server closing the connection.
2301     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2302     MockRead("Unauthorized\r\n"),
2303     MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
2304   };
2305
2306   // After calling trans->RestartWithAuth(), this is the request we should
2307   // be issuing -- the final header line contains the credentials.
2308   MockWrite data_writes2[] = {
2309     MockWrite("GET / HTTP/1.1\r\n"
2310               "Host: www.google.com\r\n"
2311               "Connection: keep-alive\r\n"
2312               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2313   };
2314
2315   // Lastly, the server responds with the actual content.
2316   MockRead data_reads2[] = {
2317     MockRead("HTTP/1.1 200 OK\r\n"),
2318     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2319     MockRead("Content-Length: 5\r\n\r\n"),
2320     MockRead("hello"),
2321   };
2322
2323   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2324                                  data_writes1, arraysize(data_writes1));
2325   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2326                                  data_writes2, arraysize(data_writes2));
2327   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2328   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2329
2330   TestCompletionCallback callback1;
2331
2332   scoped_ptr<HttpTransaction> trans(
2333       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2334   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2335   EXPECT_EQ(ERR_IO_PENDING, rv);
2336
2337   rv = callback1.WaitForResult();
2338   EXPECT_EQ(OK, rv);
2339
2340   const HttpResponseInfo* response = trans->GetResponseInfo();
2341   ASSERT_TRUE(response != NULL);
2342   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2343
2344   TestCompletionCallback callback2;
2345
2346   rv = trans->RestartWithAuth(
2347       AuthCredentials(kFoo, kBar), callback2.callback());
2348   EXPECT_EQ(ERR_IO_PENDING, rv);
2349
2350   rv = callback2.WaitForResult();
2351   EXPECT_EQ(OK, rv);
2352
2353   response = trans->GetResponseInfo();
2354   ASSERT_TRUE(response != NULL);
2355   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2356   EXPECT_EQ(5, response->headers->GetContentLength());
2357 }
2358
2359 // Test the request-challenge-retry sequence for basic auth, over a connection
2360 // that requires a restart when setting up an SSL tunnel.
2361 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
2362   HttpRequestInfo request;
2363   request.method = "GET";
2364   request.url = GURL("https://www.google.com/");
2365   // when the no authentication data flag is set.
2366   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2367
2368   // Configure against proxy server "myproxy:70".
2369   session_deps_.proxy_service.reset(
2370       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2371   CapturingBoundNetLog log;
2372   session_deps_.net_log = log.bound().net_log();
2373   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2374
2375   // Since we have proxy, should try to establish tunnel.
2376   MockWrite data_writes1[] = {
2377     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2378               "Host: www.google.com\r\n"
2379               "Proxy-Connection: keep-alive\r\n\r\n"),
2380
2381     // After calling trans->RestartWithAuth(), this is the request we should
2382     // be issuing -- the final header line contains the credentials.
2383     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2384               "Host: www.google.com\r\n"
2385               "Proxy-Connection: keep-alive\r\n"
2386               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2387
2388     MockWrite("GET / HTTP/1.1\r\n"
2389               "Host: www.google.com\r\n"
2390               "Connection: keep-alive\r\n\r\n"),
2391   };
2392
2393   // The proxy responds to the connect with a 407, using a persistent
2394   // connection.
2395   MockRead data_reads1[] = {
2396     // No credentials.
2397     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2398     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2399     MockRead("Proxy-Connection: close\r\n\r\n"),
2400
2401     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2402
2403     MockRead("HTTP/1.1 200 OK\r\n"),
2404     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2405     MockRead("Content-Length: 5\r\n\r\n"),
2406     MockRead(SYNCHRONOUS, "hello"),
2407   };
2408
2409   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2410                                  data_writes1, arraysize(data_writes1));
2411   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2412   SSLSocketDataProvider ssl(ASYNC, OK);
2413   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2414
2415   TestCompletionCallback callback1;
2416
2417   scoped_ptr<HttpTransaction> trans(
2418       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2419
2420   int rv = trans->Start(&request, callback1.callback(), log.bound());
2421   EXPECT_EQ(ERR_IO_PENDING, rv);
2422
2423   rv = callback1.WaitForResult();
2424   EXPECT_EQ(OK, rv);
2425   net::CapturingNetLog::CapturedEntryList entries;
2426   log.GetEntries(&entries);
2427   size_t pos = ExpectLogContainsSomewhere(
2428       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2429       NetLog::PHASE_NONE);
2430   ExpectLogContainsSomewhere(
2431       entries, pos,
2432       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2433       NetLog::PHASE_NONE);
2434
2435   const HttpResponseInfo* response = trans->GetResponseInfo();
2436   ASSERT_TRUE(response != NULL);
2437   ASSERT_FALSE(response->headers.get() == NULL);
2438   EXPECT_EQ(407, response->headers->response_code());
2439   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2440   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2441
2442   LoadTimingInfo load_timing_info;
2443   // CONNECT requests and responses are handled at the connect job level, so
2444   // the transaction does not yet have a connection.
2445   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2446
2447   TestCompletionCallback callback2;
2448
2449   rv = trans->RestartWithAuth(
2450       AuthCredentials(kFoo, kBar), callback2.callback());
2451   EXPECT_EQ(ERR_IO_PENDING, rv);
2452
2453   rv = callback2.WaitForResult();
2454   EXPECT_EQ(OK, rv);
2455
2456   response = trans->GetResponseInfo();
2457   ASSERT_TRUE(response != NULL);
2458
2459   EXPECT_TRUE(response->headers->IsKeepAlive());
2460   EXPECT_EQ(200, response->headers->response_code());
2461   EXPECT_EQ(5, response->headers->GetContentLength());
2462   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2463
2464   // The password prompt info should not be set.
2465   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2466
2467   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2468   TestLoadTimingNotReusedWithPac(load_timing_info,
2469                                  CONNECT_TIMING_HAS_SSL_TIMES);
2470
2471   trans.reset();
2472   session->CloseAllConnections();
2473 }
2474
2475 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2476 // proxy connection, when setting up an SSL tunnel.
2477 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
2478   HttpRequestInfo request;
2479   request.method = "GET";
2480   request.url = GURL("https://www.google.com/");
2481   // Ensure that proxy authentication is attempted even
2482   // when the no authentication data flag is set.
2483   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2484
2485   // Configure against proxy server "myproxy:70".
2486   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2487   CapturingBoundNetLog log;
2488   session_deps_.net_log = log.bound().net_log();
2489   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2490
2491   scoped_ptr<HttpTransaction> trans(
2492       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2493
2494   // Since we have proxy, should try to establish tunnel.
2495   MockWrite data_writes1[] = {
2496     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2497               "Host: www.google.com\r\n"
2498               "Proxy-Connection: keep-alive\r\n\r\n"),
2499
2500     // After calling trans->RestartWithAuth(), this is the request we should
2501     // be issuing -- the final header line contains the credentials.
2502     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2503               "Host: www.google.com\r\n"
2504               "Proxy-Connection: keep-alive\r\n"
2505               "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2506   };
2507
2508   // The proxy responds to the connect with a 407, using a persistent
2509   // connection.
2510   MockRead data_reads1[] = {
2511     // No credentials.
2512     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2513     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2514     MockRead("Content-Length: 10\r\n\r\n"),
2515     MockRead("0123456789"),
2516
2517     // Wrong credentials (wrong password).
2518     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2519     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2520     MockRead("Content-Length: 10\r\n\r\n"),
2521     // No response body because the test stops reading here.
2522     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
2523   };
2524
2525   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2526                                  data_writes1, arraysize(data_writes1));
2527   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2528
2529   TestCompletionCallback callback1;
2530
2531   int rv = trans->Start(&request, callback1.callback(), log.bound());
2532   EXPECT_EQ(ERR_IO_PENDING, rv);
2533
2534   rv = callback1.WaitForResult();
2535   EXPECT_EQ(OK, rv);
2536   net::CapturingNetLog::CapturedEntryList entries;
2537   log.GetEntries(&entries);
2538   size_t pos = ExpectLogContainsSomewhere(
2539       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2540       NetLog::PHASE_NONE);
2541   ExpectLogContainsSomewhere(
2542       entries, pos,
2543       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2544       NetLog::PHASE_NONE);
2545
2546   const HttpResponseInfo* response = trans->GetResponseInfo();
2547   ASSERT_TRUE(response != NULL);
2548   ASSERT_FALSE(response->headers.get() == NULL);
2549   EXPECT_TRUE(response->headers->IsKeepAlive());
2550   EXPECT_EQ(407, response->headers->response_code());
2551   EXPECT_EQ(10, response->headers->GetContentLength());
2552   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2553   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2554
2555   TestCompletionCallback callback2;
2556
2557   // Wrong password (should be "bar").
2558   rv = trans->RestartWithAuth(
2559       AuthCredentials(kFoo, kBaz), callback2.callback());
2560   EXPECT_EQ(ERR_IO_PENDING, rv);
2561
2562   rv = callback2.WaitForResult();
2563   EXPECT_EQ(OK, rv);
2564
2565   response = trans->GetResponseInfo();
2566   ASSERT_TRUE(response != NULL);
2567   ASSERT_FALSE(response->headers.get() == NULL);
2568   EXPECT_TRUE(response->headers->IsKeepAlive());
2569   EXPECT_EQ(407, response->headers->response_code());
2570   EXPECT_EQ(10, response->headers->GetContentLength());
2571   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2572   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2573
2574   // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2575   // out of scope.
2576   session->CloseAllConnections();
2577 }
2578
2579 // Test that we don't read the response body when we fail to establish a tunnel,
2580 // even if the user cancels the proxy's auth attempt.
2581 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
2582   HttpRequestInfo request;
2583   request.method = "GET";
2584   request.url = GURL("https://www.google.com/");
2585   request.load_flags = 0;
2586
2587   // Configure against proxy server "myproxy:70".
2588   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2589
2590   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2591
2592   scoped_ptr<HttpTransaction> trans(
2593       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2594
2595   // Since we have proxy, should try to establish tunnel.
2596   MockWrite data_writes[] = {
2597     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2598               "Host: www.google.com\r\n"
2599               "Proxy-Connection: keep-alive\r\n\r\n"),
2600   };
2601
2602   // The proxy responds to the connect with a 407.
2603   MockRead data_reads[] = {
2604     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2605     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2606     MockRead("Content-Length: 10\r\n\r\n"),
2607     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
2608   };
2609
2610   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2611                                 data_writes, arraysize(data_writes));
2612   session_deps_.socket_factory->AddSocketDataProvider(&data);
2613
2614   TestCompletionCallback callback;
2615
2616   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2617   EXPECT_EQ(ERR_IO_PENDING, rv);
2618
2619   rv = callback.WaitForResult();
2620   EXPECT_EQ(OK, rv);
2621
2622   const HttpResponseInfo* response = trans->GetResponseInfo();
2623   ASSERT_TRUE(response != NULL);
2624
2625   EXPECT_TRUE(response->headers->IsKeepAlive());
2626   EXPECT_EQ(407, response->headers->response_code());
2627   EXPECT_EQ(10, response->headers->GetContentLength());
2628   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2629
2630   std::string response_data;
2631   rv = ReadTransaction(trans.get(), &response_data);
2632   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
2633
2634   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
2635   session->CloseAllConnections();
2636 }
2637
2638 // Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2639 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
2640 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
2641   HttpRequestInfo request;
2642   request.method = "GET";
2643   request.url = GURL("http://www.google.com/");
2644   request.load_flags = 0;
2645
2646   // We are using a DIRECT connection (i.e. no proxy) for this session.
2647   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2648   scoped_ptr<HttpTransaction> trans(
2649       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
2650
2651   MockWrite data_writes1[] = {
2652     MockWrite("GET / HTTP/1.1\r\n"
2653               "Host: www.google.com\r\n"
2654               "Connection: keep-alive\r\n\r\n"),
2655   };
2656
2657   MockRead data_reads1[] = {
2658     MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2659     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2660     // Large content-length -- won't matter, as connection will be reset.
2661     MockRead("Content-Length: 10000\r\n\r\n"),
2662     MockRead(SYNCHRONOUS, ERR_FAILED),
2663   };
2664
2665   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2666                                  data_writes1, arraysize(data_writes1));
2667   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2668
2669   TestCompletionCallback callback;
2670
2671   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2672   EXPECT_EQ(ERR_IO_PENDING, rv);
2673
2674   rv = callback.WaitForResult();
2675   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2676 }
2677
2678 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2679 // through a non-authenticating proxy. The request should fail with
2680 // ERR_UNEXPECTED_PROXY_AUTH.
2681 // Note that it is impossible to detect if an HTTP server returns a 407 through
2682 // a non-authenticating proxy - there is nothing to indicate whether the
2683 // response came from the proxy or the server, so it is treated as if the proxy
2684 // issued the challenge.
2685 TEST_P(HttpNetworkTransactionTest,
2686        HttpsServerRequestsProxyAuthThroughProxy) {
2687   HttpRequestInfo request;
2688   request.method = "GET";
2689   request.url = GURL("https://www.google.com/");
2690
2691   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2692   CapturingBoundNetLog log;
2693   session_deps_.net_log = log.bound().net_log();
2694   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2695
2696   // Since we have proxy, should try to establish tunnel.
2697   MockWrite data_writes1[] = {
2698     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2699               "Host: www.google.com\r\n"
2700               "Proxy-Connection: keep-alive\r\n\r\n"),
2701
2702     MockWrite("GET / HTTP/1.1\r\n"
2703               "Host: www.google.com\r\n"
2704               "Connection: keep-alive\r\n\r\n"),
2705   };
2706
2707   MockRead data_reads1[] = {
2708     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2709
2710     MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2711     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2712     MockRead("\r\n"),
2713     MockRead(SYNCHRONOUS, OK),
2714   };
2715
2716   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2717                                  data_writes1, arraysize(data_writes1));
2718   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2719   SSLSocketDataProvider ssl(ASYNC, OK);
2720   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2721
2722   TestCompletionCallback callback1;
2723
2724   scoped_ptr<HttpTransaction> trans(
2725       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2726
2727   int rv = trans->Start(&request, callback1.callback(), log.bound());
2728   EXPECT_EQ(ERR_IO_PENDING, rv);
2729
2730   rv = callback1.WaitForResult();
2731   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2732   net::CapturingNetLog::CapturedEntryList entries;
2733   log.GetEntries(&entries);
2734   size_t pos = ExpectLogContainsSomewhere(
2735       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2736       NetLog::PHASE_NONE);
2737   ExpectLogContainsSomewhere(
2738       entries, pos,
2739       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2740       NetLog::PHASE_NONE);
2741 }
2742
2743 // Test the load timing for HTTPS requests with an HTTP proxy.
2744 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
2745   HttpRequestInfo request1;
2746   request1.method = "GET";
2747   request1.url = GURL("https://www.google.com/1");
2748
2749   HttpRequestInfo request2;
2750   request2.method = "GET";
2751   request2.url = GURL("https://www.google.com/2");
2752
2753   // Configure against proxy server "myproxy:70".
2754   session_deps_.proxy_service.reset(
2755       ProxyService::CreateFixed("PROXY myproxy:70"));
2756   CapturingBoundNetLog log;
2757   session_deps_.net_log = log.bound().net_log();
2758   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2759
2760   // Since we have proxy, should try to establish tunnel.
2761   MockWrite data_writes1[] = {
2762     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2763               "Host: www.google.com\r\n"
2764               "Proxy-Connection: keep-alive\r\n\r\n"),
2765
2766     MockWrite("GET /1 HTTP/1.1\r\n"
2767               "Host: www.google.com\r\n"
2768               "Connection: keep-alive\r\n\r\n"),
2769
2770     MockWrite("GET /2 HTTP/1.1\r\n"
2771               "Host: www.google.com\r\n"
2772               "Connection: keep-alive\r\n\r\n"),
2773   };
2774
2775   // The proxy responds to the connect with a 407, using a persistent
2776   // connection.
2777   MockRead data_reads1[] = {
2778     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2779
2780     MockRead("HTTP/1.1 200 OK\r\n"),
2781     MockRead("Content-Length: 1\r\n\r\n"),
2782     MockRead(SYNCHRONOUS, "1"),
2783
2784     MockRead("HTTP/1.1 200 OK\r\n"),
2785     MockRead("Content-Length: 2\r\n\r\n"),
2786     MockRead(SYNCHRONOUS, "22"),
2787   };
2788
2789   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2790                                  data_writes1, arraysize(data_writes1));
2791   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2792   SSLSocketDataProvider ssl(ASYNC, OK);
2793   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2794
2795   TestCompletionCallback callback1;
2796   scoped_ptr<HttpTransaction> trans1(
2797       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2798
2799   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2800   EXPECT_EQ(ERR_IO_PENDING, rv);
2801
2802   rv = callback1.WaitForResult();
2803   EXPECT_EQ(OK, rv);
2804
2805   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2806   ASSERT_TRUE(response1 != NULL);
2807   ASSERT_TRUE(response1->headers.get() != NULL);
2808   EXPECT_EQ(1, response1->headers->GetContentLength());
2809
2810   LoadTimingInfo load_timing_info1;
2811   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2812   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2813
2814   trans1.reset();
2815
2816   TestCompletionCallback callback2;
2817   scoped_ptr<HttpTransaction> trans2(
2818       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2819
2820   rv = trans2->Start(&request2, callback2.callback(), log.bound());
2821   EXPECT_EQ(ERR_IO_PENDING, rv);
2822
2823   rv = callback2.WaitForResult();
2824   EXPECT_EQ(OK, rv);
2825
2826   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2827   ASSERT_TRUE(response2 != NULL);
2828   ASSERT_TRUE(response2->headers.get() != NULL);
2829   EXPECT_EQ(2, response2->headers->GetContentLength());
2830
2831   LoadTimingInfo load_timing_info2;
2832   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2833   TestLoadTimingReused(load_timing_info2);
2834
2835   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2836
2837   trans2.reset();
2838   session->CloseAllConnections();
2839 }
2840
2841 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
2842 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
2843   HttpRequestInfo request1;
2844   request1.method = "GET";
2845   request1.url = GURL("https://www.google.com/1");
2846
2847   HttpRequestInfo request2;
2848   request2.method = "GET";
2849   request2.url = GURL("https://www.google.com/2");
2850
2851   // Configure against proxy server "myproxy:70".
2852   session_deps_.proxy_service.reset(
2853       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2854   CapturingBoundNetLog log;
2855   session_deps_.net_log = log.bound().net_log();
2856   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2857
2858   // Since we have proxy, should try to establish tunnel.
2859   MockWrite data_writes1[] = {
2860     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2861               "Host: www.google.com\r\n"
2862               "Proxy-Connection: keep-alive\r\n\r\n"),
2863
2864     MockWrite("GET /1 HTTP/1.1\r\n"
2865               "Host: www.google.com\r\n"
2866               "Connection: keep-alive\r\n\r\n"),
2867
2868     MockWrite("GET /2 HTTP/1.1\r\n"
2869               "Host: www.google.com\r\n"
2870               "Connection: keep-alive\r\n\r\n"),
2871   };
2872
2873   // The proxy responds to the connect with a 407, using a persistent
2874   // connection.
2875   MockRead data_reads1[] = {
2876     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2877
2878     MockRead("HTTP/1.1 200 OK\r\n"),
2879     MockRead("Content-Length: 1\r\n\r\n"),
2880     MockRead(SYNCHRONOUS, "1"),
2881
2882     MockRead("HTTP/1.1 200 OK\r\n"),
2883     MockRead("Content-Length: 2\r\n\r\n"),
2884     MockRead(SYNCHRONOUS, "22"),
2885   };
2886
2887   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2888                                  data_writes1, arraysize(data_writes1));
2889   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2890   SSLSocketDataProvider ssl(ASYNC, OK);
2891   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2892
2893   TestCompletionCallback callback1;
2894   scoped_ptr<HttpTransaction> trans1(
2895       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2896
2897   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2898   EXPECT_EQ(ERR_IO_PENDING, rv);
2899
2900   rv = callback1.WaitForResult();
2901   EXPECT_EQ(OK, rv);
2902
2903   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2904   ASSERT_TRUE(response1 != NULL);
2905   ASSERT_TRUE(response1->headers.get() != NULL);
2906   EXPECT_EQ(1, response1->headers->GetContentLength());
2907
2908   LoadTimingInfo load_timing_info1;
2909   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2910   TestLoadTimingNotReusedWithPac(load_timing_info1,
2911                                  CONNECT_TIMING_HAS_SSL_TIMES);
2912
2913   trans1.reset();
2914
2915   TestCompletionCallback callback2;
2916   scoped_ptr<HttpTransaction> trans2(
2917       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2918
2919   rv = trans2->Start(&request2, callback2.callback(), log.bound());
2920   EXPECT_EQ(ERR_IO_PENDING, rv);
2921
2922   rv = callback2.WaitForResult();
2923   EXPECT_EQ(OK, rv);
2924
2925   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2926   ASSERT_TRUE(response2 != NULL);
2927   ASSERT_TRUE(response2->headers.get() != NULL);
2928   EXPECT_EQ(2, response2->headers->GetContentLength());
2929
2930   LoadTimingInfo load_timing_info2;
2931   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2932   TestLoadTimingReusedWithPac(load_timing_info2);
2933
2934   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2935
2936   trans2.reset();
2937   session->CloseAllConnections();
2938 }
2939
2940 // Test a simple get through an HTTPS Proxy.
2941 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
2942   HttpRequestInfo request;
2943   request.method = "GET";
2944   request.url = GURL("http://www.google.com/");
2945
2946   // Configure against https proxy server "proxy:70".
2947   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
2948       "https://proxy:70"));
2949   CapturingBoundNetLog log;
2950   session_deps_.net_log = log.bound().net_log();
2951   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2952
2953   // Since we have proxy, should use full url
2954   MockWrite data_writes1[] = {
2955     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2956               "Host: www.google.com\r\n"
2957               "Proxy-Connection: keep-alive\r\n\r\n"),
2958   };
2959
2960   MockRead data_reads1[] = {
2961     MockRead("HTTP/1.1 200 OK\r\n"),
2962     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2963     MockRead("Content-Length: 100\r\n\r\n"),
2964     MockRead(SYNCHRONOUS, OK),
2965   };
2966
2967   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2968                                  data_writes1, arraysize(data_writes1));
2969   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2970   SSLSocketDataProvider ssl(ASYNC, OK);
2971   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2972
2973   TestCompletionCallback callback1;
2974
2975   scoped_ptr<HttpTransaction> trans(
2976       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2977
2978   int rv = trans->Start(&request, callback1.callback(), log.bound());
2979   EXPECT_EQ(ERR_IO_PENDING, rv);
2980
2981   rv = callback1.WaitForResult();
2982   EXPECT_EQ(OK, rv);
2983
2984   LoadTimingInfo load_timing_info;
2985   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2986   TestLoadTimingNotReused(load_timing_info,
2987                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2988
2989   const HttpResponseInfo* response = trans->GetResponseInfo();
2990   ASSERT_TRUE(response != NULL);
2991
2992   EXPECT_TRUE(response->headers->IsKeepAlive());
2993   EXPECT_EQ(200, response->headers->response_code());
2994   EXPECT_EQ(100, response->headers->GetContentLength());
2995   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2996
2997   // The password prompt info should not be set.
2998   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2999 }
3000
3001 // Test a SPDY get through an HTTPS Proxy.
3002 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
3003   HttpRequestInfo request;
3004   request.method = "GET";
3005   request.url = GURL("http://www.google.com/");
3006   request.load_flags = 0;
3007
3008   // Configure against https proxy server "proxy:70".
3009   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3010       "https://proxy:70"));
3011   CapturingBoundNetLog log;
3012   session_deps_.net_log = log.bound().net_log();
3013   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3014
3015   // fetch http://www.google.com/ via SPDY
3016   scoped_ptr<SpdyFrame> req(
3017       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3018   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
3019
3020   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3021   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3022   MockRead spdy_reads[] = {
3023     CreateMockRead(*resp),
3024     CreateMockRead(*data),
3025     MockRead(ASYNC, 0, 0),
3026   };
3027
3028   DelayedSocketData spdy_data(
3029       1,  // wait for one write to finish before reading.
3030       spdy_reads, arraysize(spdy_reads),
3031       spdy_writes, arraysize(spdy_writes));
3032   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3033
3034   SSLSocketDataProvider ssl(ASYNC, OK);
3035   ssl.SetNextProto(GetParam());
3036   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3037
3038   TestCompletionCallback callback1;
3039
3040   scoped_ptr<HttpTransaction> trans(
3041       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3042
3043   int rv = trans->Start(&request, callback1.callback(), log.bound());
3044   EXPECT_EQ(ERR_IO_PENDING, rv);
3045
3046   rv = callback1.WaitForResult();
3047   EXPECT_EQ(OK, rv);
3048
3049   LoadTimingInfo load_timing_info;
3050   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3051   TestLoadTimingNotReused(load_timing_info,
3052                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3053
3054   const HttpResponseInfo* response = trans->GetResponseInfo();
3055   ASSERT_TRUE(response != NULL);
3056   ASSERT_TRUE(response->headers.get() != NULL);
3057   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3058
3059   std::string response_data;
3060   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3061   EXPECT_EQ(kUploadData, response_data);
3062 }
3063
3064 // Verifies that a session which races and wins against the owning transaction
3065 // (completing prior to host resolution), doesn't fail the transaction.
3066 // Regression test for crbug.com/334413.
3067 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3068   HttpRequestInfo request;
3069   request.method = "GET";
3070   request.url = GURL("http://www.google.com/");
3071   request.load_flags = 0;
3072
3073   // Configure SPDY proxy server "proxy:70".
3074   session_deps_.proxy_service.reset(
3075       ProxyService::CreateFixed("https://proxy:70"));
3076   CapturingBoundNetLog log;
3077   session_deps_.net_log = log.bound().net_log();
3078   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3079
3080   // Fetch http://www.google.com/ through the SPDY proxy.
3081   scoped_ptr<SpdyFrame> req(
3082       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3083   MockWrite spdy_writes[] = {CreateMockWrite(*req)};
3084
3085   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3086   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3087   MockRead spdy_reads[] = {
3088       CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
3089   };
3090
3091   DelayedSocketData spdy_data(
3092       1,  // wait for one write to finish before reading.
3093       spdy_reads,
3094       arraysize(spdy_reads),
3095       spdy_writes,
3096       arraysize(spdy_writes));
3097   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3098
3099   SSLSocketDataProvider ssl(ASYNC, OK);
3100   ssl.SetNextProto(GetParam());
3101   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3102
3103   TestCompletionCallback callback1;
3104
3105   scoped_ptr<HttpTransaction> trans(
3106       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3107
3108   // Stall the hostname resolution begun by the transaction.
3109   session_deps_.host_resolver->set_synchronous_mode(false);
3110   session_deps_.host_resolver->set_ondemand_mode(true);
3111
3112   int rv = trans->Start(&request, callback1.callback(), log.bound());
3113   EXPECT_EQ(ERR_IO_PENDING, rv);
3114
3115   // Race a session to the proxy, which completes first.
3116   session_deps_.host_resolver->set_ondemand_mode(false);
3117   SpdySessionKey key(
3118       HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3119   base::WeakPtr<SpdySession> spdy_session =
3120       CreateSecureSpdySession(session, key, log.bound());
3121
3122   // Unstall the resolution begun by the transaction.
3123   session_deps_.host_resolver->set_ondemand_mode(true);
3124   session_deps_.host_resolver->ResolveAllPending();
3125
3126   EXPECT_FALSE(callback1.have_result());
3127   rv = callback1.WaitForResult();
3128   EXPECT_EQ(OK, rv);
3129
3130   const HttpResponseInfo* response = trans->GetResponseInfo();
3131   ASSERT_TRUE(response != NULL);
3132   ASSERT_TRUE(response->headers.get() != NULL);
3133   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3134
3135   std::string response_data;
3136   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3137   EXPECT_EQ(kUploadData, response_data);
3138 }
3139
3140 // Test a SPDY get through an HTTPS Proxy.
3141 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
3142   HttpRequestInfo request;
3143   request.method = "GET";
3144   request.url = GURL("http://www.google.com/");
3145   request.load_flags = 0;
3146
3147   // Configure against https proxy server "myproxy:70".
3148   session_deps_.proxy_service.reset(
3149       ProxyService::CreateFixed("https://myproxy:70"));
3150   CapturingBoundNetLog log;
3151   session_deps_.net_log = log.bound().net_log();
3152   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3153
3154   // The first request will be a bare GET, the second request will be a
3155   // GET with a Proxy-Authorization header.
3156   scoped_ptr<SpdyFrame> req_get(
3157       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3158   const char* const kExtraAuthorizationHeaders[] = {
3159     "proxy-authorization", "Basic Zm9vOmJhcg=="
3160   };
3161   scoped_ptr<SpdyFrame> req_get_authorization(
3162       spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3163                                   arraysize(kExtraAuthorizationHeaders) / 2,
3164                                   false,
3165                                   3,
3166                                   LOWEST,
3167                                   false));
3168   MockWrite spdy_writes[] = {
3169     CreateMockWrite(*req_get, 1),
3170     CreateMockWrite(*req_get_authorization, 4),
3171   };
3172
3173   // The first response is a 407 proxy authentication challenge, and the second
3174   // response will be a 200 response since the second request includes a valid
3175   // Authorization header.
3176   const char* const kExtraAuthenticationHeaders[] = {
3177     "proxy-authenticate", "Basic realm=\"MyRealm1\""
3178   };
3179   scoped_ptr<SpdyFrame> resp_authentication(
3180       spdy_util_.ConstructSpdySynReplyError(
3181           "407 Proxy Authentication Required",
3182           kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3183           1));
3184   scoped_ptr<SpdyFrame> body_authentication(
3185       spdy_util_.ConstructSpdyBodyFrame(1, true));
3186   scoped_ptr<SpdyFrame> resp_data(
3187       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3188   scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
3189   MockRead spdy_reads[] = {
3190     CreateMockRead(*resp_authentication, 2),
3191     CreateMockRead(*body_authentication, 3),
3192     CreateMockRead(*resp_data, 5),
3193     CreateMockRead(*body_data, 6),
3194     MockRead(ASYNC, 0, 7),
3195   };
3196
3197   OrderedSocketData data(
3198       spdy_reads, arraysize(spdy_reads),
3199       spdy_writes, arraysize(spdy_writes));
3200   session_deps_.socket_factory->AddSocketDataProvider(&data);
3201
3202   SSLSocketDataProvider ssl(ASYNC, OK);
3203   ssl.SetNextProto(GetParam());
3204   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3205
3206   TestCompletionCallback callback1;
3207
3208   scoped_ptr<HttpTransaction> trans(
3209       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3210
3211   int rv = trans->Start(&request, callback1.callback(), log.bound());
3212   EXPECT_EQ(ERR_IO_PENDING, rv);
3213
3214   rv = callback1.WaitForResult();
3215   EXPECT_EQ(OK, rv);
3216
3217   const HttpResponseInfo* const response = trans->GetResponseInfo();
3218
3219   ASSERT_TRUE(response != NULL);
3220   ASSERT_TRUE(response->headers.get() != NULL);
3221   EXPECT_EQ(407, response->headers->response_code());
3222   EXPECT_TRUE(response->was_fetched_via_spdy);
3223   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3224
3225   TestCompletionCallback callback2;
3226
3227   rv = trans->RestartWithAuth(
3228       AuthCredentials(kFoo, kBar), callback2.callback());
3229   EXPECT_EQ(ERR_IO_PENDING, rv);
3230
3231   rv = callback2.WaitForResult();
3232   EXPECT_EQ(OK, rv);
3233
3234   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3235
3236   ASSERT_TRUE(response_restart != NULL);
3237   ASSERT_TRUE(response_restart->headers.get() != NULL);
3238   EXPECT_EQ(200, response_restart->headers->response_code());
3239   // The password prompt info should not be set.
3240   EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3241 }
3242
3243 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
3244 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
3245   HttpRequestInfo request;
3246   request.method = "GET";
3247   request.url = GURL("https://www.google.com/");
3248   request.load_flags = 0;
3249
3250   // Configure against https proxy server "proxy:70".
3251   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3252       "https://proxy:70"));
3253   CapturingBoundNetLog log;
3254   session_deps_.net_log = log.bound().net_log();
3255   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3256
3257   scoped_ptr<HttpTransaction> trans(
3258       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3259
3260   // CONNECT to www.google.com:443 via SPDY
3261   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3262                                                                 LOWEST));
3263   // fetch https://www.google.com/ via HTTP
3264
3265   const char get[] = "GET / HTTP/1.1\r\n"
3266     "Host: www.google.com\r\n"
3267     "Connection: keep-alive\r\n\r\n";
3268   scoped_ptr<SpdyFrame> wrapped_get(
3269       spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3270   scoped_ptr<SpdyFrame> conn_resp(
3271       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3272   const char resp[] = "HTTP/1.1 200 OK\r\n"
3273       "Content-Length: 10\r\n\r\n";
3274   scoped_ptr<SpdyFrame> wrapped_get_resp(
3275       spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
3276   scoped_ptr<SpdyFrame> wrapped_body(
3277       spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
3278   scoped_ptr<SpdyFrame> window_update(
3279       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
3280
3281   MockWrite spdy_writes[] = {
3282       CreateMockWrite(*connect, 1),
3283       CreateMockWrite(*wrapped_get, 3),
3284       CreateMockWrite(*window_update, 5),
3285   };
3286
3287   MockRead spdy_reads[] = {
3288     CreateMockRead(*conn_resp, 2, ASYNC),
3289     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3290     CreateMockRead(*wrapped_body, 6, ASYNC),
3291     CreateMockRead(*wrapped_body, 7, ASYNC),
3292     MockRead(ASYNC, 0, 8),
3293   };
3294
3295   OrderedSocketData spdy_data(
3296       spdy_reads, arraysize(spdy_reads),
3297       spdy_writes, arraysize(spdy_writes));
3298   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3299
3300   SSLSocketDataProvider ssl(ASYNC, OK);
3301   ssl.SetNextProto(GetParam());
3302   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3303   SSLSocketDataProvider ssl2(ASYNC, OK);
3304   ssl2.was_npn_negotiated = false;
3305   ssl2.protocol_negotiated = kProtoUnknown;
3306   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
3307
3308   TestCompletionCallback callback1;
3309
3310   int rv = trans->Start(&request, callback1.callback(), log.bound());
3311   EXPECT_EQ(ERR_IO_PENDING, rv);
3312
3313   rv = callback1.WaitForResult();
3314   EXPECT_EQ(OK, rv);
3315
3316   LoadTimingInfo load_timing_info;
3317   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3318   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3319
3320   const HttpResponseInfo* response = trans->GetResponseInfo();
3321   ASSERT_TRUE(response != NULL);
3322   ASSERT_TRUE(response->headers.get() != NULL);
3323   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3324
3325   std::string response_data;
3326   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3327   EXPECT_EQ("1234567890", response_data);
3328 }
3329
3330 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
3331 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
3332   HttpRequestInfo request;
3333   request.method = "GET";
3334   request.url = GURL("https://www.google.com/");
3335   request.load_flags = 0;
3336
3337   // Configure against https proxy server "proxy:70".
3338   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3339       "https://proxy:70"));
3340   CapturingBoundNetLog log;
3341   session_deps_.net_log = log.bound().net_log();
3342   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3343
3344   scoped_ptr<HttpTransaction> trans(
3345       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3346
3347   // CONNECT to www.google.com:443 via SPDY
3348   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3349                                                                 LOWEST));
3350   // fetch https://www.google.com/ via SPDY
3351   const char* const kMyUrl = "https://www.google.com/";
3352   scoped_ptr<SpdyFrame> get(
3353       spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
3354   scoped_ptr<SpdyFrame> wrapped_get(
3355       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3356   scoped_ptr<SpdyFrame> conn_resp(
3357       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3358   scoped_ptr<SpdyFrame> get_resp(
3359       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3360   scoped_ptr<SpdyFrame> wrapped_get_resp(
3361       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3362   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3363   scoped_ptr<SpdyFrame> wrapped_body(
3364       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
3365   scoped_ptr<SpdyFrame> window_update_get_resp(
3366       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
3367   scoped_ptr<SpdyFrame> window_update_body(
3368       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
3369
3370   MockWrite spdy_writes[] = {
3371       CreateMockWrite(*connect, 1),
3372       CreateMockWrite(*wrapped_get, 3),
3373       CreateMockWrite(*window_update_get_resp, 5),
3374       CreateMockWrite(*window_update_body, 7),
3375   };
3376
3377   MockRead spdy_reads[] = {
3378     CreateMockRead(*conn_resp, 2, ASYNC),
3379     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3380     CreateMockRead(*wrapped_body, 6, ASYNC),
3381     MockRead(ASYNC, 0, 8),
3382   };
3383
3384   OrderedSocketData spdy_data(
3385       spdy_reads, arraysize(spdy_reads),
3386       spdy_writes, arraysize(spdy_writes));
3387   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3388
3389   SSLSocketDataProvider ssl(ASYNC, OK);
3390   ssl.SetNextProto(GetParam());
3391   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3392   SSLSocketDataProvider ssl2(ASYNC, OK);
3393   ssl2.SetNextProto(GetParam());
3394   ssl2.protocol_negotiated = GetParam();
3395   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
3396
3397   TestCompletionCallback callback1;
3398
3399   int rv = trans->Start(&request, callback1.callback(), log.bound());
3400   EXPECT_EQ(ERR_IO_PENDING, rv);
3401
3402   rv = callback1.WaitForResult();
3403   EXPECT_EQ(OK, rv);
3404
3405   LoadTimingInfo load_timing_info;
3406   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3407   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3408
3409   const HttpResponseInfo* response = trans->GetResponseInfo();
3410   ASSERT_TRUE(response != NULL);
3411   ASSERT_TRUE(response->headers.get() != NULL);
3412   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3413
3414   std::string response_data;
3415   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3416   EXPECT_EQ(kUploadData, response_data);
3417 }
3418
3419 // Test a SPDY CONNECT failure through an HTTPS Proxy.
3420 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
3421   HttpRequestInfo request;
3422   request.method = "GET";
3423   request.url = GURL("https://www.google.com/");
3424   request.load_flags = 0;
3425
3426   // Configure against https proxy server "proxy:70".
3427   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3428       "https://proxy:70"));
3429   CapturingBoundNetLog log;
3430   session_deps_.net_log = log.bound().net_log();
3431   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3432
3433   scoped_ptr<HttpTransaction> trans(
3434       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3435
3436   // CONNECT to www.google.com:443 via SPDY
3437   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3438                                                                 LOWEST));
3439   scoped_ptr<SpdyFrame> get(
3440       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
3441
3442   MockWrite spdy_writes[] = {
3443       CreateMockWrite(*connect, 1),
3444       CreateMockWrite(*get, 3),
3445   };
3446
3447   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3448   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3449   MockRead spdy_reads[] = {
3450     CreateMockRead(*resp, 2, ASYNC),
3451     MockRead(ASYNC, 0, 4),
3452   };
3453
3454   OrderedSocketData spdy_data(
3455       spdy_reads, arraysize(spdy_reads),
3456       spdy_writes, arraysize(spdy_writes));
3457   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3458
3459   SSLSocketDataProvider ssl(ASYNC, OK);
3460   ssl.SetNextProto(GetParam());
3461   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3462   SSLSocketDataProvider ssl2(ASYNC, OK);
3463   ssl2.SetNextProto(GetParam());
3464   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
3465
3466   TestCompletionCallback callback1;
3467
3468   int rv = trans->Start(&request, callback1.callback(), log.bound());
3469   EXPECT_EQ(ERR_IO_PENDING, rv);
3470
3471   rv = callback1.WaitForResult();
3472   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3473
3474   // TODO(ttuttle): Anything else to check here?
3475 }
3476
3477 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3478 // HTTPS Proxy to different servers.
3479 TEST_P(HttpNetworkTransactionTest,
3480        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3481   // Configure against https proxy server "proxy:70".
3482   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3483       "https://proxy:70"));
3484   CapturingBoundNetLog log;
3485   session_deps_.net_log = log.bound().net_log();
3486   scoped_refptr<HttpNetworkSession> session(
3487       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
3488
3489   HttpRequestInfo request1;
3490   request1.method = "GET";
3491   request1.url = GURL("https://www.google.com/");
3492   request1.load_flags = 0;
3493
3494   HttpRequestInfo request2;
3495   request2.method = "GET";
3496   request2.url = GURL("https://news.google.com/");
3497   request2.load_flags = 0;
3498
3499   // CONNECT to www.google.com:443 via SPDY.
3500   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3501                                                                  LOWEST));
3502   scoped_ptr<SpdyFrame> conn_resp1(
3503       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3504
3505   // Fetch https://www.google.com/ via HTTP.
3506   const char get1[] = "GET / HTTP/1.1\r\n"
3507       "Host: www.google.com\r\n"
3508       "Connection: keep-alive\r\n\r\n";
3509   scoped_ptr<SpdyFrame> wrapped_get1(
3510       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
3511   const char resp1[] = "HTTP/1.1 200 OK\r\n"
3512       "Content-Length: 1\r\n\r\n";
3513   scoped_ptr<SpdyFrame> wrapped_get_resp1(
3514       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3515   scoped_ptr<SpdyFrame> wrapped_body1(
3516       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
3517   scoped_ptr<SpdyFrame> window_update(
3518       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
3519
3520   // CONNECT to news.google.com:443 via SPDY.
3521   SpdyHeaderBlock connect2_block;
3522   connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
3523   connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443";
3524   connect2_block[spdy_util_.GetHostKey()] = "news.google.com";
3525   spdy_util_.MaybeAddVersionHeader(&connect2_block);
3526   scoped_ptr<SpdyFrame> connect2(
3527       spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
3528
3529   scoped_ptr<SpdyFrame> conn_resp2(
3530       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3531
3532   // Fetch https://news.google.com/ via HTTP.
3533   const char get2[] = "GET / HTTP/1.1\r\n"
3534       "Host: news.google.com\r\n"
3535       "Connection: keep-alive\r\n\r\n";
3536   scoped_ptr<SpdyFrame> wrapped_get2(
3537       spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
3538   const char resp2[] = "HTTP/1.1 200 OK\r\n"
3539       "Content-Length: 2\r\n\r\n";
3540   scoped_ptr<SpdyFrame> wrapped_get_resp2(
3541       spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
3542   scoped_ptr<SpdyFrame> wrapped_body2(
3543       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
3544
3545   MockWrite spdy_writes[] = {
3546       CreateMockWrite(*connect1, 0),
3547       CreateMockWrite(*wrapped_get1, 2),
3548       CreateMockWrite(*connect2, 5),
3549       CreateMockWrite(*wrapped_get2, 7),
3550   };
3551
3552   MockRead spdy_reads[] = {
3553     CreateMockRead(*conn_resp1, 1, ASYNC),
3554     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3555     CreateMockRead(*wrapped_body1, 4, ASYNC),
3556     CreateMockRead(*conn_resp2, 6, ASYNC),
3557     CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3558     CreateMockRead(*wrapped_body2, 9, ASYNC),
3559     MockRead(ASYNC, 0, 10),
3560   };
3561
3562   DeterministicSocketData spdy_data(
3563       spdy_reads, arraysize(spdy_reads),
3564       spdy_writes, arraysize(spdy_writes));
3565   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
3566
3567   SSLSocketDataProvider ssl(ASYNC, OK);
3568   ssl.SetNextProto(GetParam());
3569   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3570   SSLSocketDataProvider ssl2(ASYNC, OK);
3571   ssl2.was_npn_negotiated = false;
3572   ssl2.protocol_negotiated = kProtoUnknown;
3573   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
3574   SSLSocketDataProvider ssl3(ASYNC, OK);
3575   ssl3.was_npn_negotiated = false;
3576   ssl3.protocol_negotiated = kProtoUnknown;
3577   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
3578
3579   TestCompletionCallback callback;
3580
3581   scoped_ptr<HttpTransaction> trans(
3582       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3583   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3584   EXPECT_EQ(ERR_IO_PENDING, rv);
3585   // The first connect and request, each of their responses, and the body.
3586   spdy_data.RunFor(5);
3587
3588   rv = callback.WaitForResult();
3589   EXPECT_EQ(OK, rv);
3590
3591   LoadTimingInfo load_timing_info;
3592   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3593   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3594
3595   const HttpResponseInfo* response = trans->GetResponseInfo();
3596   ASSERT_TRUE(response != NULL);
3597   ASSERT_TRUE(response->headers.get() != NULL);
3598   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3599
3600   std::string response_data;
3601   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3602   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
3603
3604   scoped_ptr<HttpTransaction> trans2(
3605       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3606   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3607   EXPECT_EQ(ERR_IO_PENDING, rv);
3608
3609   // The second connect and request, each of their responses, and the body.
3610   spdy_data.RunFor(5);
3611   rv = callback.WaitForResult();
3612   EXPECT_EQ(OK, rv);
3613
3614   LoadTimingInfo load_timing_info2;
3615   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3616   // Even though the SPDY connection is reused, a new tunnelled connection has
3617   // to be created, so the socket's load timing looks like a fresh connection.
3618   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3619
3620   // The requests should have different IDs, since they each are using their own
3621   // separate stream.
3622   EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3623
3624   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
3625 }
3626
3627 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3628 // HTTPS Proxy to the same server.
3629 TEST_P(HttpNetworkTransactionTest,
3630        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3631   // Configure against https proxy server "proxy:70".
3632   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3633       "https://proxy:70"));
3634   CapturingBoundNetLog log;
3635   session_deps_.net_log = log.bound().net_log();
3636   scoped_refptr<HttpNetworkSession> session(
3637       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
3638
3639   HttpRequestInfo request1;
3640   request1.method = "GET";
3641   request1.url = GURL("https://www.google.com/");
3642   request1.load_flags = 0;
3643
3644   HttpRequestInfo request2;
3645   request2.method = "GET";
3646   request2.url = GURL("https://www.google.com/2");
3647   request2.load_flags = 0;
3648
3649   // CONNECT to www.google.com:443 via SPDY.
3650   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3651                                                                  LOWEST));
3652   scoped_ptr<SpdyFrame> conn_resp1(
3653       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3654
3655   // Fetch https://www.google.com/ via HTTP.
3656   const char get1[] = "GET / HTTP/1.1\r\n"
3657       "Host: www.google.com\r\n"
3658       "Connection: keep-alive\r\n\r\n";
3659   scoped_ptr<SpdyFrame> wrapped_get1(
3660       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
3661   const char resp1[] = "HTTP/1.1 200 OK\r\n"
3662       "Content-Length: 1\r\n\r\n";
3663   scoped_ptr<SpdyFrame> wrapped_get_resp1(
3664       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3665   scoped_ptr<SpdyFrame> wrapped_body1(
3666       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
3667   scoped_ptr<SpdyFrame> window_update(
3668       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
3669
3670   // Fetch https://www.google.com/2 via HTTP.
3671   const char get2[] = "GET /2 HTTP/1.1\r\n"
3672       "Host: www.google.com\r\n"
3673       "Connection: keep-alive\r\n\r\n";
3674   scoped_ptr<SpdyFrame> wrapped_get2(
3675       spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
3676   const char resp2[] = "HTTP/1.1 200 OK\r\n"
3677       "Content-Length: 2\r\n\r\n";
3678   scoped_ptr<SpdyFrame> wrapped_get_resp2(
3679       spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
3680   scoped_ptr<SpdyFrame> wrapped_body2(
3681       spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
3682
3683   MockWrite spdy_writes[] = {
3684       CreateMockWrite(*connect1, 0),
3685       CreateMockWrite(*wrapped_get1, 2),
3686       CreateMockWrite(*wrapped_get2, 5),
3687   };
3688
3689   MockRead spdy_reads[] = {
3690     CreateMockRead(*conn_resp1, 1, ASYNC),
3691     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3692     CreateMockRead(*wrapped_body1, 4, ASYNC),
3693     CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3694     CreateMockRead(*wrapped_body2, 7, ASYNC),
3695     MockRead(ASYNC, 0, 8),
3696   };
3697
3698   DeterministicSocketData spdy_data(
3699       spdy_reads, arraysize(spdy_reads),
3700       spdy_writes, arraysize(spdy_writes));
3701   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
3702
3703   SSLSocketDataProvider ssl(ASYNC, OK);
3704   ssl.SetNextProto(GetParam());
3705   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3706   SSLSocketDataProvider ssl2(ASYNC, OK);
3707   ssl2.was_npn_negotiated = false;
3708   ssl2.protocol_negotiated = kProtoUnknown;
3709   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
3710
3711   TestCompletionCallback callback;
3712
3713   scoped_ptr<HttpTransaction> trans(
3714       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3715   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3716   EXPECT_EQ(ERR_IO_PENDING, rv);
3717   // The first connect and request, each of their responses, and the body.
3718   spdy_data.RunFor(5);
3719
3720   rv = callback.WaitForResult();
3721   EXPECT_EQ(OK, rv);
3722
3723   LoadTimingInfo load_timing_info;
3724   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3725   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3726
3727   const HttpResponseInfo* response = trans->GetResponseInfo();
3728   ASSERT_TRUE(response != NULL);
3729   ASSERT_TRUE(response->headers.get() != NULL);
3730   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3731
3732   std::string response_data;
3733   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3734   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
3735   trans.reset();
3736
3737   scoped_ptr<HttpTransaction> trans2(
3738       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3739   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3740   EXPECT_EQ(ERR_IO_PENDING, rv);
3741
3742   // The second request, response, and body.  There should not be a second
3743   // connect.
3744   spdy_data.RunFor(3);
3745   rv = callback.WaitForResult();
3746   EXPECT_EQ(OK, rv);
3747
3748   LoadTimingInfo load_timing_info2;
3749   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3750   TestLoadTimingReused(load_timing_info2);
3751
3752   // The requests should have the same ID.
3753   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3754
3755   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
3756 }
3757
3758 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3759 // Proxy to different servers.
3760 TEST_P(HttpNetworkTransactionTest,
3761        HttpsProxySpdyLoadTimingTwoHttpRequests) {
3762   // Configure against https proxy server "proxy:70".
3763   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3764       "https://proxy:70"));
3765   CapturingBoundNetLog log;
3766   session_deps_.net_log = log.bound().net_log();
3767   scoped_refptr<HttpNetworkSession> session(
3768       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
3769
3770   HttpRequestInfo request1;
3771   request1.method = "GET";
3772   request1.url = GURL("http://www.google.com/");
3773   request1.load_flags = 0;
3774
3775   HttpRequestInfo request2;
3776   request2.method = "GET";
3777   request2.url = GURL("http://news.google.com/");
3778   request2.load_flags = 0;
3779
3780   // http://www.google.com/
3781   scoped_ptr<SpdyHeaderBlock> headers(
3782       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
3783   scoped_ptr<SpdyFrame> get1(
3784       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
3785   scoped_ptr<SpdyFrame> get_resp1(
3786       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3787   scoped_ptr<SpdyFrame> body1(
3788       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
3789
3790   // http://news.google.com/
3791   scoped_ptr<SpdyHeaderBlock> headers2(
3792       spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
3793   scoped_ptr<SpdyFrame> get2(
3794       spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
3795   scoped_ptr<SpdyFrame> get_resp2(
3796       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3797   scoped_ptr<SpdyFrame> body2(
3798       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
3799
3800   MockWrite spdy_writes[] = {
3801       CreateMockWrite(*get1, 0),
3802       CreateMockWrite(*get2, 3),
3803   };
3804
3805   MockRead spdy_reads[] = {
3806     CreateMockRead(*get_resp1, 1, ASYNC),
3807     CreateMockRead(*body1, 2, ASYNC),
3808     CreateMockRead(*get_resp2, 4, ASYNC),
3809     CreateMockRead(*body2, 5, ASYNC),
3810     MockRead(ASYNC, 0, 6),
3811   };
3812
3813   DeterministicSocketData spdy_data(
3814       spdy_reads, arraysize(spdy_reads),
3815       spdy_writes, arraysize(spdy_writes));
3816   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
3817
3818   SSLSocketDataProvider ssl(ASYNC, OK);
3819   ssl.SetNextProto(GetParam());
3820   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3821
3822   TestCompletionCallback callback;
3823
3824   scoped_ptr<HttpTransaction> trans(
3825       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3826   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3827   EXPECT_EQ(ERR_IO_PENDING, rv);
3828   spdy_data.RunFor(2);
3829
3830   rv = callback.WaitForResult();
3831   EXPECT_EQ(OK, rv);
3832
3833   LoadTimingInfo load_timing_info;
3834   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3835   TestLoadTimingNotReused(load_timing_info,
3836                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3837
3838   const HttpResponseInfo* response = trans->GetResponseInfo();
3839   ASSERT_TRUE(response != NULL);
3840   ASSERT_TRUE(response->headers.get() != NULL);
3841   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3842
3843   std::string response_data;
3844   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3845   EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
3846   spdy_data.RunFor(1);
3847   EXPECT_EQ(1, callback.WaitForResult());
3848   // Delete the first request, so the second one can reuse the socket.
3849   trans.reset();
3850
3851   scoped_ptr<HttpTransaction> trans2(
3852       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3853   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3854   EXPECT_EQ(ERR_IO_PENDING, rv);
3855
3856   spdy_data.RunFor(2);
3857   rv = callback.WaitForResult();
3858   EXPECT_EQ(OK, rv);
3859
3860   LoadTimingInfo load_timing_info2;
3861   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3862   TestLoadTimingReused(load_timing_info2);
3863
3864   // The requests should have the same ID.
3865   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3866
3867   EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
3868   spdy_data.RunFor(1);
3869   EXPECT_EQ(2, callback.WaitForResult());
3870 }
3871
3872 // Test the challenge-response-retry sequence through an HTTPS Proxy
3873 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
3874   HttpRequestInfo request;
3875   request.method = "GET";
3876   request.url = GURL("http://www.google.com/");
3877   // when the no authentication data flag is set.
3878   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3879
3880   // Configure against https proxy server "myproxy:70".
3881   session_deps_.proxy_service.reset(
3882       ProxyService::CreateFixed("https://myproxy:70"));
3883   CapturingBoundNetLog log;
3884   session_deps_.net_log = log.bound().net_log();
3885   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3886
3887   // Since we have proxy, should use full url
3888   MockWrite data_writes1[] = {
3889     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3890               "Host: www.google.com\r\n"
3891               "Proxy-Connection: keep-alive\r\n\r\n"),
3892
3893     // After calling trans->RestartWithAuth(), this is the request we should
3894     // be issuing -- the final header line contains the credentials.
3895     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3896               "Host: www.google.com\r\n"
3897               "Proxy-Connection: keep-alive\r\n"
3898               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3899   };
3900
3901   // The proxy responds to the GET with a 407, using a persistent
3902   // connection.
3903   MockRead data_reads1[] = {
3904     // No credentials.
3905     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3906     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3907     MockRead("Proxy-Connection: keep-alive\r\n"),
3908     MockRead("Content-Length: 0\r\n\r\n"),
3909
3910     MockRead("HTTP/1.1 200 OK\r\n"),
3911     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3912     MockRead("Content-Length: 100\r\n\r\n"),
3913     MockRead(SYNCHRONOUS, OK),
3914   };
3915
3916   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3917                                  data_writes1, arraysize(data_writes1));
3918   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3919   SSLSocketDataProvider ssl(ASYNC, OK);
3920   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3921
3922   TestCompletionCallback callback1;
3923
3924   scoped_ptr<HttpTransaction> trans(
3925       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3926
3927   int rv = trans->Start(&request, callback1.callback(), log.bound());
3928   EXPECT_EQ(ERR_IO_PENDING, rv);
3929
3930   rv = callback1.WaitForResult();
3931   EXPECT_EQ(OK, rv);
3932
3933   LoadTimingInfo load_timing_info;
3934   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3935   TestLoadTimingNotReused(load_timing_info,
3936                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3937
3938   const HttpResponseInfo* response = trans->GetResponseInfo();
3939   ASSERT_TRUE(response != NULL);
3940   ASSERT_FALSE(response->headers.get() == NULL);
3941   EXPECT_EQ(407, response->headers->response_code());
3942   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3943   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3944
3945   TestCompletionCallback callback2;
3946
3947   rv = trans->RestartWithAuth(
3948       AuthCredentials(kFoo, kBar), callback2.callback());
3949   EXPECT_EQ(ERR_IO_PENDING, rv);
3950
3951   rv = callback2.WaitForResult();
3952   EXPECT_EQ(OK, rv);
3953
3954   load_timing_info = LoadTimingInfo();
3955   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3956   // Retrying with HTTP AUTH is considered to be reusing a socket.
3957   TestLoadTimingReused(load_timing_info);
3958
3959   response = trans->GetResponseInfo();
3960   ASSERT_TRUE(response != NULL);
3961
3962   EXPECT_TRUE(response->headers->IsKeepAlive());
3963   EXPECT_EQ(200, response->headers->response_code());
3964   EXPECT_EQ(100, response->headers->GetContentLength());
3965   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3966
3967   // The password prompt info should not be set.
3968   EXPECT_TRUE(response->auth_challenge.get() == NULL);
3969 }
3970
3971 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
3972     const MockRead& status, int expected_status) {
3973   HttpRequestInfo request;
3974   request.method = "GET";
3975   request.url = GURL("https://www.google.com/");
3976   request.load_flags = 0;
3977
3978   // Configure against proxy server "myproxy:70".
3979   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3980   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3981
3982   // Since we have proxy, should try to establish tunnel.
3983   MockWrite data_writes[] = {
3984     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
3985               "Host: www.google.com\r\n"
3986               "Proxy-Connection: keep-alive\r\n\r\n"),
3987   };
3988
3989   MockRead data_reads[] = {
3990     status,
3991     MockRead("Content-Length: 10\r\n\r\n"),
3992     // No response body because the test stops reading here.
3993     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
3994   };
3995
3996   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3997                                 data_writes, arraysize(data_writes));
3998   session_deps_.socket_factory->AddSocketDataProvider(&data);
3999
4000   TestCompletionCallback callback;
4001
4002   scoped_ptr<HttpTransaction> trans(
4003       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4004
4005   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4006   EXPECT_EQ(ERR_IO_PENDING, rv);
4007
4008   rv = callback.WaitForResult();
4009   EXPECT_EQ(expected_status, rv);
4010 }
4011
4012 void HttpNetworkTransactionTest::ConnectStatusHelper(
4013     const MockRead& status) {
4014   ConnectStatusHelperWithExpectedStatus(
4015       status, ERR_TUNNEL_CONNECTION_FAILED);
4016 }
4017
4018 TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
4019   ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4020 }
4021
4022 TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
4023   ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4024 }
4025
4026 TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
4027   ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4028 }
4029
4030 TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
4031   ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4032 }
4033
4034 TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
4035   ConnectStatusHelper(
4036       MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4037 }
4038
4039 TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
4040   ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4041 }
4042
4043 TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
4044   ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4045 }
4046
4047 TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
4048   ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4049 }
4050
4051 TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
4052   ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4053 }
4054
4055 TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
4056   ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4057 }
4058
4059 TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
4060   ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4061 }
4062
4063 TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
4064   ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4065 }
4066
4067 TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
4068   ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4069 }
4070
4071 TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
4072   ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4073 }
4074
4075 TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
4076   ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4077 }
4078
4079 TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
4080   ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4081 }
4082
4083 TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4084   ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4085 }
4086
4087 TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
4088   ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4089 }
4090
4091 TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
4092   ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4093 }
4094
4095 TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
4096   ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4097 }
4098
4099 TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
4100   ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4101 }
4102
4103 TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
4104   ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4105 }
4106
4107 TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
4108   ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4109 }
4110
4111 TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
4112   ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4113 }
4114
4115 TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
4116   ConnectStatusHelperWithExpectedStatus(
4117       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4118       ERR_PROXY_AUTH_UNSUPPORTED);
4119 }
4120
4121 TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
4122   ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4123 }
4124
4125 TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
4126   ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4127 }
4128
4129 TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
4130   ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4131 }
4132
4133 TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
4134   ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4135 }
4136
4137 TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
4138   ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4139 }
4140
4141 TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
4142   ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4143 }
4144
4145 TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
4146   ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4147 }
4148
4149 TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
4150   ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4151 }
4152
4153 TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
4154   ConnectStatusHelper(
4155       MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4156 }
4157
4158 TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
4159   ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4160 }
4161
4162 TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
4163   ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4164 }
4165
4166 TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
4167   ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4168 }
4169
4170 TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
4171   ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4172 }
4173
4174 TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
4175   ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4176 }
4177
4178 TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
4179   ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4180 }
4181
4182 TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
4183   ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4184 }
4185
4186 // Test the flow when both the proxy server AND origin server require
4187 // authentication. Again, this uses basic auth for both since that is
4188 // the simplest to mock.
4189 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
4190   HttpRequestInfo request;
4191   request.method = "GET";
4192   request.url = GURL("http://www.google.com/");
4193   request.load_flags = 0;
4194
4195   // Configure against proxy server "myproxy:70".
4196   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4197   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4198
4199   scoped_ptr<HttpTransaction> trans(
4200       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
4201
4202   MockWrite data_writes1[] = {
4203     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4204               "Host: www.google.com\r\n"
4205               "Proxy-Connection: keep-alive\r\n\r\n"),
4206   };
4207
4208   MockRead data_reads1[] = {
4209     MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4210     // Give a couple authenticate options (only the middle one is actually
4211     // supported).
4212     MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
4213     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4214     MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4215     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4216     // Large content-length -- won't matter, as connection will be reset.
4217     MockRead("Content-Length: 10000\r\n\r\n"),
4218     MockRead(SYNCHRONOUS, ERR_FAILED),
4219   };
4220
4221   // After calling trans->RestartWithAuth() the first time, this is the
4222   // request we should be issuing -- the final header line contains the
4223   // proxy's credentials.
4224   MockWrite data_writes2[] = {
4225     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4226               "Host: www.google.com\r\n"
4227               "Proxy-Connection: keep-alive\r\n"
4228               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4229   };
4230
4231   // Now the proxy server lets the request pass through to origin server.
4232   // The origin server responds with a 401.
4233   MockRead data_reads2[] = {
4234     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4235     // Note: We are using the same realm-name as the proxy server. This is
4236     // completely valid, as realms are unique across hosts.
4237     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4238     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4239     MockRead("Content-Length: 2000\r\n\r\n"),
4240     MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
4241   };
4242
4243   // After calling trans->RestartWithAuth() the second time, we should send
4244   // the credentials for both the proxy and origin server.
4245   MockWrite data_writes3[] = {
4246     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4247               "Host: www.google.com\r\n"
4248               "Proxy-Connection: keep-alive\r\n"
4249               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4250               "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4251   };
4252
4253   // Lastly we get the desired content.
4254   MockRead data_reads3[] = {
4255     MockRead("HTTP/1.0 200 OK\r\n"),
4256     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4257     MockRead("Content-Length: 100\r\n\r\n"),
4258     MockRead(SYNCHRONOUS, OK),
4259   };
4260
4261   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4262                                  data_writes1, arraysize(data_writes1));
4263   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4264                                  data_writes2, arraysize(data_writes2));
4265   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4266                                  data_writes3, arraysize(data_writes3));
4267   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4268   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4269   session_deps_.socket_factory->AddSocketDataProvider(&data3);
4270
4271   TestCompletionCallback callback1;
4272
4273   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4274   EXPECT_EQ(ERR_IO_PENDING, rv);
4275
4276   rv = callback1.WaitForResult();
4277   EXPECT_EQ(OK, rv);
4278
4279   const HttpResponseInfo* response = trans->GetResponseInfo();
4280   ASSERT_TRUE(response != NULL);
4281   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
4282
4283   TestCompletionCallback callback2;
4284
4285   rv = trans->RestartWithAuth(
4286       AuthCredentials(kFoo, kBar), callback2.callback());
4287   EXPECT_EQ(ERR_IO_PENDING, rv);
4288
4289   rv = callback2.WaitForResult();
4290   EXPECT_EQ(OK, rv);
4291
4292   response = trans->GetResponseInfo();
4293   ASSERT_TRUE(response != NULL);
4294   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4295
4296   TestCompletionCallback callback3;
4297
4298   rv = trans->RestartWithAuth(
4299       AuthCredentials(kFoo2, kBar2), callback3.callback());
4300   EXPECT_EQ(ERR_IO_PENDING, rv);
4301
4302   rv = callback3.WaitForResult();
4303   EXPECT_EQ(OK, rv);
4304
4305   response = trans->GetResponseInfo();
4306   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4307   EXPECT_EQ(100, response->headers->GetContentLength());
4308 }
4309
4310 // For the NTLM implementation using SSPI, we skip the NTLM tests since we
4311 // can't hook into its internals to cause it to generate predictable NTLM
4312 // authorization headers.
4313 #if defined(NTLM_PORTABLE)
4314 // The NTLM authentication unit tests were generated by capturing the HTTP
4315 // requests and responses using Fiddler 2 and inspecting the generated random
4316 // bytes in the debugger.
4317
4318 // Enter the correct password and authenticate successfully.
4319 TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
4320   HttpRequestInfo request;
4321   request.method = "GET";
4322   request.url = GURL("http://172.22.68.17/kids/login.aspx");
4323
4324   // Ensure load is not disrupted by flags which suppress behaviour specific
4325   // to other auth schemes.
4326   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
4327
4328   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4329                                                     MockGetHostName);
4330   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4331
4332   MockWrite data_writes1[] = {
4333     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4334               "Host: 172.22.68.17\r\n"
4335               "Connection: keep-alive\r\n\r\n"),
4336   };
4337
4338   MockRead data_reads1[] = {
4339     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4340     // Negotiate and NTLM are often requested together.  However, we only want
4341     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4342     // the header that requests Negotiate for this test.
4343     MockRead("WWW-Authenticate: NTLM\r\n"),
4344     MockRead("Connection: close\r\n"),
4345     MockRead("Content-Length: 42\r\n"),
4346     MockRead("Content-Type: text/html\r\n\r\n"),
4347     // Missing content -- won't matter, as connection will be reset.
4348     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4349   };
4350
4351   MockWrite data_writes2[] = {
4352     // After restarting with a null identity, this is the
4353     // request we should be issuing -- the final header line contains a Type
4354     // 1 message.
4355     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4356               "Host: 172.22.68.17\r\n"
4357               "Connection: keep-alive\r\n"
4358               "Authorization: NTLM "
4359               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4360
4361     // After calling trans->RestartWithAuth(), we should send a Type 3 message
4362     // (the credentials for the origin server).  The second request continues
4363     // on the same connection.
4364     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4365               "Host: 172.22.68.17\r\n"
4366               "Connection: keep-alive\r\n"
4367               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4368               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4369               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4370               "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4371               "ahlhx5I=\r\n\r\n"),
4372   };
4373
4374   MockRead data_reads2[] = {
4375     // The origin server responds with a Type 2 message.
4376     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4377     MockRead("WWW-Authenticate: NTLM "
4378              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
4379              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4380              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4381              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4382              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4383              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4384              "BtAAAAAAA=\r\n"),
4385     MockRead("Content-Length: 42\r\n"),
4386     MockRead("Content-Type: text/html\r\n\r\n"),
4387     MockRead("You are not authorized to view this page\r\n"),
4388
4389     // Lastly we get the desired content.
4390     MockRead("HTTP/1.1 200 OK\r\n"),
4391     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4392     MockRead("Content-Length: 13\r\n\r\n"),
4393     MockRead("Please Login\r\n"),
4394     MockRead(SYNCHRONOUS, OK),
4395   };
4396
4397   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4398                                  data_writes1, arraysize(data_writes1));
4399   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4400                                  data_writes2, arraysize(data_writes2));
4401   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4402   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4403
4404   TestCompletionCallback callback1;
4405
4406   scoped_ptr<HttpTransaction> trans(
4407       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4408
4409   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4410   EXPECT_EQ(ERR_IO_PENDING, rv);
4411
4412   rv = callback1.WaitForResult();
4413   EXPECT_EQ(OK, rv);
4414
4415   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4416
4417   const HttpResponseInfo* response = trans->GetResponseInfo();
4418   ASSERT_FALSE(response == NULL);
4419   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
4420
4421   TestCompletionCallback callback2;
4422
4423   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
4424                               callback2.callback());
4425   EXPECT_EQ(ERR_IO_PENDING, rv);
4426
4427   rv = callback2.WaitForResult();
4428   EXPECT_EQ(OK, rv);
4429
4430   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4431
4432   response = trans->GetResponseInfo();
4433   ASSERT_TRUE(response != NULL);
4434   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4435
4436   TestCompletionCallback callback3;
4437
4438   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
4439   EXPECT_EQ(ERR_IO_PENDING, rv);
4440
4441   rv = callback3.WaitForResult();
4442   EXPECT_EQ(OK, rv);
4443
4444   response = trans->GetResponseInfo();
4445   ASSERT_TRUE(response != NULL);
4446   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4447   EXPECT_EQ(13, response->headers->GetContentLength());
4448 }
4449
4450 // Enter a wrong password, and then the correct one.
4451 TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
4452   HttpRequestInfo request;
4453   request.method = "GET";
4454   request.url = GURL("http://172.22.68.17/kids/login.aspx");
4455   request.load_flags = 0;
4456
4457   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4458                                                     MockGetHostName);
4459   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4460
4461   MockWrite data_writes1[] = {
4462     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4463               "Host: 172.22.68.17\r\n"
4464               "Connection: keep-alive\r\n\r\n"),
4465   };
4466
4467   MockRead data_reads1[] = {
4468     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4469     // Negotiate and NTLM are often requested together.  However, we only want
4470     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4471     // the header that requests Negotiate for this test.
4472     MockRead("WWW-Authenticate: NTLM\r\n"),
4473     MockRead("Connection: close\r\n"),
4474     MockRead("Content-Length: 42\r\n"),
4475     MockRead("Content-Type: text/html\r\n\r\n"),
4476     // Missing content -- won't matter, as connection will be reset.
4477     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4478   };
4479
4480   MockWrite data_writes2[] = {
4481     // After restarting with a null identity, this is the
4482     // request we should be issuing -- the final header line contains a Type
4483     // 1 message.
4484     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4485               "Host: 172.22.68.17\r\n"
4486               "Connection: keep-alive\r\n"
4487               "Authorization: NTLM "
4488               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4489
4490     // After calling trans->RestartWithAuth(), we should send a Type 3 message
4491     // (the credentials for the origin server).  The second request continues
4492     // on the same connection.
4493     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4494               "Host: 172.22.68.17\r\n"
4495               "Connection: keep-alive\r\n"
4496               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4497               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4498               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4499               "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4500               "4Ww7b7E=\r\n\r\n"),
4501   };
4502
4503   MockRead data_reads2[] = {
4504     // The origin server responds with a Type 2 message.
4505     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4506     MockRead("WWW-Authenticate: NTLM "
4507              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4508              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4509              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4510              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4511              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4512              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4513              "BtAAAAAAA=\r\n"),
4514     MockRead("Content-Length: 42\r\n"),
4515     MockRead("Content-Type: text/html\r\n\r\n"),
4516     MockRead("You are not authorized to view this page\r\n"),
4517
4518     // Wrong password.
4519     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4520     MockRead("WWW-Authenticate: NTLM\r\n"),
4521     MockRead("Connection: close\r\n"),
4522     MockRead("Content-Length: 42\r\n"),
4523     MockRead("Content-Type: text/html\r\n\r\n"),
4524     // Missing content -- won't matter, as connection will be reset.
4525     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4526   };
4527
4528   MockWrite data_writes3[] = {
4529     // After restarting with a null identity, this is the
4530     // request we should be issuing -- the final header line contains a Type
4531     // 1 message.
4532     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4533               "Host: 172.22.68.17\r\n"
4534               "Connection: keep-alive\r\n"
4535               "Authorization: NTLM "
4536               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4537
4538     // After calling trans->RestartWithAuth(), we should send a Type 3 message
4539     // (the credentials for the origin server).  The second request continues
4540     // on the same connection.
4541     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4542               "Host: 172.22.68.17\r\n"
4543               "Connection: keep-alive\r\n"
4544               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4545               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4546               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4547               "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4548               "+4MUm7c=\r\n\r\n"),
4549   };
4550
4551   MockRead data_reads3[] = {
4552     // The origin server responds with a Type 2 message.
4553     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4554     MockRead("WWW-Authenticate: NTLM "
4555              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4556              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4557              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4558              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4559              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4560              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4561              "BtAAAAAAA=\r\n"),
4562     MockRead("Content-Length: 42\r\n"),
4563     MockRead("Content-Type: text/html\r\n\r\n"),
4564     MockRead("You are not authorized to view this page\r\n"),
4565
4566     // Lastly we get the desired content.
4567     MockRead("HTTP/1.1 200 OK\r\n"),
4568     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4569     MockRead("Content-Length: 13\r\n\r\n"),
4570     MockRead("Please Login\r\n"),
4571     MockRead(SYNCHRONOUS, OK),
4572   };
4573
4574   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4575                                  data_writes1, arraysize(data_writes1));
4576   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4577                                  data_writes2, arraysize(data_writes2));
4578   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4579                                  data_writes3, arraysize(data_writes3));
4580   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4581   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4582   session_deps_.socket_factory->AddSocketDataProvider(&data3);
4583
4584   TestCompletionCallback callback1;
4585
4586   scoped_ptr<HttpTransaction> trans(
4587       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4588
4589   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4590   EXPECT_EQ(ERR_IO_PENDING, rv);
4591
4592   rv = callback1.WaitForResult();
4593   EXPECT_EQ(OK, rv);
4594
4595   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4596
4597   const HttpResponseInfo* response = trans->GetResponseInfo();
4598   ASSERT_TRUE(response != NULL);
4599   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
4600
4601   TestCompletionCallback callback2;
4602
4603   // Enter the wrong password.
4604   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
4605                               callback2.callback());
4606   EXPECT_EQ(ERR_IO_PENDING, rv);
4607
4608   rv = callback2.WaitForResult();
4609   EXPECT_EQ(OK, rv);
4610
4611   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4612   TestCompletionCallback callback3;
4613   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
4614   EXPECT_EQ(ERR_IO_PENDING, rv);
4615   rv = callback3.WaitForResult();
4616   EXPECT_EQ(OK, rv);
4617   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4618
4619   response = trans->GetResponseInfo();
4620   ASSERT_FALSE(response == NULL);
4621   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
4622
4623   TestCompletionCallback callback4;
4624
4625   // Now enter the right password.
4626   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
4627                               callback4.callback());
4628   EXPECT_EQ(ERR_IO_PENDING, rv);
4629
4630   rv = callback4.WaitForResult();
4631   EXPECT_EQ(OK, rv);
4632
4633   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4634
4635   TestCompletionCallback callback5;
4636
4637   // One more roundtrip
4638   rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
4639   EXPECT_EQ(ERR_IO_PENDING, rv);
4640
4641   rv = callback5.WaitForResult();
4642   EXPECT_EQ(OK, rv);
4643
4644   response = trans->GetResponseInfo();
4645   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4646   EXPECT_EQ(13, response->headers->GetContentLength());
4647 }
4648 #endif  // NTLM_PORTABLE
4649
4650 // Test reading a server response which has only headers, and no body.
4651 // After some maximum number of bytes is consumed, the transaction should
4652 // fail with ERR_RESPONSE_HEADERS_TOO_BIG.
4653 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
4654   HttpRequestInfo request;
4655   request.method = "GET";
4656   request.url = GURL("http://www.google.com/");
4657   request.load_flags = 0;
4658
4659   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4660   scoped_ptr<HttpTransaction> trans(
4661       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
4662
4663   // Respond with 300 kb of headers (we should fail after 256 kb).
4664   std::string large_headers_string;
4665   FillLargeHeadersString(&large_headers_string, 300 * 1024);
4666
4667   MockRead data_reads[] = {
4668     MockRead("HTTP/1.0 200 OK\r\n"),
4669     MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
4670     MockRead("\r\nBODY"),
4671     MockRead(SYNCHRONOUS, OK),
4672   };
4673   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4674   session_deps_.socket_factory->AddSocketDataProvider(&data);
4675
4676   TestCompletionCallback callback;
4677
4678   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4679   EXPECT_EQ(ERR_IO_PENDING, rv);
4680
4681   rv = callback.WaitForResult();
4682   EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
4683
4684   const HttpResponseInfo* response = trans->GetResponseInfo();
4685   EXPECT_TRUE(response == NULL);
4686 }
4687
4688 // Make sure that we don't try to reuse a TCPClientSocket when failing to
4689 // establish tunnel.
4690 // http://code.google.com/p/chromium/issues/detail?id=3772
4691 TEST_P(HttpNetworkTransactionTest,
4692        DontRecycleTransportSocketForSSLTunnel) {
4693   HttpRequestInfo request;
4694   request.method = "GET";
4695   request.url = GURL("https://www.google.com/");
4696   request.load_flags = 0;
4697
4698   // Configure against proxy server "myproxy:70".
4699   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4700
4701   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4702
4703   scoped_ptr<HttpTransaction> trans(
4704       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4705
4706   // Since we have proxy, should try to establish tunnel.
4707   MockWrite data_writes1[] = {
4708     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
4709               "Host: www.google.com\r\n"
4710               "Proxy-Connection: keep-alive\r\n\r\n"),
4711   };
4712
4713   // The proxy responds to the connect with a 404, using a persistent
4714   // connection. Usually a proxy would return 501 (not implemented),
4715   // or 200 (tunnel established).
4716   MockRead data_reads1[] = {
4717     MockRead("HTTP/1.1 404 Not Found\r\n"),
4718     MockRead("Content-Length: 10\r\n\r\n"),
4719     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
4720   };
4721
4722   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4723                                  data_writes1, arraysize(data_writes1));
4724   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4725
4726   TestCompletionCallback callback1;
4727
4728   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4729   EXPECT_EQ(ERR_IO_PENDING, rv);
4730
4731   rv = callback1.WaitForResult();
4732   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
4733
4734   const HttpResponseInfo* response = trans->GetResponseInfo();
4735   EXPECT_TRUE(response == NULL);
4736
4737   // Empty the current queue.  This is necessary because idle sockets are
4738   // added to the connection pool asynchronously with a PostTask.
4739   base::MessageLoop::current()->RunUntilIdle();
4740
4741   // We now check to make sure the TCPClientSocket was not added back to
4742   // the pool.
4743   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4744   trans.reset();
4745   base::MessageLoop::current()->RunUntilIdle();
4746   // Make sure that the socket didn't get recycled after calling the destructor.
4747   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4748 }
4749
4750 // Make sure that we recycle a socket after reading all of the response body.
4751 TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
4752   HttpRequestInfo request;
4753   request.method = "GET";
4754   request.url = GURL("http://www.google.com/");
4755   request.load_flags = 0;
4756
4757   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4758
4759   scoped_ptr<HttpTransaction> trans(
4760       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4761
4762   MockRead data_reads[] = {
4763     // A part of the response body is received with the response headers.
4764     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4765     // The rest of the response body is received in two parts.
4766     MockRead("lo"),
4767     MockRead(" world"),
4768     MockRead("junk"),  // Should not be read!!
4769     MockRead(SYNCHRONOUS, OK),
4770   };
4771
4772   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4773   session_deps_.socket_factory->AddSocketDataProvider(&data);
4774
4775   TestCompletionCallback callback;
4776
4777   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4778   EXPECT_EQ(ERR_IO_PENDING, rv);
4779
4780   rv = callback.WaitForResult();
4781   EXPECT_EQ(OK, rv);
4782
4783   const HttpResponseInfo* response = trans->GetResponseInfo();
4784   ASSERT_TRUE(response != NULL);
4785
4786   EXPECT_TRUE(response->headers.get() != NULL);
4787   std::string status_line = response->headers->GetStatusLine();
4788   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4789
4790   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4791
4792   std::string response_data;
4793   rv = ReadTransaction(trans.get(), &response_data);
4794   EXPECT_EQ(OK, rv);
4795   EXPECT_EQ("hello world", response_data);
4796
4797   // Empty the current queue.  This is necessary because idle sockets are
4798   // added to the connection pool asynchronously with a PostTask.
4799   base::MessageLoop::current()->RunUntilIdle();
4800
4801   // We now check to make sure the socket was added back to the pool.
4802   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
4803 }
4804
4805 // Make sure that we recycle a SSL socket after reading all of the response
4806 // body.
4807 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
4808   HttpRequestInfo request;
4809   request.method = "GET";
4810   request.url = GURL("https://www.google.com/");
4811   request.load_flags = 0;
4812
4813   MockWrite data_writes[] = {
4814     MockWrite("GET / HTTP/1.1\r\n"
4815               "Host: www.google.com\r\n"
4816               "Connection: keep-alive\r\n\r\n"),
4817   };
4818
4819   MockRead data_reads[] = {
4820     MockRead("HTTP/1.1 200 OK\r\n"),
4821     MockRead("Content-Length: 11\r\n\r\n"),
4822     MockRead("hello world"),
4823     MockRead(SYNCHRONOUS, OK),
4824   };
4825
4826   SSLSocketDataProvider ssl(ASYNC, OK);
4827   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4828
4829   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4830                                 data_writes, arraysize(data_writes));
4831   session_deps_.socket_factory->AddSocketDataProvider(&data);
4832
4833   TestCompletionCallback callback;
4834
4835   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4836   scoped_ptr<HttpTransaction> trans(
4837       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4838
4839   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4840
4841   EXPECT_EQ(ERR_IO_PENDING, rv);
4842   EXPECT_EQ(OK, callback.WaitForResult());
4843
4844   const HttpResponseInfo* response = trans->GetResponseInfo();
4845   ASSERT_TRUE(response != NULL);
4846   ASSERT_TRUE(response->headers.get() != NULL);
4847   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4848
4849   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4850
4851   std::string response_data;
4852   rv = ReadTransaction(trans.get(), &response_data);
4853   EXPECT_EQ(OK, rv);
4854   EXPECT_EQ("hello world", response_data);
4855
4856   // Empty the current queue.  This is necessary because idle sockets are
4857   // added to the connection pool asynchronously with a PostTask.
4858   base::MessageLoop::current()->RunUntilIdle();
4859
4860   // We now check to make sure the socket was added back to the pool.
4861   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
4862 }
4863
4864 // Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
4865 // from the pool and make sure that we recover okay.
4866 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
4867   HttpRequestInfo request;
4868   request.method = "GET";
4869   request.url = GURL("https://www.google.com/");
4870   request.load_flags = 0;
4871
4872   MockWrite data_writes[] = {
4873     MockWrite("GET / HTTP/1.1\r\n"
4874               "Host: www.google.com\r\n"
4875               "Connection: keep-alive\r\n\r\n"),
4876     MockWrite("GET / HTTP/1.1\r\n"
4877               "Host: www.google.com\r\n"
4878               "Connection: keep-alive\r\n\r\n"),
4879   };
4880
4881   MockRead data_reads[] = {
4882     MockRead("HTTP/1.1 200 OK\r\n"),
4883     MockRead("Content-Length: 11\r\n\r\n"),
4884     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4885     MockRead("hello world"),
4886     MockRead(ASYNC, 0, 0)   // EOF
4887   };
4888
4889   SSLSocketDataProvider ssl(ASYNC, OK);
4890   SSLSocketDataProvider ssl2(ASYNC, OK);
4891   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4892   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
4893
4894   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4895                                 data_writes, arraysize(data_writes));
4896   StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4897                                 data_writes, arraysize(data_writes));
4898   session_deps_.socket_factory->AddSocketDataProvider(&data);
4899   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4900
4901   TestCompletionCallback callback;
4902
4903   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4904   scoped_ptr<HttpTransaction> trans(
4905       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4906
4907   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4908
4909   EXPECT_EQ(ERR_IO_PENDING, rv);
4910   EXPECT_EQ(OK, callback.WaitForResult());
4911
4912   const HttpResponseInfo* response = trans->GetResponseInfo();
4913   ASSERT_TRUE(response != NULL);
4914   ASSERT_TRUE(response->headers.get() != NULL);
4915   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4916
4917   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4918
4919   std::string response_data;
4920   rv = ReadTransaction(trans.get(), &response_data);
4921   EXPECT_EQ(OK, rv);
4922   EXPECT_EQ("hello world", response_data);
4923
4924   // Empty the current queue.  This is necessary because idle sockets are
4925   // added to the connection pool asynchronously with a PostTask.
4926   base::MessageLoop::current()->RunUntilIdle();
4927
4928   // We now check to make sure the socket was added back to the pool.
4929   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
4930
4931   // Now start the second transaction, which should reuse the previous socket.
4932
4933   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4934
4935   rv = trans->Start(&request, callback.callback(), BoundNetLog());
4936
4937   EXPECT_EQ(ERR_IO_PENDING, rv);
4938   EXPECT_EQ(OK, callback.WaitForResult());
4939
4940   response = trans->GetResponseInfo();
4941   ASSERT_TRUE(response != NULL);
4942   ASSERT_TRUE(response->headers.get() != NULL);
4943   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4944
4945   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4946
4947   rv = ReadTransaction(trans.get(), &response_data);
4948   EXPECT_EQ(OK, rv);
4949   EXPECT_EQ("hello world", response_data);
4950
4951   // Empty the current queue.  This is necessary because idle sockets are
4952   // added to the connection pool asynchronously with a PostTask.
4953   base::MessageLoop::current()->RunUntilIdle();
4954
4955   // We now check to make sure the socket was added back to the pool.
4956   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
4957 }
4958
4959 // Make sure that we recycle a socket after a zero-length response.
4960 // http://crbug.com/9880
4961 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
4962   HttpRequestInfo request;
4963   request.method = "GET";
4964   request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4965                      "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4966                      "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4967                      "rt=prt.2642,ol.2649,xjs.2951");
4968   request.load_flags = 0;
4969
4970   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4971
4972   scoped_ptr<HttpTransaction> trans(
4973       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4974
4975   MockRead data_reads[] = {
4976     MockRead("HTTP/1.1 204 No Content\r\n"
4977              "Content-Length: 0\r\n"
4978              "Content-Type: text/html\r\n\r\n"),
4979     MockRead("junk"),  // Should not be read!!
4980     MockRead(SYNCHRONOUS, OK),
4981   };
4982
4983   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4984   session_deps_.socket_factory->AddSocketDataProvider(&data);
4985
4986   TestCompletionCallback callback;
4987
4988   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4989   EXPECT_EQ(ERR_IO_PENDING, rv);
4990
4991   rv = callback.WaitForResult();
4992   EXPECT_EQ(OK, rv);
4993
4994   const HttpResponseInfo* response = trans->GetResponseInfo();
4995   ASSERT_TRUE(response != NULL);
4996
4997   EXPECT_TRUE(response->headers.get() != NULL);
4998   std::string status_line = response->headers->GetStatusLine();
4999   EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5000
5001   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
5002
5003   std::string response_data;
5004   rv = ReadTransaction(trans.get(), &response_data);
5005   EXPECT_EQ(OK, rv);
5006   EXPECT_EQ("", response_data);
5007
5008   // Empty the current queue.  This is necessary because idle sockets are
5009   // added to the connection pool asynchronously with a PostTask.
5010   base::MessageLoop::current()->RunUntilIdle();
5011
5012   // We now check to make sure the socket was added back to the pool.
5013   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
5014 }
5015
5016 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
5017   ScopedVector<UploadElementReader> element_readers;
5018   element_readers.push_back(new UploadBytesElementReader("foo", 3));
5019   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
5020
5021   HttpRequestInfo request[2];
5022   // Transaction 1: a GET request that succeeds.  The socket is recycled
5023   // after use.
5024   request[0].method = "GET";
5025   request[0].url = GURL("http://www.google.com/");
5026   request[0].load_flags = 0;
5027   // Transaction 2: a POST request.  Reuses the socket kept alive from
5028   // transaction 1.  The first attempts fails when writing the POST data.
5029   // This causes the transaction to retry with a new socket.  The second
5030   // attempt succeeds.
5031   request[1].method = "POST";
5032   request[1].url = GURL("http://www.google.com/login.cgi");
5033   request[1].upload_data_stream = &upload_data_stream;
5034   request[1].load_flags = 0;
5035
5036   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5037
5038   // The first socket is used for transaction 1 and the first attempt of
5039   // transaction 2.
5040
5041   // The response of transaction 1.
5042   MockRead data_reads1[] = {
5043     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5044     MockRead("hello world"),
5045     MockRead(SYNCHRONOUS, OK),
5046   };
5047   // The mock write results of transaction 1 and the first attempt of
5048   // transaction 2.
5049   MockWrite data_writes1[] = {
5050     MockWrite(SYNCHRONOUS, 64),  // GET
5051     MockWrite(SYNCHRONOUS, 93),  // POST
5052     MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
5053   };
5054   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5055                                  data_writes1, arraysize(data_writes1));
5056
5057   // The second socket is used for the second attempt of transaction 2.
5058
5059   // The response of transaction 2.
5060   MockRead data_reads2[] = {
5061     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5062     MockRead("welcome"),
5063     MockRead(SYNCHRONOUS, OK),
5064   };
5065   // The mock write results of the second attempt of transaction 2.
5066   MockWrite data_writes2[] = {
5067     MockWrite(SYNCHRONOUS, 93),  // POST
5068     MockWrite(SYNCHRONOUS, 3),  // POST data
5069   };
5070   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5071                                  data_writes2, arraysize(data_writes2));
5072
5073   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5074   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5075
5076   const char* kExpectedResponseData[] = {
5077     "hello world", "welcome"
5078   };
5079
5080   for (int i = 0; i < 2; ++i) {
5081     scoped_ptr<HttpTransaction> trans(
5082         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5083
5084     TestCompletionCallback callback;
5085
5086     int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
5087     EXPECT_EQ(ERR_IO_PENDING, rv);
5088
5089     rv = callback.WaitForResult();
5090     EXPECT_EQ(OK, rv);
5091
5092     const HttpResponseInfo* response = trans->GetResponseInfo();
5093     ASSERT_TRUE(response != NULL);
5094
5095     EXPECT_TRUE(response->headers.get() != NULL);
5096     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5097
5098     std::string response_data;
5099     rv = ReadTransaction(trans.get(), &response_data);
5100     EXPECT_EQ(OK, rv);
5101     EXPECT_EQ(kExpectedResponseData[i], response_data);
5102   }
5103 }
5104
5105 // Test the request-challenge-retry sequence for basic auth when there is
5106 // an identity in the URL. The request should be sent as normal, but when
5107 // it fails the identity from the URL is used to answer the challenge.
5108 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
5109   HttpRequestInfo request;
5110   request.method = "GET";
5111   request.url = GURL("http://foo:b@r@www.google.com/");
5112   request.load_flags = LOAD_NORMAL;
5113
5114   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5115   scoped_ptr<HttpTransaction> trans(
5116       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5117
5118   // The password contains an escaped character -- for this test to pass it
5119   // will need to be unescaped by HttpNetworkTransaction.
5120   EXPECT_EQ("b%40r", request.url.password());
5121
5122   MockWrite data_writes1[] = {
5123     MockWrite("GET / HTTP/1.1\r\n"
5124               "Host: www.google.com\r\n"
5125               "Connection: keep-alive\r\n\r\n"),
5126   };
5127
5128   MockRead data_reads1[] = {
5129     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5130     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5131     MockRead("Content-Length: 10\r\n\r\n"),
5132     MockRead(SYNCHRONOUS, ERR_FAILED),
5133   };
5134
5135   // After the challenge above, the transaction will be restarted using the
5136   // identity from the url (foo, b@r) to answer the challenge.
5137   MockWrite data_writes2[] = {
5138     MockWrite("GET / HTTP/1.1\r\n"
5139               "Host: www.google.com\r\n"
5140               "Connection: keep-alive\r\n"
5141               "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
5142   };
5143
5144   MockRead data_reads2[] = {
5145     MockRead("HTTP/1.0 200 OK\r\n"),
5146     MockRead("Content-Length: 100\r\n\r\n"),
5147     MockRead(SYNCHRONOUS, OK),
5148   };
5149
5150   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5151                                  data_writes1, arraysize(data_writes1));
5152   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5153                                  data_writes2, arraysize(data_writes2));
5154   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5155   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5156
5157   TestCompletionCallback callback1;
5158   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5159   EXPECT_EQ(ERR_IO_PENDING, rv);
5160   rv = callback1.WaitForResult();
5161   EXPECT_EQ(OK, rv);
5162   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5163
5164   TestCompletionCallback callback2;
5165   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5166   EXPECT_EQ(ERR_IO_PENDING, rv);
5167   rv = callback2.WaitForResult();
5168   EXPECT_EQ(OK, rv);
5169   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5170
5171   const HttpResponseInfo* response = trans->GetResponseInfo();
5172   ASSERT_TRUE(response != NULL);
5173
5174   // There is no challenge info, since the identity in URL worked.
5175   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5176
5177   EXPECT_EQ(100, response->headers->GetContentLength());
5178
5179   // Empty the current queue.
5180   base::MessageLoop::current()->RunUntilIdle();
5181 }
5182
5183 // Test the request-challenge-retry sequence for basic auth when there is an
5184 // incorrect identity in the URL. The identity from the URL should be used only
5185 // once.
5186 TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
5187   HttpRequestInfo request;
5188   request.method = "GET";
5189   // Note: the URL has a username:password in it.  The password "baz" is
5190   // wrong (should be "bar").
5191   request.url = GURL("http://foo:baz@www.google.com/");
5192
5193   request.load_flags = LOAD_NORMAL;
5194
5195   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5196   scoped_ptr<HttpTransaction> trans(
5197       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5198
5199   MockWrite data_writes1[] = {
5200     MockWrite("GET / HTTP/1.1\r\n"
5201               "Host: www.google.com\r\n"
5202               "Connection: keep-alive\r\n\r\n"),
5203   };
5204
5205   MockRead data_reads1[] = {
5206     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5207     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5208     MockRead("Content-Length: 10\r\n\r\n"),
5209     MockRead(SYNCHRONOUS, ERR_FAILED),
5210   };
5211
5212   // After the challenge above, the transaction will be restarted using the
5213   // identity from the url (foo, baz) to answer the challenge.
5214   MockWrite data_writes2[] = {
5215     MockWrite("GET / HTTP/1.1\r\n"
5216               "Host: www.google.com\r\n"
5217               "Connection: keep-alive\r\n"
5218               "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
5219   };
5220
5221   MockRead data_reads2[] = {
5222     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5223     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5224     MockRead("Content-Length: 10\r\n\r\n"),
5225     MockRead(SYNCHRONOUS, ERR_FAILED),
5226   };
5227
5228   // After the challenge above, the transaction will be restarted using the
5229   // identity supplied by the user (foo, bar) to answer the challenge.
5230   MockWrite data_writes3[] = {
5231     MockWrite("GET / HTTP/1.1\r\n"
5232               "Host: www.google.com\r\n"
5233               "Connection: keep-alive\r\n"
5234               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5235   };
5236
5237   MockRead data_reads3[] = {
5238     MockRead("HTTP/1.0 200 OK\r\n"),
5239     MockRead("Content-Length: 100\r\n\r\n"),
5240     MockRead(SYNCHRONOUS, OK),
5241   };
5242
5243   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5244                                  data_writes1, arraysize(data_writes1));
5245   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5246                                  data_writes2, arraysize(data_writes2));
5247   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5248                                  data_writes3, arraysize(data_writes3));
5249   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5250   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5251   session_deps_.socket_factory->AddSocketDataProvider(&data3);
5252
5253   TestCompletionCallback callback1;
5254
5255   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5256   EXPECT_EQ(ERR_IO_PENDING, rv);
5257
5258   rv = callback1.WaitForResult();
5259   EXPECT_EQ(OK, rv);
5260
5261   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5262   TestCompletionCallback callback2;
5263   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5264   EXPECT_EQ(ERR_IO_PENDING, rv);
5265   rv = callback2.WaitForResult();
5266   EXPECT_EQ(OK, rv);
5267   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5268
5269   const HttpResponseInfo* response = trans->GetResponseInfo();
5270   ASSERT_TRUE(response != NULL);
5271   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5272
5273   TestCompletionCallback callback3;
5274   rv = trans->RestartWithAuth(
5275       AuthCredentials(kFoo, kBar), callback3.callback());
5276   EXPECT_EQ(ERR_IO_PENDING, rv);
5277   rv = callback3.WaitForResult();
5278   EXPECT_EQ(OK, rv);
5279   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5280
5281   response = trans->GetResponseInfo();
5282   ASSERT_TRUE(response != NULL);
5283
5284   // There is no challenge info, since the identity worked.
5285   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5286
5287   EXPECT_EQ(100, response->headers->GetContentLength());
5288
5289   // Empty the current queue.
5290   base::MessageLoop::current()->RunUntilIdle();
5291 }
5292
5293
5294 // Test the request-challenge-retry sequence for basic auth when there is a
5295 // correct identity in the URL, but its use is being suppressed. The identity
5296 // from the URL should never be used.
5297 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5298   HttpRequestInfo request;
5299   request.method = "GET";
5300   request.url = GURL("http://foo:bar@www.google.com/");
5301   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5302
5303   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5304   scoped_ptr<HttpTransaction> trans(
5305       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5306
5307   MockWrite data_writes1[] = {
5308     MockWrite("GET / HTTP/1.1\r\n"
5309               "Host: www.google.com\r\n"
5310               "Connection: keep-alive\r\n\r\n"),
5311   };
5312
5313   MockRead data_reads1[] = {
5314     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5315     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5316     MockRead("Content-Length: 10\r\n\r\n"),
5317     MockRead(SYNCHRONOUS, ERR_FAILED),
5318   };
5319
5320   // After the challenge above, the transaction will be restarted using the
5321   // identity supplied by the user, not the one in the URL, to answer the
5322   // challenge.
5323   MockWrite data_writes3[] = {
5324     MockWrite("GET / HTTP/1.1\r\n"
5325               "Host: www.google.com\r\n"
5326               "Connection: keep-alive\r\n"
5327               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5328   };
5329
5330   MockRead data_reads3[] = {
5331     MockRead("HTTP/1.0 200 OK\r\n"),
5332     MockRead("Content-Length: 100\r\n\r\n"),
5333     MockRead(SYNCHRONOUS, OK),
5334   };
5335
5336   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5337                                  data_writes1, arraysize(data_writes1));
5338   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5339                                  data_writes3, arraysize(data_writes3));
5340   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5341   session_deps_.socket_factory->AddSocketDataProvider(&data3);
5342
5343   TestCompletionCallback callback1;
5344   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5345   EXPECT_EQ(ERR_IO_PENDING, rv);
5346   rv = callback1.WaitForResult();
5347   EXPECT_EQ(OK, rv);
5348   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5349
5350   const HttpResponseInfo* response = trans->GetResponseInfo();
5351   ASSERT_TRUE(response != NULL);
5352   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5353
5354   TestCompletionCallback callback3;
5355   rv = trans->RestartWithAuth(
5356       AuthCredentials(kFoo, kBar), callback3.callback());
5357   EXPECT_EQ(ERR_IO_PENDING, rv);
5358   rv = callback3.WaitForResult();
5359   EXPECT_EQ(OK, rv);
5360   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5361
5362   response = trans->GetResponseInfo();
5363   ASSERT_TRUE(response != NULL);
5364
5365   // There is no challenge info, since the identity worked.
5366   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5367   EXPECT_EQ(100, response->headers->GetContentLength());
5368
5369   // Empty the current queue.
5370   base::MessageLoop::current()->RunUntilIdle();
5371 }
5372
5373 // Test that previously tried username/passwords for a realm get re-used.
5374 TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
5375   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5376
5377   // Transaction 1: authenticate (foo, bar) on MyRealm1
5378   {
5379     HttpRequestInfo request;
5380     request.method = "GET";
5381     request.url = GURL("http://www.google.com/x/y/z");
5382     request.load_flags = 0;
5383
5384     scoped_ptr<HttpTransaction> trans(
5385         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5386
5387     MockWrite data_writes1[] = {
5388       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5389                 "Host: www.google.com\r\n"
5390                 "Connection: keep-alive\r\n\r\n"),
5391     };
5392
5393     MockRead data_reads1[] = {
5394       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5395       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5396       MockRead("Content-Length: 10000\r\n\r\n"),
5397       MockRead(SYNCHRONOUS, ERR_FAILED),
5398     };
5399
5400     // Resend with authorization (username=foo, password=bar)
5401     MockWrite data_writes2[] = {
5402       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5403                 "Host: www.google.com\r\n"
5404                 "Connection: keep-alive\r\n"
5405                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5406     };
5407
5408     // Sever accepts the authorization.
5409     MockRead data_reads2[] = {
5410       MockRead("HTTP/1.0 200 OK\r\n"),
5411       MockRead("Content-Length: 100\r\n\r\n"),
5412       MockRead(SYNCHRONOUS, OK),
5413     };
5414
5415     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5416                                    data_writes1, arraysize(data_writes1));
5417     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5418                                    data_writes2, arraysize(data_writes2));
5419     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5420     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5421
5422     TestCompletionCallback callback1;
5423
5424     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5425     EXPECT_EQ(ERR_IO_PENDING, rv);
5426
5427     rv = callback1.WaitForResult();
5428     EXPECT_EQ(OK, rv);
5429
5430     const HttpResponseInfo* response = trans->GetResponseInfo();
5431     ASSERT_TRUE(response != NULL);
5432     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5433
5434     TestCompletionCallback callback2;
5435
5436     rv = trans->RestartWithAuth(
5437         AuthCredentials(kFoo, kBar), callback2.callback());
5438     EXPECT_EQ(ERR_IO_PENDING, rv);
5439
5440     rv = callback2.WaitForResult();
5441     EXPECT_EQ(OK, rv);
5442
5443     response = trans->GetResponseInfo();
5444     ASSERT_TRUE(response != NULL);
5445     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5446     EXPECT_EQ(100, response->headers->GetContentLength());
5447   }
5448
5449   // ------------------------------------------------------------------------
5450
5451   // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5452   {
5453     HttpRequestInfo request;
5454     request.method = "GET";
5455     // Note that Transaction 1 was at /x/y/z, so this is in the same
5456     // protection space as MyRealm1.
5457     request.url = GURL("http://www.google.com/x/y/a/b");
5458     request.load_flags = 0;
5459
5460     scoped_ptr<HttpTransaction> trans(
5461         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5462
5463     MockWrite data_writes1[] = {
5464       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5465                 "Host: www.google.com\r\n"
5466                 "Connection: keep-alive\r\n"
5467                 // Send preemptive authorization for MyRealm1
5468                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5469     };
5470
5471     // The server didn't like the preemptive authorization, and
5472     // challenges us for a different realm (MyRealm2).
5473     MockRead data_reads1[] = {
5474       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5475       MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5476       MockRead("Content-Length: 10000\r\n\r\n"),
5477       MockRead(SYNCHRONOUS, ERR_FAILED),
5478     };
5479
5480     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5481     MockWrite data_writes2[] = {
5482       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5483                 "Host: www.google.com\r\n"
5484                 "Connection: keep-alive\r\n"
5485                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5486     };
5487
5488     // Sever accepts the authorization.
5489     MockRead data_reads2[] = {
5490       MockRead("HTTP/1.0 200 OK\r\n"),
5491       MockRead("Content-Length: 100\r\n\r\n"),
5492       MockRead(SYNCHRONOUS, OK),
5493     };
5494
5495     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5496                                    data_writes1, arraysize(data_writes1));
5497     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5498                                    data_writes2, arraysize(data_writes2));
5499     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5500     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5501
5502     TestCompletionCallback callback1;
5503
5504     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5505     EXPECT_EQ(ERR_IO_PENDING, rv);
5506
5507     rv = callback1.WaitForResult();
5508     EXPECT_EQ(OK, rv);
5509
5510     const HttpResponseInfo* response = trans->GetResponseInfo();
5511     ASSERT_TRUE(response != NULL);
5512     ASSERT_TRUE(response->auth_challenge.get());
5513     EXPECT_FALSE(response->auth_challenge->is_proxy);
5514     EXPECT_EQ("www.google.com:80",
5515               response->auth_challenge->challenger.ToString());
5516     EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5517     EXPECT_EQ("basic", response->auth_challenge->scheme);
5518
5519     TestCompletionCallback callback2;
5520
5521     rv = trans->RestartWithAuth(
5522         AuthCredentials(kFoo2, kBar2), callback2.callback());
5523     EXPECT_EQ(ERR_IO_PENDING, rv);
5524
5525     rv = callback2.WaitForResult();
5526     EXPECT_EQ(OK, rv);
5527
5528     response = trans->GetResponseInfo();
5529     ASSERT_TRUE(response != NULL);
5530     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5531     EXPECT_EQ(100, response->headers->GetContentLength());
5532   }
5533
5534   // ------------------------------------------------------------------------
5535
5536   // Transaction 3: Resend a request in MyRealm's protection space --
5537   // succeed with preemptive authorization.
5538   {
5539     HttpRequestInfo request;
5540     request.method = "GET";
5541     request.url = GURL("http://www.google.com/x/y/z2");
5542     request.load_flags = 0;
5543
5544     scoped_ptr<HttpTransaction> trans(
5545         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5546
5547     MockWrite data_writes1[] = {
5548       MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5549                 "Host: www.google.com\r\n"
5550                 "Connection: keep-alive\r\n"
5551                 // The authorization for MyRealm1 gets sent preemptively
5552                 // (since the url is in the same protection space)
5553                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5554     };
5555
5556     // Sever accepts the preemptive authorization
5557     MockRead data_reads1[] = {
5558       MockRead("HTTP/1.0 200 OK\r\n"),
5559       MockRead("Content-Length: 100\r\n\r\n"),
5560       MockRead(SYNCHRONOUS, OK),
5561     };
5562
5563     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5564                                    data_writes1, arraysize(data_writes1));
5565     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5566
5567     TestCompletionCallback callback1;
5568
5569     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5570     EXPECT_EQ(ERR_IO_PENDING, rv);
5571
5572     rv = callback1.WaitForResult();
5573     EXPECT_EQ(OK, rv);
5574
5575     const HttpResponseInfo* response = trans->GetResponseInfo();
5576     ASSERT_TRUE(response != NULL);
5577
5578     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5579     EXPECT_EQ(100, response->headers->GetContentLength());
5580   }
5581
5582   // ------------------------------------------------------------------------
5583
5584   // Transaction 4: request another URL in MyRealm (however the
5585   // url is not known to belong to the protection space, so no pre-auth).
5586   {
5587     HttpRequestInfo request;
5588     request.method = "GET";
5589     request.url = GURL("http://www.google.com/x/1");
5590     request.load_flags = 0;
5591
5592     scoped_ptr<HttpTransaction> trans(
5593         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5594
5595     MockWrite data_writes1[] = {
5596       MockWrite("GET /x/1 HTTP/1.1\r\n"
5597                 "Host: www.google.com\r\n"
5598                 "Connection: keep-alive\r\n\r\n"),
5599     };
5600
5601     MockRead data_reads1[] = {
5602       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5603       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5604       MockRead("Content-Length: 10000\r\n\r\n"),
5605       MockRead(SYNCHRONOUS, ERR_FAILED),
5606     };
5607
5608     // Resend with authorization from MyRealm's cache.
5609     MockWrite data_writes2[] = {
5610       MockWrite("GET /x/1 HTTP/1.1\r\n"
5611                 "Host: www.google.com\r\n"
5612                 "Connection: keep-alive\r\n"
5613                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5614     };
5615
5616     // Sever accepts the authorization.
5617     MockRead data_reads2[] = {
5618       MockRead("HTTP/1.0 200 OK\r\n"),
5619       MockRead("Content-Length: 100\r\n\r\n"),
5620       MockRead(SYNCHRONOUS, OK),
5621     };
5622
5623     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5624                                    data_writes1, arraysize(data_writes1));
5625     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5626                                    data_writes2, arraysize(data_writes2));
5627     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5628     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5629
5630     TestCompletionCallback callback1;
5631
5632     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5633     EXPECT_EQ(ERR_IO_PENDING, rv);
5634
5635     rv = callback1.WaitForResult();
5636     EXPECT_EQ(OK, rv);
5637
5638     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5639     TestCompletionCallback callback2;
5640     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5641     EXPECT_EQ(ERR_IO_PENDING, rv);
5642     rv = callback2.WaitForResult();
5643     EXPECT_EQ(OK, rv);
5644     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5645
5646     const HttpResponseInfo* response = trans->GetResponseInfo();
5647     ASSERT_TRUE(response != NULL);
5648     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5649     EXPECT_EQ(100, response->headers->GetContentLength());
5650   }
5651
5652   // ------------------------------------------------------------------------
5653
5654   // Transaction 5: request a URL in MyRealm, but the server rejects the
5655   // cached identity. Should invalidate and re-prompt.
5656   {
5657     HttpRequestInfo request;
5658     request.method = "GET";
5659     request.url = GURL("http://www.google.com/p/q/t");
5660     request.load_flags = 0;
5661
5662     scoped_ptr<HttpTransaction> trans(
5663         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5664
5665     MockWrite data_writes1[] = {
5666       MockWrite("GET /p/q/t HTTP/1.1\r\n"
5667                 "Host: www.google.com\r\n"
5668                 "Connection: keep-alive\r\n\r\n"),
5669     };
5670
5671     MockRead data_reads1[] = {
5672       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5673       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5674       MockRead("Content-Length: 10000\r\n\r\n"),
5675       MockRead(SYNCHRONOUS, ERR_FAILED),
5676     };
5677
5678     // Resend with authorization from cache for MyRealm.
5679     MockWrite data_writes2[] = {
5680       MockWrite("GET /p/q/t HTTP/1.1\r\n"
5681                 "Host: www.google.com\r\n"
5682                 "Connection: keep-alive\r\n"
5683                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5684     };
5685
5686     // Sever rejects the authorization.
5687     MockRead data_reads2[] = {
5688       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5689       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5690       MockRead("Content-Length: 10000\r\n\r\n"),
5691       MockRead(SYNCHRONOUS, ERR_FAILED),
5692     };
5693
5694     // At this point we should prompt for new credentials for MyRealm.
5695     // Restart with username=foo3, password=foo4.
5696     MockWrite data_writes3[] = {
5697       MockWrite("GET /p/q/t HTTP/1.1\r\n"
5698                 "Host: www.google.com\r\n"
5699                 "Connection: keep-alive\r\n"
5700                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5701     };
5702
5703     // Sever accepts the authorization.
5704     MockRead data_reads3[] = {
5705       MockRead("HTTP/1.0 200 OK\r\n"),
5706       MockRead("Content-Length: 100\r\n\r\n"),
5707       MockRead(SYNCHRONOUS, OK),
5708     };
5709
5710     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5711                                    data_writes1, arraysize(data_writes1));
5712     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5713                                    data_writes2, arraysize(data_writes2));
5714     StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5715                                    data_writes3, arraysize(data_writes3));
5716     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5717     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5718     session_deps_.socket_factory->AddSocketDataProvider(&data3);
5719
5720     TestCompletionCallback callback1;
5721
5722     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5723     EXPECT_EQ(ERR_IO_PENDING, rv);
5724
5725     rv = callback1.WaitForResult();
5726     EXPECT_EQ(OK, rv);
5727
5728     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5729     TestCompletionCallback callback2;
5730     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5731     EXPECT_EQ(ERR_IO_PENDING, rv);
5732     rv = callback2.WaitForResult();
5733     EXPECT_EQ(OK, rv);
5734     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5735
5736     const HttpResponseInfo* response = trans->GetResponseInfo();
5737     ASSERT_TRUE(response != NULL);
5738     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5739
5740     TestCompletionCallback callback3;
5741
5742     rv = trans->RestartWithAuth(
5743         AuthCredentials(kFoo3, kBar3), callback3.callback());
5744     EXPECT_EQ(ERR_IO_PENDING, rv);
5745
5746     rv = callback3.WaitForResult();
5747     EXPECT_EQ(OK, rv);
5748
5749     response = trans->GetResponseInfo();
5750     ASSERT_TRUE(response != NULL);
5751     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5752     EXPECT_EQ(100, response->headers->GetContentLength());
5753   }
5754 }
5755
5756 // Tests that nonce count increments when multiple auth attempts
5757 // are started with the same nonce.
5758 TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
5759   HttpAuthHandlerDigest::Factory* digest_factory =
5760       new HttpAuthHandlerDigest::Factory();
5761   HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5762       new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5763   digest_factory->set_nonce_generator(nonce_generator);
5764   session_deps_.http_auth_handler_factory.reset(digest_factory);
5765   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5766
5767   // Transaction 1: authenticate (foo, bar) on MyRealm1
5768   {
5769     HttpRequestInfo request;
5770     request.method = "GET";
5771     request.url = GURL("http://www.google.com/x/y/z");
5772     request.load_flags = 0;
5773
5774     scoped_ptr<HttpTransaction> trans(
5775         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5776
5777     MockWrite data_writes1[] = {
5778       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5779                 "Host: www.google.com\r\n"
5780                 "Connection: keep-alive\r\n\r\n"),
5781     };
5782
5783     MockRead data_reads1[] = {
5784       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5785       MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5786                "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
5787       MockRead(SYNCHRONOUS, OK),
5788     };
5789
5790     // Resend with authorization (username=foo, password=bar)
5791     MockWrite data_writes2[] = {
5792       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5793                 "Host: www.google.com\r\n"
5794                 "Connection: keep-alive\r\n"
5795                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5796                 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5797                 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5798                 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5799     };
5800
5801     // Sever accepts the authorization.
5802     MockRead data_reads2[] = {
5803       MockRead("HTTP/1.0 200 OK\r\n"),
5804       MockRead(SYNCHRONOUS, OK),
5805     };
5806
5807     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5808                                    data_writes1, arraysize(data_writes1));
5809     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5810                                    data_writes2, arraysize(data_writes2));
5811     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5812     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5813
5814     TestCompletionCallback callback1;
5815
5816     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5817     EXPECT_EQ(ERR_IO_PENDING, rv);
5818
5819     rv = callback1.WaitForResult();
5820     EXPECT_EQ(OK, rv);
5821
5822     const HttpResponseInfo* response = trans->GetResponseInfo();
5823     ASSERT_TRUE(response != NULL);
5824     EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
5825
5826     TestCompletionCallback callback2;
5827
5828     rv = trans->RestartWithAuth(
5829         AuthCredentials(kFoo, kBar), callback2.callback());
5830     EXPECT_EQ(ERR_IO_PENDING, rv);
5831
5832     rv = callback2.WaitForResult();
5833     EXPECT_EQ(OK, rv);
5834
5835     response = trans->GetResponseInfo();
5836     ASSERT_TRUE(response != NULL);
5837     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5838   }
5839
5840   // ------------------------------------------------------------------------
5841
5842   // Transaction 2: Request another resource in digestive's protection space.
5843   // This will preemptively add an Authorization header which should have an
5844   // "nc" value of 2 (as compared to 1 in the first use.
5845   {
5846     HttpRequestInfo request;
5847     request.method = "GET";
5848     // Note that Transaction 1 was at /x/y/z, so this is in the same
5849     // protection space as digest.
5850     request.url = GURL("http://www.google.com/x/y/a/b");
5851     request.load_flags = 0;
5852
5853     scoped_ptr<HttpTransaction> trans(
5854         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5855
5856     MockWrite data_writes1[] = {
5857       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5858                 "Host: www.google.com\r\n"
5859                 "Connection: keep-alive\r\n"
5860                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5861                 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5862                 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5863                 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5864     };
5865
5866     // Sever accepts the authorization.
5867     MockRead data_reads1[] = {
5868       MockRead("HTTP/1.0 200 OK\r\n"),
5869       MockRead("Content-Length: 100\r\n\r\n"),
5870       MockRead(SYNCHRONOUS, OK),
5871     };
5872
5873     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5874                                    data_writes1, arraysize(data_writes1));
5875     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5876
5877     TestCompletionCallback callback1;
5878
5879     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5880     EXPECT_EQ(ERR_IO_PENDING, rv);
5881
5882     rv = callback1.WaitForResult();
5883     EXPECT_EQ(OK, rv);
5884
5885     const HttpResponseInfo* response = trans->GetResponseInfo();
5886     ASSERT_TRUE(response != NULL);
5887     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5888   }
5889 }
5890
5891 // Test the ResetStateForRestart() private method.
5892 TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
5893   // Create a transaction (the dependencies aren't important).
5894   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5895   scoped_ptr<HttpNetworkTransaction> trans(
5896       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5897
5898   // Setup some state (which we expect ResetStateForRestart() will clear).
5899   trans->read_buf_ = new IOBuffer(15);
5900   trans->read_buf_len_ = 15;
5901   trans->request_headers_.SetHeader("Authorization", "NTLM");
5902
5903   // Setup state in response_
5904   HttpResponseInfo* response = &trans->response_;
5905   response->auth_challenge = new AuthChallengeInfo();
5906   response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
5907   response->response_time = base::Time::Now();
5908   response->was_cached = true;  // (Wouldn't ever actually be true...)
5909
5910   { // Setup state for response_.vary_data
5911     HttpRequestInfo request;
5912     std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5913     std::replace(temp.begin(), temp.end(), '\n', '\0');
5914     scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
5915     request.extra_headers.SetHeader("Foo", "1");
5916     request.extra_headers.SetHeader("bar", "23");
5917     EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
5918   }
5919
5920   // Cause the above state to be reset.
5921   trans->ResetStateForRestart();
5922
5923   // Verify that the state that needed to be reset, has been reset.
5924   EXPECT_TRUE(trans->read_buf_.get() == NULL);
5925   EXPECT_EQ(0, trans->read_buf_len_);
5926   EXPECT_TRUE(trans->request_headers_.IsEmpty());
5927   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5928   EXPECT_TRUE(response->headers.get() == NULL);
5929   EXPECT_FALSE(response->was_cached);
5930   EXPECT_EQ(0U, response->ssl_info.cert_status);
5931   EXPECT_FALSE(response->vary_data.is_valid());
5932 }
5933
5934 // Test HTTPS connections to a site with a bad certificate
5935 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
5936   HttpRequestInfo request;
5937   request.method = "GET";
5938   request.url = GURL("https://www.google.com/");
5939   request.load_flags = 0;
5940
5941   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5942   scoped_ptr<HttpTransaction> trans(
5943       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5944
5945   MockWrite data_writes[] = {
5946     MockWrite("GET / HTTP/1.1\r\n"
5947               "Host: www.google.com\r\n"
5948               "Connection: keep-alive\r\n\r\n"),
5949   };
5950
5951   MockRead data_reads[] = {
5952     MockRead("HTTP/1.0 200 OK\r\n"),
5953     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5954     MockRead("Content-Length: 100\r\n\r\n"),
5955     MockRead(SYNCHRONOUS, OK),
5956   };
5957
5958   StaticSocketDataProvider ssl_bad_certificate;
5959   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5960                                 data_writes, arraysize(data_writes));
5961   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5962   SSLSocketDataProvider ssl(ASYNC, OK);
5963
5964   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5965   session_deps_.socket_factory->AddSocketDataProvider(&data);
5966   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5967   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5968
5969   TestCompletionCallback callback;
5970
5971   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5972   EXPECT_EQ(ERR_IO_PENDING, rv);
5973
5974   rv = callback.WaitForResult();
5975   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5976
5977   rv = trans->RestartIgnoringLastError(callback.callback());
5978   EXPECT_EQ(ERR_IO_PENDING, rv);
5979
5980   rv = callback.WaitForResult();
5981   EXPECT_EQ(OK, rv);
5982
5983   const HttpResponseInfo* response = trans->GetResponseInfo();
5984
5985   ASSERT_TRUE(response != NULL);
5986   EXPECT_EQ(100, response->headers->GetContentLength());
5987 }
5988
5989 // Test HTTPS connections to a site with a bad certificate, going through a
5990 // proxy
5991 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
5992   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
5993
5994   HttpRequestInfo request;
5995   request.method = "GET";
5996   request.url = GURL("https://www.google.com/");
5997   request.load_flags = 0;
5998
5999   MockWrite proxy_writes[] = {
6000     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6001               "Host: www.google.com\r\n"
6002               "Proxy-Connection: keep-alive\r\n\r\n"),
6003   };
6004
6005   MockRead proxy_reads[] = {
6006     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6007     MockRead(SYNCHRONOUS, OK)
6008   };
6009
6010   MockWrite data_writes[] = {
6011     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6012               "Host: www.google.com\r\n"
6013               "Proxy-Connection: keep-alive\r\n\r\n"),
6014     MockWrite("GET / HTTP/1.1\r\n"
6015               "Host: www.google.com\r\n"
6016               "Connection: keep-alive\r\n\r\n"),
6017   };
6018
6019   MockRead data_reads[] = {
6020     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6021     MockRead("HTTP/1.0 200 OK\r\n"),
6022     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6023     MockRead("Content-Length: 100\r\n\r\n"),
6024     MockRead(SYNCHRONOUS, OK),
6025   };
6026
6027   StaticSocketDataProvider ssl_bad_certificate(
6028       proxy_reads, arraysize(proxy_reads),
6029       proxy_writes, arraysize(proxy_writes));
6030   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6031                                 data_writes, arraysize(data_writes));
6032   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6033   SSLSocketDataProvider ssl(ASYNC, OK);
6034
6035   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6036   session_deps_.socket_factory->AddSocketDataProvider(&data);
6037   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6038   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6039
6040   TestCompletionCallback callback;
6041
6042   for (int i = 0; i < 2; i++) {
6043     session_deps_.socket_factory->ResetNextMockIndexes();
6044
6045     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6046     scoped_ptr<HttpTransaction> trans(
6047         new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6048
6049     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6050     EXPECT_EQ(ERR_IO_PENDING, rv);
6051
6052     rv = callback.WaitForResult();
6053     EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6054
6055     rv = trans->RestartIgnoringLastError(callback.callback());
6056     EXPECT_EQ(ERR_IO_PENDING, rv);
6057
6058     rv = callback.WaitForResult();
6059     EXPECT_EQ(OK, rv);
6060
6061     const HttpResponseInfo* response = trans->GetResponseInfo();
6062
6063     ASSERT_TRUE(response != NULL);
6064     EXPECT_EQ(100, response->headers->GetContentLength());
6065   }
6066 }
6067
6068
6069 // Test HTTPS connections to a site, going through an HTTPS proxy
6070 TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
6071   session_deps_.proxy_service.reset(
6072       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6073   CapturingNetLog net_log;
6074   session_deps_.net_log = &net_log;
6075
6076   HttpRequestInfo request;
6077   request.method = "GET";
6078   request.url = GURL("https://www.google.com/");
6079   request.load_flags = 0;
6080
6081   MockWrite data_writes[] = {
6082     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6083               "Host: www.google.com\r\n"
6084               "Proxy-Connection: keep-alive\r\n\r\n"),
6085     MockWrite("GET / HTTP/1.1\r\n"
6086               "Host: www.google.com\r\n"
6087               "Connection: keep-alive\r\n\r\n"),
6088   };
6089
6090   MockRead data_reads[] = {
6091     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6092     MockRead("HTTP/1.1 200 OK\r\n"),
6093     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6094     MockRead("Content-Length: 100\r\n\r\n"),
6095     MockRead(SYNCHRONOUS, OK),
6096   };
6097
6098   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6099                                 data_writes, arraysize(data_writes));
6100   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6101   SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
6102
6103   session_deps_.socket_factory->AddSocketDataProvider(&data);
6104   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6105   session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
6106
6107   TestCompletionCallback callback;
6108
6109   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6110   scoped_ptr<HttpTransaction> trans(
6111       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6112
6113   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6114   EXPECT_EQ(ERR_IO_PENDING, rv);
6115
6116   rv = callback.WaitForResult();
6117   EXPECT_EQ(OK, rv);
6118   const HttpResponseInfo* response = trans->GetResponseInfo();
6119
6120   ASSERT_TRUE(response != NULL);
6121
6122   EXPECT_TRUE(response->headers->IsKeepAlive());
6123   EXPECT_EQ(200, response->headers->response_code());
6124   EXPECT_EQ(100, response->headers->GetContentLength());
6125   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6126
6127   LoadTimingInfo load_timing_info;
6128   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6129   TestLoadTimingNotReusedWithPac(load_timing_info,
6130                                  CONNECT_TIMING_HAS_SSL_TIMES);
6131 }
6132
6133 // Test an HTTPS Proxy's ability to redirect a CONNECT request
6134 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
6135   session_deps_.proxy_service.reset(
6136       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6137   CapturingNetLog net_log;
6138   session_deps_.net_log = &net_log;
6139
6140   HttpRequestInfo request;
6141   request.method = "GET";
6142   request.url = GURL("https://www.google.com/");
6143   request.load_flags = 0;
6144
6145   MockWrite data_writes[] = {
6146     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6147               "Host: www.google.com\r\n"
6148               "Proxy-Connection: keep-alive\r\n\r\n"),
6149   };
6150
6151   MockRead data_reads[] = {
6152     MockRead("HTTP/1.1 302 Redirect\r\n"),
6153     MockRead("Location: http://login.example.com/\r\n"),
6154     MockRead("Content-Length: 0\r\n\r\n"),
6155     MockRead(SYNCHRONOUS, OK),
6156   };
6157
6158   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6159                                 data_writes, arraysize(data_writes));
6160   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6161
6162   session_deps_.socket_factory->AddSocketDataProvider(&data);
6163   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6164
6165   TestCompletionCallback callback;
6166
6167   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6168   scoped_ptr<HttpTransaction> trans(
6169       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6170
6171   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6172   EXPECT_EQ(ERR_IO_PENDING, rv);
6173
6174   rv = callback.WaitForResult();
6175   EXPECT_EQ(OK, rv);
6176   const HttpResponseInfo* response = trans->GetResponseInfo();
6177
6178   ASSERT_TRUE(response != NULL);
6179
6180   EXPECT_EQ(302, response->headers->response_code());
6181   std::string url;
6182   EXPECT_TRUE(response->headers->IsRedirect(&url));
6183   EXPECT_EQ("http://login.example.com/", url);
6184
6185   // In the case of redirects from proxies, HttpNetworkTransaction returns
6186   // timing for the proxy connection instead of the connection to the host,
6187   // and no send / receive times.
6188   // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6189   LoadTimingInfo load_timing_info;
6190   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6191
6192   EXPECT_FALSE(load_timing_info.socket_reused);
6193   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
6194
6195   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6196   EXPECT_LE(load_timing_info.proxy_resolve_start,
6197             load_timing_info.proxy_resolve_end);
6198   EXPECT_LE(load_timing_info.proxy_resolve_end,
6199             load_timing_info.connect_timing.connect_start);
6200   ExpectConnectTimingHasTimes(
6201       load_timing_info.connect_timing,
6202       CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6203
6204   EXPECT_TRUE(load_timing_info.send_start.is_null());
6205   EXPECT_TRUE(load_timing_info.send_end.is_null());
6206   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
6207 }
6208
6209 // Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
6210 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
6211   session_deps_.proxy_service.reset(
6212       ProxyService::CreateFixed("https://proxy:70"));
6213
6214   HttpRequestInfo request;
6215   request.method = "GET";
6216   request.url = GURL("https://www.google.com/");
6217   request.load_flags = 0;
6218
6219   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6220                                                              LOWEST));
6221   scoped_ptr<SpdyFrame> goaway(
6222       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
6223   MockWrite data_writes[] = {
6224     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6225     CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
6226   };
6227
6228   static const char* const kExtraHeaders[] = {
6229     "location",
6230     "http://login.example.com/",
6231   };
6232   scoped_ptr<SpdyFrame> resp(
6233       spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
6234                                  arraysize(kExtraHeaders)/2, 1));
6235   MockRead data_reads[] = {
6236     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6237     MockRead(ASYNC, 0, 2),  // EOF
6238   };
6239
6240   DelayedSocketData data(
6241       1,  // wait for one write to finish before reading.
6242       data_reads, arraysize(data_reads),
6243       data_writes, arraysize(data_writes));
6244   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6245   proxy_ssl.SetNextProto(GetParam());
6246
6247   session_deps_.socket_factory->AddSocketDataProvider(&data);
6248   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6249
6250   TestCompletionCallback callback;
6251
6252   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6253   scoped_ptr<HttpTransaction> trans(
6254       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6255
6256   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6257   EXPECT_EQ(ERR_IO_PENDING, rv);
6258
6259   rv = callback.WaitForResult();
6260   EXPECT_EQ(OK, rv);
6261   const HttpResponseInfo* response = trans->GetResponseInfo();
6262
6263   ASSERT_TRUE(response != NULL);
6264
6265   EXPECT_EQ(302, response->headers->response_code());
6266   std::string url;
6267   EXPECT_TRUE(response->headers->IsRedirect(&url));
6268   EXPECT_EQ("http://login.example.com/", url);
6269 }
6270
6271 // Test that an HTTPS proxy's response to a CONNECT request is filtered.
6272 TEST_P(HttpNetworkTransactionTest,
6273        ErrorResponseToHttpsConnectViaHttpsProxy) {
6274   session_deps_.proxy_service.reset(
6275       ProxyService::CreateFixed("https://proxy:70"));
6276
6277   HttpRequestInfo request;
6278   request.method = "GET";
6279   request.url = GURL("https://www.google.com/");
6280   request.load_flags = 0;
6281
6282   MockWrite data_writes[] = {
6283     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6284               "Host: www.google.com\r\n"
6285               "Proxy-Connection: keep-alive\r\n\r\n"),
6286   };
6287
6288   MockRead data_reads[] = {
6289     MockRead("HTTP/1.1 404 Not Found\r\n"),
6290     MockRead("Content-Length: 23\r\n\r\n"),
6291     MockRead("The host does not exist"),
6292     MockRead(SYNCHRONOUS, OK),
6293   };
6294
6295   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6296                                 data_writes, arraysize(data_writes));
6297   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6298
6299   session_deps_.socket_factory->AddSocketDataProvider(&data);
6300   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6301
6302   TestCompletionCallback callback;
6303
6304   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6305   scoped_ptr<HttpTransaction> trans(
6306       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6307
6308   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6309   EXPECT_EQ(ERR_IO_PENDING, rv);
6310
6311   rv = callback.WaitForResult();
6312   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
6313
6314   // TODO(ttuttle): Anything else to check here?
6315 }
6316
6317 // Test that a SPDY proxy's response to a CONNECT request is filtered.
6318 TEST_P(HttpNetworkTransactionTest,
6319        ErrorResponseToHttpsConnectViaSpdyProxy) {
6320   session_deps_.proxy_service.reset(
6321      ProxyService::CreateFixed("https://proxy:70"));
6322
6323   HttpRequestInfo request;
6324   request.method = "GET";
6325   request.url = GURL("https://www.google.com/");
6326   request.load_flags = 0;
6327
6328   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6329                                                              LOWEST));
6330   scoped_ptr<SpdyFrame> rst(
6331       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
6332   MockWrite data_writes[] = {
6333     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6334     CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
6335   };
6336
6337   static const char* const kExtraHeaders[] = {
6338     "location",
6339     "http://login.example.com/",
6340   };
6341   scoped_ptr<SpdyFrame> resp(
6342       spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
6343                                  arraysize(kExtraHeaders)/2, 1));
6344   scoped_ptr<SpdyFrame> body(
6345       spdy_util_.ConstructSpdyBodyFrame(
6346           1, "The host does not exist", 23, true));
6347   MockRead data_reads[] = {
6348     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6349     CreateMockRead(*body.get(), 2, SYNCHRONOUS),
6350     MockRead(ASYNC, 0, 4),  // EOF
6351   };
6352
6353   DelayedSocketData data(
6354       1,  // wait for one write to finish before reading.
6355       data_reads, arraysize(data_reads),
6356       data_writes, arraysize(data_writes));
6357   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6358   proxy_ssl.SetNextProto(GetParam());
6359
6360   session_deps_.socket_factory->AddSocketDataProvider(&data);
6361   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6362
6363   TestCompletionCallback callback;
6364
6365   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6366   scoped_ptr<HttpTransaction> trans(
6367       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6368
6369   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6370   EXPECT_EQ(ERR_IO_PENDING, rv);
6371
6372   rv = callback.WaitForResult();
6373   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
6374
6375   // TODO(ttuttle): Anything else to check here?
6376 }
6377
6378 // Test the request-challenge-retry sequence for basic auth, through
6379 // a SPDY proxy over a single SPDY session.
6380 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
6381   HttpRequestInfo request;
6382   request.method = "GET";
6383   request.url = GURL("https://www.google.com/");
6384   // when the no authentication data flag is set.
6385   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6386
6387   // Configure against https proxy server "myproxy:70".
6388   session_deps_.proxy_service.reset(
6389       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
6390   CapturingBoundNetLog log;
6391   session_deps_.net_log = log.bound().net_log();
6392   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6393
6394   // Since we have proxy, should try to establish tunnel.
6395   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6396                                                             LOWEST));
6397   scoped_ptr<SpdyFrame> rst(
6398       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
6399
6400   // After calling trans->RestartWithAuth(), this is the request we should
6401   // be issuing -- the final header line contains the credentials.
6402   const char* const kAuthCredentials[] = {
6403       "proxy-authorization", "Basic Zm9vOmJhcg==",
6404   };
6405   scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
6406       kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
6407   // fetch https://www.google.com/ via HTTP
6408   const char get[] = "GET / HTTP/1.1\r\n"
6409     "Host: www.google.com\r\n"
6410     "Connection: keep-alive\r\n\r\n";
6411   scoped_ptr<SpdyFrame> wrapped_get(
6412       spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
6413
6414   MockWrite spdy_writes[] = {
6415     CreateMockWrite(*req, 1, ASYNC),
6416     CreateMockWrite(*rst, 4, ASYNC),
6417     CreateMockWrite(*connect2, 5),
6418     CreateMockWrite(*wrapped_get, 8),
6419   };
6420
6421   // The proxy responds to the connect with a 407, using a persistent
6422   // connection.
6423   const char* const kAuthStatus = "407";
6424   const char* const kAuthChallenge[] = {
6425     "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6426   };
6427   scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6428       kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
6429
6430   scoped_ptr<SpdyFrame> conn_resp(
6431       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
6432   const char resp[] = "HTTP/1.1 200 OK\r\n"
6433       "Content-Length: 5\r\n\r\n";
6434
6435   scoped_ptr<SpdyFrame> wrapped_get_resp(
6436       spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
6437   scoped_ptr<SpdyFrame> wrapped_body(
6438       spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
6439   MockRead spdy_reads[] = {
6440     CreateMockRead(*conn_auth_resp, 2, ASYNC),
6441     CreateMockRead(*conn_resp, 6, ASYNC),
6442     CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6443     CreateMockRead(*wrapped_body, 10, ASYNC),
6444     MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
6445   };
6446
6447   OrderedSocketData spdy_data(
6448       spdy_reads, arraysize(spdy_reads),
6449       spdy_writes, arraysize(spdy_writes));
6450   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6451   // Negotiate SPDY to the proxy
6452   SSLSocketDataProvider proxy(ASYNC, OK);
6453   proxy.SetNextProto(GetParam());
6454   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
6455   // Vanilla SSL to the server
6456   SSLSocketDataProvider server(ASYNC, OK);
6457   session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
6458
6459   TestCompletionCallback callback1;
6460
6461   scoped_ptr<HttpTransaction> trans(
6462       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6463
6464   int rv = trans->Start(&request, callback1.callback(), log.bound());
6465   EXPECT_EQ(ERR_IO_PENDING, rv);
6466
6467   rv = callback1.WaitForResult();
6468   EXPECT_EQ(OK, rv);
6469   net::CapturingNetLog::CapturedEntryList entries;
6470   log.GetEntries(&entries);
6471   size_t pos = ExpectLogContainsSomewhere(
6472       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6473       NetLog::PHASE_NONE);
6474   ExpectLogContainsSomewhere(
6475       entries, pos,
6476       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6477       NetLog::PHASE_NONE);
6478
6479   const HttpResponseInfo* response = trans->GetResponseInfo();
6480   ASSERT_TRUE(response != NULL);
6481   ASSERT_FALSE(response->headers.get() == NULL);
6482   EXPECT_EQ(407, response->headers->response_code());
6483   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6484   EXPECT_TRUE(response->auth_challenge.get() != NULL);
6485   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6486
6487   TestCompletionCallback callback2;
6488
6489   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6490                               callback2.callback());
6491   EXPECT_EQ(ERR_IO_PENDING, rv);
6492
6493   rv = callback2.WaitForResult();
6494   EXPECT_EQ(OK, rv);
6495
6496   response = trans->GetResponseInfo();
6497   ASSERT_TRUE(response != NULL);
6498
6499   EXPECT_TRUE(response->headers->IsKeepAlive());
6500   EXPECT_EQ(200, response->headers->response_code());
6501   EXPECT_EQ(5, response->headers->GetContentLength());
6502   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6503
6504   // The password prompt info should not be set.
6505   EXPECT_TRUE(response->auth_challenge.get() == NULL);
6506
6507   LoadTimingInfo load_timing_info;
6508   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6509   TestLoadTimingNotReusedWithPac(load_timing_info,
6510                                  CONNECT_TIMING_HAS_SSL_TIMES);
6511
6512   trans.reset();
6513   session->CloseAllConnections();
6514 }
6515
6516 // Test that an explicitly trusted SPDY proxy can push a resource from an
6517 // origin that is different from that of its associated resource.
6518 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
6519   HttpRequestInfo request;
6520   HttpRequestInfo push_request;
6521
6522   request.method = "GET";
6523   request.url = GURL("http://www.google.com/");
6524   push_request.method = "GET";
6525   push_request.url = GURL("http://www.another-origin.com/foo.dat");
6526
6527   // Configure against https proxy server "myproxy:70".
6528   session_deps_.proxy_service.reset(
6529       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
6530   CapturingBoundNetLog log;
6531   session_deps_.net_log = log.bound().net_log();
6532
6533   // Enable cross-origin push.
6534   session_deps_.trusted_spdy_proxy = "myproxy:70";
6535
6536   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6537
6538   scoped_ptr<SpdyFrame> stream1_syn(
6539       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
6540
6541   MockWrite spdy_writes[] = {
6542     CreateMockWrite(*stream1_syn, 1, ASYNC),
6543   };
6544
6545   scoped_ptr<SpdyFrame>
6546       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
6547
6548   scoped_ptr<SpdyFrame>
6549       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
6550
6551   scoped_ptr<SpdyFrame>
6552       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
6553                                     0,
6554                                     2,
6555                                     1,
6556                                     "http://www.another-origin.com/foo.dat"));
6557   const char kPushedData[] = "pushed";
6558   scoped_ptr<SpdyFrame> stream2_body(
6559       spdy_util_.ConstructSpdyBodyFrame(
6560           2, kPushedData, strlen(kPushedData), true));
6561
6562   MockRead spdy_reads[] = {
6563     CreateMockRead(*stream1_reply, 2, ASYNC),
6564     CreateMockRead(*stream2_syn, 3, ASYNC),
6565     CreateMockRead(*stream1_body, 4, ASYNC),
6566     CreateMockRead(*stream2_body, 5, ASYNC),
6567     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
6568   };
6569
6570   OrderedSocketData spdy_data(
6571       spdy_reads, arraysize(spdy_reads),
6572       spdy_writes, arraysize(spdy_writes));
6573   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6574   // Negotiate SPDY to the proxy
6575   SSLSocketDataProvider proxy(ASYNC, OK);
6576   proxy.SetNextProto(GetParam());
6577   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
6578
6579   scoped_ptr<HttpTransaction> trans(
6580       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6581   TestCompletionCallback callback;
6582   int rv = trans->Start(&request, callback.callback(), log.bound());
6583   EXPECT_EQ(ERR_IO_PENDING, rv);
6584
6585   rv = callback.WaitForResult();
6586   EXPECT_EQ(OK, rv);
6587   const HttpResponseInfo* response = trans->GetResponseInfo();
6588
6589   scoped_ptr<HttpTransaction> push_trans(
6590       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6591   rv = push_trans->Start(&push_request, callback.callback(), log.bound());
6592   EXPECT_EQ(ERR_IO_PENDING, rv);
6593
6594   rv = callback.WaitForResult();
6595   EXPECT_EQ(OK, rv);
6596   const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6597
6598   ASSERT_TRUE(response != NULL);
6599   EXPECT_TRUE(response->headers->IsKeepAlive());
6600
6601   EXPECT_EQ(200, response->headers->response_code());
6602   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6603
6604   std::string response_data;
6605   rv = ReadTransaction(trans.get(), &response_data);
6606   EXPECT_EQ(OK, rv);
6607   EXPECT_EQ("hello!", response_data);
6608
6609   LoadTimingInfo load_timing_info;
6610   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6611   TestLoadTimingNotReusedWithPac(load_timing_info,
6612                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6613
6614   // Verify the pushed stream.
6615   EXPECT_TRUE(push_response->headers.get() != NULL);
6616   EXPECT_EQ(200, push_response->headers->response_code());
6617
6618   rv = ReadTransaction(push_trans.get(), &response_data);
6619   EXPECT_EQ(OK, rv);
6620   EXPECT_EQ("pushed", response_data);
6621
6622   LoadTimingInfo push_load_timing_info;
6623   EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6624   TestLoadTimingReusedWithPac(push_load_timing_info);
6625   // The transactions should share a socket ID, despite being for different
6626   // origins.
6627   EXPECT_EQ(load_timing_info.socket_log_id,
6628             push_load_timing_info.socket_log_id);
6629
6630   trans.reset();
6631   push_trans.reset();
6632   session->CloseAllConnections();
6633 }
6634
6635 // Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
6636 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
6637   HttpRequestInfo request;
6638
6639   request.method = "GET";
6640   request.url = GURL("http://www.google.com/");
6641
6642   // Configure against https proxy server "myproxy:70".
6643   session_deps_.proxy_service.reset(
6644       ProxyService::CreateFixed("https://myproxy:70"));
6645   CapturingBoundNetLog log;
6646   session_deps_.net_log = log.bound().net_log();
6647
6648   // Enable cross-origin push.
6649   session_deps_.trusted_spdy_proxy = "myproxy:70";
6650
6651   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6652
6653   scoped_ptr<SpdyFrame> stream1_syn(
6654       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
6655
6656   scoped_ptr<SpdyFrame> push_rst(
6657       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
6658
6659   MockWrite spdy_writes[] = {
6660     CreateMockWrite(*stream1_syn, 1, ASYNC),
6661     CreateMockWrite(*push_rst, 4),
6662   };
6663
6664   scoped_ptr<SpdyFrame>
6665       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
6666
6667   scoped_ptr<SpdyFrame>
6668       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
6669
6670   scoped_ptr<SpdyFrame>
6671       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
6672                                     0,
6673                                     2,
6674                                     1,
6675                                     "https://www.another-origin.com/foo.dat"));
6676
6677   MockRead spdy_reads[] = {
6678     CreateMockRead(*stream1_reply, 2, ASYNC),
6679     CreateMockRead(*stream2_syn, 3, ASYNC),
6680     CreateMockRead(*stream1_body, 5, ASYNC),
6681     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
6682   };
6683
6684   OrderedSocketData spdy_data(
6685       spdy_reads, arraysize(spdy_reads),
6686       spdy_writes, arraysize(spdy_writes));
6687   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6688   // Negotiate SPDY to the proxy
6689   SSLSocketDataProvider proxy(ASYNC, OK);
6690   proxy.SetNextProto(GetParam());
6691   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
6692
6693   scoped_ptr<HttpTransaction> trans(
6694       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6695   TestCompletionCallback callback;
6696   int rv = trans->Start(&request, callback.callback(), log.bound());
6697   EXPECT_EQ(ERR_IO_PENDING, rv);
6698
6699   rv = callback.WaitForResult();
6700   EXPECT_EQ(OK, rv);
6701   const HttpResponseInfo* response = trans->GetResponseInfo();
6702
6703   ASSERT_TRUE(response != NULL);
6704   EXPECT_TRUE(response->headers->IsKeepAlive());
6705
6706   EXPECT_EQ(200, response->headers->response_code());
6707   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6708
6709   std::string response_data;
6710   rv = ReadTransaction(trans.get(), &response_data);
6711   EXPECT_EQ(OK, rv);
6712   EXPECT_EQ("hello!", response_data);
6713
6714   trans.reset();
6715   session->CloseAllConnections();
6716 }
6717
6718 // Test HTTPS connections to a site with a bad certificate, going through an
6719 // HTTPS proxy
6720 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
6721   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
6722       "https://proxy:70"));
6723
6724   HttpRequestInfo request;
6725   request.method = "GET";
6726   request.url = GURL("https://www.google.com/");
6727   request.load_flags = 0;
6728
6729   // Attempt to fetch the URL from a server with a bad cert
6730   MockWrite bad_cert_writes[] = {
6731     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6732               "Host: www.google.com\r\n"
6733               "Proxy-Connection: keep-alive\r\n\r\n"),
6734   };
6735
6736   MockRead bad_cert_reads[] = {
6737     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6738     MockRead(SYNCHRONOUS, OK)
6739   };
6740
6741   // Attempt to fetch the URL with a good cert
6742   MockWrite good_data_writes[] = {
6743     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6744               "Host: www.google.com\r\n"
6745               "Proxy-Connection: keep-alive\r\n\r\n"),
6746     MockWrite("GET / HTTP/1.1\r\n"
6747               "Host: www.google.com\r\n"
6748               "Connection: keep-alive\r\n\r\n"),
6749   };
6750
6751   MockRead good_cert_reads[] = {
6752     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6753     MockRead("HTTP/1.0 200 OK\r\n"),
6754     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6755     MockRead("Content-Length: 100\r\n\r\n"),
6756     MockRead(SYNCHRONOUS, OK),
6757   };
6758
6759   StaticSocketDataProvider ssl_bad_certificate(
6760       bad_cert_reads, arraysize(bad_cert_reads),
6761       bad_cert_writes, arraysize(bad_cert_writes));
6762   StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6763                                 good_data_writes, arraysize(good_data_writes));
6764   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6765   SSLSocketDataProvider ssl(ASYNC, OK);
6766
6767   // SSL to the proxy, then CONNECT request, then SSL with bad certificate
6768   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6769   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6770   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6771
6772   // SSL to the proxy, then CONNECT request, then valid SSL certificate
6773   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6774   session_deps_.socket_factory->AddSocketDataProvider(&data);
6775   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6776
6777   TestCompletionCallback callback;
6778
6779   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6780   scoped_ptr<HttpTransaction> trans(
6781       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6782
6783   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6784   EXPECT_EQ(ERR_IO_PENDING, rv);
6785
6786   rv = callback.WaitForResult();
6787   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6788
6789   rv = trans->RestartIgnoringLastError(callback.callback());
6790   EXPECT_EQ(ERR_IO_PENDING, rv);
6791
6792   rv = callback.WaitForResult();
6793   EXPECT_EQ(OK, rv);
6794
6795   const HttpResponseInfo* response = trans->GetResponseInfo();
6796
6797   ASSERT_TRUE(response != NULL);
6798   EXPECT_EQ(100, response->headers->GetContentLength());
6799 }
6800
6801 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
6802   HttpRequestInfo request;
6803   request.method = "GET";
6804   request.url = GURL("http://www.google.com/");
6805   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6806                                   "Chromium Ultra Awesome X Edition");
6807
6808   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6809   scoped_ptr<HttpTransaction> trans(
6810       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6811
6812   MockWrite data_writes[] = {
6813     MockWrite("GET / HTTP/1.1\r\n"
6814               "Host: www.google.com\r\n"
6815               "Connection: keep-alive\r\n"
6816               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6817   };
6818
6819   // Lastly, the server responds with the actual content.
6820   MockRead data_reads[] = {
6821     MockRead("HTTP/1.0 200 OK\r\n"),
6822     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6823     MockRead("Content-Length: 100\r\n\r\n"),
6824     MockRead(SYNCHRONOUS, OK),
6825   };
6826
6827   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6828                                 data_writes, arraysize(data_writes));
6829   session_deps_.socket_factory->AddSocketDataProvider(&data);
6830
6831   TestCompletionCallback callback;
6832
6833   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6834   EXPECT_EQ(ERR_IO_PENDING, rv);
6835
6836   rv = callback.WaitForResult();
6837   EXPECT_EQ(OK, rv);
6838 }
6839
6840 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
6841   HttpRequestInfo request;
6842   request.method = "GET";
6843   request.url = GURL("https://www.google.com/");
6844   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6845                                   "Chromium Ultra Awesome X Edition");
6846
6847   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
6848   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6849   scoped_ptr<HttpTransaction> trans(
6850       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6851
6852   MockWrite data_writes[] = {
6853     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6854               "Host: www.google.com\r\n"
6855               "Proxy-Connection: keep-alive\r\n"
6856               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6857   };
6858   MockRead data_reads[] = {
6859     // Return an error, so the transaction stops here (this test isn't
6860     // interested in the rest).
6861     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6862     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6863     MockRead("Proxy-Connection: close\r\n\r\n"),
6864   };
6865
6866   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6867                                 data_writes, arraysize(data_writes));
6868   session_deps_.socket_factory->AddSocketDataProvider(&data);
6869
6870   TestCompletionCallback callback;
6871
6872   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6873   EXPECT_EQ(ERR_IO_PENDING, rv);
6874
6875   rv = callback.WaitForResult();
6876   EXPECT_EQ(OK, rv);
6877 }
6878
6879 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
6880   HttpRequestInfo request;
6881   request.method = "GET";
6882   request.url = GURL("http://www.google.com/");
6883   request.load_flags = 0;
6884   request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6885                                   "http://the.previous.site.com/");
6886
6887   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6888   scoped_ptr<HttpTransaction> trans(
6889       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6890
6891   MockWrite data_writes[] = {
6892     MockWrite("GET / HTTP/1.1\r\n"
6893               "Host: www.google.com\r\n"
6894               "Connection: keep-alive\r\n"
6895               "Referer: http://the.previous.site.com/\r\n\r\n"),
6896   };
6897
6898   // Lastly, the server responds with the actual content.
6899   MockRead data_reads[] = {
6900     MockRead("HTTP/1.0 200 OK\r\n"),
6901     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6902     MockRead("Content-Length: 100\r\n\r\n"),
6903     MockRead(SYNCHRONOUS, OK),
6904   };
6905
6906   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6907                                 data_writes, arraysize(data_writes));
6908   session_deps_.socket_factory->AddSocketDataProvider(&data);
6909
6910   TestCompletionCallback callback;
6911
6912   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6913   EXPECT_EQ(ERR_IO_PENDING, rv);
6914
6915   rv = callback.WaitForResult();
6916   EXPECT_EQ(OK, rv);
6917 }
6918
6919 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
6920   HttpRequestInfo request;
6921   request.method = "POST";
6922   request.url = GURL("http://www.google.com/");
6923
6924   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6925   scoped_ptr<HttpTransaction> trans(
6926       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6927
6928   MockWrite data_writes[] = {
6929     MockWrite("POST / HTTP/1.1\r\n"
6930               "Host: www.google.com\r\n"
6931               "Connection: keep-alive\r\n"
6932               "Content-Length: 0\r\n\r\n"),
6933   };
6934
6935   // Lastly, the server responds with the actual content.
6936   MockRead data_reads[] = {
6937     MockRead("HTTP/1.0 200 OK\r\n"),
6938     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6939     MockRead("Content-Length: 100\r\n\r\n"),
6940     MockRead(SYNCHRONOUS, OK),
6941   };
6942
6943   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6944                                 data_writes, arraysize(data_writes));
6945   session_deps_.socket_factory->AddSocketDataProvider(&data);
6946
6947   TestCompletionCallback callback;
6948
6949   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6950   EXPECT_EQ(ERR_IO_PENDING, rv);
6951
6952   rv = callback.WaitForResult();
6953   EXPECT_EQ(OK, rv);
6954 }
6955
6956 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
6957   HttpRequestInfo request;
6958   request.method = "PUT";
6959   request.url = GURL("http://www.google.com/");
6960
6961   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6962   scoped_ptr<HttpTransaction> trans(
6963       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6964
6965   MockWrite data_writes[] = {
6966     MockWrite("PUT / HTTP/1.1\r\n"
6967               "Host: www.google.com\r\n"
6968               "Connection: keep-alive\r\n"
6969               "Content-Length: 0\r\n\r\n"),
6970   };
6971
6972   // Lastly, the server responds with the actual content.
6973   MockRead data_reads[] = {
6974     MockRead("HTTP/1.0 200 OK\r\n"),
6975     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6976     MockRead("Content-Length: 100\r\n\r\n"),
6977     MockRead(SYNCHRONOUS, OK),
6978   };
6979
6980   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6981                                 data_writes, arraysize(data_writes));
6982   session_deps_.socket_factory->AddSocketDataProvider(&data);
6983
6984   TestCompletionCallback callback;
6985
6986   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6987   EXPECT_EQ(ERR_IO_PENDING, rv);
6988
6989   rv = callback.WaitForResult();
6990   EXPECT_EQ(OK, rv);
6991 }
6992
6993 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
6994   HttpRequestInfo request;
6995   request.method = "HEAD";
6996   request.url = GURL("http://www.google.com/");
6997
6998   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6999   scoped_ptr<HttpTransaction> trans(
7000       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7001
7002   MockWrite data_writes[] = {
7003     MockWrite("HEAD / HTTP/1.1\r\n"
7004               "Host: www.google.com\r\n"
7005               "Connection: keep-alive\r\n"
7006               "Content-Length: 0\r\n\r\n"),
7007   };
7008
7009   // Lastly, the server responds with the actual content.
7010   MockRead data_reads[] = {
7011     MockRead("HTTP/1.0 200 OK\r\n"),
7012     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7013     MockRead("Content-Length: 100\r\n\r\n"),
7014     MockRead(SYNCHRONOUS, OK),
7015   };
7016
7017   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7018                                 data_writes, arraysize(data_writes));
7019   session_deps_.socket_factory->AddSocketDataProvider(&data);
7020
7021   TestCompletionCallback callback;
7022
7023   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7024   EXPECT_EQ(ERR_IO_PENDING, rv);
7025
7026   rv = callback.WaitForResult();
7027   EXPECT_EQ(OK, rv);
7028 }
7029
7030 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
7031   HttpRequestInfo request;
7032   request.method = "GET";
7033   request.url = GURL("http://www.google.com/");
7034   request.load_flags = LOAD_BYPASS_CACHE;
7035
7036   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7037   scoped_ptr<HttpTransaction> trans(
7038       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7039
7040   MockWrite data_writes[] = {
7041     MockWrite("GET / HTTP/1.1\r\n"
7042               "Host: www.google.com\r\n"
7043               "Connection: keep-alive\r\n"
7044               "Pragma: no-cache\r\n"
7045               "Cache-Control: no-cache\r\n\r\n"),
7046   };
7047
7048   // Lastly, the server responds with the actual content.
7049   MockRead data_reads[] = {
7050     MockRead("HTTP/1.0 200 OK\r\n"),
7051     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7052     MockRead("Content-Length: 100\r\n\r\n"),
7053     MockRead(SYNCHRONOUS, OK),
7054   };
7055
7056   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7057                                 data_writes, arraysize(data_writes));
7058   session_deps_.socket_factory->AddSocketDataProvider(&data);
7059
7060   TestCompletionCallback callback;
7061
7062   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7063   EXPECT_EQ(ERR_IO_PENDING, rv);
7064
7065   rv = callback.WaitForResult();
7066   EXPECT_EQ(OK, rv);
7067 }
7068
7069 TEST_P(HttpNetworkTransactionTest,
7070        BuildRequest_CacheControlValidateCache) {
7071   HttpRequestInfo request;
7072   request.method = "GET";
7073   request.url = GURL("http://www.google.com/");
7074   request.load_flags = LOAD_VALIDATE_CACHE;
7075
7076   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7077   scoped_ptr<HttpTransaction> trans(
7078       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7079
7080   MockWrite data_writes[] = {
7081     MockWrite("GET / HTTP/1.1\r\n"
7082               "Host: www.google.com\r\n"
7083               "Connection: keep-alive\r\n"
7084               "Cache-Control: max-age=0\r\n\r\n"),
7085   };
7086
7087   // Lastly, the server responds with the actual content.
7088   MockRead data_reads[] = {
7089     MockRead("HTTP/1.0 200 OK\r\n"),
7090     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7091     MockRead("Content-Length: 100\r\n\r\n"),
7092     MockRead(SYNCHRONOUS, OK),
7093   };
7094
7095   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7096                                 data_writes, arraysize(data_writes));
7097   session_deps_.socket_factory->AddSocketDataProvider(&data);
7098
7099   TestCompletionCallback callback;
7100
7101   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7102   EXPECT_EQ(ERR_IO_PENDING, rv);
7103
7104   rv = callback.WaitForResult();
7105   EXPECT_EQ(OK, rv);
7106 }
7107
7108 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
7109   HttpRequestInfo request;
7110   request.method = "GET";
7111   request.url = GURL("http://www.google.com/");
7112   request.extra_headers.SetHeader("FooHeader", "Bar");
7113
7114   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7115   scoped_ptr<HttpTransaction> trans(
7116       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7117
7118   MockWrite data_writes[] = {
7119     MockWrite("GET / HTTP/1.1\r\n"
7120               "Host: www.google.com\r\n"
7121               "Connection: keep-alive\r\n"
7122               "FooHeader: Bar\r\n\r\n"),
7123   };
7124
7125   // Lastly, the server responds with the actual content.
7126   MockRead data_reads[] = {
7127     MockRead("HTTP/1.0 200 OK\r\n"),
7128     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7129     MockRead("Content-Length: 100\r\n\r\n"),
7130     MockRead(SYNCHRONOUS, OK),
7131   };
7132
7133   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7134                                 data_writes, arraysize(data_writes));
7135   session_deps_.socket_factory->AddSocketDataProvider(&data);
7136
7137   TestCompletionCallback callback;
7138
7139   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7140   EXPECT_EQ(ERR_IO_PENDING, rv);
7141
7142   rv = callback.WaitForResult();
7143   EXPECT_EQ(OK, rv);
7144 }
7145
7146 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
7147   HttpRequestInfo request;
7148   request.method = "GET";
7149   request.url = GURL("http://www.google.com/");
7150   request.extra_headers.SetHeader("referer", "www.foo.com");
7151   request.extra_headers.SetHeader("hEllo", "Kitty");
7152   request.extra_headers.SetHeader("FoO", "bar");
7153
7154   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7155   scoped_ptr<HttpTransaction> trans(
7156       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7157
7158   MockWrite data_writes[] = {
7159     MockWrite("GET / HTTP/1.1\r\n"
7160               "Host: www.google.com\r\n"
7161               "Connection: keep-alive\r\n"
7162               "referer: www.foo.com\r\n"
7163               "hEllo: Kitty\r\n"
7164               "FoO: bar\r\n\r\n"),
7165   };
7166
7167   // Lastly, the server responds with the actual content.
7168   MockRead data_reads[] = {
7169     MockRead("HTTP/1.0 200 OK\r\n"),
7170     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7171     MockRead("Content-Length: 100\r\n\r\n"),
7172     MockRead(SYNCHRONOUS, OK),
7173   };
7174
7175   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7176                                 data_writes, arraysize(data_writes));
7177   session_deps_.socket_factory->AddSocketDataProvider(&data);
7178
7179   TestCompletionCallback callback;
7180
7181   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7182   EXPECT_EQ(ERR_IO_PENDING, rv);
7183
7184   rv = callback.WaitForResult();
7185   EXPECT_EQ(OK, rv);
7186 }
7187
7188 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
7189   HttpRequestInfo request;
7190   request.method = "GET";
7191   request.url = GURL("http://www.google.com/");
7192   request.load_flags = 0;
7193
7194   session_deps_.proxy_service.reset(
7195       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7196   CapturingNetLog net_log;
7197   session_deps_.net_log = &net_log;
7198
7199   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7200   scoped_ptr<HttpTransaction> trans(
7201       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7202
7203   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7204   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7205
7206   MockWrite data_writes[] = {
7207     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7208     MockWrite("GET / HTTP/1.1\r\n"
7209               "Host: www.google.com\r\n"
7210               "Connection: keep-alive\r\n\r\n")
7211   };
7212
7213   MockRead data_reads[] = {
7214     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7215     MockRead("HTTP/1.0 200 OK\r\n"),
7216     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7217     MockRead("Payload"),
7218     MockRead(SYNCHRONOUS, OK)
7219   };
7220
7221   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7222                                 data_writes, arraysize(data_writes));
7223   session_deps_.socket_factory->AddSocketDataProvider(&data);
7224
7225   TestCompletionCallback callback;
7226
7227   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7228   EXPECT_EQ(ERR_IO_PENDING, rv);
7229
7230   rv = callback.WaitForResult();
7231   EXPECT_EQ(OK, rv);
7232
7233   const HttpResponseInfo* response = trans->GetResponseInfo();
7234   ASSERT_TRUE(response != NULL);
7235
7236   LoadTimingInfo load_timing_info;
7237   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7238   TestLoadTimingNotReusedWithPac(load_timing_info,
7239                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7240
7241   std::string response_text;
7242   rv = ReadTransaction(trans.get(), &response_text);
7243   EXPECT_EQ(OK, rv);
7244   EXPECT_EQ("Payload", response_text);
7245 }
7246
7247 TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
7248   HttpRequestInfo request;
7249   request.method = "GET";
7250   request.url = GURL("https://www.google.com/");
7251   request.load_flags = 0;
7252
7253   session_deps_.proxy_service.reset(
7254       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7255   CapturingNetLog net_log;
7256   session_deps_.net_log = &net_log;
7257
7258   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7259   scoped_ptr<HttpTransaction> trans(
7260       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7261
7262   unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7263   unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7264
7265   MockWrite data_writes[] = {
7266     MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7267               arraysize(write_buffer)),
7268     MockWrite("GET / HTTP/1.1\r\n"
7269               "Host: www.google.com\r\n"
7270               "Connection: keep-alive\r\n\r\n")
7271   };
7272
7273   MockRead data_reads[] = {
7274     MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7275              arraysize(read_buffer)),
7276     MockRead("HTTP/1.0 200 OK\r\n"),
7277     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7278     MockRead("Payload"),
7279     MockRead(SYNCHRONOUS, OK)
7280   };
7281
7282   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7283                                 data_writes, arraysize(data_writes));
7284   session_deps_.socket_factory->AddSocketDataProvider(&data);
7285
7286   SSLSocketDataProvider ssl(ASYNC, OK);
7287   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7288
7289   TestCompletionCallback callback;
7290
7291   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7292   EXPECT_EQ(ERR_IO_PENDING, rv);
7293
7294   rv = callback.WaitForResult();
7295   EXPECT_EQ(OK, rv);
7296
7297   LoadTimingInfo load_timing_info;
7298   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7299   TestLoadTimingNotReusedWithPac(load_timing_info,
7300                                  CONNECT_TIMING_HAS_SSL_TIMES);
7301
7302   const HttpResponseInfo* response = trans->GetResponseInfo();
7303   ASSERT_TRUE(response != NULL);
7304
7305   std::string response_text;
7306   rv = ReadTransaction(trans.get(), &response_text);
7307   EXPECT_EQ(OK, rv);
7308   EXPECT_EQ("Payload", response_text);
7309 }
7310
7311 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
7312   HttpRequestInfo request;
7313   request.method = "GET";
7314   request.url = GURL("http://www.google.com/");
7315   request.load_flags = 0;
7316
7317   session_deps_.proxy_service.reset(
7318       ProxyService::CreateFixed("socks4://myproxy:1080"));
7319   CapturingNetLog net_log;
7320   session_deps_.net_log = &net_log;
7321
7322   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7323   scoped_ptr<HttpTransaction> trans(
7324       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7325
7326   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7327   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7328
7329   MockWrite data_writes[] = {
7330     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7331     MockWrite("GET / HTTP/1.1\r\n"
7332               "Host: www.google.com\r\n"
7333               "Connection: keep-alive\r\n\r\n")
7334   };
7335
7336   MockRead data_reads[] = {
7337     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7338     MockRead("HTTP/1.0 200 OK\r\n"),
7339     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7340     MockRead("Payload"),
7341     MockRead(SYNCHRONOUS, OK)
7342   };
7343
7344   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7345                                 data_writes, arraysize(data_writes));
7346   session_deps_.socket_factory->AddSocketDataProvider(&data);
7347
7348   TestCompletionCallback callback;
7349
7350   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7351   EXPECT_EQ(ERR_IO_PENDING, rv);
7352
7353   rv = callback.WaitForResult();
7354   EXPECT_EQ(OK, rv);
7355
7356   const HttpResponseInfo* response = trans->GetResponseInfo();
7357   ASSERT_TRUE(response != NULL);
7358
7359   LoadTimingInfo load_timing_info;
7360   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7361   TestLoadTimingNotReused(load_timing_info,
7362                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7363
7364   std::string response_text;
7365   rv = ReadTransaction(trans.get(), &response_text);
7366   EXPECT_EQ(OK, rv);
7367   EXPECT_EQ("Payload", response_text);
7368 }
7369
7370 TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
7371   HttpRequestInfo request;
7372   request.method = "GET";
7373   request.url = GURL("http://www.google.com/");
7374   request.load_flags = 0;
7375
7376   session_deps_.proxy_service.reset(
7377       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7378   CapturingNetLog net_log;
7379   session_deps_.net_log = &net_log;
7380
7381   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7382   scoped_ptr<HttpTransaction> trans(
7383       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7384
7385   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7386   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
7387   const char kSOCKS5OkRequest[] = {
7388     0x05,  // Version
7389     0x01,  // Command (CONNECT)
7390     0x00,  // Reserved.
7391     0x03,  // Address type (DOMAINNAME).
7392     0x0E,  // Length of domain (14)
7393     // Domain string:
7394     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7395     0x00, 0x50,  // 16-bit port (80)
7396   };
7397   const char kSOCKS5OkResponse[] =
7398       { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7399
7400   MockWrite data_writes[] = {
7401     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7402     MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7403     MockWrite("GET / HTTP/1.1\r\n"
7404               "Host: www.google.com\r\n"
7405               "Connection: keep-alive\r\n\r\n")
7406   };
7407
7408   MockRead data_reads[] = {
7409     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7410     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
7411     MockRead("HTTP/1.0 200 OK\r\n"),
7412     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7413     MockRead("Payload"),
7414     MockRead(SYNCHRONOUS, OK)
7415   };
7416
7417   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7418                                 data_writes, arraysize(data_writes));
7419   session_deps_.socket_factory->AddSocketDataProvider(&data);
7420
7421   TestCompletionCallback callback;
7422
7423   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7424   EXPECT_EQ(ERR_IO_PENDING, rv);
7425
7426   rv = callback.WaitForResult();
7427   EXPECT_EQ(OK, rv);
7428
7429   const HttpResponseInfo* response = trans->GetResponseInfo();
7430   ASSERT_TRUE(response != NULL);
7431
7432   LoadTimingInfo load_timing_info;
7433   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7434   TestLoadTimingNotReusedWithPac(load_timing_info,
7435                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7436
7437   std::string response_text;
7438   rv = ReadTransaction(trans.get(), &response_text);
7439   EXPECT_EQ(OK, rv);
7440   EXPECT_EQ("Payload", response_text);
7441 }
7442
7443 TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
7444   HttpRequestInfo request;
7445   request.method = "GET";
7446   request.url = GURL("https://www.google.com/");
7447   request.load_flags = 0;
7448
7449   session_deps_.proxy_service.reset(
7450       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7451   CapturingNetLog net_log;
7452   session_deps_.net_log = &net_log;
7453
7454   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7455   scoped_ptr<HttpTransaction> trans(
7456       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7457
7458   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7459   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
7460   const unsigned char kSOCKS5OkRequest[] = {
7461     0x05,  // Version
7462     0x01,  // Command (CONNECT)
7463     0x00,  // Reserved.
7464     0x03,  // Address type (DOMAINNAME).
7465     0x0E,  // Length of domain (14)
7466     // Domain string:
7467     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7468     0x01, 0xBB,  // 16-bit port (443)
7469   };
7470
7471   const char kSOCKS5OkResponse[] =
7472       { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7473
7474   MockWrite data_writes[] = {
7475     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7476     MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7477               arraysize(kSOCKS5OkRequest)),
7478     MockWrite("GET / HTTP/1.1\r\n"
7479               "Host: www.google.com\r\n"
7480               "Connection: keep-alive\r\n\r\n")
7481   };
7482
7483   MockRead data_reads[] = {
7484     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7485     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
7486     MockRead("HTTP/1.0 200 OK\r\n"),
7487     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7488     MockRead("Payload"),
7489     MockRead(SYNCHRONOUS, OK)
7490   };
7491
7492   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7493                                 data_writes, arraysize(data_writes));
7494   session_deps_.socket_factory->AddSocketDataProvider(&data);
7495
7496   SSLSocketDataProvider ssl(ASYNC, OK);
7497   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7498
7499   TestCompletionCallback callback;
7500
7501   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7502   EXPECT_EQ(ERR_IO_PENDING, rv);
7503
7504   rv = callback.WaitForResult();
7505   EXPECT_EQ(OK, rv);
7506
7507   const HttpResponseInfo* response = trans->GetResponseInfo();
7508   ASSERT_TRUE(response != NULL);
7509
7510   LoadTimingInfo load_timing_info;
7511   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7512   TestLoadTimingNotReusedWithPac(load_timing_info,
7513                                  CONNECT_TIMING_HAS_SSL_TIMES);
7514
7515   std::string response_text;
7516   rv = ReadTransaction(trans.get(), &response_text);
7517   EXPECT_EQ(OK, rv);
7518   EXPECT_EQ("Payload", response_text);
7519 }
7520
7521 namespace {
7522
7523 // Tests that for connection endpoints the group names are correctly set.
7524
7525 struct GroupNameTest {
7526   std::string proxy_server;
7527   std::string url;
7528   std::string expected_group_name;
7529   bool ssl;
7530 };
7531
7532 scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
7533     NextProto next_proto,
7534     SpdySessionDependencies* session_deps_) {
7535   scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
7536
7537   base::WeakPtr<HttpServerProperties> http_server_properties =
7538       session->http_server_properties();
7539   http_server_properties->SetAlternateProtocol(
7540       HostPortPair("host.with.alternate", 80), 443,
7541       AlternateProtocolFromNextProto(next_proto), 1);
7542
7543   return session;
7544 }
7545
7546 int GroupNameTransactionHelper(
7547     const std::string& url,
7548     const scoped_refptr<HttpNetworkSession>& session) {
7549   HttpRequestInfo request;
7550   request.method = "GET";
7551   request.url = GURL(url);
7552   request.load_flags = 0;
7553
7554   scoped_ptr<HttpTransaction> trans(
7555       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7556
7557   TestCompletionCallback callback;
7558
7559   // We do not complete this request, the dtor will clean the transaction up.
7560   return trans->Start(&request, callback.callback(), BoundNetLog());
7561 }
7562
7563 }  // namespace
7564
7565 TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
7566   const GroupNameTest tests[] = {
7567     {
7568       "",  // unused
7569       "http://www.google.com/direct",
7570       "www.google.com:80",
7571       false,
7572     },
7573     {
7574       "",  // unused
7575       "http://[2001:1418:13:1::25]/direct",
7576       "[2001:1418:13:1::25]:80",
7577       false,
7578     },
7579
7580     // SSL Tests
7581     {
7582       "",  // unused
7583       "https://www.google.com/direct_ssl",
7584       "ssl/www.google.com:443",
7585       true,
7586     },
7587     {
7588       "",  // unused
7589       "https://[2001:1418:13:1::25]/direct",
7590       "ssl/[2001:1418:13:1::25]:443",
7591       true,
7592     },
7593     {
7594       "",  // unused
7595       "http://host.with.alternate/direct",
7596       "ssl/host.with.alternate:443",
7597       true,
7598     },
7599   };
7600
7601   session_deps_.use_alternate_protocols = true;
7602
7603   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7604     session_deps_.proxy_service.reset(
7605         ProxyService::CreateFixed(tests[i].proxy_server));
7606     scoped_refptr<HttpNetworkSession> session(
7607         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
7608
7609     HttpNetworkSessionPeer peer(session);
7610     CaptureGroupNameTransportSocketPool* transport_conn_pool =
7611         new CaptureGroupNameTransportSocketPool(NULL, NULL);
7612     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
7613         new CaptureGroupNameSSLSocketPool(NULL, NULL);
7614     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7615         new MockClientSocketPoolManager);
7616     mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7617     mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
7618     peer.SetClientSocketPoolManager(
7619         mock_pool_manager.PassAs<ClientSocketPoolManager>());
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_UNSAFE(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(
7686         mock_pool_manager.PassAs<ClientSocketPoolManager>());
7687
7688     EXPECT_EQ(ERR_IO_PENDING,
7689               GroupNameTransactionHelper(tests[i].url, session));
7690     if (tests[i].ssl)
7691       EXPECT_EQ(tests[i].expected_group_name,
7692                 ssl_conn_pool->last_group_name_received());
7693     else
7694       EXPECT_EQ(tests[i].expected_group_name,
7695                 http_proxy_pool->last_group_name_received());
7696   }
7697 }
7698
7699 TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
7700   const GroupNameTest tests[] = {
7701     {
7702       "socks4://socks_proxy:1080",
7703       "http://www.google.com/socks4_direct",
7704       "socks4/www.google.com:80",
7705       false,
7706     },
7707     {
7708       "socks5://socks_proxy:1080",
7709       "http://www.google.com/socks5_direct",
7710       "socks5/www.google.com:80",
7711       false,
7712     },
7713
7714     // SSL Tests
7715     {
7716       "socks4://socks_proxy:1080",
7717       "https://www.google.com/socks4_ssl",
7718       "socks4/ssl/www.google.com:443",
7719       true,
7720     },
7721     {
7722       "socks5://socks_proxy:1080",
7723       "https://www.google.com/socks5_ssl",
7724       "socks5/ssl/www.google.com:443",
7725       true,
7726     },
7727
7728     {
7729       "socks4://socks_proxy:1080",
7730       "http://host.with.alternate/direct",
7731       "socks4/ssl/host.with.alternate:443",
7732       true,
7733     },
7734   };
7735
7736   session_deps_.use_alternate_protocols = true;
7737
7738   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7739     session_deps_.proxy_service.reset(
7740         ProxyService::CreateFixed(tests[i].proxy_server));
7741     scoped_refptr<HttpNetworkSession> session(
7742         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
7743
7744     HttpNetworkSessionPeer peer(session);
7745
7746     HostPortPair proxy_host("socks_proxy", 1080);
7747     CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
7748         new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
7749     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
7750         new CaptureGroupNameSSLSocketPool(NULL, NULL);
7751
7752     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7753         new MockClientSocketPoolManager);
7754     mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7755     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7756     peer.SetClientSocketPoolManager(
7757         mock_pool_manager.PassAs<ClientSocketPoolManager>());
7758
7759     scoped_ptr<HttpTransaction> trans(
7760         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7761
7762     EXPECT_EQ(ERR_IO_PENDING,
7763               GroupNameTransactionHelper(tests[i].url, session));
7764     if (tests[i].ssl)
7765       EXPECT_EQ(tests[i].expected_group_name,
7766                 ssl_conn_pool->last_group_name_received());
7767     else
7768       EXPECT_EQ(tests[i].expected_group_name,
7769                 socks_conn_pool->last_group_name_received());
7770   }
7771 }
7772
7773 TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
7774   HttpRequestInfo request;
7775   request.method = "GET";
7776   request.url = GURL("http://www.google.com/");
7777
7778   session_deps_.proxy_service.reset(
7779       ProxyService::CreateFixed("myproxy:70;foobar:80"));
7780
7781   // This simulates failure resolving all hostnames; that means we will fail
7782   // connecting to both proxies (myproxy:70 and foobar:80).
7783   session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
7784
7785   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7786   scoped_ptr<HttpTransaction> trans(
7787       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7788
7789   TestCompletionCallback callback;
7790
7791   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7792   EXPECT_EQ(ERR_IO_PENDING, rv);
7793
7794   rv = callback.WaitForResult();
7795   EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
7796 }
7797
7798 // Base test to make sure that when the load flags for a request specify to
7799 // bypass the cache, the DNS cache is not used.
7800 void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
7801     int load_flags) {
7802   // Issue a request, asking to bypass the cache(s).
7803   HttpRequestInfo request;
7804   request.method = "GET";
7805   request.load_flags = load_flags;
7806   request.url = GURL("http://www.google.com/");
7807
7808   // Select a host resolver that does caching.
7809   session_deps_.host_resolver.reset(new MockCachingHostResolver);
7810
7811   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7812   scoped_ptr<HttpTransaction> trans(
7813       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7814
7815   // Warm up the host cache so it has an entry for "www.google.com".
7816   AddressList addrlist;
7817   TestCompletionCallback callback;
7818   int rv = session_deps_.host_resolver->Resolve(
7819       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7820       DEFAULT_PRIORITY,
7821       &addrlist,
7822       callback.callback(),
7823       NULL,
7824       BoundNetLog());
7825   EXPECT_EQ(ERR_IO_PENDING, rv);
7826   rv = callback.WaitForResult();
7827   EXPECT_EQ(OK, rv);
7828
7829   // Verify that it was added to host cache, by doing a subsequent async lookup
7830   // and confirming it completes synchronously.
7831   rv = session_deps_.host_resolver->Resolve(
7832       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7833       DEFAULT_PRIORITY,
7834       &addrlist,
7835       callback.callback(),
7836       NULL,
7837       BoundNetLog());
7838   ASSERT_EQ(OK, rv);
7839
7840   // Inject a failure the next time that "www.google.com" is resolved. This way
7841   // we can tell if the next lookup hit the cache, or the "network".
7842   // (cache --> success, "network" --> failure).
7843   session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
7844
7845   // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7846   // first read -- this won't be reached as the host resolution will fail first.
7847   MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
7848   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7849   session_deps_.socket_factory->AddSocketDataProvider(&data);
7850
7851   // Run the request.
7852   rv = trans->Start(&request, callback.callback(), BoundNetLog());
7853   ASSERT_EQ(ERR_IO_PENDING, rv);
7854   rv = callback.WaitForResult();
7855
7856   // If we bypassed the cache, we would have gotten a failure while resolving
7857   // "www.google.com".
7858   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7859 }
7860
7861 // There are multiple load flags that should trigger the host cache bypass.
7862 // Test each in isolation:
7863 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
7864   BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7865 }
7866
7867 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
7868   BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7869 }
7870
7871 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
7872   BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7873 }
7874
7875 // Make sure we can handle an error when writing the request.
7876 TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
7877   HttpRequestInfo request;
7878   request.method = "GET";
7879   request.url = GURL("http://www.foo.com/");
7880   request.load_flags = 0;
7881
7882   MockWrite write_failure[] = {
7883     MockWrite(ASYNC, ERR_CONNECTION_RESET),
7884   };
7885   StaticSocketDataProvider data(NULL, 0,
7886                                 write_failure, arraysize(write_failure));
7887   session_deps_.socket_factory->AddSocketDataProvider(&data);
7888   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7889
7890   TestCompletionCallback callback;
7891
7892   scoped_ptr<HttpTransaction> trans(
7893       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7894
7895   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7896   EXPECT_EQ(ERR_IO_PENDING, rv);
7897
7898   rv = callback.WaitForResult();
7899   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7900 }
7901
7902 // Check that a connection closed after the start of the headers finishes ok.
7903 TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
7904   HttpRequestInfo request;
7905   request.method = "GET";
7906   request.url = GURL("http://www.foo.com/");
7907   request.load_flags = 0;
7908
7909   MockRead data_reads[] = {
7910     MockRead("HTTP/1."),
7911     MockRead(SYNCHRONOUS, OK),
7912   };
7913
7914   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7915   session_deps_.socket_factory->AddSocketDataProvider(&data);
7916   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7917
7918   TestCompletionCallback callback;
7919
7920   scoped_ptr<HttpTransaction> trans(
7921       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7922
7923   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7924   EXPECT_EQ(ERR_IO_PENDING, rv);
7925
7926   rv = callback.WaitForResult();
7927   EXPECT_EQ(OK, rv);
7928
7929   const HttpResponseInfo* response = trans->GetResponseInfo();
7930   ASSERT_TRUE(response != NULL);
7931
7932   EXPECT_TRUE(response->headers.get() != NULL);
7933   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7934
7935   std::string response_data;
7936   rv = ReadTransaction(trans.get(), &response_data);
7937   EXPECT_EQ(OK, rv);
7938   EXPECT_EQ("", response_data);
7939 }
7940
7941 // Make sure that a dropped connection while draining the body for auth
7942 // restart does the right thing.
7943 TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
7944   HttpRequestInfo request;
7945   request.method = "GET";
7946   request.url = GURL("http://www.google.com/");
7947   request.load_flags = 0;
7948
7949   MockWrite data_writes1[] = {
7950     MockWrite("GET / HTTP/1.1\r\n"
7951               "Host: www.google.com\r\n"
7952               "Connection: keep-alive\r\n\r\n"),
7953   };
7954
7955   MockRead data_reads1[] = {
7956     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7957     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7958     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7959     MockRead("Content-Length: 14\r\n\r\n"),
7960     MockRead("Unauth"),
7961     MockRead(ASYNC, ERR_CONNECTION_RESET),
7962   };
7963
7964   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7965                                  data_writes1, arraysize(data_writes1));
7966   session_deps_.socket_factory->AddSocketDataProvider(&data1);
7967
7968   // After calling trans->RestartWithAuth(), this is the request we should
7969   // be issuing -- the final header line contains the credentials.
7970   MockWrite data_writes2[] = {
7971     MockWrite("GET / HTTP/1.1\r\n"
7972               "Host: www.google.com\r\n"
7973               "Connection: keep-alive\r\n"
7974               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7975   };
7976
7977   // Lastly, the server responds with the actual content.
7978   MockRead data_reads2[] = {
7979     MockRead("HTTP/1.1 200 OK\r\n"),
7980     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7981     MockRead("Content-Length: 100\r\n\r\n"),
7982     MockRead(SYNCHRONOUS, OK),
7983   };
7984
7985   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7986                                  data_writes2, arraysize(data_writes2));
7987   session_deps_.socket_factory->AddSocketDataProvider(&data2);
7988   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7989
7990   TestCompletionCallback callback1;
7991
7992   scoped_ptr<HttpTransaction> trans(
7993       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7994
7995   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
7996   EXPECT_EQ(ERR_IO_PENDING, rv);
7997
7998   rv = callback1.WaitForResult();
7999   EXPECT_EQ(OK, rv);
8000
8001   const HttpResponseInfo* response = trans->GetResponseInfo();
8002   ASSERT_TRUE(response != NULL);
8003   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8004
8005   TestCompletionCallback callback2;
8006
8007   rv = trans->RestartWithAuth(
8008       AuthCredentials(kFoo, kBar), callback2.callback());
8009   EXPECT_EQ(ERR_IO_PENDING, rv);
8010
8011   rv = callback2.WaitForResult();
8012   EXPECT_EQ(OK, rv);
8013
8014   response = trans->GetResponseInfo();
8015   ASSERT_TRUE(response != NULL);
8016   EXPECT_TRUE(response->auth_challenge.get() == NULL);
8017   EXPECT_EQ(100, response->headers->GetContentLength());
8018 }
8019
8020 // Test HTTPS connections going through a proxy that sends extra data.
8021 TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
8022   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
8023
8024   HttpRequestInfo request;
8025   request.method = "GET";
8026   request.url = GURL("https://www.google.com/");
8027   request.load_flags = 0;
8028
8029   MockRead proxy_reads[] = {
8030     MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
8031     MockRead(SYNCHRONOUS, OK)
8032   };
8033
8034   StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
8035   SSLSocketDataProvider ssl(ASYNC, OK);
8036
8037   session_deps_.socket_factory->AddSocketDataProvider(&data);
8038   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8039
8040   TestCompletionCallback callback;
8041
8042   session_deps_.socket_factory->ResetNextMockIndexes();
8043
8044   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8045   scoped_ptr<HttpTransaction> trans(
8046       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
8047
8048   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8049   EXPECT_EQ(ERR_IO_PENDING, rv);
8050
8051   rv = callback.WaitForResult();
8052   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8053 }
8054
8055 TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
8056   HttpRequestInfo request;
8057   request.method = "GET";
8058   request.url = GURL("http://www.google.com/");
8059   request.load_flags = 0;
8060
8061   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8062   scoped_ptr<HttpTransaction> trans(
8063       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
8064
8065   MockRead data_reads[] = {
8066     MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
8067     MockRead(SYNCHRONOUS, OK),
8068   };
8069
8070   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8071   session_deps_.socket_factory->AddSocketDataProvider(&data);
8072
8073   TestCompletionCallback callback;
8074
8075   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8076   EXPECT_EQ(ERR_IO_PENDING, rv);
8077
8078   EXPECT_EQ(OK, callback.WaitForResult());
8079
8080   const HttpResponseInfo* response = trans->GetResponseInfo();
8081   ASSERT_TRUE(response != NULL);
8082
8083   EXPECT_TRUE(response->headers.get() != NULL);
8084   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8085
8086   std::string response_data;
8087   rv = ReadTransaction(trans.get(), &response_data);
8088   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
8089 }
8090
8091 TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
8092   base::FilePath temp_file_path;
8093   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
8094   const uint64 kFakeSize = 100000;  // file is actually blank
8095   UploadFileElementReader::ScopedOverridingContentLengthForTests
8096       overriding_content_length(kFakeSize);
8097
8098   ScopedVector<UploadElementReader> element_readers;
8099   element_readers.push_back(
8100       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8101                                   temp_file_path,
8102                                   0,
8103                                   kuint64max,
8104                                   base::Time()));
8105   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
8106
8107   HttpRequestInfo request;
8108   request.method = "POST";
8109   request.url = GURL("http://www.google.com/upload");
8110   request.upload_data_stream = &upload_data_stream;
8111   request.load_flags = 0;
8112
8113   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8114   scoped_ptr<HttpTransaction> trans(
8115       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
8116
8117   MockRead data_reads[] = {
8118     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8119     MockRead("hello world"),
8120     MockRead(SYNCHRONOUS, OK),
8121   };
8122   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8123   session_deps_.socket_factory->AddSocketDataProvider(&data);
8124
8125   TestCompletionCallback callback;
8126
8127   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8128   EXPECT_EQ(ERR_IO_PENDING, rv);
8129
8130   rv = callback.WaitForResult();
8131   EXPECT_EQ(OK, rv);
8132
8133   const HttpResponseInfo* response = trans->GetResponseInfo();
8134   ASSERT_TRUE(response != NULL);
8135
8136   EXPECT_TRUE(response->headers.get() != NULL);
8137   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8138
8139   std::string response_data;
8140   rv = ReadTransaction(trans.get(), &response_data);
8141   EXPECT_EQ(OK, rv);
8142   EXPECT_EQ("hello world", response_data);
8143
8144   base::DeleteFile(temp_file_path, false);
8145 }
8146
8147 TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
8148   base::FilePath temp_file;
8149   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
8150   std::string temp_file_content("Unreadable file.");
8151   ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
8152                                    temp_file_content.length()));
8153   ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
8154
8155   ScopedVector<UploadElementReader> element_readers;
8156   element_readers.push_back(
8157       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8158                                   temp_file,
8159                                   0,
8160                                   kuint64max,
8161                                   base::Time()));
8162   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
8163
8164   HttpRequestInfo request;
8165   request.method = "POST";
8166   request.url = GURL("http://www.google.com/upload");
8167   request.upload_data_stream = &upload_data_stream;
8168   request.load_flags = 0;
8169
8170   // If we try to upload an unreadable file, the transaction should fail.
8171   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8172   scoped_ptr<HttpTransaction> trans(
8173       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
8174
8175   StaticSocketDataProvider data(NULL, 0, NULL, 0);
8176   session_deps_.socket_factory->AddSocketDataProvider(&data);
8177
8178   TestCompletionCallback callback;
8179
8180   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8181   EXPECT_EQ(ERR_IO_PENDING, rv);
8182
8183   rv = callback.WaitForResult();
8184   EXPECT_EQ(ERR_ACCESS_DENIED, rv);
8185
8186   const HttpResponseInfo* response = trans->GetResponseInfo();
8187   EXPECT_FALSE(response);
8188
8189   base::DeleteFile(temp_file, false);
8190 }
8191
8192 TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8193   class FakeUploadElementReader : public UploadElementReader {
8194    public:
8195     FakeUploadElementReader() {}
8196     virtual ~FakeUploadElementReader() {}
8197
8198     const CompletionCallback& callback() const { return callback_; }
8199
8200     // UploadElementReader overrides:
8201     virtual int Init(const CompletionCallback& callback) OVERRIDE {
8202       callback_ = callback;
8203       return ERR_IO_PENDING;
8204     }
8205     virtual uint64 GetContentLength() const OVERRIDE { return 0; }
8206     virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
8207     virtual int Read(IOBuffer* buf,
8208                      int buf_length,
8209                      const CompletionCallback& callback) OVERRIDE {
8210       return ERR_FAILED;
8211     }
8212
8213    private:
8214     CompletionCallback callback_;
8215   };
8216
8217   FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8218   ScopedVector<UploadElementReader> element_readers;
8219   element_readers.push_back(fake_reader);
8220   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
8221
8222   HttpRequestInfo request;
8223   request.method = "POST";
8224   request.url = GURL("http://www.google.com/upload");
8225   request.upload_data_stream = &upload_data_stream;
8226   request.load_flags = 0;
8227
8228   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8229   scoped_ptr<HttpTransaction> trans(
8230       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
8231
8232   StaticSocketDataProvider data;
8233   session_deps_.socket_factory->AddSocketDataProvider(&data);
8234
8235   TestCompletionCallback callback;
8236   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8237   EXPECT_EQ(ERR_IO_PENDING, rv);
8238   base::MessageLoop::current()->RunUntilIdle();
8239
8240   // Transaction is pending on request body initialization.
8241   ASSERT_FALSE(fake_reader->callback().is_null());
8242
8243   // Return Init()'s result after the transaction gets destroyed.
8244   trans.reset();
8245   fake_reader->callback().Run(OK);  // Should not crash.
8246 }
8247
8248 // Tests that changes to Auth realms are treated like auth rejections.
8249 TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
8250
8251   HttpRequestInfo request;
8252   request.method = "GET";
8253   request.url = GURL("http://www.google.com/");
8254   request.load_flags = 0;
8255
8256   // First transaction will request a resource and receive a Basic challenge
8257   // with realm="first_realm".
8258   MockWrite data_writes1[] = {
8259     MockWrite("GET / HTTP/1.1\r\n"
8260               "Host: www.google.com\r\n"
8261               "Connection: keep-alive\r\n"
8262               "\r\n"),
8263   };
8264   MockRead data_reads1[] = {
8265     MockRead("HTTP/1.1 401 Unauthorized\r\n"
8266              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8267              "\r\n"),
8268   };
8269
8270   // After calling trans->RestartWithAuth(), provide an Authentication header
8271   // for first_realm. The server will reject and provide a challenge with
8272   // second_realm.
8273   MockWrite data_writes2[] = {
8274     MockWrite("GET / HTTP/1.1\r\n"
8275               "Host: www.google.com\r\n"
8276               "Connection: keep-alive\r\n"
8277               "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8278               "\r\n"),
8279   };
8280   MockRead data_reads2[] = {
8281     MockRead("HTTP/1.1 401 Unauthorized\r\n"
8282              "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8283              "\r\n"),
8284   };
8285
8286   // This again fails, and goes back to first_realm. Make sure that the
8287   // entry is removed from cache.
8288   MockWrite data_writes3[] = {
8289     MockWrite("GET / HTTP/1.1\r\n"
8290               "Host: www.google.com\r\n"
8291               "Connection: keep-alive\r\n"
8292               "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8293               "\r\n"),
8294   };
8295   MockRead data_reads3[] = {
8296     MockRead("HTTP/1.1 401 Unauthorized\r\n"
8297              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8298              "\r\n"),
8299   };
8300
8301   // Try one last time (with the correct password) and get the resource.
8302   MockWrite data_writes4[] = {
8303     MockWrite("GET / HTTP/1.1\r\n"
8304               "Host: www.google.com\r\n"
8305               "Connection: keep-alive\r\n"
8306               "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8307               "\r\n"),
8308   };
8309   MockRead data_reads4[] = {
8310     MockRead("HTTP/1.1 200 OK\r\n"
8311              "Content-Type: text/html; charset=iso-8859-1\r\n"
8312              "Content-Length: 5\r\n"
8313              "\r\n"
8314              "hello"),
8315   };
8316
8317   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8318                                  data_writes1, arraysize(data_writes1));
8319   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8320                                  data_writes2, arraysize(data_writes2));
8321   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8322                                  data_writes3, arraysize(data_writes3));
8323   StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8324                                  data_writes4, arraysize(data_writes4));
8325   session_deps_.socket_factory->AddSocketDataProvider(&data1);
8326   session_deps_.socket_factory->AddSocketDataProvider(&data2);
8327   session_deps_.socket_factory->AddSocketDataProvider(&data3);
8328   session_deps_.socket_factory->AddSocketDataProvider(&data4);
8329
8330   TestCompletionCallback callback1;
8331
8332   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8333   scoped_ptr<HttpTransaction> trans(
8334       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
8335
8336   // Issue the first request with Authorize headers. There should be a
8337   // password prompt for first_realm waiting to be filled in after the
8338   // transaction completes.
8339   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
8340   EXPECT_EQ(ERR_IO_PENDING, rv);
8341   rv = callback1.WaitForResult();
8342   EXPECT_EQ(OK, rv);
8343   const HttpResponseInfo* response = trans->GetResponseInfo();
8344   ASSERT_TRUE(response != NULL);
8345   const AuthChallengeInfo* challenge = response->auth_challenge.get();
8346   ASSERT_FALSE(challenge == NULL);
8347   EXPECT_FALSE(challenge->is_proxy);
8348   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8349   EXPECT_EQ("first_realm", challenge->realm);
8350   EXPECT_EQ("basic", challenge->scheme);
8351
8352   // Issue the second request with an incorrect password. There should be a
8353   // password prompt for second_realm waiting to be filled in after the
8354   // transaction completes.
8355   TestCompletionCallback callback2;
8356   rv = trans->RestartWithAuth(
8357       AuthCredentials(kFirst, kBaz), callback2.callback());
8358   EXPECT_EQ(ERR_IO_PENDING, rv);
8359   rv = callback2.WaitForResult();
8360   EXPECT_EQ(OK, rv);
8361   response = trans->GetResponseInfo();
8362   ASSERT_TRUE(response != NULL);
8363   challenge = response->auth_challenge.get();
8364   ASSERT_FALSE(challenge == NULL);
8365   EXPECT_FALSE(challenge->is_proxy);
8366   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8367   EXPECT_EQ("second_realm", challenge->realm);
8368   EXPECT_EQ("basic", challenge->scheme);
8369
8370   // Issue the third request with another incorrect password. There should be
8371   // a password prompt for first_realm waiting to be filled in. If the password
8372   // prompt is not present, it indicates that the HttpAuthCacheEntry for
8373   // first_realm was not correctly removed.
8374   TestCompletionCallback callback3;
8375   rv = trans->RestartWithAuth(
8376       AuthCredentials(kSecond, kFou), callback3.callback());
8377   EXPECT_EQ(ERR_IO_PENDING, rv);
8378   rv = callback3.WaitForResult();
8379   EXPECT_EQ(OK, rv);
8380   response = trans->GetResponseInfo();
8381   ASSERT_TRUE(response != NULL);
8382   challenge = response->auth_challenge.get();
8383   ASSERT_FALSE(challenge == NULL);
8384   EXPECT_FALSE(challenge->is_proxy);
8385   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8386   EXPECT_EQ("first_realm", challenge->realm);
8387   EXPECT_EQ("basic", challenge->scheme);
8388
8389   // Issue the fourth request with the correct password and username.
8390   TestCompletionCallback callback4;
8391   rv = trans->RestartWithAuth(
8392       AuthCredentials(kFirst, kBar), callback4.callback());
8393   EXPECT_EQ(ERR_IO_PENDING, rv);
8394   rv = callback4.WaitForResult();
8395   EXPECT_EQ(OK, rv);
8396   response = trans->GetResponseInfo();
8397   ASSERT_TRUE(response != NULL);
8398   EXPECT_TRUE(response->auth_challenge.get() == NULL);
8399 }
8400
8401 TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
8402   session_deps_.next_protos = SpdyNextProtos();
8403   session_deps_.use_alternate_protocols = true;
8404
8405   std::string alternate_protocol_http_header =
8406       GetAlternateProtocolHttpHeader();
8407
8408   MockRead data_reads[] = {
8409     MockRead("HTTP/1.1 200 OK\r\n"),
8410     MockRead(alternate_protocol_http_header.c_str()),
8411     MockRead("hello world"),
8412     MockRead(SYNCHRONOUS, OK),
8413   };
8414
8415   HttpRequestInfo request;
8416   request.method = "GET";
8417   request.url = GURL("http://www.google.com/");
8418   request.load_flags = 0;
8419
8420   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8421
8422   session_deps_.socket_factory->AddSocketDataProvider(&data);
8423
8424   TestCompletionCallback callback;
8425
8426   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8427   scoped_ptr<HttpTransaction> trans(
8428       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8429
8430   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8431   EXPECT_EQ(ERR_IO_PENDING, rv);
8432
8433   HostPortPair http_host_port_pair("www.google.com", 80);
8434   HttpServerProperties& http_server_properties =
8435       *session->http_server_properties();
8436   EXPECT_FALSE(
8437       http_server_properties.HasAlternateProtocol(http_host_port_pair));
8438
8439   EXPECT_EQ(OK, callback.WaitForResult());
8440
8441   const HttpResponseInfo* response = trans->GetResponseInfo();
8442   ASSERT_TRUE(response != NULL);
8443   ASSERT_TRUE(response->headers.get() != NULL);
8444   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8445   EXPECT_FALSE(response->was_fetched_via_spdy);
8446   EXPECT_FALSE(response->was_npn_negotiated);
8447
8448   std::string response_data;
8449   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8450   EXPECT_EQ("hello world", response_data);
8451
8452   ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8453   const AlternateProtocolInfo alternate =
8454       http_server_properties.GetAlternateProtocol(http_host_port_pair);
8455   AlternateProtocolInfo expected_alternate(
8456       443, AlternateProtocolFromNextProto(GetParam()), 1);
8457   EXPECT_TRUE(expected_alternate.Equals(alternate));
8458 }
8459
8460 TEST_P(HttpNetworkTransactionTest,
8461        MarkBrokenAlternateProtocolAndFallback) {
8462   session_deps_.use_alternate_protocols = true;
8463
8464   HttpRequestInfo request;
8465   request.method = "GET";
8466   request.url = GURL("http://www.google.com/");
8467   request.load_flags = 0;
8468
8469   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8470   StaticSocketDataProvider first_data;
8471   first_data.set_connect_data(mock_connect);
8472   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8473
8474   MockRead data_reads[] = {
8475     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8476     MockRead("hello world"),
8477     MockRead(ASYNC, OK),
8478   };
8479   StaticSocketDataProvider second_data(
8480       data_reads, arraysize(data_reads), NULL, 0);
8481   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8482
8483   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8484
8485   base::WeakPtr<HttpServerProperties> http_server_properties =
8486       session->http_server_properties();
8487   // Port must be < 1024, or the header will be ignored (since initial port was
8488   // port 80 (another restricted port).
8489   http_server_properties->SetAlternateProtocol(
8490       HostPortPair::FromURL(request.url),
8491       666 /* port is ignored by MockConnect anyway */,
8492       AlternateProtocolFromNextProto(GetParam()), 1);
8493
8494   scoped_ptr<HttpTransaction> trans(
8495       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8496   TestCompletionCallback callback;
8497
8498   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8499   EXPECT_EQ(ERR_IO_PENDING, rv);
8500   EXPECT_EQ(OK, callback.WaitForResult());
8501
8502   const HttpResponseInfo* response = trans->GetResponseInfo();
8503   ASSERT_TRUE(response != NULL);
8504   ASSERT_TRUE(response->headers.get() != NULL);
8505   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8506
8507   std::string response_data;
8508   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8509   EXPECT_EQ("hello world", response_data);
8510
8511   ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
8512       HostPortPair::FromURL(request.url)));
8513   const AlternateProtocolInfo alternate =
8514       http_server_properties->GetAlternateProtocol(
8515           HostPortPair::FromURL(request.url));
8516   EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
8517 }
8518
8519 TEST_P(HttpNetworkTransactionTest,
8520        AlternateProtocolPortRestrictedBlocked) {
8521   // Ensure that we're not allowed to redirect traffic via an alternate
8522   // protocol to an unrestricted (port >= 1024) when the original traffic was
8523   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8524   // other cases.
8525   session_deps_.use_alternate_protocols = true;
8526
8527   HttpRequestInfo restricted_port_request;
8528   restricted_port_request.method = "GET";
8529   restricted_port_request.url = GURL("http://www.google.com:1023/");
8530   restricted_port_request.load_flags = 0;
8531
8532   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8533   StaticSocketDataProvider first_data;
8534   first_data.set_connect_data(mock_connect);
8535   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8536
8537   MockRead data_reads[] = {
8538     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8539     MockRead("hello world"),
8540     MockRead(ASYNC, OK),
8541   };
8542   StaticSocketDataProvider second_data(
8543       data_reads, arraysize(data_reads), NULL, 0);
8544   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8545
8546   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8547
8548   base::WeakPtr<HttpServerProperties> http_server_properties =
8549       session->http_server_properties();
8550   const int kUnrestrictedAlternatePort = 1024;
8551   http_server_properties->SetAlternateProtocol(
8552       HostPortPair::FromURL(restricted_port_request.url),
8553       kUnrestrictedAlternatePort,
8554       AlternateProtocolFromNextProto(GetParam()), 1);
8555
8556   scoped_ptr<HttpTransaction> trans(
8557       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8558   TestCompletionCallback callback;
8559
8560   int rv = trans->Start(
8561       &restricted_port_request,
8562       callback.callback(), BoundNetLog());
8563   EXPECT_EQ(ERR_IO_PENDING, rv);
8564   // Invalid change to unrestricted port should fail.
8565   EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
8566 }
8567
8568 TEST_P(HttpNetworkTransactionTest,
8569        AlternateProtocolPortRestrictedPermitted) {
8570   // Ensure that we're allowed to redirect traffic via an alternate
8571   // protocol to an unrestricted (port >= 1024) when the original traffic was
8572   // on a restricted port (port < 1024) if we set
8573   // enable_user_alternate_protocol_ports.
8574
8575   session_deps_.use_alternate_protocols = true;
8576   session_deps_.enable_user_alternate_protocol_ports = true;
8577
8578   HttpRequestInfo restricted_port_request;
8579   restricted_port_request.method = "GET";
8580   restricted_port_request.url = GURL("http://www.google.com:1023/");
8581   restricted_port_request.load_flags = 0;
8582
8583   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8584   StaticSocketDataProvider first_data;
8585   first_data.set_connect_data(mock_connect);
8586   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8587
8588   MockRead data_reads[] = {
8589     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8590     MockRead("hello world"),
8591     MockRead(ASYNC, OK),
8592   };
8593   StaticSocketDataProvider second_data(
8594       data_reads, arraysize(data_reads), NULL, 0);
8595   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8596
8597   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8598
8599   base::WeakPtr<HttpServerProperties> http_server_properties =
8600       session->http_server_properties();
8601   const int kUnrestrictedAlternatePort = 1024;
8602   http_server_properties->SetAlternateProtocol(
8603       HostPortPair::FromURL(restricted_port_request.url),
8604       kUnrestrictedAlternatePort,
8605       AlternateProtocolFromNextProto(GetParam()), 1);
8606
8607   scoped_ptr<HttpTransaction> trans(
8608       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8609   TestCompletionCallback callback;
8610
8611   EXPECT_EQ(ERR_IO_PENDING, trans->Start(
8612       &restricted_port_request,
8613       callback.callback(), BoundNetLog()));
8614   // Change to unrestricted port should succeed.
8615   EXPECT_EQ(OK, callback.WaitForResult());
8616 }
8617
8618 TEST_P(HttpNetworkTransactionTest,
8619        AlternateProtocolPortRestrictedAllowed) {
8620   // Ensure that we're not allowed to redirect traffic via an alternate
8621   // protocol to an unrestricted (port >= 1024) when the original traffic was
8622   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8623   // other cases.
8624   session_deps_.use_alternate_protocols = true;
8625
8626   HttpRequestInfo restricted_port_request;
8627   restricted_port_request.method = "GET";
8628   restricted_port_request.url = GURL("http://www.google.com:1023/");
8629   restricted_port_request.load_flags = 0;
8630
8631   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8632   StaticSocketDataProvider first_data;
8633   first_data.set_connect_data(mock_connect);
8634   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8635
8636   MockRead data_reads[] = {
8637     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8638     MockRead("hello world"),
8639     MockRead(ASYNC, OK),
8640   };
8641   StaticSocketDataProvider second_data(
8642       data_reads, arraysize(data_reads), NULL, 0);
8643   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8644
8645   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8646
8647   base::WeakPtr<HttpServerProperties> http_server_properties =
8648       session->http_server_properties();
8649   const int kRestrictedAlternatePort = 80;
8650   http_server_properties->SetAlternateProtocol(
8651       HostPortPair::FromURL(restricted_port_request.url),
8652       kRestrictedAlternatePort,
8653       AlternateProtocolFromNextProto(GetParam()), 1);
8654
8655   scoped_ptr<HttpTransaction> trans(
8656       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8657   TestCompletionCallback callback;
8658
8659   int rv = trans->Start(
8660       &restricted_port_request,
8661       callback.callback(), BoundNetLog());
8662   EXPECT_EQ(ERR_IO_PENDING, rv);
8663   // Valid change to restricted port should pass.
8664   EXPECT_EQ(OK, callback.WaitForResult());
8665 }
8666
8667 TEST_P(HttpNetworkTransactionTest,
8668        AlternateProtocolPortUnrestrictedAllowed1) {
8669   // Ensure that we're not allowed to redirect traffic via an alternate
8670   // protocol to an unrestricted (port >= 1024) when the original traffic was
8671   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8672   // other cases.
8673   session_deps_.use_alternate_protocols = true;
8674
8675   HttpRequestInfo unrestricted_port_request;
8676   unrestricted_port_request.method = "GET";
8677   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8678   unrestricted_port_request.load_flags = 0;
8679
8680   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8681   StaticSocketDataProvider first_data;
8682   first_data.set_connect_data(mock_connect);
8683   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8684
8685   MockRead data_reads[] = {
8686     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8687     MockRead("hello world"),
8688     MockRead(ASYNC, OK),
8689   };
8690   StaticSocketDataProvider second_data(
8691       data_reads, arraysize(data_reads), NULL, 0);
8692   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8693
8694   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8695
8696   base::WeakPtr<HttpServerProperties> http_server_properties =
8697       session->http_server_properties();
8698   const int kRestrictedAlternatePort = 80;
8699   http_server_properties->SetAlternateProtocol(
8700       HostPortPair::FromURL(unrestricted_port_request.url),
8701       kRestrictedAlternatePort,
8702       AlternateProtocolFromNextProto(GetParam()), 1);
8703
8704   scoped_ptr<HttpTransaction> trans(
8705       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8706   TestCompletionCallback callback;
8707
8708   int rv = trans->Start(
8709       &unrestricted_port_request, callback.callback(), BoundNetLog());
8710   EXPECT_EQ(ERR_IO_PENDING, rv);
8711   // Valid change to restricted port should pass.
8712   EXPECT_EQ(OK, callback.WaitForResult());
8713 }
8714
8715 TEST_P(HttpNetworkTransactionTest,
8716        AlternateProtocolPortUnrestrictedAllowed2) {
8717   // Ensure that we're not allowed to redirect traffic via an alternate
8718   // protocol to an unrestricted (port >= 1024) when the original traffic was
8719   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8720   // other cases.
8721   session_deps_.use_alternate_protocols = true;
8722
8723   HttpRequestInfo unrestricted_port_request;
8724   unrestricted_port_request.method = "GET";
8725   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8726   unrestricted_port_request.load_flags = 0;
8727
8728   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8729   StaticSocketDataProvider first_data;
8730   first_data.set_connect_data(mock_connect);
8731   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8732
8733   MockRead data_reads[] = {
8734     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8735     MockRead("hello world"),
8736     MockRead(ASYNC, OK),
8737   };
8738   StaticSocketDataProvider second_data(
8739       data_reads, arraysize(data_reads), NULL, 0);
8740   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8741
8742   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8743
8744   base::WeakPtr<HttpServerProperties> http_server_properties =
8745       session->http_server_properties();
8746   const int kUnrestrictedAlternatePort = 1024;
8747   http_server_properties->SetAlternateProtocol(
8748       HostPortPair::FromURL(unrestricted_port_request.url),
8749       kUnrestrictedAlternatePort,
8750       AlternateProtocolFromNextProto(GetParam()), 1);
8751
8752   scoped_ptr<HttpTransaction> trans(
8753       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8754   TestCompletionCallback callback;
8755
8756   int rv = trans->Start(
8757       &unrestricted_port_request, callback.callback(), BoundNetLog());
8758   EXPECT_EQ(ERR_IO_PENDING, rv);
8759   // Valid change to an unrestricted port should pass.
8760   EXPECT_EQ(OK, callback.WaitForResult());
8761 }
8762
8763 TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
8764   // Ensure that we're not allowed to redirect traffic via an alternate
8765   // protocol to an unsafe port, and that we resume the second
8766   // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8767   session_deps_.use_alternate_protocols = true;
8768
8769   HttpRequestInfo request;
8770   request.method = "GET";
8771   request.url = GURL("http://www.google.com/");
8772   request.load_flags = 0;
8773
8774   // The alternate protocol request will error out before we attempt to connect,
8775   // so only the standard HTTP request will try to connect.
8776   MockRead data_reads[] = {
8777     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8778     MockRead("hello world"),
8779     MockRead(ASYNC, OK),
8780   };
8781   StaticSocketDataProvider data(
8782       data_reads, arraysize(data_reads), NULL, 0);
8783   session_deps_.socket_factory->AddSocketDataProvider(&data);
8784
8785   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8786
8787   base::WeakPtr<HttpServerProperties> http_server_properties =
8788       session->http_server_properties();
8789   const int kUnsafePort = 7;
8790   http_server_properties->SetAlternateProtocol(
8791       HostPortPair::FromURL(request.url),
8792       kUnsafePort,
8793       AlternateProtocolFromNextProto(GetParam()), 1);
8794
8795   scoped_ptr<HttpTransaction> trans(
8796       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8797   TestCompletionCallback callback;
8798
8799   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8800   EXPECT_EQ(ERR_IO_PENDING, rv);
8801   // The HTTP request should succeed.
8802   EXPECT_EQ(OK, callback.WaitForResult());
8803
8804   // Disable alternate protocol before the asserts.
8805  // HttpStreamFactory::set_use_alternate_protocols(false);
8806
8807   const HttpResponseInfo* response = trans->GetResponseInfo();
8808   ASSERT_TRUE(response != NULL);
8809   ASSERT_TRUE(response->headers.get() != NULL);
8810   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8811
8812   std::string response_data;
8813   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8814   EXPECT_EQ("hello world", response_data);
8815 }
8816
8817 TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
8818   session_deps_.use_alternate_protocols = true;
8819   session_deps_.next_protos = SpdyNextProtos();
8820
8821   HttpRequestInfo request;
8822   request.method = "GET";
8823   request.url = GURL("http://www.google.com/");
8824   request.load_flags = 0;
8825
8826   std::string alternate_protocol_http_header =
8827       GetAlternateProtocolHttpHeader();
8828
8829   MockRead data_reads[] = {
8830     MockRead("HTTP/1.1 200 OK\r\n"),
8831     MockRead(alternate_protocol_http_header.c_str()),
8832     MockRead("hello world"),
8833     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8834     MockRead(ASYNC, OK)
8835   };
8836
8837   StaticSocketDataProvider first_transaction(
8838       data_reads, arraysize(data_reads), NULL, 0);
8839   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
8840
8841   SSLSocketDataProvider ssl(ASYNC, OK);
8842   ssl.SetNextProto(GetParam());
8843   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8844
8845   scoped_ptr<SpdyFrame> req(
8846       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8847   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
8848
8849   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8850   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
8851   MockRead spdy_reads[] = {
8852     CreateMockRead(*resp),
8853     CreateMockRead(*data),
8854     MockRead(ASYNC, 0, 0),
8855   };
8856
8857   DelayedSocketData spdy_data(
8858       1,  // wait for one write to finish before reading.
8859       spdy_reads, arraysize(spdy_reads),
8860       spdy_writes, arraysize(spdy_writes));
8861   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8862
8863   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
8864   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8865       NULL, 0, NULL, 0);
8866   hanging_non_alternate_protocol_socket.set_connect_data(
8867       never_finishing_connect);
8868   session_deps_.socket_factory->AddSocketDataProvider(
8869       &hanging_non_alternate_protocol_socket);
8870
8871   TestCompletionCallback callback;
8872
8873   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8874   scoped_ptr<HttpTransaction> trans(
8875       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8876
8877   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8878   EXPECT_EQ(ERR_IO_PENDING, rv);
8879   EXPECT_EQ(OK, callback.WaitForResult());
8880
8881   const HttpResponseInfo* response = trans->GetResponseInfo();
8882   ASSERT_TRUE(response != NULL);
8883   ASSERT_TRUE(response->headers.get() != NULL);
8884   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8885
8886   std::string response_data;
8887   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8888   EXPECT_EQ("hello world", response_data);
8889
8890   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8891
8892   rv = trans->Start(&request, callback.callback(), BoundNetLog());
8893   EXPECT_EQ(ERR_IO_PENDING, rv);
8894   EXPECT_EQ(OK, callback.WaitForResult());
8895
8896   response = trans->GetResponseInfo();
8897   ASSERT_TRUE(response != NULL);
8898   ASSERT_TRUE(response->headers.get() != NULL);
8899   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8900   EXPECT_TRUE(response->was_fetched_via_spdy);
8901   EXPECT_TRUE(response->was_npn_negotiated);
8902
8903   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8904   EXPECT_EQ("hello!", response_data);
8905 }
8906
8907 TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
8908   session_deps_.use_alternate_protocols = true;
8909   session_deps_.next_protos = SpdyNextProtos();
8910
8911   HttpRequestInfo request;
8912   request.method = "GET";
8913   request.url = GURL("http://www.google.com/");
8914   request.load_flags = 0;
8915
8916   std::string alternate_protocol_http_header =
8917       GetAlternateProtocolHttpHeader();
8918
8919   MockRead data_reads[] = {
8920     MockRead("HTTP/1.1 200 OK\r\n"),
8921     MockRead(alternate_protocol_http_header.c_str()),
8922     MockRead("hello world"),
8923     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8924     MockRead(ASYNC, OK),
8925   };
8926
8927   StaticSocketDataProvider first_transaction(
8928       data_reads, arraysize(data_reads), NULL, 0);
8929   // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
8930   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
8931
8932   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
8933   StaticSocketDataProvider hanging_socket(
8934       NULL, 0, NULL, 0);
8935   hanging_socket.set_connect_data(never_finishing_connect);
8936   // Socket 2 and 3 are the hanging Alternate-Protocol and
8937   // non-Alternate-Protocol jobs from the 2nd transaction.
8938   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8939   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8940
8941   SSLSocketDataProvider ssl(ASYNC, OK);
8942   ssl.SetNextProto(GetParam());
8943   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8944
8945   scoped_ptr<SpdyFrame> req1(
8946       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8947   scoped_ptr<SpdyFrame> req2(
8948       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
8949   MockWrite spdy_writes[] = {
8950     CreateMockWrite(*req1),
8951     CreateMockWrite(*req2),
8952   };
8953   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8954   scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8955   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8956   scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
8957   MockRead spdy_reads[] = {
8958     CreateMockRead(*resp1),
8959     CreateMockRead(*data1),
8960     CreateMockRead(*resp2),
8961     CreateMockRead(*data2),
8962     MockRead(ASYNC, 0, 0),
8963   };
8964
8965   DelayedSocketData spdy_data(
8966       2,  // wait for writes to finish before reading.
8967       spdy_reads, arraysize(spdy_reads),
8968       spdy_writes, arraysize(spdy_writes));
8969   // Socket 4 is the successful Alternate-Protocol for transaction 3.
8970   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8971
8972   // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
8973   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8974
8975   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8976   TestCompletionCallback callback1;
8977   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
8978
8979   int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
8980   EXPECT_EQ(ERR_IO_PENDING, rv);
8981   EXPECT_EQ(OK, callback1.WaitForResult());
8982
8983   const HttpResponseInfo* response = trans1.GetResponseInfo();
8984   ASSERT_TRUE(response != NULL);
8985   ASSERT_TRUE(response->headers.get() != NULL);
8986   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8987
8988   std::string response_data;
8989   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8990   EXPECT_EQ("hello world", response_data);
8991
8992   TestCompletionCallback callback2;
8993   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
8994   rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
8995   EXPECT_EQ(ERR_IO_PENDING, rv);
8996
8997   TestCompletionCallback callback3;
8998   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
8999   rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
9000   EXPECT_EQ(ERR_IO_PENDING, rv);
9001
9002   EXPECT_EQ(OK, callback2.WaitForResult());
9003   EXPECT_EQ(OK, callback3.WaitForResult());
9004
9005   response = trans2.GetResponseInfo();
9006   ASSERT_TRUE(response != NULL);
9007   ASSERT_TRUE(response->headers.get() != NULL);
9008   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9009   EXPECT_TRUE(response->was_fetched_via_spdy);
9010   EXPECT_TRUE(response->was_npn_negotiated);
9011   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9012   EXPECT_EQ("hello!", response_data);
9013
9014   response = trans3.GetResponseInfo();
9015   ASSERT_TRUE(response != NULL);
9016   ASSERT_TRUE(response->headers.get() != NULL);
9017   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9018   EXPECT_TRUE(response->was_fetched_via_spdy);
9019   EXPECT_TRUE(response->was_npn_negotiated);
9020   ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9021   EXPECT_EQ("hello!", response_data);
9022 }
9023
9024 TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
9025   session_deps_.use_alternate_protocols = true;
9026   session_deps_.next_protos = SpdyNextProtos();
9027
9028   HttpRequestInfo request;
9029   request.method = "GET";
9030   request.url = GURL("http://www.google.com/");
9031   request.load_flags = 0;
9032
9033   std::string alternate_protocol_http_header =
9034       GetAlternateProtocolHttpHeader();
9035
9036   MockRead data_reads[] = {
9037     MockRead("HTTP/1.1 200 OK\r\n"),
9038     MockRead(alternate_protocol_http_header.c_str()),
9039     MockRead("hello world"),
9040     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9041     MockRead(ASYNC, OK),
9042   };
9043
9044   StaticSocketDataProvider first_transaction(
9045       data_reads, arraysize(data_reads), NULL, 0);
9046   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
9047
9048   SSLSocketDataProvider ssl(ASYNC, OK);
9049   ssl.SetNextProto(GetParam());
9050   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9051
9052   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
9053   StaticSocketDataProvider hanging_alternate_protocol_socket(
9054       NULL, 0, NULL, 0);
9055   hanging_alternate_protocol_socket.set_connect_data(
9056       never_finishing_connect);
9057   session_deps_.socket_factory->AddSocketDataProvider(
9058       &hanging_alternate_protocol_socket);
9059
9060   // 2nd request is just a copy of the first one, over HTTP again.
9061   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
9062
9063   TestCompletionCallback callback;
9064
9065   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9066   scoped_ptr<HttpTransaction> trans(
9067       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9068
9069   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9070   EXPECT_EQ(ERR_IO_PENDING, rv);
9071   EXPECT_EQ(OK, callback.WaitForResult());
9072
9073   const HttpResponseInfo* response = trans->GetResponseInfo();
9074   ASSERT_TRUE(response != NULL);
9075   ASSERT_TRUE(response->headers.get() != NULL);
9076   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9077
9078   std::string response_data;
9079   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9080   EXPECT_EQ("hello world", response_data);
9081
9082   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9083
9084   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9085   EXPECT_EQ(ERR_IO_PENDING, rv);
9086   EXPECT_EQ(OK, callback.WaitForResult());
9087
9088   response = trans->GetResponseInfo();
9089   ASSERT_TRUE(response != NULL);
9090   ASSERT_TRUE(response->headers.get() != NULL);
9091   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9092   EXPECT_FALSE(response->was_fetched_via_spdy);
9093   EXPECT_FALSE(response->was_npn_negotiated);
9094
9095   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9096   EXPECT_EQ("hello world", response_data);
9097 }
9098
9099 class CapturingProxyResolver : public ProxyResolver {
9100  public:
9101   CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
9102   virtual ~CapturingProxyResolver() {}
9103
9104   virtual int GetProxyForURL(const GURL& url,
9105                              ProxyInfo* results,
9106                              const CompletionCallback& callback,
9107                              RequestHandle* request,
9108                              const BoundNetLog& net_log) OVERRIDE {
9109     ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9110                              HostPortPair("myproxy", 80));
9111     results->UseProxyServer(proxy_server);
9112     resolved_.push_back(url);
9113     return OK;
9114   }
9115
9116   virtual void CancelRequest(RequestHandle request) OVERRIDE {
9117     NOTREACHED();
9118   }
9119
9120   virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
9121     NOTREACHED();
9122     return LOAD_STATE_IDLE;
9123   }
9124
9125   virtual void CancelSetPacScript() OVERRIDE {
9126     NOTREACHED();
9127   }
9128
9129   virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
9130                            const CompletionCallback& /*callback*/) OVERRIDE {
9131     return OK;
9132   }
9133
9134   const std::vector<GURL>& resolved() const { return resolved_; }
9135
9136  private:
9137   std::vector<GURL> resolved_;
9138
9139   DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9140 };
9141
9142 TEST_P(HttpNetworkTransactionTest,
9143        UseAlternateProtocolForTunneledNpnSpdy) {
9144   session_deps_.use_alternate_protocols = true;
9145   session_deps_.next_protos = SpdyNextProtos();
9146
9147   ProxyConfig proxy_config;
9148   proxy_config.set_auto_detect(true);
9149   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
9150
9151   CapturingProxyResolver* capturing_proxy_resolver =
9152       new CapturingProxyResolver();
9153   session_deps_.proxy_service.reset(new ProxyService(
9154       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
9155       NULL));
9156   CapturingNetLog net_log;
9157   session_deps_.net_log = &net_log;
9158
9159   HttpRequestInfo request;
9160   request.method = "GET";
9161   request.url = GURL("http://www.google.com/");
9162   request.load_flags = 0;
9163
9164   std::string alternate_protocol_http_header =
9165       GetAlternateProtocolHttpHeader();
9166
9167   MockRead data_reads[] = {
9168     MockRead("HTTP/1.1 200 OK\r\n"),
9169     MockRead(alternate_protocol_http_header.c_str()),
9170     MockRead("hello world"),
9171     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9172     MockRead(ASYNC, OK),
9173   };
9174
9175   StaticSocketDataProvider first_transaction(
9176       data_reads, arraysize(data_reads), NULL, 0);
9177   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
9178
9179   SSLSocketDataProvider ssl(ASYNC, OK);
9180   ssl.SetNextProto(GetParam());
9181   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9182
9183   scoped_ptr<SpdyFrame> req(
9184       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9185   MockWrite spdy_writes[] = {
9186     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9187               "Host: www.google.com\r\n"
9188               "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
9189     CreateMockWrite(*req),                              // 3
9190   };
9191
9192   const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9193
9194   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9195   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
9196   MockRead spdy_reads[] = {
9197     MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
9198     CreateMockRead(*resp.get(), 4),  // 2, 4
9199     CreateMockRead(*data.get(), 4),  // 5
9200     MockRead(ASYNC, 0, 0, 4),  // 6
9201   };
9202
9203   OrderedSocketData spdy_data(
9204       spdy_reads, arraysize(spdy_reads),
9205       spdy_writes, arraysize(spdy_writes));
9206   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9207
9208   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
9209   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9210       NULL, 0, NULL, 0);
9211   hanging_non_alternate_protocol_socket.set_connect_data(
9212       never_finishing_connect);
9213   session_deps_.socket_factory->AddSocketDataProvider(
9214       &hanging_non_alternate_protocol_socket);
9215
9216   TestCompletionCallback callback;
9217
9218   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9219   scoped_ptr<HttpTransaction> trans(
9220       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9221
9222   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9223   EXPECT_EQ(ERR_IO_PENDING, rv);
9224   EXPECT_EQ(OK, callback.WaitForResult());
9225
9226   const HttpResponseInfo* response = trans->GetResponseInfo();
9227   ASSERT_TRUE(response != NULL);
9228   ASSERT_TRUE(response->headers.get() != NULL);
9229   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9230   EXPECT_FALSE(response->was_fetched_via_spdy);
9231   EXPECT_FALSE(response->was_npn_negotiated);
9232
9233   std::string response_data;
9234   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9235   EXPECT_EQ("hello world", response_data);
9236
9237   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9238
9239   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9240   EXPECT_EQ(ERR_IO_PENDING, rv);
9241   EXPECT_EQ(OK, callback.WaitForResult());
9242
9243   response = trans->GetResponseInfo();
9244   ASSERT_TRUE(response != NULL);
9245   ASSERT_TRUE(response->headers.get() != NULL);
9246   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9247   EXPECT_TRUE(response->was_fetched_via_spdy);
9248   EXPECT_TRUE(response->was_npn_negotiated);
9249
9250   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9251   EXPECT_EQ("hello!", response_data);
9252   ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
9253   EXPECT_EQ("http://www.google.com/",
9254             capturing_proxy_resolver->resolved()[0].spec());
9255   EXPECT_EQ("https://www.google.com/",
9256             capturing_proxy_resolver->resolved()[1].spec());
9257
9258   LoadTimingInfo load_timing_info;
9259   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9260   TestLoadTimingNotReusedWithPac(load_timing_info,
9261                                  CONNECT_TIMING_HAS_SSL_TIMES);
9262 }
9263
9264 TEST_P(HttpNetworkTransactionTest,
9265        UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
9266   session_deps_.use_alternate_protocols = true;
9267   session_deps_.next_protos = SpdyNextProtos();
9268
9269   HttpRequestInfo request;
9270   request.method = "GET";
9271   request.url = GURL("http://www.google.com/");
9272   request.load_flags = 0;
9273
9274   std::string alternate_protocol_http_header =
9275       GetAlternateProtocolHttpHeader();
9276
9277   MockRead data_reads[] = {
9278     MockRead("HTTP/1.1 200 OK\r\n"),
9279     MockRead(alternate_protocol_http_header.c_str()),
9280     MockRead("hello world"),
9281     MockRead(ASYNC, OK),
9282   };
9283
9284   StaticSocketDataProvider first_transaction(
9285       data_reads, arraysize(data_reads), NULL, 0);
9286   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
9287
9288   SSLSocketDataProvider ssl(ASYNC, OK);
9289   ssl.SetNextProto(GetParam());
9290   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9291
9292   scoped_ptr<SpdyFrame> req(
9293       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9294   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
9295
9296   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9297   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
9298   MockRead spdy_reads[] = {
9299     CreateMockRead(*resp),
9300     CreateMockRead(*data),
9301     MockRead(ASYNC, 0, 0),
9302   };
9303
9304   DelayedSocketData spdy_data(
9305       1,  // wait for one write to finish before reading.
9306       spdy_reads, arraysize(spdy_reads),
9307       spdy_writes, arraysize(spdy_writes));
9308   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9309
9310   TestCompletionCallback callback;
9311
9312   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9313
9314   scoped_ptr<HttpTransaction> trans(
9315       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9316
9317   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9318   EXPECT_EQ(ERR_IO_PENDING, rv);
9319   EXPECT_EQ(OK, callback.WaitForResult());
9320
9321   const HttpResponseInfo* response = trans->GetResponseInfo();
9322   ASSERT_TRUE(response != NULL);
9323   ASSERT_TRUE(response->headers.get() != NULL);
9324   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9325
9326   std::string response_data;
9327   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9328   EXPECT_EQ("hello world", response_data);
9329
9330   // Set up an initial SpdySession in the pool to reuse.
9331   HostPortPair host_port_pair("www.google.com", 443);
9332   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
9333                      PRIVACY_MODE_DISABLED);
9334   base::WeakPtr<SpdySession> spdy_session =
9335       CreateSecureSpdySession(session, key, BoundNetLog());
9336
9337   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9338
9339   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9340   EXPECT_EQ(ERR_IO_PENDING, rv);
9341   EXPECT_EQ(OK, callback.WaitForResult());
9342
9343   response = trans->GetResponseInfo();
9344   ASSERT_TRUE(response != NULL);
9345   ASSERT_TRUE(response->headers.get() != NULL);
9346   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9347   EXPECT_TRUE(response->was_fetched_via_spdy);
9348   EXPECT_TRUE(response->was_npn_negotiated);
9349
9350   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9351   EXPECT_EQ("hello!", response_data);
9352 }
9353
9354 // GenerateAuthToken is a mighty big test.
9355 // It tests all permutation of GenerateAuthToken behavior:
9356 //   - Synchronous and Asynchronous completion.
9357 //   - OK or error on completion.
9358 //   - Direct connection, non-authenticating proxy, and authenticating proxy.
9359 //   - HTTP or HTTPS backend (to include proxy tunneling).
9360 //   - Non-authenticating and authenticating backend.
9361 //
9362 // In all, there are 44 reasonable permuations (for example, if there are
9363 // problems generating an auth token for an authenticating proxy, we don't
9364 // need to test all permutations of the backend server).
9365 //
9366 // The test proceeds by going over each of the configuration cases, and
9367 // potentially running up to three rounds in each of the tests. The TestConfig
9368 // specifies both the configuration for the test as well as the expectations
9369 // for the results.
9370 TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
9371   static const char kServer[] = "http://www.example.com";
9372   static const char kSecureServer[] = "https://www.example.com";
9373   static const char kProxy[] = "myproxy:70";
9374   const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9375
9376   enum AuthTiming {
9377     AUTH_NONE,
9378     AUTH_SYNC,
9379     AUTH_ASYNC,
9380   };
9381
9382   const MockWrite kGet(
9383       "GET / HTTP/1.1\r\n"
9384       "Host: www.example.com\r\n"
9385       "Connection: keep-alive\r\n\r\n");
9386   const MockWrite kGetProxy(
9387       "GET http://www.example.com/ HTTP/1.1\r\n"
9388       "Host: www.example.com\r\n"
9389       "Proxy-Connection: keep-alive\r\n\r\n");
9390   const MockWrite kGetAuth(
9391       "GET / HTTP/1.1\r\n"
9392       "Host: www.example.com\r\n"
9393       "Connection: keep-alive\r\n"
9394       "Authorization: auth_token\r\n\r\n");
9395   const MockWrite kGetProxyAuth(
9396       "GET http://www.example.com/ HTTP/1.1\r\n"
9397       "Host: www.example.com\r\n"
9398       "Proxy-Connection: keep-alive\r\n"
9399       "Proxy-Authorization: auth_token\r\n\r\n");
9400   const MockWrite kGetAuthThroughProxy(
9401       "GET http://www.example.com/ HTTP/1.1\r\n"
9402       "Host: www.example.com\r\n"
9403       "Proxy-Connection: keep-alive\r\n"
9404       "Authorization: auth_token\r\n\r\n");
9405   const MockWrite kGetAuthWithProxyAuth(
9406       "GET http://www.example.com/ HTTP/1.1\r\n"
9407       "Host: www.example.com\r\n"
9408       "Proxy-Connection: keep-alive\r\n"
9409       "Proxy-Authorization: auth_token\r\n"
9410       "Authorization: auth_token\r\n\r\n");
9411   const MockWrite kConnect(
9412       "CONNECT www.example.com:443 HTTP/1.1\r\n"
9413       "Host: www.example.com\r\n"
9414       "Proxy-Connection: keep-alive\r\n\r\n");
9415   const MockWrite kConnectProxyAuth(
9416       "CONNECT www.example.com:443 HTTP/1.1\r\n"
9417       "Host: www.example.com\r\n"
9418       "Proxy-Connection: keep-alive\r\n"
9419       "Proxy-Authorization: auth_token\r\n\r\n");
9420
9421   const MockRead kSuccess(
9422       "HTTP/1.1 200 OK\r\n"
9423       "Content-Type: text/html; charset=iso-8859-1\r\n"
9424       "Content-Length: 3\r\n\r\n"
9425       "Yes");
9426   const MockRead kFailure(
9427       "Should not be called.");
9428   const MockRead kServerChallenge(
9429       "HTTP/1.1 401 Unauthorized\r\n"
9430       "WWW-Authenticate: Mock realm=server\r\n"
9431       "Content-Type: text/html; charset=iso-8859-1\r\n"
9432       "Content-Length: 14\r\n\r\n"
9433       "Unauthorized\r\n");
9434   const MockRead kProxyChallenge(
9435       "HTTP/1.1 407 Unauthorized\r\n"
9436       "Proxy-Authenticate: Mock realm=proxy\r\n"
9437       "Proxy-Connection: close\r\n"
9438       "Content-Type: text/html; charset=iso-8859-1\r\n"
9439       "Content-Length: 14\r\n\r\n"
9440       "Unauthorized\r\n");
9441   const MockRead kProxyConnected(
9442       "HTTP/1.1 200 Connection Established\r\n\r\n");
9443
9444   // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9445   // no constructors, but the C++ compiler on Windows warns about
9446   // unspecified data in compound literals. So, moved to using constructors,
9447   // and TestRound's created with the default constructor should not be used.
9448   struct TestRound {
9449     TestRound()
9450         : expected_rv(ERR_UNEXPECTED),
9451           extra_write(NULL),
9452           extra_read(NULL) {
9453     }
9454     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9455               int expected_rv_arg)
9456         : write(write_arg),
9457           read(read_arg),
9458           expected_rv(expected_rv_arg),
9459           extra_write(NULL),
9460           extra_read(NULL) {
9461     }
9462     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9463               int expected_rv_arg, const MockWrite* extra_write_arg,
9464               const MockRead* extra_read_arg)
9465         : write(write_arg),
9466           read(read_arg),
9467           expected_rv(expected_rv_arg),
9468           extra_write(extra_write_arg),
9469           extra_read(extra_read_arg) {
9470     }
9471     MockWrite write;
9472     MockRead read;
9473     int expected_rv;
9474     const MockWrite* extra_write;
9475     const MockRead* extra_read;
9476   };
9477
9478   static const int kNoSSL = 500;
9479
9480   struct TestConfig {
9481     const char* proxy_url;
9482     AuthTiming proxy_auth_timing;
9483     int proxy_auth_rv;
9484     const char* server_url;
9485     AuthTiming server_auth_timing;
9486     int server_auth_rv;
9487     int num_auth_rounds;
9488     int first_ssl_round;
9489     TestRound rounds[3];
9490   } test_configs[] = {
9491     // Non-authenticating HTTP server with a direct connection.
9492     { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9493       { TestRound(kGet, kSuccess, OK)}},
9494     // Authenticating HTTP server with a direct connection.
9495     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9496       { TestRound(kGet, kServerChallenge, OK),
9497         TestRound(kGetAuth, kSuccess, OK)}},
9498     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9499       { TestRound(kGet, kServerChallenge, OK),
9500         TestRound(kGetAuth, kFailure, kAuthErr)}},
9501     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9502       { TestRound(kGet, kServerChallenge, OK),
9503         TestRound(kGetAuth, kSuccess, OK)}},
9504     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9505       { TestRound(kGet, kServerChallenge, OK),
9506         TestRound(kGetAuth, kFailure, kAuthErr)}},
9507     // Non-authenticating HTTP server through a non-authenticating proxy.
9508     { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9509       { TestRound(kGetProxy, kSuccess, OK)}},
9510     // Authenticating HTTP server through a non-authenticating proxy.
9511     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9512       { TestRound(kGetProxy, kServerChallenge, OK),
9513         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9514     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9515       { TestRound(kGetProxy, kServerChallenge, OK),
9516         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9517     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9518       { TestRound(kGetProxy, kServerChallenge, OK),
9519         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9520     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9521       { TestRound(kGetProxy, kServerChallenge, OK),
9522         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9523     // Non-authenticating HTTP server through an authenticating proxy.
9524     { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9525       { TestRound(kGetProxy, kProxyChallenge, OK),
9526         TestRound(kGetProxyAuth, kSuccess, OK)}},
9527     { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9528       { TestRound(kGetProxy, kProxyChallenge, OK),
9529         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9530     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9531       { TestRound(kGetProxy, kProxyChallenge, OK),
9532         TestRound(kGetProxyAuth, kSuccess, OK)}},
9533     { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9534       { TestRound(kGetProxy, kProxyChallenge, OK),
9535         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9536     // Authenticating HTTP server through an authenticating proxy.
9537     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9538       { TestRound(kGetProxy, kProxyChallenge, OK),
9539         TestRound(kGetProxyAuth, kServerChallenge, OK),
9540         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9541     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9542       { TestRound(kGetProxy, kProxyChallenge, OK),
9543         TestRound(kGetProxyAuth, kServerChallenge, OK),
9544         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9545     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9546       { TestRound(kGetProxy, kProxyChallenge, OK),
9547         TestRound(kGetProxyAuth, kServerChallenge, OK),
9548         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9549     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9550       { TestRound(kGetProxy, kProxyChallenge, OK),
9551         TestRound(kGetProxyAuth, kServerChallenge, OK),
9552         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9553     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9554       { TestRound(kGetProxy, kProxyChallenge, OK),
9555         TestRound(kGetProxyAuth, kServerChallenge, OK),
9556         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9557     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9558       { TestRound(kGetProxy, kProxyChallenge, OK),
9559         TestRound(kGetProxyAuth, kServerChallenge, OK),
9560         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9561     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9562       { TestRound(kGetProxy, kProxyChallenge, OK),
9563         TestRound(kGetProxyAuth, kServerChallenge, OK),
9564         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9565     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9566       { TestRound(kGetProxy, kProxyChallenge, OK),
9567         TestRound(kGetProxyAuth, kServerChallenge, OK),
9568         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9569     // Non-authenticating HTTPS server with a direct connection.
9570     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9571       { TestRound(kGet, kSuccess, OK)}},
9572     // Authenticating HTTPS server with a direct connection.
9573     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9574       { TestRound(kGet, kServerChallenge, OK),
9575         TestRound(kGetAuth, kSuccess, OK)}},
9576     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9577       { TestRound(kGet, kServerChallenge, OK),
9578         TestRound(kGetAuth, kFailure, kAuthErr)}},
9579     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9580       { TestRound(kGet, kServerChallenge, OK),
9581         TestRound(kGetAuth, kSuccess, OK)}},
9582     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9583       { TestRound(kGet, kServerChallenge, OK),
9584         TestRound(kGetAuth, kFailure, kAuthErr)}},
9585     // Non-authenticating HTTPS server with a non-authenticating proxy.
9586     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9587       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9588     // Authenticating HTTPS server through a non-authenticating proxy.
9589     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9590       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9591         TestRound(kGetAuth, kSuccess, OK)}},
9592     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9593       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9594         TestRound(kGetAuth, kFailure, kAuthErr)}},
9595     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9596       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9597         TestRound(kGetAuth, kSuccess, OK)}},
9598     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9599       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9600         TestRound(kGetAuth, kFailure, kAuthErr)}},
9601     // Non-Authenticating HTTPS server through an authenticating proxy.
9602     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9603       { TestRound(kConnect, kProxyChallenge, OK),
9604         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9605     { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9606       { TestRound(kConnect, kProxyChallenge, OK),
9607         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9608     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9609       { TestRound(kConnect, kProxyChallenge, OK),
9610         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9611     { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9612       { TestRound(kConnect, kProxyChallenge, OK),
9613         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9614     // Authenticating HTTPS server through an authenticating proxy.
9615     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9616       { TestRound(kConnect, kProxyChallenge, OK),
9617         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9618                   &kGet, &kServerChallenge),
9619         TestRound(kGetAuth, kSuccess, OK)}},
9620     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9621       { TestRound(kConnect, kProxyChallenge, OK),
9622         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9623                   &kGet, &kServerChallenge),
9624         TestRound(kGetAuth, kFailure, kAuthErr)}},
9625     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9626       { TestRound(kConnect, kProxyChallenge, OK),
9627         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9628                   &kGet, &kServerChallenge),
9629         TestRound(kGetAuth, kSuccess, OK)}},
9630     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9631       { TestRound(kConnect, kProxyChallenge, OK),
9632         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9633                   &kGet, &kServerChallenge),
9634         TestRound(kGetAuth, kFailure, kAuthErr)}},
9635     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9636       { TestRound(kConnect, kProxyChallenge, OK),
9637         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9638                   &kGet, &kServerChallenge),
9639         TestRound(kGetAuth, kSuccess, OK)}},
9640     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9641       { TestRound(kConnect, kProxyChallenge, OK),
9642         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9643                   &kGet, &kServerChallenge),
9644         TestRound(kGetAuth, kFailure, kAuthErr)}},
9645     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9646       { TestRound(kConnect, kProxyChallenge, OK),
9647         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9648                   &kGet, &kServerChallenge),
9649         TestRound(kGetAuth, kSuccess, OK)}},
9650     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9651       { TestRound(kConnect, kProxyChallenge, OK),
9652         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9653                   &kGet, &kServerChallenge),
9654         TestRound(kGetAuth, kFailure, kAuthErr)}},
9655   };
9656
9657   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
9658     HttpAuthHandlerMock::Factory* auth_factory(
9659         new HttpAuthHandlerMock::Factory());
9660     session_deps_.http_auth_handler_factory.reset(auth_factory);
9661     const TestConfig& test_config = test_configs[i];
9662
9663     // Set up authentication handlers as necessary.
9664     if (test_config.proxy_auth_timing != AUTH_NONE) {
9665       for (int n = 0; n < 2; n++) {
9666         HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9667         std::string auth_challenge = "Mock realm=proxy";
9668         GURL origin(test_config.proxy_url);
9669         HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9670                                              auth_challenge.end());
9671         auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9672                                         origin, BoundNetLog());
9673         auth_handler->SetGenerateExpectation(
9674             test_config.proxy_auth_timing == AUTH_ASYNC,
9675             test_config.proxy_auth_rv);
9676         auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9677       }
9678     }
9679     if (test_config.server_auth_timing != AUTH_NONE) {
9680       HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9681       std::string auth_challenge = "Mock realm=server";
9682       GURL origin(test_config.server_url);
9683       HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9684                                            auth_challenge.end());
9685       auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9686                                       origin, BoundNetLog());
9687       auth_handler->SetGenerateExpectation(
9688           test_config.server_auth_timing == AUTH_ASYNC,
9689           test_config.server_auth_rv);
9690       auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
9691     }
9692     if (test_config.proxy_url) {
9693       session_deps_.proxy_service.reset(
9694           ProxyService::CreateFixed(test_config.proxy_url));
9695     } else {
9696       session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9697     }
9698
9699     HttpRequestInfo request;
9700     request.method = "GET";
9701     request.url = GURL(test_config.server_url);
9702     request.load_flags = 0;
9703
9704     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9705     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
9706
9707     for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9708       const TestRound& read_write_round = test_config.rounds[round];
9709
9710       // Set up expected reads and writes.
9711       MockRead reads[2];
9712       reads[0] = read_write_round.read;
9713       size_t length_reads = 1;
9714       if (read_write_round.extra_read) {
9715         reads[1] = *read_write_round.extra_read;
9716         length_reads = 2;
9717       }
9718
9719       MockWrite writes[2];
9720       writes[0] = read_write_round.write;
9721       size_t length_writes = 1;
9722       if (read_write_round.extra_write) {
9723         writes[1] = *read_write_round.extra_write;
9724         length_writes = 2;
9725       }
9726       StaticSocketDataProvider data_provider(
9727           reads, length_reads, writes, length_writes);
9728       session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
9729
9730       // Add an SSL sequence if necessary.
9731       SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
9732       if (round >= test_config.first_ssl_round)
9733         session_deps_.socket_factory->AddSSLSocketDataProvider(
9734             &ssl_socket_data_provider);
9735
9736       // Start or restart the transaction.
9737       TestCompletionCallback callback;
9738       int rv;
9739       if (round == 0) {
9740         rv = trans.Start(&request, callback.callback(), BoundNetLog());
9741       } else {
9742         rv = trans.RestartWithAuth(
9743             AuthCredentials(kFoo, kBar), callback.callback());
9744       }
9745       if (rv == ERR_IO_PENDING)
9746         rv = callback.WaitForResult();
9747
9748       // Compare results with expected data.
9749       EXPECT_EQ(read_write_round.expected_rv, rv);
9750       const HttpResponseInfo* response = trans.GetResponseInfo();
9751       if (read_write_round.expected_rv == OK) {
9752         ASSERT_TRUE(response != NULL);
9753       } else {
9754         EXPECT_TRUE(response == NULL);
9755         EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9756         continue;
9757       }
9758       if (round + 1 < test_config.num_auth_rounds) {
9759         EXPECT_FALSE(response->auth_challenge.get() == NULL);
9760       } else {
9761         EXPECT_TRUE(response->auth_challenge.get() == NULL);
9762       }
9763     }
9764   }
9765 }
9766
9767 TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
9768   // Do multi-round authentication and make sure it works correctly.
9769   HttpAuthHandlerMock::Factory* auth_factory(
9770       new HttpAuthHandlerMock::Factory());
9771   session_deps_.http_auth_handler_factory.reset(auth_factory);
9772   session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9773   session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9774   session_deps_.host_resolver->set_synchronous_mode(true);
9775
9776   HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9777   auth_handler->set_connection_based(true);
9778   std::string auth_challenge = "Mock realm=server";
9779   GURL origin("http://www.example.com");
9780   HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9781                                        auth_challenge.end());
9782   auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9783                                   origin, BoundNetLog());
9784   auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
9785
9786   int rv = OK;
9787   const HttpResponseInfo* response = NULL;
9788   HttpRequestInfo request;
9789   request.method = "GET";
9790   request.url = origin;
9791   request.load_flags = 0;
9792
9793   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9794
9795   // Use a TCP Socket Pool with only one connection per group. This is used
9796   // to validate that the TCP socket is not released to the pool between
9797   // each round of multi-round authentication.
9798   HttpNetworkSessionPeer session_peer(session);
9799   ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9800   TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
9801       50,  // Max sockets for pool
9802       1,   // Max sockets per group
9803       &transport_pool_histograms,
9804       session_deps_.host_resolver.get(),
9805       session_deps_.socket_factory.get(),
9806       session_deps_.net_log);
9807   scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9808       new MockClientSocketPoolManager);
9809   mock_pool_manager->SetTransportSocketPool(transport_pool);
9810   session_peer.SetClientSocketPoolManager(
9811       mock_pool_manager.PassAs<ClientSocketPoolManager>());
9812
9813   scoped_ptr<HttpTransaction> trans(
9814       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9815   TestCompletionCallback callback;
9816
9817   const MockWrite kGet(
9818       "GET / HTTP/1.1\r\n"
9819       "Host: www.example.com\r\n"
9820       "Connection: keep-alive\r\n\r\n");
9821   const MockWrite kGetAuth(
9822       "GET / HTTP/1.1\r\n"
9823       "Host: www.example.com\r\n"
9824       "Connection: keep-alive\r\n"
9825       "Authorization: auth_token\r\n\r\n");
9826
9827   const MockRead kServerChallenge(
9828       "HTTP/1.1 401 Unauthorized\r\n"
9829       "WWW-Authenticate: Mock realm=server\r\n"
9830       "Content-Type: text/html; charset=iso-8859-1\r\n"
9831       "Content-Length: 14\r\n\r\n"
9832       "Unauthorized\r\n");
9833   const MockRead kSuccess(
9834       "HTTP/1.1 200 OK\r\n"
9835       "Content-Type: text/html; charset=iso-8859-1\r\n"
9836       "Content-Length: 3\r\n\r\n"
9837       "Yes");
9838
9839   MockWrite writes[] = {
9840     // First round
9841     kGet,
9842     // Second round
9843     kGetAuth,
9844     // Third round
9845     kGetAuth,
9846     // Fourth round
9847     kGetAuth,
9848     // Competing request
9849     kGet,
9850   };
9851   MockRead reads[] = {
9852     // First round
9853     kServerChallenge,
9854     // Second round
9855     kServerChallenge,
9856     // Third round
9857     kServerChallenge,
9858     // Fourth round
9859     kSuccess,
9860     // Competing response
9861     kSuccess,
9862   };
9863   StaticSocketDataProvider data_provider(reads, arraysize(reads),
9864                                          writes, arraysize(writes));
9865   session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
9866
9867   const char* const kSocketGroup = "www.example.com:80";
9868
9869   // First round of authentication.
9870   auth_handler->SetGenerateExpectation(false, OK);
9871   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9872   if (rv == ERR_IO_PENDING)
9873     rv = callback.WaitForResult();
9874   EXPECT_EQ(OK, rv);
9875   response = trans->GetResponseInfo();
9876   ASSERT_TRUE(response != NULL);
9877   EXPECT_FALSE(response->auth_challenge.get() == NULL);
9878   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9879
9880   // In between rounds, another request comes in for the same domain.
9881   // It should not be able to grab the TCP socket that trans has already
9882   // claimed.
9883   scoped_ptr<HttpTransaction> trans_compete(
9884       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9885   TestCompletionCallback callback_compete;
9886   rv = trans_compete->Start(
9887       &request, callback_compete.callback(), BoundNetLog());
9888   EXPECT_EQ(ERR_IO_PENDING, rv);
9889   // callback_compete.WaitForResult at this point would stall forever,
9890   // since the HttpNetworkTransaction does not release the request back to
9891   // the pool until after authentication completes.
9892
9893   // Second round of authentication.
9894   auth_handler->SetGenerateExpectation(false, OK);
9895   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
9896   if (rv == ERR_IO_PENDING)
9897     rv = callback.WaitForResult();
9898   EXPECT_EQ(OK, rv);
9899   response = trans->GetResponseInfo();
9900   ASSERT_TRUE(response != NULL);
9901   EXPECT_TRUE(response->auth_challenge.get() == NULL);
9902   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9903
9904   // Third round of authentication.
9905   auth_handler->SetGenerateExpectation(false, OK);
9906   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
9907   if (rv == ERR_IO_PENDING)
9908     rv = callback.WaitForResult();
9909   EXPECT_EQ(OK, rv);
9910   response = trans->GetResponseInfo();
9911   ASSERT_TRUE(response != NULL);
9912   EXPECT_TRUE(response->auth_challenge.get() == NULL);
9913   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9914
9915   // Fourth round of authentication, which completes successfully.
9916   auth_handler->SetGenerateExpectation(false, OK);
9917   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
9918   if (rv == ERR_IO_PENDING)
9919     rv = callback.WaitForResult();
9920   EXPECT_EQ(OK, rv);
9921   response = trans->GetResponseInfo();
9922   ASSERT_TRUE(response != NULL);
9923   EXPECT_TRUE(response->auth_challenge.get() == NULL);
9924   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9925
9926   // Read the body since the fourth round was successful. This will also
9927   // release the socket back to the pool.
9928   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
9929   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
9930   if (rv == ERR_IO_PENDING)
9931     rv = callback.WaitForResult();
9932   EXPECT_EQ(3, rv);
9933   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
9934   EXPECT_EQ(0, rv);
9935   // There are still 0 idle sockets, since the trans_compete transaction
9936   // will be handed it immediately after trans releases it to the group.
9937   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9938
9939   // The competing request can now finish. Wait for the headers and then
9940   // read the body.
9941   rv = callback_compete.WaitForResult();
9942   EXPECT_EQ(OK, rv);
9943   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
9944   if (rv == ERR_IO_PENDING)
9945     rv = callback.WaitForResult();
9946   EXPECT_EQ(3, rv);
9947   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
9948   EXPECT_EQ(0, rv);
9949
9950   // Finally, the socket is released to the group.
9951   EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9952 }
9953
9954 // This tests the case that a request is issued via http instead of spdy after
9955 // npn is negotiated.
9956 TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
9957   session_deps_.use_alternate_protocols = true;
9958   NextProtoVector next_protos;
9959   next_protos.push_back(kProtoHTTP11);
9960   session_deps_.next_protos = next_protos;
9961
9962   HttpRequestInfo request;
9963   request.method = "GET";
9964   request.url = GURL("https://www.google.com/");
9965   request.load_flags = 0;
9966
9967   MockWrite data_writes[] = {
9968     MockWrite("GET / HTTP/1.1\r\n"
9969               "Host: www.google.com\r\n"
9970               "Connection: keep-alive\r\n\r\n"),
9971   };
9972
9973   std::string alternate_protocol_http_header =
9974       GetAlternateProtocolHttpHeader();
9975
9976   MockRead data_reads[] = {
9977     MockRead("HTTP/1.1 200 OK\r\n"),
9978     MockRead(alternate_protocol_http_header.c_str()),
9979     MockRead("hello world"),
9980     MockRead(SYNCHRONOUS, OK),
9981   };
9982
9983   SSLSocketDataProvider ssl(ASYNC, OK);
9984   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9985   ssl.next_proto = "http/1.1";
9986   ssl.protocol_negotiated = kProtoHTTP11;
9987
9988   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9989
9990   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9991                                 data_writes, arraysize(data_writes));
9992   session_deps_.socket_factory->AddSocketDataProvider(&data);
9993
9994   TestCompletionCallback callback;
9995
9996   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9997   scoped_ptr<HttpTransaction> trans(
9998       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9999
10000   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10001
10002   EXPECT_EQ(ERR_IO_PENDING, rv);
10003   EXPECT_EQ(OK, callback.WaitForResult());
10004
10005   const HttpResponseInfo* response = trans->GetResponseInfo();
10006   ASSERT_TRUE(response != NULL);
10007   ASSERT_TRUE(response->headers.get() != NULL);
10008   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10009
10010   std::string response_data;
10011   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10012   EXPECT_EQ("hello world", response_data);
10013
10014   EXPECT_FALSE(response->was_fetched_via_spdy);
10015   EXPECT_TRUE(response->was_npn_negotiated);
10016 }
10017
10018 TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
10019   // Simulate the SSL handshake completing with an NPN negotiation
10020   // followed by an immediate server closing of the socket.
10021   // Fix crash:  http://crbug.com/46369
10022   session_deps_.use_alternate_protocols = true;
10023   session_deps_.next_protos = SpdyNextProtos();
10024
10025   HttpRequestInfo request;
10026   request.method = "GET";
10027   request.url = GURL("https://www.google.com/");
10028   request.load_flags = 0;
10029
10030   SSLSocketDataProvider ssl(ASYNC, OK);
10031   ssl.SetNextProto(GetParam());
10032   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10033
10034   scoped_ptr<SpdyFrame> req(
10035       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
10036   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10037
10038   MockRead spdy_reads[] = {
10039     MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
10040   };
10041
10042   DelayedSocketData spdy_data(
10043       0,  // don't wait in this case, immediate hangup.
10044       spdy_reads, arraysize(spdy_reads),
10045       spdy_writes, arraysize(spdy_writes));
10046   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10047
10048   TestCompletionCallback callback;
10049
10050   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10051   scoped_ptr<HttpTransaction> trans(
10052       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10053
10054   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10055   EXPECT_EQ(ERR_IO_PENDING, rv);
10056   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
10057 }
10058
10059 // A subclass of HttpAuthHandlerMock that records the request URL when
10060 // it gets it. This is needed since the auth handler may get destroyed
10061 // before we get a chance to query it.
10062 class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10063  public:
10064   explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10065
10066   virtual ~UrlRecordingHttpAuthHandlerMock() {}
10067
10068  protected:
10069   virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10070                                     const HttpRequestInfo* request,
10071                                     const CompletionCallback& callback,
10072                                     std::string* auth_token) OVERRIDE {
10073     *url_ = request->url;
10074     return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10075         credentials, request, callback, auth_token);
10076   }
10077
10078  private:
10079   GURL* url_;
10080 };
10081
10082 TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
10083   // This test ensures that the URL passed into the proxy is upgraded
10084   // to https when doing an Alternate Protocol upgrade.
10085   session_deps_.use_alternate_protocols = true;
10086   session_deps_.next_protos = SpdyNextProtos();
10087
10088   session_deps_.proxy_service.reset(
10089       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10090   CapturingNetLog net_log;
10091   session_deps_.net_log = &net_log;
10092   GURL request_url;
10093   {
10094     HttpAuthHandlerMock::Factory* auth_factory =
10095         new HttpAuthHandlerMock::Factory();
10096     UrlRecordingHttpAuthHandlerMock* auth_handler =
10097         new UrlRecordingHttpAuthHandlerMock(&request_url);
10098     auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10099     auth_factory->set_do_init_from_challenge(true);
10100     session_deps_.http_auth_handler_factory.reset(auth_factory);
10101   }
10102
10103   HttpRequestInfo request;
10104   request.method = "GET";
10105   request.url = GURL("http://www.google.com");
10106   request.load_flags = 0;
10107
10108   // First round goes unauthenticated through the proxy.
10109   MockWrite data_writes_1[] = {
10110     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10111               "Host: www.google.com\r\n"
10112               "Proxy-Connection: keep-alive\r\n"
10113               "\r\n"),
10114   };
10115   MockRead data_reads_1[] = {
10116     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10117     MockRead("HTTP/1.1 200 OK\r\n"
10118              "Alternate-Protocol: 443:npn-spdy/2\r\n"
10119              "Proxy-Connection: close\r\n"
10120              "\r\n"),
10121   };
10122   StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10123                                   data_writes_1, arraysize(data_writes_1));
10124
10125   // Second round tries to tunnel to www.google.com due to the
10126   // Alternate-Protocol announcement in the first round. It fails due
10127   // to a proxy authentication challenge.
10128   // After the failure, a tunnel is established to www.google.com using
10129   // Proxy-Authorization headers. There is then a SPDY request round.
10130   //
10131   // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10132   // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10133   // does a Disconnect and Connect on the same socket, rather than trying
10134   // to obtain a new one.
10135   //
10136   // NOTE: Originally, the proxy response to the second CONNECT request
10137   // simply returned another 407 so the unit test could skip the SSL connection
10138   // establishment and SPDY framing issues. Alas, the
10139   // retry-http-when-alternate-protocol fails logic kicks in, which was more
10140   // complicated to set up expectations for than the SPDY session.
10141
10142   scoped_ptr<SpdyFrame> req(
10143       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
10144   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10145   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
10146
10147   MockWrite data_writes_2[] = {
10148     // First connection attempt without Proxy-Authorization.
10149     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10150               "Host: www.google.com\r\n"
10151               "Proxy-Connection: keep-alive\r\n"
10152               "\r\n"),
10153
10154     // Second connection attempt with Proxy-Authorization.
10155     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10156               "Host: www.google.com\r\n"
10157               "Proxy-Connection: keep-alive\r\n"
10158               "Proxy-Authorization: auth_token\r\n"
10159               "\r\n"),
10160
10161     // SPDY request
10162     CreateMockWrite(*req),
10163   };
10164   const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10165                                          "Proxy-Authenticate: Mock\r\n"
10166                                          "Proxy-Connection: close\r\n"
10167                                          "\r\n");
10168   const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10169   MockRead data_reads_2[] = {
10170     // First connection attempt fails
10171     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
10172     MockRead(ASYNC, kRejectConnectResponse,
10173              arraysize(kRejectConnectResponse) - 1, 1),
10174
10175     // Second connection attempt passes
10176     MockRead(ASYNC, kAcceptConnectResponse,
10177              arraysize(kAcceptConnectResponse) -1, 4),
10178
10179     // SPDY response
10180     CreateMockRead(*resp.get(), 6),
10181     CreateMockRead(*data.get(), 6),
10182     MockRead(ASYNC, 0, 0, 6),
10183   };
10184   OrderedSocketData data_2(
10185       data_reads_2, arraysize(data_reads_2),
10186       data_writes_2, arraysize(data_writes_2));
10187
10188   SSLSocketDataProvider ssl(ASYNC, OK);
10189   ssl.SetNextProto(GetParam());
10190
10191   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
10192   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10193       NULL, 0, NULL, 0);
10194   hanging_non_alternate_protocol_socket.set_connect_data(
10195       never_finishing_connect);
10196
10197   session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10198   session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10199   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10200   session_deps_.socket_factory->AddSocketDataProvider(
10201       &hanging_non_alternate_protocol_socket);
10202   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10203
10204   // First round should work and provide the Alternate-Protocol state.
10205   TestCompletionCallback callback_1;
10206   scoped_ptr<HttpTransaction> trans_1(
10207       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10208   int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
10209   EXPECT_EQ(ERR_IO_PENDING, rv);
10210   EXPECT_EQ(OK, callback_1.WaitForResult());
10211
10212   // Second round should attempt a tunnel connect and get an auth challenge.
10213   TestCompletionCallback callback_2;
10214   scoped_ptr<HttpTransaction> trans_2(
10215       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10216   rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
10217   EXPECT_EQ(ERR_IO_PENDING, rv);
10218   EXPECT_EQ(OK, callback_2.WaitForResult());
10219   const HttpResponseInfo* response = trans_2->GetResponseInfo();
10220   ASSERT_TRUE(response != NULL);
10221   ASSERT_FALSE(response->auth_challenge.get() == NULL);
10222
10223   // Restart with auth. Tunnel should work and response received.
10224   TestCompletionCallback callback_3;
10225   rv = trans_2->RestartWithAuth(
10226       AuthCredentials(kFoo, kBar), callback_3.callback());
10227   EXPECT_EQ(ERR_IO_PENDING, rv);
10228   EXPECT_EQ(OK, callback_3.WaitForResult());
10229
10230   // After all that work, these two lines (or actually, just the scheme) are
10231   // what this test is all about. Make sure it happens correctly.
10232   EXPECT_EQ("https", request_url.scheme());
10233   EXPECT_EQ("www.google.com", request_url.host());
10234
10235   LoadTimingInfo load_timing_info;
10236   EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10237   TestLoadTimingNotReusedWithPac(load_timing_info,
10238                                  CONNECT_TIMING_HAS_SSL_TIMES);
10239 }
10240
10241 // Test that if we cancel the transaction as the connection is completing, that
10242 // everything tears down correctly.
10243 TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
10244   // Setup everything about the connection to complete synchronously, so that
10245   // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10246   // for is the callback from the HttpStreamRequest.
10247   // Then cancel the transaction.
10248   // Verify that we don't crash.
10249   MockConnect mock_connect(SYNCHRONOUS, OK);
10250   MockRead data_reads[] = {
10251     MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10252     MockRead(SYNCHRONOUS, "hello world"),
10253     MockRead(SYNCHRONOUS, OK),
10254   };
10255
10256   HttpRequestInfo request;
10257   request.method = "GET";
10258   request.url = GURL("http://www.google.com/");
10259   request.load_flags = 0;
10260
10261   session_deps_.host_resolver->set_synchronous_mode(true);
10262   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10263   scoped_ptr<HttpTransaction> trans(
10264       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
10265
10266   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10267   data.set_connect_data(mock_connect);
10268   session_deps_.socket_factory->AddSocketDataProvider(&data);
10269
10270   TestCompletionCallback callback;
10271
10272   CapturingBoundNetLog log;
10273   int rv = trans->Start(&request, callback.callback(), log.bound());
10274   EXPECT_EQ(ERR_IO_PENDING, rv);
10275   trans.reset();  // Cancel the transaction here.
10276
10277   base::MessageLoop::current()->RunUntilIdle();
10278 }
10279
10280 // Test that if a transaction is cancelled after receiving the headers, the
10281 // stream is drained properly and added back to the socket pool.  The main
10282 // purpose of this test is to make sure that an HttpStreamParser can be read
10283 // from after the HttpNetworkTransaction and the objects it owns have been
10284 // deleted.
10285 // See http://crbug.com/368418
10286 TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10287   MockRead data_reads[] = {
10288     MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10289     MockRead(ASYNC, "Content-Length: 2\r\n"),
10290     MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10291     MockRead(ASYNC, "1"),
10292     // 2 async reads are necessary to trigger a ReadResponseBody call after the
10293     // HttpNetworkTransaction has been deleted.
10294     MockRead(ASYNC, "2"),
10295     MockRead(SYNCHRONOUS, ERR_IO_PENDING),  // Should never read this.
10296   };
10297   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10298   session_deps_.socket_factory->AddSocketDataProvider(&data);
10299
10300   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10301
10302   {
10303     HttpRequestInfo request;
10304     request.method = "GET";
10305     request.url = GURL("http://www.google.com/");
10306     request.load_flags = 0;
10307
10308     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
10309     TestCompletionCallback callback;
10310
10311     int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10312     EXPECT_EQ(ERR_IO_PENDING, rv);
10313     callback.WaitForResult();
10314
10315     const HttpResponseInfo* response = trans.GetResponseInfo();
10316     ASSERT_TRUE(response != NULL);
10317     EXPECT_TRUE(response->headers.get() != NULL);
10318     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10319
10320     // The transaction and HttpRequestInfo are deleted.
10321   }
10322
10323   // Let the HttpResponseBodyDrainer drain the socket.
10324   base::MessageLoop::current()->RunUntilIdle();
10325
10326   // Socket should now be idle, waiting to be reused.
10327   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
10328 }
10329
10330 // Test a basic GET request through a proxy.
10331 TEST_P(HttpNetworkTransactionTest, ProxyGet) {
10332   session_deps_.proxy_service.reset(
10333       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10334   CapturingBoundNetLog log;
10335   session_deps_.net_log = log.bound().net_log();
10336   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10337
10338   HttpRequestInfo request;
10339   request.method = "GET";
10340   request.url = GURL("http://www.google.com/");
10341
10342   MockWrite data_writes1[] = {
10343     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10344               "Host: www.google.com\r\n"
10345               "Proxy-Connection: keep-alive\r\n\r\n"),
10346   };
10347
10348   MockRead data_reads1[] = {
10349     MockRead("HTTP/1.1 200 OK\r\n"),
10350     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10351     MockRead("Content-Length: 100\r\n\r\n"),
10352     MockRead(SYNCHRONOUS, OK),
10353   };
10354
10355   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10356                                  data_writes1, arraysize(data_writes1));
10357   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10358
10359   TestCompletionCallback callback1;
10360
10361   scoped_ptr<HttpTransaction> trans(
10362       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10363   BeforeProxyHeadersSentHandler proxy_headers_handler;
10364   trans->SetBeforeProxyHeadersSentCallback(
10365       base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10366                  base::Unretained(&proxy_headers_handler)));
10367
10368   int rv = trans->Start(&request, callback1.callback(), log.bound());
10369   EXPECT_EQ(ERR_IO_PENDING, rv);
10370
10371   rv = callback1.WaitForResult();
10372   EXPECT_EQ(OK, rv);
10373
10374   const HttpResponseInfo* response = trans->GetResponseInfo();
10375   ASSERT_TRUE(response != NULL);
10376
10377   EXPECT_TRUE(response->headers->IsKeepAlive());
10378   EXPECT_EQ(200, response->headers->response_code());
10379   EXPECT_EQ(100, response->headers->GetContentLength());
10380   EXPECT_TRUE(response->was_fetched_via_proxy);
10381   EXPECT_TRUE(
10382       response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
10383   EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10384   EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
10385   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10386
10387   LoadTimingInfo load_timing_info;
10388   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10389   TestLoadTimingNotReusedWithPac(load_timing_info,
10390                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10391 }
10392
10393 // Test a basic HTTPS GET request through a proxy.
10394 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
10395   session_deps_.proxy_service.reset(
10396       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10397   CapturingBoundNetLog log;
10398   session_deps_.net_log = log.bound().net_log();
10399   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10400
10401   HttpRequestInfo request;
10402   request.method = "GET";
10403   request.url = GURL("https://www.google.com/");
10404
10405   // Since we have proxy, should try to establish tunnel.
10406   MockWrite data_writes1[] = {
10407     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10408               "Host: www.google.com\r\n"
10409               "Proxy-Connection: keep-alive\r\n\r\n"),
10410
10411     MockWrite("GET / HTTP/1.1\r\n"
10412               "Host: www.google.com\r\n"
10413               "Connection: keep-alive\r\n\r\n"),
10414   };
10415
10416   MockRead data_reads1[] = {
10417     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10418
10419     MockRead("HTTP/1.1 200 OK\r\n"),
10420     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10421     MockRead("Content-Length: 100\r\n\r\n"),
10422     MockRead(SYNCHRONOUS, OK),
10423   };
10424
10425   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10426                                  data_writes1, arraysize(data_writes1));
10427   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10428   SSLSocketDataProvider ssl(ASYNC, OK);
10429   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10430
10431   TestCompletionCallback callback1;
10432
10433   scoped_ptr<HttpTransaction> trans(
10434       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10435
10436   int rv = trans->Start(&request, callback1.callback(), log.bound());
10437   EXPECT_EQ(ERR_IO_PENDING, rv);
10438
10439   rv = callback1.WaitForResult();
10440   EXPECT_EQ(OK, rv);
10441   net::CapturingNetLog::CapturedEntryList entries;
10442   log.GetEntries(&entries);
10443   size_t pos = ExpectLogContainsSomewhere(
10444       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10445       NetLog::PHASE_NONE);
10446   ExpectLogContainsSomewhere(
10447       entries, pos,
10448       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10449       NetLog::PHASE_NONE);
10450
10451   const HttpResponseInfo* response = trans->GetResponseInfo();
10452   ASSERT_TRUE(response != NULL);
10453
10454   EXPECT_TRUE(response->headers->IsKeepAlive());
10455   EXPECT_EQ(200, response->headers->response_code());
10456   EXPECT_EQ(100, response->headers->GetContentLength());
10457   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10458   EXPECT_TRUE(response->was_fetched_via_proxy);
10459   EXPECT_TRUE(
10460       response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
10461
10462   LoadTimingInfo load_timing_info;
10463   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10464   TestLoadTimingNotReusedWithPac(load_timing_info,
10465                                  CONNECT_TIMING_HAS_SSL_TIMES);
10466 }
10467
10468 // Test a basic HTTPS GET request through a proxy, but the server hangs up
10469 // while establishing the tunnel.
10470 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
10471   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
10472   CapturingBoundNetLog log;
10473   session_deps_.net_log = log.bound().net_log();
10474   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10475
10476   HttpRequestInfo request;
10477   request.method = "GET";
10478   request.url = GURL("https://www.google.com/");
10479
10480   // Since we have proxy, should try to establish tunnel.
10481   MockWrite data_writes1[] = {
10482     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10483               "Host: www.google.com\r\n"
10484               "Proxy-Connection: keep-alive\r\n\r\n"),
10485
10486     MockWrite("GET / HTTP/1.1\r\n"
10487               "Host: www.google.com\r\n"
10488               "Connection: keep-alive\r\n\r\n"),
10489   };
10490
10491   MockRead data_reads1[] = {
10492     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10493     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10494     MockRead(ASYNC, 0, 0),  // EOF
10495   };
10496
10497   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10498                                  data_writes1, arraysize(data_writes1));
10499   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10500   SSLSocketDataProvider ssl(ASYNC, OK);
10501   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10502
10503   TestCompletionCallback callback1;
10504
10505   scoped_ptr<HttpTransaction> trans(
10506       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10507
10508   int rv = trans->Start(&request, callback1.callback(), log.bound());
10509   EXPECT_EQ(ERR_IO_PENDING, rv);
10510
10511   rv = callback1.WaitForResult();
10512   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
10513   net::CapturingNetLog::CapturedEntryList entries;
10514   log.GetEntries(&entries);
10515   size_t pos = ExpectLogContainsSomewhere(
10516       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10517       NetLog::PHASE_NONE);
10518   ExpectLogContainsSomewhere(
10519       entries, pos,
10520       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10521       NetLog::PHASE_NONE);
10522 }
10523
10524 // Test for crbug.com/55424.
10525 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
10526   scoped_ptr<SpdyFrame> req(
10527       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10528   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10529
10530   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10531   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
10532   MockRead spdy_reads[] = {
10533     CreateMockRead(*resp),
10534     CreateMockRead(*data),
10535     MockRead(ASYNC, 0, 0),
10536   };
10537
10538   DelayedSocketData spdy_data(
10539       1,  // wait for one write to finish before reading.
10540       spdy_reads, arraysize(spdy_reads),
10541       spdy_writes, arraysize(spdy_writes));
10542   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10543
10544   SSLSocketDataProvider ssl(ASYNC, OK);
10545   ssl.SetNextProto(GetParam());
10546   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10547
10548   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10549
10550   // Set up an initial SpdySession in the pool to reuse.
10551   HostPortPair host_port_pair("www.google.com", 443);
10552   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10553                      PRIVACY_MODE_DISABLED);
10554   base::WeakPtr<SpdySession> spdy_session =
10555       CreateInsecureSpdySession(session, key, BoundNetLog());
10556
10557   HttpRequestInfo request;
10558   request.method = "GET";
10559   request.url = GURL("https://www.google.com/");
10560   request.load_flags = 0;
10561
10562   // This is the important line that marks this as a preconnect.
10563   request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10564
10565   scoped_ptr<HttpTransaction> trans(
10566       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10567
10568   TestCompletionCallback callback;
10569   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10570   EXPECT_EQ(ERR_IO_PENDING, rv);
10571   EXPECT_EQ(OK, callback.WaitForResult());
10572 }
10573
10574 // Given a net error, cause that error to be returned from the first Write()
10575 // call and verify that the HttpTransaction fails with that error.
10576 void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
10577     int error, IoMode mode) {
10578   net::HttpRequestInfo request_info;
10579   request_info.url = GURL("https://www.example.com/");
10580   request_info.method = "GET";
10581   request_info.load_flags = net::LOAD_NORMAL;
10582
10583   SSLSocketDataProvider ssl_data(mode, OK);
10584   net::MockWrite data_writes[] = {
10585     net::MockWrite(mode, error),
10586   };
10587   net::StaticSocketDataProvider data(NULL, 0,
10588                                      data_writes, arraysize(data_writes));
10589   session_deps_.socket_factory->AddSocketDataProvider(&data);
10590   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
10591
10592   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10593   scoped_ptr<HttpTransaction> trans(
10594       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10595
10596   TestCompletionCallback callback;
10597   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
10598   if (rv == net::ERR_IO_PENDING)
10599     rv = callback.WaitForResult();
10600   ASSERT_EQ(error, rv);
10601 }
10602
10603 TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
10604   // Just check a grab bag of cert errors.
10605   static const int kErrors[] = {
10606     ERR_CERT_COMMON_NAME_INVALID,
10607     ERR_CERT_AUTHORITY_INVALID,
10608     ERR_CERT_DATE_INVALID,
10609   };
10610   for (size_t i = 0; i < arraysize(kErrors); i++) {
10611     CheckErrorIsPassedBack(kErrors[i], ASYNC);
10612     CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
10613   }
10614 }
10615
10616 // Ensure that a client certificate is removed from the SSL client auth
10617 // cache when:
10618 //  1) No proxy is involved.
10619 //  2) TLS False Start is disabled.
10620 //  3) The initial TLS handshake requests a client certificate.
10621 //  4) The client supplies an invalid/unacceptable certificate.
10622 TEST_P(HttpNetworkTransactionTest,
10623        ClientAuthCertCache_Direct_NoFalseStart) {
10624   net::HttpRequestInfo request_info;
10625   request_info.url = GURL("https://www.example.com/");
10626   request_info.method = "GET";
10627   request_info.load_flags = net::LOAD_NORMAL;
10628
10629   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10630   cert_request->host_and_port = HostPortPair("www.example.com", 443);
10631
10632   // [ssl_]data1 contains the data for the first SSL handshake. When a
10633   // CertificateRequest is received for the first time, the handshake will
10634   // be aborted to allow the caller to provide a certificate.
10635   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
10636   ssl_data1.cert_request_info = cert_request.get();
10637   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
10638   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10639   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10640
10641   // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10642   // False Start is not being used, the result of the SSL handshake will be
10643   // returned as part of the SSLClientSocket::Connect() call. This test
10644   // matches the result of a server sending a handshake_failure alert,
10645   // rather than a Finished message, because it requires a client
10646   // certificate and none was supplied.
10647   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10648   ssl_data2.cert_request_info = cert_request.get();
10649   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
10650   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10651   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10652
10653   // [ssl_]data3 contains the data for the third SSL handshake. When a
10654   // connection to a server fails during an SSL handshake,
10655   // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10656   // connection was attempted with TLSv1.1. This is transparent to the caller
10657   // of the HttpNetworkTransaction. Because this test failure is due to
10658   // requiring a client certificate, this fallback handshake should also
10659   // fail.
10660   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10661   ssl_data3.cert_request_info = cert_request.get();
10662   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
10663   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10664   session_deps_.socket_factory->AddSocketDataProvider(&data3);
10665
10666   // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10667   // connection to a server fails during an SSL handshake,
10668   // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10669   // connection was attempted with TLSv1. This is transparent to the caller
10670   // of the HttpNetworkTransaction. Because this test failure is due to
10671   // requiring a client certificate, this fallback handshake should also
10672   // fail.
10673   SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10674   ssl_data4.cert_request_info = cert_request.get();
10675   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
10676   net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
10677   session_deps_.socket_factory->AddSocketDataProvider(&data4);
10678
10679   // Need one more if TLSv1.2 is enabled.
10680   SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10681   ssl_data5.cert_request_info = cert_request.get();
10682   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10683   net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10684   session_deps_.socket_factory->AddSocketDataProvider(&data5);
10685
10686   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10687   scoped_ptr<HttpTransaction> trans(
10688       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10689
10690   // Begin the SSL handshake with the peer. This consumes ssl_data1.
10691   TestCompletionCallback callback;
10692   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
10693   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10694
10695   // Complete the SSL handshake, which should abort due to requiring a
10696   // client certificate.
10697   rv = callback.WaitForResult();
10698   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10699
10700   // Indicate that no certificate should be supplied. From the perspective
10701   // of SSLClientCertCache, NULL is just as meaningful as a real
10702   // certificate, so this is the same as supply a
10703   // legitimate-but-unacceptable certificate.
10704   rv = trans->RestartWithCertificate(NULL, callback.callback());
10705   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10706
10707   // Ensure the certificate was added to the client auth cache before
10708   // allowing the connection to continue restarting.
10709   scoped_refptr<X509Certificate> client_cert;
10710   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10711       HostPortPair("www.example.com", 443), &client_cert));
10712   ASSERT_EQ(NULL, client_cert.get());
10713
10714   // Restart the handshake. This will consume ssl_data2, which fails, and
10715   // then consume ssl_data3 and ssl_data4, both of which should also fail.
10716   // The result code is checked against what ssl_data4 should return.
10717   rv = callback.WaitForResult();
10718   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10719
10720   // Ensure that the client certificate is removed from the cache on a
10721   // handshake failure.
10722   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10723       HostPortPair("www.example.com", 443), &client_cert));
10724 }
10725
10726 // Ensure that a client certificate is removed from the SSL client auth
10727 // cache when:
10728 //  1) No proxy is involved.
10729 //  2) TLS False Start is enabled.
10730 //  3) The initial TLS handshake requests a client certificate.
10731 //  4) The client supplies an invalid/unacceptable certificate.
10732 TEST_P(HttpNetworkTransactionTest,
10733        ClientAuthCertCache_Direct_FalseStart) {
10734   net::HttpRequestInfo request_info;
10735   request_info.url = GURL("https://www.example.com/");
10736   request_info.method = "GET";
10737   request_info.load_flags = net::LOAD_NORMAL;
10738
10739   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10740   cert_request->host_and_port = HostPortPair("www.example.com", 443);
10741
10742   // When TLS False Start is used, SSLClientSocket::Connect() calls will
10743   // return successfully after reading up to the peer's Certificate message.
10744   // This is to allow the caller to call SSLClientSocket::Write(), which can
10745   // enqueue application data to be sent in the same packet as the
10746   // ChangeCipherSpec and Finished messages.
10747   // The actual handshake will be finished when SSLClientSocket::Read() is
10748   // called, which expects to process the peer's ChangeCipherSpec and
10749   // Finished messages. If there was an error negotiating with the peer,
10750   // such as due to the peer requiring a client certificate when none was
10751   // supplied, the alert sent by the peer won't be processed until Read() is
10752   // called.
10753
10754   // Like the non-False Start case, when a client certificate is requested by
10755   // the peer, the handshake is aborted during the Connect() call.
10756   // [ssl_]data1 represents the initial SSL handshake with the peer.
10757   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
10758   ssl_data1.cert_request_info = cert_request.get();
10759   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
10760   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10761   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10762
10763   // When a client certificate is supplied, Connect() will not be aborted
10764   // when the peer requests the certificate. Instead, the handshake will
10765   // artificially succeed, allowing the caller to write the HTTP request to
10766   // the socket. The handshake messages are not processed until Read() is
10767   // called, which then detects that the handshake was aborted, due to the
10768   // peer sending a handshake_failure because it requires a client
10769   // certificate.
10770   SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
10771   ssl_data2.cert_request_info = cert_request.get();
10772   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
10773   net::MockRead data2_reads[] = {
10774     net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
10775   };
10776   net::StaticSocketDataProvider data2(
10777       data2_reads, arraysize(data2_reads), NULL, 0);
10778   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10779
10780   // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
10781   // the data for the SSL handshake once the TLSv1.1 connection falls back to
10782   // TLSv1. It has the same behaviour as [ssl_]data2.
10783   SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
10784   ssl_data3.cert_request_info = cert_request.get();
10785   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
10786   net::StaticSocketDataProvider data3(
10787       data2_reads, arraysize(data2_reads), NULL, 0);
10788   session_deps_.socket_factory->AddSocketDataProvider(&data3);
10789
10790   // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10791   // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10792   SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10793   ssl_data4.cert_request_info = cert_request.get();
10794   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
10795   net::StaticSocketDataProvider data4(
10796       data2_reads, arraysize(data2_reads), NULL, 0);
10797   session_deps_.socket_factory->AddSocketDataProvider(&data4);
10798
10799   // Need one more if TLSv1.2 is enabled.
10800   SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10801   ssl_data5.cert_request_info = cert_request.get();
10802   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10803   net::StaticSocketDataProvider data5(
10804       data2_reads, arraysize(data2_reads), NULL, 0);
10805   session_deps_.socket_factory->AddSocketDataProvider(&data5);
10806
10807   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10808   scoped_ptr<HttpTransaction> trans(
10809       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10810
10811   // Begin the initial SSL handshake.
10812   TestCompletionCallback callback;
10813   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
10814   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10815
10816   // Complete the SSL handshake, which should abort due to requiring a
10817   // client certificate.
10818   rv = callback.WaitForResult();
10819   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10820
10821   // Indicate that no certificate should be supplied. From the perspective
10822   // of SSLClientCertCache, NULL is just as meaningful as a real
10823   // certificate, so this is the same as supply a
10824   // legitimate-but-unacceptable certificate.
10825   rv = trans->RestartWithCertificate(NULL, callback.callback());
10826   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10827
10828   // Ensure the certificate was added to the client auth cache before
10829   // allowing the connection to continue restarting.
10830   scoped_refptr<X509Certificate> client_cert;
10831   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10832       HostPortPair("www.example.com", 443), &client_cert));
10833   ASSERT_EQ(NULL, client_cert.get());
10834
10835   // Restart the handshake. This will consume ssl_data2, which fails, and
10836   // then consume ssl_data3 and ssl_data4, both of which should also fail.
10837   // The result code is checked against what ssl_data4 should return.
10838   rv = callback.WaitForResult();
10839   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10840
10841   // Ensure that the client certificate is removed from the cache on a
10842   // handshake failure.
10843   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10844       HostPortPair("www.example.com", 443), &client_cert));
10845 }
10846
10847 // Ensure that a client certificate is removed from the SSL client auth
10848 // cache when:
10849 //  1) An HTTPS proxy is involved.
10850 //  3) The HTTPS proxy requests a client certificate.
10851 //  4) The client supplies an invalid/unacceptable certificate for the
10852 //     proxy.
10853 // The test is repeated twice, first for connecting to an HTTPS endpoint,
10854 // then for connecting to an HTTP endpoint.
10855 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
10856   session_deps_.proxy_service.reset(
10857       ProxyService::CreateFixed("https://proxy:70"));
10858   CapturingBoundNetLog log;
10859   session_deps_.net_log = log.bound().net_log();
10860
10861   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10862   cert_request->host_and_port = HostPortPair("proxy", 70);
10863
10864   // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10865   // [ssl_]data[1-3]. Rather than represending the endpoint
10866   // (www.example.com:443), they represent failures with the HTTPS proxy
10867   // (proxy:70).
10868   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
10869   ssl_data1.cert_request_info = cert_request.get();
10870   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
10871   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10872   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10873
10874   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10875   ssl_data2.cert_request_info = cert_request.get();
10876   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
10877   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10878   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10879
10880   // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10881 #if 0
10882   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10883   ssl_data3.cert_request_info = cert_request.get();
10884   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
10885   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10886   session_deps_.socket_factory->AddSocketDataProvider(&data3);
10887 #endif
10888
10889   net::HttpRequestInfo requests[2];
10890   requests[0].url = GURL("https://www.example.com/");
10891   requests[0].method = "GET";
10892   requests[0].load_flags = net::LOAD_NORMAL;
10893
10894   requests[1].url = GURL("http://www.example.com/");
10895   requests[1].method = "GET";
10896   requests[1].load_flags = net::LOAD_NORMAL;
10897
10898   for (size_t i = 0; i < arraysize(requests); ++i) {
10899     session_deps_.socket_factory->ResetNextMockIndexes();
10900     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10901     scoped_ptr<HttpNetworkTransaction> trans(
10902         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10903
10904     // Begin the SSL handshake with the proxy.
10905     TestCompletionCallback callback;
10906     int rv = trans->Start(
10907         &requests[i], callback.callback(), net::BoundNetLog());
10908     ASSERT_EQ(net::ERR_IO_PENDING, rv);
10909
10910     // Complete the SSL handshake, which should abort due to requiring a
10911     // client certificate.
10912     rv = callback.WaitForResult();
10913     ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10914
10915     // Indicate that no certificate should be supplied. From the perspective
10916     // of SSLClientCertCache, NULL is just as meaningful as a real
10917     // certificate, so this is the same as supply a
10918     // legitimate-but-unacceptable certificate.
10919     rv = trans->RestartWithCertificate(NULL, callback.callback());
10920     ASSERT_EQ(net::ERR_IO_PENDING, rv);
10921
10922     // Ensure the certificate was added to the client auth cache before
10923     // allowing the connection to continue restarting.
10924     scoped_refptr<X509Certificate> client_cert;
10925     ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10926         HostPortPair("proxy", 70), &client_cert));
10927     ASSERT_EQ(NULL, client_cert.get());
10928     // Ensure the certificate was NOT cached for the endpoint. This only
10929     // applies to HTTPS requests, but is fine to check for HTTP requests.
10930     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10931         HostPortPair("www.example.com", 443), &client_cert));
10932
10933     // Restart the handshake. This will consume ssl_data2, which fails, and
10934     // then consume ssl_data3, which should also fail. The result code is
10935     // checked against what ssl_data3 should return.
10936     rv = callback.WaitForResult();
10937     ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10938
10939     // Now that the new handshake has failed, ensure that the client
10940     // certificate was removed from the client auth cache.
10941     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10942         HostPortPair("proxy", 70), &client_cert));
10943     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10944         HostPortPair("www.example.com", 443), &client_cert));
10945   }
10946 }
10947
10948 // Unlike TEST/TEST_F, which are macros that expand to further macros,
10949 // TEST_P is a macro that expands directly to code that stringizes the
10950 // arguments. As a result, macros passed as parameters (such as prefix
10951 // or test_case_name) will not be expanded by the preprocessor. To
10952 // work around this, indirect the macro for TEST_P, so that the
10953 // pre-processor will expand macros such as MAYBE_test_name before
10954 // instantiating the test.
10955 #define WRAPPED_TEST_P(test_case_name, test_name) \
10956   TEST_P(test_case_name, test_name)
10957
10958 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
10959 #if defined(OS_WIN)
10960 #define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10961 #else
10962 #define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10963 #endif
10964 WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
10965   session_deps_.use_alternate_protocols = true;
10966   session_deps_.next_protos = SpdyNextProtos();
10967
10968   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
10969   session_deps_.host_resolver.reset(new MockCachingHostResolver());
10970   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10971   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10972   pool_peer.DisableDomainAuthenticationVerification();
10973
10974   SSLSocketDataProvider ssl(ASYNC, OK);
10975   ssl.SetNextProto(GetParam());
10976   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10977
10978   scoped_ptr<SpdyFrame> host1_req(
10979       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10980   scoped_ptr<SpdyFrame> host2_req(
10981       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
10982   MockWrite spdy_writes[] = {
10983     CreateMockWrite(*host1_req, 1),
10984     CreateMockWrite(*host2_req, 4),
10985   };
10986   scoped_ptr<SpdyFrame> host1_resp(
10987       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10988   scoped_ptr<SpdyFrame> host1_resp_body(
10989       spdy_util_.ConstructSpdyBodyFrame(1, true));
10990   scoped_ptr<SpdyFrame> host2_resp(
10991       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10992   scoped_ptr<SpdyFrame> host2_resp_body(
10993       spdy_util_.ConstructSpdyBodyFrame(3, true));
10994   MockRead spdy_reads[] = {
10995     CreateMockRead(*host1_resp, 2),
10996     CreateMockRead(*host1_resp_body, 3),
10997     CreateMockRead(*host2_resp, 5),
10998     CreateMockRead(*host2_resp_body, 6),
10999     MockRead(ASYNC, 0, 7),
11000   };
11001
11002   IPAddressNumber ip;
11003   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11004   IPEndPoint peer_addr = IPEndPoint(ip, 443);
11005   MockConnect connect(ASYNC, OK, peer_addr);
11006   OrderedSocketData spdy_data(
11007       connect,
11008       spdy_reads, arraysize(spdy_reads),
11009       spdy_writes, arraysize(spdy_writes));
11010   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11011
11012   TestCompletionCallback callback;
11013   HttpRequestInfo request1;
11014   request1.method = "GET";
11015   request1.url = GURL("https://www.google.com/");
11016   request1.load_flags = 0;
11017   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
11018
11019   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11020   EXPECT_EQ(ERR_IO_PENDING, rv);
11021   EXPECT_EQ(OK, callback.WaitForResult());
11022
11023   const HttpResponseInfo* response = trans1.GetResponseInfo();
11024   ASSERT_TRUE(response != NULL);
11025   ASSERT_TRUE(response->headers.get() != NULL);
11026   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11027
11028   std::string response_data;
11029   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11030   EXPECT_EQ("hello!", response_data);
11031
11032   // Preload www.gmail.com into HostCache.
11033   HostPortPair host_port("www.gmail.com", 443);
11034   HostResolver::RequestInfo resolve_info(host_port);
11035   AddressList ignored;
11036   rv = session_deps_.host_resolver->Resolve(resolve_info,
11037                                             DEFAULT_PRIORITY,
11038                                             &ignored,
11039                                             callback.callback(),
11040                                             NULL,
11041                                             BoundNetLog());
11042   EXPECT_EQ(ERR_IO_PENDING, rv);
11043   rv = callback.WaitForResult();
11044   EXPECT_EQ(OK, rv);
11045
11046   HttpRequestInfo request2;
11047   request2.method = "GET";
11048   request2.url = GURL("https://www.gmail.com/");
11049   request2.load_flags = 0;
11050   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
11051
11052   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11053   EXPECT_EQ(ERR_IO_PENDING, rv);
11054   EXPECT_EQ(OK, callback.WaitForResult());
11055
11056   response = trans2.GetResponseInfo();
11057   ASSERT_TRUE(response != NULL);
11058   ASSERT_TRUE(response->headers.get() != NULL);
11059   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11060   EXPECT_TRUE(response->was_fetched_via_spdy);
11061   EXPECT_TRUE(response->was_npn_negotiated);
11062   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11063   EXPECT_EQ("hello!", response_data);
11064 }
11065 #undef MAYBE_UseIPConnectionPooling
11066
11067 TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
11068   session_deps_.use_alternate_protocols = true;
11069   session_deps_.next_protos = SpdyNextProtos();
11070
11071   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
11072   session_deps_.host_resolver.reset(new MockCachingHostResolver());
11073   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11074   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11075   pool_peer.DisableDomainAuthenticationVerification();
11076
11077   SSLSocketDataProvider ssl(ASYNC, OK);
11078   ssl.SetNextProto(GetParam());
11079   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11080
11081   scoped_ptr<SpdyFrame> host1_req(
11082       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11083   scoped_ptr<SpdyFrame> host2_req(
11084       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
11085   MockWrite spdy_writes[] = {
11086     CreateMockWrite(*host1_req, 1),
11087     CreateMockWrite(*host2_req, 4),
11088   };
11089   scoped_ptr<SpdyFrame> host1_resp(
11090       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11091   scoped_ptr<SpdyFrame> host1_resp_body(
11092       spdy_util_.ConstructSpdyBodyFrame(1, true));
11093   scoped_ptr<SpdyFrame> host2_resp(
11094       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11095   scoped_ptr<SpdyFrame> host2_resp_body(
11096       spdy_util_.ConstructSpdyBodyFrame(3, true));
11097   MockRead spdy_reads[] = {
11098     CreateMockRead(*host1_resp, 2),
11099     CreateMockRead(*host1_resp_body, 3),
11100     CreateMockRead(*host2_resp, 5),
11101     CreateMockRead(*host2_resp_body, 6),
11102     MockRead(ASYNC, 0, 7),
11103   };
11104
11105   IPAddressNumber ip;
11106   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11107   IPEndPoint peer_addr = IPEndPoint(ip, 443);
11108   MockConnect connect(ASYNC, OK, peer_addr);
11109   OrderedSocketData spdy_data(
11110       connect,
11111       spdy_reads, arraysize(spdy_reads),
11112       spdy_writes, arraysize(spdy_writes));
11113   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11114
11115   TestCompletionCallback callback;
11116   HttpRequestInfo request1;
11117   request1.method = "GET";
11118   request1.url = GURL("https://www.google.com/");
11119   request1.load_flags = 0;
11120   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
11121
11122   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11123   EXPECT_EQ(ERR_IO_PENDING, rv);
11124   EXPECT_EQ(OK, callback.WaitForResult());
11125
11126   const HttpResponseInfo* response = trans1.GetResponseInfo();
11127   ASSERT_TRUE(response != NULL);
11128   ASSERT_TRUE(response->headers.get() != NULL);
11129   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11130
11131   std::string response_data;
11132   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11133   EXPECT_EQ("hello!", response_data);
11134
11135   HttpRequestInfo request2;
11136   request2.method = "GET";
11137   request2.url = GURL("https://www.gmail.com/");
11138   request2.load_flags = 0;
11139   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
11140
11141   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11142   EXPECT_EQ(ERR_IO_PENDING, rv);
11143   EXPECT_EQ(OK, callback.WaitForResult());
11144
11145   response = trans2.GetResponseInfo();
11146   ASSERT_TRUE(response != NULL);
11147   ASSERT_TRUE(response->headers.get() != NULL);
11148   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11149   EXPECT_TRUE(response->was_fetched_via_spdy);
11150   EXPECT_TRUE(response->was_npn_negotiated);
11151   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11152   EXPECT_EQ("hello!", response_data);
11153 }
11154
11155 class OneTimeCachingHostResolver : public net::HostResolver {
11156  public:
11157   explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11158       : host_port_(host_port) {}
11159   virtual ~OneTimeCachingHostResolver() {}
11160
11161   RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11162
11163   // HostResolver methods:
11164   virtual int Resolve(const RequestInfo& info,
11165                       RequestPriority priority,
11166                       AddressList* addresses,
11167                       const CompletionCallback& callback,
11168                       RequestHandle* out_req,
11169                       const BoundNetLog& net_log) OVERRIDE {
11170     return host_resolver_.Resolve(
11171         info, priority, addresses, callback, out_req, net_log);
11172   }
11173
11174   virtual int ResolveFromCache(const RequestInfo& info,
11175                                AddressList* addresses,
11176                                const BoundNetLog& net_log) OVERRIDE {
11177     int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11178     if (rv == OK && info.host_port_pair().Equals(host_port_))
11179       host_resolver_.GetHostCache()->clear();
11180     return rv;
11181   }
11182
11183   virtual void CancelRequest(RequestHandle req) OVERRIDE {
11184     host_resolver_.CancelRequest(req);
11185   }
11186
11187   MockCachingHostResolver* GetMockHostResolver() {
11188     return &host_resolver_;
11189   }
11190
11191  private:
11192   MockCachingHostResolver host_resolver_;
11193   const HostPortPair host_port_;
11194 };
11195
11196 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
11197 #if defined(OS_WIN)
11198 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11199     DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
11200 #else
11201 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11202     UseIPConnectionPoolingWithHostCacheExpiration
11203 #endif
11204 WRAPPED_TEST_P(HttpNetworkTransactionTest,
11205                MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
11206 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11207 // prefix doesn't work with parametrized tests).
11208 #if defined(OS_WIN)
11209   return;
11210 #else
11211   session_deps_.use_alternate_protocols = true;
11212   session_deps_.next_protos = SpdyNextProtos();
11213
11214   // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
11215   OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
11216   HttpNetworkSession::Params params =
11217       SpdySessionDependencies::CreateSessionParams(&session_deps_);
11218   params.host_resolver = &host_resolver;
11219   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11220   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11221   pool_peer.DisableDomainAuthenticationVerification();
11222
11223   SSLSocketDataProvider ssl(ASYNC, OK);
11224   ssl.SetNextProto(GetParam());
11225   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11226
11227   scoped_ptr<SpdyFrame> host1_req(
11228       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11229   scoped_ptr<SpdyFrame> host2_req(
11230       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
11231   MockWrite spdy_writes[] = {
11232     CreateMockWrite(*host1_req, 1),
11233     CreateMockWrite(*host2_req, 4),
11234   };
11235   scoped_ptr<SpdyFrame> host1_resp(
11236       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11237   scoped_ptr<SpdyFrame> host1_resp_body(
11238       spdy_util_.ConstructSpdyBodyFrame(1, true));
11239   scoped_ptr<SpdyFrame> host2_resp(
11240       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11241   scoped_ptr<SpdyFrame> host2_resp_body(
11242       spdy_util_.ConstructSpdyBodyFrame(3, true));
11243   MockRead spdy_reads[] = {
11244     CreateMockRead(*host1_resp, 2),
11245     CreateMockRead(*host1_resp_body, 3),
11246     CreateMockRead(*host2_resp, 5),
11247     CreateMockRead(*host2_resp_body, 6),
11248     MockRead(ASYNC, 0, 7),
11249   };
11250
11251   IPAddressNumber ip;
11252   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11253   IPEndPoint peer_addr = IPEndPoint(ip, 443);
11254   MockConnect connect(ASYNC, OK, peer_addr);
11255   OrderedSocketData spdy_data(
11256       connect,
11257       spdy_reads, arraysize(spdy_reads),
11258       spdy_writes, arraysize(spdy_writes));
11259   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11260
11261   TestCompletionCallback callback;
11262   HttpRequestInfo request1;
11263   request1.method = "GET";
11264   request1.url = GURL("https://www.google.com/");
11265   request1.load_flags = 0;
11266   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
11267
11268   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11269   EXPECT_EQ(ERR_IO_PENDING, rv);
11270   EXPECT_EQ(OK, callback.WaitForResult());
11271
11272   const HttpResponseInfo* response = trans1.GetResponseInfo();
11273   ASSERT_TRUE(response != NULL);
11274   ASSERT_TRUE(response->headers.get() != NULL);
11275   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11276
11277   std::string response_data;
11278   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11279   EXPECT_EQ("hello!", response_data);
11280
11281   // Preload cache entries into HostCache.
11282   HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
11283   AddressList ignored;
11284   rv = host_resolver.Resolve(resolve_info,
11285                              DEFAULT_PRIORITY,
11286                              &ignored,
11287                              callback.callback(),
11288                              NULL,
11289                              BoundNetLog());
11290   EXPECT_EQ(ERR_IO_PENDING, rv);
11291   rv = callback.WaitForResult();
11292   EXPECT_EQ(OK, rv);
11293
11294   HttpRequestInfo request2;
11295   request2.method = "GET";
11296   request2.url = GURL("https://www.gmail.com/");
11297   request2.load_flags = 0;
11298   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
11299
11300   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11301   EXPECT_EQ(ERR_IO_PENDING, rv);
11302   EXPECT_EQ(OK, callback.WaitForResult());
11303
11304   response = trans2.GetResponseInfo();
11305   ASSERT_TRUE(response != NULL);
11306   ASSERT_TRUE(response->headers.get() != NULL);
11307   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11308   EXPECT_TRUE(response->was_fetched_via_spdy);
11309   EXPECT_TRUE(response->was_npn_negotiated);
11310   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11311   EXPECT_EQ("hello!", response_data);
11312 #endif
11313 }
11314 #undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
11315
11316 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
11317   const std::string https_url = "https://www.google.com/";
11318   const std::string http_url = "http://www.google.com:443/";
11319
11320   // SPDY GET for HTTPS URL
11321   scoped_ptr<SpdyFrame> req1(
11322       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
11323
11324   MockWrite writes1[] = {
11325     CreateMockWrite(*req1, 0),
11326   };
11327
11328   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11329   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11330   MockRead reads1[] = {
11331     CreateMockRead(*resp1, 1),
11332     CreateMockRead(*body1, 2),
11333     MockRead(ASYNC, ERR_IO_PENDING, 3)
11334   };
11335
11336   DelayedSocketData data1(
11337       1, reads1, arraysize(reads1),
11338       writes1, arraysize(writes1));
11339   MockConnect connect_data1(ASYNC, OK);
11340   data1.set_connect_data(connect_data1);
11341
11342   // HTTP GET for the HTTP URL
11343   MockWrite writes2[] = {
11344     MockWrite(ASYNC, 4,
11345               "GET / HTTP/1.1\r\n"
11346               "Host: www.google.com:443\r\n"
11347               "Connection: keep-alive\r\n\r\n"),
11348   };
11349
11350   MockRead reads2[] = {
11351     MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11352     MockRead(ASYNC, 6, "hello"),
11353     MockRead(ASYNC, 7, OK),
11354   };
11355
11356   DelayedSocketData data2(
11357       1, reads2, arraysize(reads2),
11358       writes2, arraysize(writes2));
11359
11360   SSLSocketDataProvider ssl(ASYNC, OK);
11361   ssl.SetNextProto(GetParam());
11362   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11363   session_deps_.socket_factory->AddSocketDataProvider(&data1);
11364   session_deps_.socket_factory->AddSocketDataProvider(&data2);
11365
11366   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11367
11368   // Start the first transaction to set up the SpdySession
11369   HttpRequestInfo request1;
11370   request1.method = "GET";
11371   request1.url = GURL(https_url);
11372   request1.load_flags = 0;
11373   HttpNetworkTransaction trans1(LOWEST, session.get());
11374   TestCompletionCallback callback1;
11375   EXPECT_EQ(ERR_IO_PENDING,
11376             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11377   base::MessageLoop::current()->RunUntilIdle();
11378
11379   EXPECT_EQ(OK, callback1.WaitForResult());
11380   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11381
11382   // Now, start the HTTP request
11383   HttpRequestInfo request2;
11384   request2.method = "GET";
11385   request2.url = GURL(http_url);
11386   request2.load_flags = 0;
11387   HttpNetworkTransaction trans2(MEDIUM, session.get());
11388   TestCompletionCallback callback2;
11389   EXPECT_EQ(ERR_IO_PENDING,
11390             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11391   base::MessageLoop::current()->RunUntilIdle();
11392
11393   EXPECT_EQ(OK, callback2.WaitForResult());
11394   EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11395 }
11396
11397 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
11398   const std::string https_url = "https://www.google.com/";
11399   const std::string http_url = "http://www.google.com:443/";
11400
11401   // SPDY GET for HTTPS URL (through CONNECT tunnel)
11402   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
11403                                                                 LOWEST));
11404   scoped_ptr<SpdyFrame> req1(
11405       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
11406   scoped_ptr<SpdyFrame> wrapped_req1(
11407       spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
11408
11409   // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
11410   SpdyHeaderBlock req2_block;
11411   req2_block[spdy_util_.GetMethodKey()] = "GET";
11412   req2_block[spdy_util_.GetPathKey()] =
11413       spdy_util_.is_spdy2() ? http_url.c_str() : "/";
11414   req2_block[spdy_util_.GetHostKey()] = "www.google.com:443";
11415   req2_block[spdy_util_.GetSchemeKey()] = "http";
11416   spdy_util_.MaybeAddVersionHeader(&req2_block);
11417   scoped_ptr<SpdyFrame> req2(
11418       spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
11419
11420   MockWrite writes1[] = {
11421     CreateMockWrite(*connect, 0),
11422     CreateMockWrite(*wrapped_req1, 2),
11423     CreateMockWrite(*req2, 5),
11424   };
11425
11426   scoped_ptr<SpdyFrame> conn_resp(
11427       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11428   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11429   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11430   scoped_ptr<SpdyFrame> wrapped_resp1(
11431       spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11432   scoped_ptr<SpdyFrame> wrapped_body1(
11433       spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11434   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11435   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
11436   MockRead reads1[] = {
11437     CreateMockRead(*conn_resp, 1),
11438     CreateMockRead(*wrapped_resp1, 3),
11439     CreateMockRead(*wrapped_body1, 4),
11440     CreateMockRead(*resp2, 6),
11441     CreateMockRead(*body2, 7),
11442     MockRead(ASYNC, ERR_IO_PENDING, 8)
11443   };
11444
11445   DeterministicSocketData data1(reads1, arraysize(reads1),
11446                                 writes1, arraysize(writes1));
11447   MockConnect connect_data1(ASYNC, OK);
11448   data1.set_connect_data(connect_data1);
11449
11450   session_deps_.proxy_service.reset(
11451       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11452   CapturingNetLog log;
11453   session_deps_.net_log = &log;
11454   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
11455   ssl1.SetNextProto(GetParam());
11456   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11457   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
11458   ssl2.SetNextProto(GetParam());
11459   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11460   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
11461
11462   scoped_refptr<HttpNetworkSession> session(
11463       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11464
11465   // Start the first transaction to set up the SpdySession
11466   HttpRequestInfo request1;
11467   request1.method = "GET";
11468   request1.url = GURL(https_url);
11469   request1.load_flags = 0;
11470   HttpNetworkTransaction trans1(LOWEST, session.get());
11471   TestCompletionCallback callback1;
11472   EXPECT_EQ(ERR_IO_PENDING,
11473             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11474   base::MessageLoop::current()->RunUntilIdle();
11475   data1.RunFor(4);
11476
11477   EXPECT_EQ(OK, callback1.WaitForResult());
11478   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11479
11480   LoadTimingInfo load_timing_info1;
11481   EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11482   TestLoadTimingNotReusedWithPac(load_timing_info1,
11483                                  CONNECT_TIMING_HAS_SSL_TIMES);
11484
11485   // Now, start the HTTP request
11486   HttpRequestInfo request2;
11487   request2.method = "GET";
11488   request2.url = GURL(http_url);
11489   request2.load_flags = 0;
11490   HttpNetworkTransaction trans2(MEDIUM, session.get());
11491   TestCompletionCallback callback2;
11492   EXPECT_EQ(ERR_IO_PENDING,
11493             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11494   base::MessageLoop::current()->RunUntilIdle();
11495   data1.RunFor(3);
11496
11497   EXPECT_EQ(OK, callback2.WaitForResult());
11498   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11499
11500   LoadTimingInfo load_timing_info2;
11501   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11502   // The established SPDY sessions is considered reused by the HTTP request.
11503   TestLoadTimingReusedWithPac(load_timing_info2);
11504   // HTTP requests over a SPDY session should have a different connection
11505   // socket_log_id than requests over a tunnel.
11506   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
11507 }
11508
11509 TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
11510   session_deps_.force_spdy_always = true;
11511   const std::string https_url = "https://www.google.com/";
11512   const std::string http_url = "http://www.google.com:443/";
11513
11514   // SPDY GET for HTTPS URL
11515   scoped_ptr<SpdyFrame> req1(
11516       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
11517   // SPDY GET for the HTTP URL
11518   scoped_ptr<SpdyFrame> req2(
11519       spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
11520
11521   MockWrite writes[] = {
11522     CreateMockWrite(*req1, 1),
11523     CreateMockWrite(*req2, 4),
11524   };
11525
11526   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11527   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11528   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11529   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
11530   MockRead reads[] = {
11531     CreateMockRead(*resp1, 2),
11532     CreateMockRead(*body1, 3),
11533     CreateMockRead(*resp2, 5),
11534     CreateMockRead(*body2, 6),
11535     MockRead(ASYNC, ERR_IO_PENDING, 7)
11536   };
11537
11538   OrderedSocketData data(reads, arraysize(reads),
11539                          writes, arraysize(writes));
11540
11541   SSLSocketDataProvider ssl(ASYNC, OK);
11542   ssl.SetNextProto(GetParam());
11543   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11544   session_deps_.socket_factory->AddSocketDataProvider(&data);
11545
11546   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11547
11548   // Start the first transaction to set up the SpdySession
11549   HttpRequestInfo request1;
11550   request1.method = "GET";
11551   request1.url = GURL(https_url);
11552   request1.load_flags = 0;
11553   HttpNetworkTransaction trans1(LOWEST, session.get());
11554   TestCompletionCallback callback1;
11555   EXPECT_EQ(ERR_IO_PENDING,
11556             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11557   base::MessageLoop::current()->RunUntilIdle();
11558
11559   EXPECT_EQ(OK, callback1.WaitForResult());
11560   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11561
11562   // Now, start the HTTP request
11563   HttpRequestInfo request2;
11564   request2.method = "GET";
11565   request2.url = GURL(http_url);
11566   request2.load_flags = 0;
11567   HttpNetworkTransaction trans2(MEDIUM, session.get());
11568   TestCompletionCallback callback2;
11569   EXPECT_EQ(ERR_IO_PENDING,
11570             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11571   base::MessageLoop::current()->RunUntilIdle();
11572
11573   EXPECT_EQ(OK, callback2.WaitForResult());
11574   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11575 }
11576
11577 // Test that in the case where we have a SPDY session to a SPDY proxy
11578 // that we do not pool other origins that resolve to the same IP when
11579 // the certificate does not match the new origin.
11580 // http://crbug.com/134690
11581 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
11582   const std::string url1 = "http://www.google.com/";
11583   const std::string url2 = "https://mail.google.com/";
11584   const std::string ip_addr = "1.2.3.4";
11585
11586   // SPDY GET for HTTP URL (through SPDY proxy)
11587   scoped_ptr<SpdyHeaderBlock> headers(
11588       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
11589   scoped_ptr<SpdyFrame> req1(
11590       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
11591
11592   MockWrite writes1[] = {
11593     CreateMockWrite(*req1, 0),
11594   };
11595
11596   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11597   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11598   MockRead reads1[] = {
11599     CreateMockRead(*resp1, 1),
11600     CreateMockRead(*body1, 2),
11601     MockRead(ASYNC, OK, 3) // EOF
11602   };
11603
11604   scoped_ptr<DeterministicSocketData> data1(
11605       new DeterministicSocketData(reads1, arraysize(reads1),
11606                                   writes1, arraysize(writes1)));
11607   IPAddressNumber ip;
11608   ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11609   IPEndPoint peer_addr = IPEndPoint(ip, 443);
11610   MockConnect connect_data1(ASYNC, OK, peer_addr);
11611   data1->set_connect_data(connect_data1);
11612
11613   // SPDY GET for HTTPS URL (direct)
11614   scoped_ptr<SpdyFrame> req2(
11615       spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
11616
11617   MockWrite writes2[] = {
11618     CreateMockWrite(*req2, 0),
11619   };
11620
11621   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11622   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11623   MockRead reads2[] = {
11624     CreateMockRead(*resp2, 1),
11625     CreateMockRead(*body2, 2),
11626     MockRead(ASYNC, OK, 3) // EOF
11627   };
11628
11629   scoped_ptr<DeterministicSocketData> data2(
11630       new DeterministicSocketData(reads2, arraysize(reads2),
11631                                   writes2, arraysize(writes2)));
11632   MockConnect connect_data2(ASYNC, OK);
11633   data2->set_connect_data(connect_data2);
11634
11635   // Set up a proxy config that sends HTTP requests to a proxy, and
11636   // all others direct.
11637   ProxyConfig proxy_config;
11638   proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11639   CapturingProxyResolver* capturing_proxy_resolver =
11640       new CapturingProxyResolver();
11641   session_deps_.proxy_service.reset(new ProxyService(
11642       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11643       NULL));
11644
11645   // Load a valid cert.  Note, that this does not need to
11646   // be valid for proxy because the MockSSLClientSocket does
11647   // not actually verify it.  But SpdySession will use this
11648   // to see if it is valid for the new origin
11649   base::FilePath certs_dir = GetTestCertsDirectory();
11650   scoped_refptr<X509Certificate> server_cert(
11651       ImportCertFromFile(certs_dir, "ok_cert.pem"));
11652   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11653
11654   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
11655   ssl1.SetNextProto(GetParam());
11656   ssl1.cert = server_cert;
11657   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11658   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11659       data1.get());
11660
11661   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
11662   ssl2.SetNextProto(GetParam());
11663   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11664   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11665       data2.get());
11666
11667   session_deps_.host_resolver.reset(new MockCachingHostResolver());
11668   session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11669   session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
11670
11671   scoped_refptr<HttpNetworkSession> session(
11672       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11673
11674   // Start the first transaction to set up the SpdySession
11675   HttpRequestInfo request1;
11676   request1.method = "GET";
11677   request1.url = GURL(url1);
11678   request1.load_flags = 0;
11679   HttpNetworkTransaction trans1(LOWEST, session.get());
11680   TestCompletionCallback callback1;
11681   ASSERT_EQ(ERR_IO_PENDING,
11682             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11683   data1->RunFor(3);
11684
11685   ASSERT_TRUE(callback1.have_result());
11686   EXPECT_EQ(OK, callback1.WaitForResult());
11687   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11688
11689   // Now, start the HTTP request
11690   HttpRequestInfo request2;
11691   request2.method = "GET";
11692   request2.url = GURL(url2);
11693   request2.load_flags = 0;
11694   HttpNetworkTransaction trans2(MEDIUM, session.get());
11695   TestCompletionCallback callback2;
11696   EXPECT_EQ(ERR_IO_PENDING,
11697             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11698   base::MessageLoop::current()->RunUntilIdle();
11699   data2->RunFor(3);
11700
11701   ASSERT_TRUE(callback2.have_result());
11702   EXPECT_EQ(OK, callback2.WaitForResult());
11703   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11704 }
11705
11706 // Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11707 // error) in SPDY session, removes the socket from pool and closes the SPDY
11708 // session. Verify that new url's from the same HttpNetworkSession (and a new
11709 // SpdySession) do work. http://crbug.com/224701
11710 TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
11711   const std::string https_url = "https://www.google.com/";
11712
11713   MockRead reads1[] = {
11714     MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11715   };
11716
11717   scoped_ptr<DeterministicSocketData> data1(
11718       new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11719   data1->SetStop(1);
11720
11721   scoped_ptr<SpdyFrame> req2(
11722       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
11723   MockWrite writes2[] = {
11724     CreateMockWrite(*req2, 0),
11725   };
11726
11727   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11728   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11729   MockRead reads2[] = {
11730     CreateMockRead(*resp2, 1),
11731     CreateMockRead(*body2, 2),
11732     MockRead(ASYNC, OK, 3)  // EOF
11733   };
11734
11735   scoped_ptr<DeterministicSocketData> data2(
11736       new DeterministicSocketData(reads2, arraysize(reads2),
11737                                   writes2, arraysize(writes2)));
11738
11739   SSLSocketDataProvider ssl1(ASYNC, OK);
11740   ssl1.SetNextProto(GetParam());
11741   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11742   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11743       data1.get());
11744
11745   SSLSocketDataProvider ssl2(ASYNC, OK);
11746   ssl2.SetNextProto(GetParam());
11747   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11748   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11749       data2.get());
11750
11751   scoped_refptr<HttpNetworkSession> session(
11752       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11753
11754   // Start the first transaction to set up the SpdySession and verify that
11755   // connection was closed.
11756   HttpRequestInfo request1;
11757   request1.method = "GET";
11758   request1.url = GURL(https_url);
11759   request1.load_flags = 0;
11760   HttpNetworkTransaction trans1(MEDIUM, session.get());
11761   TestCompletionCallback callback1;
11762   EXPECT_EQ(ERR_IO_PENDING,
11763             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11764   base::MessageLoop::current()->RunUntilIdle();
11765   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11766
11767   // Now, start the second request and make sure it succeeds.
11768   HttpRequestInfo request2;
11769   request2.method = "GET";
11770   request2.url = GURL(https_url);
11771   request2.load_flags = 0;
11772   HttpNetworkTransaction trans2(MEDIUM, session.get());
11773   TestCompletionCallback callback2;
11774   EXPECT_EQ(ERR_IO_PENDING,
11775             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11776   base::MessageLoop::current()->RunUntilIdle();
11777   data2->RunFor(3);
11778
11779   ASSERT_TRUE(callback2.have_result());
11780   EXPECT_EQ(OK, callback2.WaitForResult());
11781   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11782 }
11783
11784 TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
11785   session_deps_.next_protos = SpdyNextProtos();
11786   ClientSocketPoolManager::set_max_sockets_per_group(
11787       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11788   ClientSocketPoolManager::set_max_sockets_per_pool(
11789       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11790
11791   // Use two different hosts with different IPs so they don't get pooled.
11792   session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11793   session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11794   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11795
11796   SSLSocketDataProvider ssl1(ASYNC, OK);
11797   ssl1.SetNextProto(GetParam());
11798   SSLSocketDataProvider ssl2(ASYNC, OK);
11799   ssl2.SetNextProto(GetParam());
11800   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11801   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11802
11803   scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
11804       "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11805   MockWrite spdy1_writes[] = {
11806     CreateMockWrite(*host1_req, 1),
11807   };
11808   scoped_ptr<SpdyFrame> host1_resp(
11809       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11810   scoped_ptr<SpdyFrame> host1_resp_body(
11811       spdy_util_.ConstructSpdyBodyFrame(1, true));
11812   MockRead spdy1_reads[] = {
11813     CreateMockRead(*host1_resp, 2),
11814     CreateMockRead(*host1_resp_body, 3),
11815     MockRead(ASYNC, ERR_IO_PENDING, 4),
11816   };
11817
11818   scoped_ptr<OrderedSocketData> spdy1_data(
11819       new OrderedSocketData(
11820           spdy1_reads, arraysize(spdy1_reads),
11821           spdy1_writes, arraysize(spdy1_writes)));
11822   session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11823
11824   scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
11825       "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11826   MockWrite spdy2_writes[] = {
11827     CreateMockWrite(*host2_req, 1),
11828   };
11829   scoped_ptr<SpdyFrame> host2_resp(
11830       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11831   scoped_ptr<SpdyFrame> host2_resp_body(
11832       spdy_util_.ConstructSpdyBodyFrame(1, true));
11833   MockRead spdy2_reads[] = {
11834     CreateMockRead(*host2_resp, 2),
11835     CreateMockRead(*host2_resp_body, 3),
11836     MockRead(ASYNC, ERR_IO_PENDING, 4),
11837   };
11838
11839   scoped_ptr<OrderedSocketData> spdy2_data(
11840       new OrderedSocketData(
11841           spdy2_reads, arraysize(spdy2_reads),
11842           spdy2_writes, arraysize(spdy2_writes)));
11843   session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11844
11845   MockWrite http_write[] = {
11846     MockWrite("GET / HTTP/1.1\r\n"
11847               "Host: www.a.com\r\n"
11848               "Connection: keep-alive\r\n\r\n"),
11849   };
11850
11851   MockRead http_read[] = {
11852     MockRead("HTTP/1.1 200 OK\r\n"),
11853     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11854     MockRead("Content-Length: 6\r\n\r\n"),
11855     MockRead("hello!"),
11856   };
11857   StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11858                                      http_write, arraysize(http_write));
11859   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11860
11861   HostPortPair host_port_pair_a("www.a.com", 443);
11862   SpdySessionKey spdy_session_key_a(
11863       host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11864   EXPECT_FALSE(
11865       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11866
11867   TestCompletionCallback callback;
11868   HttpRequestInfo request1;
11869   request1.method = "GET";
11870   request1.url = GURL("https://www.a.com/");
11871   request1.load_flags = 0;
11872   scoped_ptr<HttpNetworkTransaction> trans(
11873       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11874
11875   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11876   EXPECT_EQ(ERR_IO_PENDING, rv);
11877   EXPECT_EQ(OK, callback.WaitForResult());
11878
11879   const HttpResponseInfo* response = trans->GetResponseInfo();
11880   ASSERT_TRUE(response != NULL);
11881   ASSERT_TRUE(response->headers.get() != NULL);
11882   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11883   EXPECT_TRUE(response->was_fetched_via_spdy);
11884   EXPECT_TRUE(response->was_npn_negotiated);
11885
11886   std::string response_data;
11887   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11888   EXPECT_EQ("hello!", response_data);
11889   trans.reset();
11890   EXPECT_TRUE(
11891       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11892
11893   HostPortPair host_port_pair_b("www.b.com", 443);
11894   SpdySessionKey spdy_session_key_b(
11895       host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11896   EXPECT_FALSE(
11897       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11898   HttpRequestInfo request2;
11899   request2.method = "GET";
11900   request2.url = GURL("https://www.b.com/");
11901   request2.load_flags = 0;
11902   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11903
11904   rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11905   EXPECT_EQ(ERR_IO_PENDING, rv);
11906   EXPECT_EQ(OK, callback.WaitForResult());
11907
11908   response = trans->GetResponseInfo();
11909   ASSERT_TRUE(response != NULL);
11910   ASSERT_TRUE(response->headers.get() != NULL);
11911   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11912   EXPECT_TRUE(response->was_fetched_via_spdy);
11913   EXPECT_TRUE(response->was_npn_negotiated);
11914   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11915   EXPECT_EQ("hello!", response_data);
11916   EXPECT_FALSE(
11917       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11918   EXPECT_TRUE(
11919       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11920
11921   HostPortPair host_port_pair_a1("www.a.com", 80);
11922   SpdySessionKey spdy_session_key_a1(
11923       host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11924   EXPECT_FALSE(
11925       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
11926   HttpRequestInfo request3;
11927   request3.method = "GET";
11928   request3.url = GURL("http://www.a.com/");
11929   request3.load_flags = 0;
11930   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11931
11932   rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11933   EXPECT_EQ(ERR_IO_PENDING, rv);
11934   EXPECT_EQ(OK, callback.WaitForResult());
11935
11936   response = trans->GetResponseInfo();
11937   ASSERT_TRUE(response != NULL);
11938   ASSERT_TRUE(response->headers.get() != NULL);
11939   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11940   EXPECT_FALSE(response->was_fetched_via_spdy);
11941   EXPECT_FALSE(response->was_npn_negotiated);
11942   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11943   EXPECT_EQ("hello!", response_data);
11944   EXPECT_FALSE(
11945       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11946   EXPECT_FALSE(
11947       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11948 }
11949
11950 TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11951   HttpRequestInfo request;
11952   request.method = "GET";
11953   request.url = GURL("http://www.google.com/");
11954   request.load_flags = 0;
11955
11956   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11957   scoped_ptr<HttpTransaction> trans(
11958       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11959
11960   MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11961   StaticSocketDataProvider data;
11962   data.set_connect_data(mock_connect);
11963   session_deps_.socket_factory->AddSocketDataProvider(&data);
11964
11965   TestCompletionCallback callback;
11966
11967   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11968   EXPECT_EQ(ERR_IO_PENDING, rv);
11969
11970   rv = callback.WaitForResult();
11971   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11972
11973   EXPECT_EQ(NULL, trans->GetResponseInfo());
11974
11975   // We don't care whether this succeeds or fails, but it shouldn't crash.
11976   HttpRequestHeaders request_headers;
11977   trans->GetFullRequestHeaders(&request_headers);
11978 }
11979
11980 TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11981   HttpRequestInfo request;
11982   request.method = "GET";
11983   request.url = GURL("http://www.google.com/");
11984   request.load_flags = 0;
11985
11986   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11987   scoped_ptr<HttpTransaction> trans(
11988       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11989
11990   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11991   StaticSocketDataProvider data;
11992   data.set_connect_data(mock_connect);
11993   session_deps_.socket_factory->AddSocketDataProvider(&data);
11994
11995   TestCompletionCallback callback;
11996
11997   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11998   EXPECT_EQ(ERR_IO_PENDING, rv);
11999
12000   rv = callback.WaitForResult();
12001   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12002
12003   EXPECT_EQ(NULL, trans->GetResponseInfo());
12004
12005   // We don't care whether this succeeds or fails, but it shouldn't crash.
12006   HttpRequestHeaders request_headers;
12007   trans->GetFullRequestHeaders(&request_headers);
12008 }
12009
12010 TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12011   HttpRequestInfo request;
12012   request.method = "GET";
12013   request.url = GURL("http://www.google.com/");
12014   request.load_flags = 0;
12015
12016   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12017   scoped_ptr<HttpTransaction> trans(
12018       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12019
12020   MockWrite data_writes[] = {
12021     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12022   };
12023   MockRead data_reads[] = {
12024     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
12025   };
12026
12027   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12028                                 data_writes, arraysize(data_writes));
12029   session_deps_.socket_factory->AddSocketDataProvider(&data);
12030
12031   TestCompletionCallback callback;
12032
12033   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12034   EXPECT_EQ(ERR_IO_PENDING, rv);
12035
12036   rv = callback.WaitForResult();
12037   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12038
12039   EXPECT_EQ(NULL, trans->GetResponseInfo());
12040
12041   HttpRequestHeaders request_headers;
12042   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12043   EXPECT_TRUE(request_headers.HasHeader("Host"));
12044 }
12045
12046 TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12047   HttpRequestInfo request;
12048   request.method = "GET";
12049   request.url = GURL("http://www.google.com/");
12050   request.load_flags = 0;
12051
12052   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12053   scoped_ptr<HttpTransaction> trans(
12054       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12055
12056   MockWrite data_writes[] = {
12057     MockWrite(ASYNC, ERR_CONNECTION_RESET),
12058   };
12059   MockRead data_reads[] = {
12060     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
12061   };
12062
12063   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12064                                 data_writes, arraysize(data_writes));
12065   session_deps_.socket_factory->AddSocketDataProvider(&data);
12066
12067   TestCompletionCallback callback;
12068
12069   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12070   EXPECT_EQ(ERR_IO_PENDING, rv);
12071
12072   rv = callback.WaitForResult();
12073   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12074
12075   EXPECT_EQ(NULL, trans->GetResponseInfo());
12076
12077   HttpRequestHeaders request_headers;
12078   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12079   EXPECT_TRUE(request_headers.HasHeader("Host"));
12080 }
12081
12082 TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12083   HttpRequestInfo request;
12084   request.method = "GET";
12085   request.url = GURL("http://www.google.com/");
12086   request.load_flags = 0;
12087
12088   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12089   scoped_ptr<HttpTransaction> trans(
12090       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12091
12092   MockWrite data_writes[] = {
12093     MockWrite("GET / HTTP/1.1\r\n"
12094               "Host: www.google.com\r\n"
12095               "Connection: keep-alive\r\n\r\n"),
12096   };
12097   MockRead data_reads[] = {
12098     MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12099   };
12100
12101   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12102                                 data_writes, arraysize(data_writes));
12103   session_deps_.socket_factory->AddSocketDataProvider(&data);
12104
12105   TestCompletionCallback callback;
12106
12107   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12108   EXPECT_EQ(ERR_IO_PENDING, rv);
12109
12110   rv = callback.WaitForResult();
12111   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12112
12113   EXPECT_EQ(NULL, trans->GetResponseInfo());
12114
12115   HttpRequestHeaders request_headers;
12116   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12117   EXPECT_TRUE(request_headers.HasHeader("Host"));
12118 }
12119
12120 TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12121   HttpRequestInfo request;
12122   request.method = "GET";
12123   request.url = GURL("http://www.google.com/");
12124   request.load_flags = 0;
12125
12126   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12127   scoped_ptr<HttpTransaction> trans(
12128       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12129
12130   MockWrite data_writes[] = {
12131     MockWrite("GET / HTTP/1.1\r\n"
12132               "Host: www.google.com\r\n"
12133               "Connection: keep-alive\r\n\r\n"),
12134   };
12135   MockRead data_reads[] = {
12136     MockRead(ASYNC, ERR_CONNECTION_RESET),
12137   };
12138
12139   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12140                                 data_writes, arraysize(data_writes));
12141   session_deps_.socket_factory->AddSocketDataProvider(&data);
12142
12143   TestCompletionCallback callback;
12144
12145   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12146   EXPECT_EQ(ERR_IO_PENDING, rv);
12147
12148   rv = callback.WaitForResult();
12149   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12150
12151   EXPECT_EQ(NULL, trans->GetResponseInfo());
12152
12153   HttpRequestHeaders request_headers;
12154   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12155   EXPECT_TRUE(request_headers.HasHeader("Host"));
12156 }
12157
12158 TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12159   HttpRequestInfo request;
12160   request.method = "GET";
12161   request.url = GURL("http://www.google.com/");
12162   request.load_flags = 0;
12163   request.extra_headers.SetHeader("X-Foo", "bar");
12164
12165   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12166   scoped_ptr<HttpTransaction> trans(
12167       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12168
12169   MockWrite data_writes[] = {
12170     MockWrite("GET / HTTP/1.1\r\n"
12171               "Host: www.google.com\r\n"
12172               "Connection: keep-alive\r\n"
12173               "X-Foo: bar\r\n\r\n"),
12174   };
12175   MockRead data_reads[] = {
12176     MockRead("HTTP/1.1 200 OK\r\n"
12177              "Content-Length: 5\r\n\r\n"
12178              "hello"),
12179     MockRead(ASYNC, ERR_UNEXPECTED),
12180   };
12181
12182   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12183                                 data_writes, arraysize(data_writes));
12184   session_deps_.socket_factory->AddSocketDataProvider(&data);
12185
12186   TestCompletionCallback callback;
12187
12188   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12189   EXPECT_EQ(ERR_IO_PENDING, rv);
12190
12191   rv = callback.WaitForResult();
12192   EXPECT_EQ(OK, rv);
12193
12194   HttpRequestHeaders request_headers;
12195   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12196   std::string foo;
12197   EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12198   EXPECT_EQ("bar", foo);
12199 }
12200
12201 namespace {
12202
12203 // Fake HttpStreamBase that simply records calls to SetPriority().
12204 class FakeStream : public HttpStreamBase,
12205                    public base::SupportsWeakPtr<FakeStream> {
12206  public:
12207   explicit FakeStream(RequestPriority priority) : priority_(priority) {}
12208   virtual ~FakeStream() {}
12209
12210   RequestPriority priority() const { return priority_; }
12211
12212   virtual int InitializeStream(const HttpRequestInfo* request_info,
12213                                RequestPriority priority,
12214                                const BoundNetLog& net_log,
12215                                const CompletionCallback& callback) OVERRIDE {
12216     return ERR_IO_PENDING;
12217   }
12218
12219   virtual int SendRequest(const HttpRequestHeaders& request_headers,
12220                           HttpResponseInfo* response,
12221                           const CompletionCallback& callback) OVERRIDE {
12222     ADD_FAILURE();
12223     return ERR_UNEXPECTED;
12224   }
12225
12226   virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
12227     ADD_FAILURE();
12228     return ERR_UNEXPECTED;
12229   }
12230
12231   virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
12232                                const CompletionCallback& callback) OVERRIDE {
12233     ADD_FAILURE();
12234     return ERR_UNEXPECTED;
12235   }
12236
12237   virtual void Close(bool not_reusable) OVERRIDE {}
12238
12239   virtual bool IsResponseBodyComplete() const OVERRIDE {
12240     ADD_FAILURE();
12241     return false;
12242   }
12243
12244   virtual bool CanFindEndOfResponse() const OVERRIDE {
12245     return false;
12246   }
12247
12248   virtual bool IsConnectionReused() const OVERRIDE {
12249     ADD_FAILURE();
12250     return false;
12251   }
12252
12253   virtual void SetConnectionReused() OVERRIDE {
12254     ADD_FAILURE();
12255   }
12256
12257   virtual bool IsConnectionReusable() const OVERRIDE {
12258     ADD_FAILURE();
12259     return false;
12260   }
12261
12262   virtual int64 GetTotalReceivedBytes() const OVERRIDE {
12263     ADD_FAILURE();
12264     return 0;
12265   }
12266
12267   virtual bool GetLoadTimingInfo(
12268       LoadTimingInfo* load_timing_info) const OVERRIDE {
12269     ADD_FAILURE();
12270     return false;
12271   }
12272
12273   virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
12274     ADD_FAILURE();
12275   }
12276
12277   virtual void GetSSLCertRequestInfo(
12278       SSLCertRequestInfo* cert_request_info) OVERRIDE {
12279     ADD_FAILURE();
12280   }
12281
12282   virtual bool IsSpdyHttpStream() const OVERRIDE {
12283     ADD_FAILURE();
12284     return false;
12285   }
12286
12287   virtual void Drain(HttpNetworkSession* session) OVERRIDE {
12288     ADD_FAILURE();
12289   }
12290
12291   virtual void SetPriority(RequestPriority priority) OVERRIDE {
12292     priority_ = priority;
12293   }
12294
12295  private:
12296   RequestPriority priority_;
12297
12298   DISALLOW_COPY_AND_ASSIGN(FakeStream);
12299 };
12300
12301 // Fake HttpStreamRequest that simply records calls to SetPriority()
12302 // and vends FakeStreams with its current priority.
12303 class FakeStreamRequest : public HttpStreamRequest,
12304                           public base::SupportsWeakPtr<FakeStreamRequest> {
12305  public:
12306   FakeStreamRequest(RequestPriority priority,
12307                     HttpStreamRequest::Delegate* delegate)
12308       : priority_(priority),
12309         delegate_(delegate),
12310         websocket_stream_create_helper_(NULL) {}
12311
12312   FakeStreamRequest(RequestPriority priority,
12313                     HttpStreamRequest::Delegate* delegate,
12314                     WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12315       : priority_(priority),
12316         delegate_(delegate),
12317         websocket_stream_create_helper_(create_helper) {}
12318
12319   virtual ~FakeStreamRequest() {}
12320
12321   RequestPriority priority() const { return priority_; }
12322
12323   const WebSocketHandshakeStreamBase::CreateHelper*
12324   websocket_stream_create_helper() const {
12325     return websocket_stream_create_helper_;
12326   }
12327
12328   // Create a new FakeStream and pass it to the request's
12329   // delegate. Returns a weak pointer to the FakeStream.
12330   base::WeakPtr<FakeStream> FinishStreamRequest() {
12331     FakeStream* fake_stream = new FakeStream(priority_);
12332     // Do this before calling OnStreamReady() as OnStreamReady() may
12333     // immediately delete |fake_stream|.
12334     base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12335     delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12336     return weak_stream;
12337   }
12338
12339   virtual int RestartTunnelWithProxyAuth(
12340       const AuthCredentials& credentials) OVERRIDE {
12341     ADD_FAILURE();
12342     return ERR_UNEXPECTED;
12343   }
12344
12345   virtual LoadState GetLoadState() const OVERRIDE {
12346     ADD_FAILURE();
12347     return LoadState();
12348   }
12349
12350   virtual void SetPriority(RequestPriority priority) OVERRIDE {
12351     priority_ = priority;
12352   }
12353
12354   virtual bool was_npn_negotiated() const OVERRIDE {
12355     return false;
12356   }
12357
12358   virtual NextProto protocol_negotiated() const OVERRIDE {
12359     return kProtoUnknown;
12360   }
12361
12362   virtual bool using_spdy() const OVERRIDE {
12363     return false;
12364   }
12365
12366  private:
12367   RequestPriority priority_;
12368   HttpStreamRequest::Delegate* const delegate_;
12369   WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
12370
12371   DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12372 };
12373
12374 // Fake HttpStreamFactory that vends FakeStreamRequests.
12375 class FakeStreamFactory : public HttpStreamFactory {
12376  public:
12377   FakeStreamFactory() {}
12378   virtual ~FakeStreamFactory() {}
12379
12380   // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12381   // RequestStream() (which may be NULL if it was destroyed already).
12382   base::WeakPtr<FakeStreamRequest> last_stream_request() {
12383     return last_stream_request_;
12384   }
12385
12386   virtual HttpStreamRequest* RequestStream(
12387       const HttpRequestInfo& info,
12388       RequestPriority priority,
12389       const SSLConfig& server_ssl_config,
12390       const SSLConfig& proxy_ssl_config,
12391       HttpStreamRequest::Delegate* delegate,
12392       const BoundNetLog& net_log) OVERRIDE {
12393     FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
12394     last_stream_request_ = fake_request->AsWeakPtr();
12395     return fake_request;
12396   }
12397
12398   virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
12399       const HttpRequestInfo& info,
12400       RequestPriority priority,
12401       const SSLConfig& server_ssl_config,
12402       const SSLConfig& proxy_ssl_config,
12403       HttpStreamRequest::Delegate* delegate,
12404       WebSocketHandshakeStreamBase::CreateHelper* create_helper,
12405       const BoundNetLog& net_log) OVERRIDE {
12406     FakeStreamRequest* fake_request =
12407         new FakeStreamRequest(priority, delegate, create_helper);
12408     last_stream_request_ = fake_request->AsWeakPtr();
12409     return fake_request;
12410   }
12411
12412   virtual void PreconnectStreams(int num_streams,
12413                                  const HttpRequestInfo& info,
12414                                  RequestPriority priority,
12415                                  const SSLConfig& server_ssl_config,
12416                                  const SSLConfig& proxy_ssl_config) OVERRIDE {
12417     ADD_FAILURE();
12418   }
12419
12420   virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
12421     ADD_FAILURE();
12422     return NULL;
12423   }
12424
12425  private:
12426   base::WeakPtr<FakeStreamRequest> last_stream_request_;
12427
12428   DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12429 };
12430
12431 // TODO(yhirano): Split this class out into a net/websockets file, if it is
12432 // worth doing.
12433 class FakeWebSocketStreamCreateHelper :
12434       public WebSocketHandshakeStreamBase::CreateHelper {
12435  public:
12436   virtual WebSocketHandshakeStreamBase* CreateBasicStream(
12437       scoped_ptr<ClientSocketHandle> connection,
12438       bool using_proxy) OVERRIDE {
12439     NOTREACHED();
12440     return NULL;
12441   }
12442
12443   virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12444       const base::WeakPtr<SpdySession>& session,
12445       bool use_relative_url) OVERRIDE {
12446     NOTREACHED();
12447     return NULL;
12448   };
12449
12450   virtual ~FakeWebSocketStreamCreateHelper() {}
12451
12452   virtual scoped_ptr<WebSocketStream> Upgrade() {
12453     NOTREACHED();
12454     return scoped_ptr<WebSocketStream>();
12455   }
12456 };
12457
12458 }  // namespace
12459
12460 // Make sure that HttpNetworkTransaction passes on its priority to its
12461 // stream request on start.
12462 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12463   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12464   HttpNetworkSessionPeer peer(session);
12465   FakeStreamFactory* fake_factory = new FakeStreamFactory();
12466   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
12467
12468   HttpNetworkTransaction trans(LOW, session);
12469
12470   ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12471
12472   HttpRequestInfo request;
12473   TestCompletionCallback callback;
12474   EXPECT_EQ(ERR_IO_PENDING,
12475             trans.Start(&request, callback.callback(), BoundNetLog()));
12476
12477   base::WeakPtr<FakeStreamRequest> fake_request =
12478       fake_factory->last_stream_request();
12479   ASSERT_TRUE(fake_request != NULL);
12480   EXPECT_EQ(LOW, fake_request->priority());
12481 }
12482
12483 // Make sure that HttpNetworkTransaction passes on its priority
12484 // updates to its stream request.
12485 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12486   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12487   HttpNetworkSessionPeer peer(session);
12488   FakeStreamFactory* fake_factory = new FakeStreamFactory();
12489   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
12490
12491   HttpNetworkTransaction trans(LOW, session);
12492
12493   HttpRequestInfo request;
12494   TestCompletionCallback callback;
12495   EXPECT_EQ(ERR_IO_PENDING,
12496             trans.Start(&request, callback.callback(), BoundNetLog()));
12497
12498   base::WeakPtr<FakeStreamRequest> fake_request =
12499       fake_factory->last_stream_request();
12500   ASSERT_TRUE(fake_request != NULL);
12501   EXPECT_EQ(LOW, fake_request->priority());
12502
12503   trans.SetPriority(LOWEST);
12504   ASSERT_TRUE(fake_request != NULL);
12505   EXPECT_EQ(LOWEST, fake_request->priority());
12506 }
12507
12508 // Make sure that HttpNetworkTransaction passes on its priority
12509 // updates to its stream.
12510 TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12511   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12512   HttpNetworkSessionPeer peer(session);
12513   FakeStreamFactory* fake_factory = new FakeStreamFactory();
12514   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
12515
12516   HttpNetworkTransaction trans(LOW, session);
12517
12518   HttpRequestInfo request;
12519   TestCompletionCallback callback;
12520   EXPECT_EQ(ERR_IO_PENDING,
12521             trans.Start(&request, callback.callback(), BoundNetLog()));
12522
12523   base::WeakPtr<FakeStreamRequest> fake_request =
12524       fake_factory->last_stream_request();
12525   ASSERT_TRUE(fake_request != NULL);
12526   base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12527   ASSERT_TRUE(fake_stream != NULL);
12528   EXPECT_EQ(LOW, fake_stream->priority());
12529
12530   trans.SetPriority(LOWEST);
12531   EXPECT_EQ(LOWEST, fake_stream->priority());
12532 }
12533
12534 TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12535   // The same logic needs to be tested for both ws: and wss: schemes, but this
12536   // test is already parameterised on NextProto, so it uses a loop to verify
12537   // that the different schemes work.
12538   std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12539   for (size_t i = 0; i < arraysize(test_cases); ++i) {
12540     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12541     HttpNetworkSessionPeer peer(session);
12542     FakeStreamFactory* fake_factory = new FakeStreamFactory();
12543     FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
12544     peer.SetHttpStreamFactoryForWebSocket(
12545         scoped_ptr<HttpStreamFactory>(fake_factory));
12546
12547     HttpNetworkTransaction trans(LOW, session);
12548     trans.SetWebSocketHandshakeStreamCreateHelper(
12549         &websocket_stream_create_helper);
12550
12551     HttpRequestInfo request;
12552     TestCompletionCallback callback;
12553     request.method = "GET";
12554     request.url = GURL(test_cases[i]);
12555
12556     EXPECT_EQ(ERR_IO_PENDING,
12557               trans.Start(&request, callback.callback(), BoundNetLog()));
12558
12559     base::WeakPtr<FakeStreamRequest> fake_request =
12560         fake_factory->last_stream_request();
12561     ASSERT_TRUE(fake_request != NULL);
12562     EXPECT_EQ(&websocket_stream_create_helper,
12563               fake_request->websocket_stream_create_helper());
12564   }
12565 }
12566
12567 // Tests that when a used socket is returned to the SSL socket pool, it's closed
12568 // if the transport socket pool is stalled on the global socket limit.
12569 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12570   ClientSocketPoolManager::set_max_sockets_per_group(
12571       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12572   ClientSocketPoolManager::set_max_sockets_per_pool(
12573       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12574
12575   // Set up SSL request.
12576
12577   HttpRequestInfo ssl_request;
12578   ssl_request.method = "GET";
12579   ssl_request.url = GURL("https://www.google.com/");
12580
12581   MockWrite ssl_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 ssl_reads[] = {
12587     MockRead("HTTP/1.1 200 OK\r\n"),
12588     MockRead("Content-Length: 11\r\n\r\n"),
12589     MockRead("hello world"),
12590     MockRead(SYNCHRONOUS, OK),
12591   };
12592   StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12593                                     ssl_writes, arraysize(ssl_writes));
12594   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12595
12596   SSLSocketDataProvider ssl(ASYNC, OK);
12597   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12598
12599   // Set up HTTP request.
12600
12601   HttpRequestInfo http_request;
12602   http_request.method = "GET";
12603   http_request.url = GURL("http://www.google.com/");
12604
12605   MockWrite http_writes[] = {
12606     MockWrite("GET / HTTP/1.1\r\n"
12607               "Host: www.google.com\r\n"
12608               "Connection: keep-alive\r\n\r\n"),
12609   };
12610   MockRead http_reads[] = {
12611     MockRead("HTTP/1.1 200 OK\r\n"),
12612     MockRead("Content-Length: 7\r\n\r\n"),
12613     MockRead("falafel"),
12614     MockRead(SYNCHRONOUS, OK),
12615   };
12616   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12617                                      http_writes, arraysize(http_writes));
12618   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12619
12620   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12621
12622   // Start the SSL request.
12623   TestCompletionCallback ssl_callback;
12624   scoped_ptr<HttpTransaction> ssl_trans(
12625       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12626   ASSERT_EQ(ERR_IO_PENDING,
12627             ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12628             BoundNetLog()));
12629
12630   // Start the HTTP request.  Pool should stall.
12631   TestCompletionCallback http_callback;
12632   scoped_ptr<HttpTransaction> http_trans(
12633       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12634   ASSERT_EQ(ERR_IO_PENDING,
12635             http_trans->Start(&http_request, http_callback.callback(),
12636                               BoundNetLog()));
12637   EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12638
12639   // Wait for response from SSL request.
12640   ASSERT_EQ(OK, ssl_callback.WaitForResult());
12641   std::string response_data;
12642   ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12643   EXPECT_EQ("hello world", response_data);
12644
12645   // The SSL socket should automatically be closed, so the HTTP request can
12646   // start.
12647   EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12648   ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12649
12650   // The HTTP request can now complete.
12651   ASSERT_EQ(OK, http_callback.WaitForResult());
12652   ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12653   EXPECT_EQ("falafel", response_data);
12654
12655   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12656 }
12657
12658 // Tests that when a SSL connection is established but there's no corresponding
12659 // request that needs it, the new socket is closed if the transport socket pool
12660 // is stalled on the global socket limit.
12661 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12662   ClientSocketPoolManager::set_max_sockets_per_group(
12663       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12664   ClientSocketPoolManager::set_max_sockets_per_pool(
12665       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12666
12667   // Set up an ssl request.
12668
12669   HttpRequestInfo ssl_request;
12670   ssl_request.method = "GET";
12671   ssl_request.url = GURL("https://www.foopy.com/");
12672
12673   // No data will be sent on the SSL socket.
12674   StaticSocketDataProvider ssl_data;
12675   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12676
12677   SSLSocketDataProvider ssl(ASYNC, OK);
12678   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12679
12680   // Set up HTTP request.
12681
12682   HttpRequestInfo http_request;
12683   http_request.method = "GET";
12684   http_request.url = GURL("http://www.google.com/");
12685
12686   MockWrite http_writes[] = {
12687     MockWrite("GET / HTTP/1.1\r\n"
12688               "Host: www.google.com\r\n"
12689               "Connection: keep-alive\r\n\r\n"),
12690   };
12691   MockRead http_reads[] = {
12692     MockRead("HTTP/1.1 200 OK\r\n"),
12693     MockRead("Content-Length: 7\r\n\r\n"),
12694     MockRead("falafel"),
12695     MockRead(SYNCHRONOUS, OK),
12696   };
12697   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12698                                      http_writes, arraysize(http_writes));
12699   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12700
12701   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12702
12703   // Preconnect an SSL socket.  A preconnect is needed because connect jobs are
12704   // cancelled when a normal transaction is cancelled.
12705   net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12706   net::SSLConfig ssl_config;
12707   session->ssl_config_service()->GetSSLConfig(&ssl_config);
12708   http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12709                                          ssl_config, ssl_config);
12710   EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12711
12712   // Start the HTTP request.  Pool should stall.
12713   TestCompletionCallback http_callback;
12714   scoped_ptr<HttpTransaction> http_trans(
12715       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12716   ASSERT_EQ(ERR_IO_PENDING,
12717             http_trans->Start(&http_request, http_callback.callback(),
12718                               BoundNetLog()));
12719   EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12720
12721   // The SSL connection will automatically be closed once the connection is
12722   // established, to let the HTTP request start.
12723   ASSERT_EQ(OK, http_callback.WaitForResult());
12724   std::string response_data;
12725   ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12726   EXPECT_EQ("falafel", response_data);
12727
12728   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12729 }
12730
12731 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
12732   ScopedVector<UploadElementReader> element_readers;
12733   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12734   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12735
12736   HttpRequestInfo request;
12737   request.method = "POST";
12738   request.url = GURL("http://www.foo.com/");
12739   request.upload_data_stream = &upload_data_stream;
12740   request.load_flags = 0;
12741
12742   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12743   scoped_ptr<HttpTransaction> trans(
12744       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12745   // Send headers successfully, but get an error while sending the body.
12746   MockWrite data_writes[] = {
12747     MockWrite("POST / HTTP/1.1\r\n"
12748               "Host: www.foo.com\r\n"
12749               "Connection: keep-alive\r\n"
12750               "Content-Length: 3\r\n\r\n"),
12751     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12752   };
12753
12754   MockRead data_reads[] = {
12755     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12756     MockRead("hello world"),
12757     MockRead(SYNCHRONOUS, OK),
12758   };
12759   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12760                                 arraysize(data_writes));
12761   session_deps_.socket_factory->AddSocketDataProvider(&data);
12762
12763   TestCompletionCallback callback;
12764
12765   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12766   EXPECT_EQ(ERR_IO_PENDING, rv);
12767
12768   rv = callback.WaitForResult();
12769   EXPECT_EQ(OK, rv);
12770
12771   const HttpResponseInfo* response = trans->GetResponseInfo();
12772   ASSERT_TRUE(response != NULL);
12773
12774   EXPECT_TRUE(response->headers.get() != NULL);
12775   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12776
12777   std::string response_data;
12778   rv = ReadTransaction(trans.get(), &response_data);
12779   EXPECT_EQ(OK, rv);
12780   EXPECT_EQ("hello world", response_data);
12781 }
12782
12783 // This test makes sure the retry logic doesn't trigger when reading an error
12784 // response from a server that rejected a POST with a CONNECTION_RESET.
12785 TEST_P(HttpNetworkTransactionTest,
12786        PostReadsErrorResponseAfterResetOnReusedSocket) {
12787   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12788   MockWrite data_writes[] = {
12789     MockWrite("GET / HTTP/1.1\r\n"
12790               "Host: www.foo.com\r\n"
12791               "Connection: keep-alive\r\n\r\n"),
12792     MockWrite("POST / HTTP/1.1\r\n"
12793               "Host: www.foo.com\r\n"
12794               "Connection: keep-alive\r\n"
12795               "Content-Length: 3\r\n\r\n"),
12796     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12797   };
12798
12799   MockRead data_reads[] = {
12800     MockRead("HTTP/1.1 200 Peachy\r\n"
12801              "Content-Length: 14\r\n\r\n"),
12802     MockRead("first response"),
12803     MockRead("HTTP/1.1 400 Not OK\r\n"
12804              "Content-Length: 15\r\n\r\n"),
12805     MockRead("second response"),
12806     MockRead(SYNCHRONOUS, OK),
12807   };
12808   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12809                                 arraysize(data_writes));
12810   session_deps_.socket_factory->AddSocketDataProvider(&data);
12811
12812   TestCompletionCallback callback;
12813   HttpRequestInfo request1;
12814   request1.method = "GET";
12815   request1.url = GURL("http://www.foo.com/");
12816   request1.load_flags = 0;
12817
12818   scoped_ptr<HttpTransaction> trans1(
12819       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12820   int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
12821   EXPECT_EQ(ERR_IO_PENDING, rv);
12822
12823   rv = callback.WaitForResult();
12824   EXPECT_EQ(OK, rv);
12825
12826   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12827   ASSERT_TRUE(response1 != NULL);
12828
12829   EXPECT_TRUE(response1->headers.get() != NULL);
12830   EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
12831
12832   std::string response_data1;
12833   rv = ReadTransaction(trans1.get(), &response_data1);
12834   EXPECT_EQ(OK, rv);
12835   EXPECT_EQ("first response", response_data1);
12836   // Delete the transaction to release the socket back into the socket pool.
12837   trans1.reset();
12838
12839   ScopedVector<UploadElementReader> element_readers;
12840   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12841   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12842
12843   HttpRequestInfo request2;
12844   request2.method = "POST";
12845   request2.url = GURL("http://www.foo.com/");
12846   request2.upload_data_stream = &upload_data_stream;
12847   request2.load_flags = 0;
12848
12849   scoped_ptr<HttpTransaction> trans2(
12850       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12851   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
12852   EXPECT_EQ(ERR_IO_PENDING, rv);
12853
12854   rv = callback.WaitForResult();
12855   EXPECT_EQ(OK, rv);
12856
12857   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
12858   ASSERT_TRUE(response2 != NULL);
12859
12860   EXPECT_TRUE(response2->headers.get() != NULL);
12861   EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
12862
12863   std::string response_data2;
12864   rv = ReadTransaction(trans2.get(), &response_data2);
12865   EXPECT_EQ(OK, rv);
12866   EXPECT_EQ("second response", response_data2);
12867 }
12868
12869 TEST_P(HttpNetworkTransactionTest,
12870        PostReadsErrorResponseAfterResetPartialBodySent) {
12871   ScopedVector<UploadElementReader> element_readers;
12872   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12873   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12874
12875   HttpRequestInfo request;
12876   request.method = "POST";
12877   request.url = GURL("http://www.foo.com/");
12878   request.upload_data_stream = &upload_data_stream;
12879   request.load_flags = 0;
12880
12881   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12882   scoped_ptr<HttpTransaction> trans(
12883       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12884   // Send headers successfully, but get an error while sending the body.
12885   MockWrite data_writes[] = {
12886     MockWrite("POST / HTTP/1.1\r\n"
12887               "Host: www.foo.com\r\n"
12888               "Connection: keep-alive\r\n"
12889               "Content-Length: 3\r\n\r\n"
12890               "fo"),
12891     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12892   };
12893
12894   MockRead data_reads[] = {
12895     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12896     MockRead("hello world"),
12897     MockRead(SYNCHRONOUS, OK),
12898   };
12899   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12900                                 arraysize(data_writes));
12901   session_deps_.socket_factory->AddSocketDataProvider(&data);
12902
12903   TestCompletionCallback callback;
12904
12905   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12906   EXPECT_EQ(ERR_IO_PENDING, rv);
12907
12908   rv = callback.WaitForResult();
12909   EXPECT_EQ(OK, rv);
12910
12911   const HttpResponseInfo* response = trans->GetResponseInfo();
12912   ASSERT_TRUE(response != NULL);
12913
12914   EXPECT_TRUE(response->headers.get() != NULL);
12915   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12916
12917   std::string response_data;
12918   rv = ReadTransaction(trans.get(), &response_data);
12919   EXPECT_EQ(OK, rv);
12920   EXPECT_EQ("hello world", response_data);
12921 }
12922
12923 // This tests the more common case than the previous test, where headers and
12924 // body are not merged into a single request.
12925 TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
12926   ScopedVector<UploadElementReader> element_readers;
12927   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12928   UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
12929
12930   HttpRequestInfo request;
12931   request.method = "POST";
12932   request.url = GURL("http://www.foo.com/");
12933   request.upload_data_stream = &upload_data_stream;
12934   request.load_flags = 0;
12935
12936   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12937   scoped_ptr<HttpTransaction> trans(
12938       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12939   // Send headers successfully, but get an error while sending the body.
12940   MockWrite data_writes[] = {
12941     MockWrite("POST / HTTP/1.1\r\n"
12942               "Host: www.foo.com\r\n"
12943               "Connection: keep-alive\r\n"
12944               "Transfer-Encoding: chunked\r\n\r\n"),
12945     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12946   };
12947
12948   MockRead data_reads[] = {
12949     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12950     MockRead("hello world"),
12951     MockRead(SYNCHRONOUS, OK),
12952   };
12953   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12954                                 arraysize(data_writes));
12955   session_deps_.socket_factory->AddSocketDataProvider(&data);
12956
12957   TestCompletionCallback callback;
12958
12959   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12960   EXPECT_EQ(ERR_IO_PENDING, rv);
12961   // Make sure the headers are sent before adding a chunk.  This ensures that
12962   // they can't be merged with the body in a single send.  Not currently
12963   // necessary since a chunked body is never merged with headers, but this makes
12964   // the test more future proof.
12965   base::RunLoop().RunUntilIdle();
12966
12967   upload_data_stream.AppendChunk("last chunk", 10, true);
12968
12969   rv = callback.WaitForResult();
12970   EXPECT_EQ(OK, rv);
12971
12972   const HttpResponseInfo* response = trans->GetResponseInfo();
12973   ASSERT_TRUE(response != NULL);
12974
12975   EXPECT_TRUE(response->headers.get() != NULL);
12976   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12977
12978   std::string response_data;
12979   rv = ReadTransaction(trans.get(), &response_data);
12980   EXPECT_EQ(OK, rv);
12981   EXPECT_EQ("hello world", response_data);
12982 }
12983
12984 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
12985   ScopedVector<UploadElementReader> element_readers;
12986   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12987   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12988
12989   HttpRequestInfo request;
12990   request.method = "POST";
12991   request.url = GURL("http://www.foo.com/");
12992   request.upload_data_stream = &upload_data_stream;
12993   request.load_flags = 0;
12994
12995   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12996   scoped_ptr<HttpTransaction> trans(
12997       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12998
12999   MockWrite data_writes[] = {
13000     MockWrite("POST / HTTP/1.1\r\n"
13001               "Host: www.foo.com\r\n"
13002               "Connection: keep-alive\r\n"
13003               "Content-Length: 3\r\n\r\n"),
13004     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13005   };
13006
13007   MockRead data_reads[] = {
13008     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13009     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13010     MockRead("hello world"),
13011     MockRead(SYNCHRONOUS, OK),
13012   };
13013   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13014                                 arraysize(data_writes));
13015   session_deps_.socket_factory->AddSocketDataProvider(&data);
13016
13017   TestCompletionCallback callback;
13018
13019   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13020   EXPECT_EQ(ERR_IO_PENDING, rv);
13021
13022   rv = callback.WaitForResult();
13023   EXPECT_EQ(OK, rv);
13024
13025   const HttpResponseInfo* response = trans->GetResponseInfo();
13026   ASSERT_TRUE(response != NULL);
13027
13028   EXPECT_TRUE(response->headers.get() != NULL);
13029   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13030
13031   std::string response_data;
13032   rv = ReadTransaction(trans.get(), &response_data);
13033   EXPECT_EQ(OK, rv);
13034   EXPECT_EQ("hello world", response_data);
13035 }
13036
13037 TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13038   ScopedVector<UploadElementReader> element_readers;
13039   element_readers.push_back(new UploadBytesElementReader("foo", 3));
13040   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13041
13042   HttpRequestInfo request;
13043   request.method = "POST";
13044   request.url = GURL("http://www.foo.com/");
13045   request.upload_data_stream = &upload_data_stream;
13046   request.load_flags = 0;
13047
13048   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13049   scoped_ptr<HttpTransaction> trans(
13050       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13051   // Send headers successfully, but get an error while sending the body.
13052   MockWrite data_writes[] = {
13053     MockWrite("POST / HTTP/1.1\r\n"
13054               "Host: www.foo.com\r\n"
13055               "Connection: keep-alive\r\n"
13056               "Content-Length: 3\r\n\r\n"),
13057     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13058   };
13059
13060   MockRead data_reads[] = {
13061     MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13062     MockRead("hello world"),
13063     MockRead(SYNCHRONOUS, OK),
13064   };
13065   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13066                                 arraysize(data_writes));
13067   session_deps_.socket_factory->AddSocketDataProvider(&data);
13068
13069   TestCompletionCallback callback;
13070
13071   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13072   EXPECT_EQ(ERR_IO_PENDING, rv);
13073
13074   rv = callback.WaitForResult();
13075   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13076
13077   const HttpResponseInfo* response = trans->GetResponseInfo();
13078   EXPECT_TRUE(response == NULL);
13079 }
13080
13081 TEST_P(HttpNetworkTransactionTest,
13082        PostIgnoresNonErrorResponseAfterResetAnd100) {
13083   ScopedVector<UploadElementReader> element_readers;
13084   element_readers.push_back(new UploadBytesElementReader("foo", 3));
13085   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13086
13087   HttpRequestInfo request;
13088   request.method = "POST";
13089   request.url = GURL("http://www.foo.com/");
13090   request.upload_data_stream = &upload_data_stream;
13091   request.load_flags = 0;
13092
13093   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13094   scoped_ptr<HttpTransaction> trans(
13095       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13096   // Send headers successfully, but get an error while sending the body.
13097   MockWrite data_writes[] = {
13098     MockWrite("POST / HTTP/1.1\r\n"
13099               "Host: www.foo.com\r\n"
13100               "Connection: keep-alive\r\n"
13101               "Content-Length: 3\r\n\r\n"),
13102     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13103   };
13104
13105   MockRead data_reads[] = {
13106     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13107     MockRead("HTTP/1.0 302 Redirect\r\n"),
13108     MockRead("Location: http://somewhere-else.com/\r\n"),
13109     MockRead("Content-Length: 0\r\n\r\n"),
13110     MockRead(SYNCHRONOUS, OK),
13111   };
13112   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13113                                 arraysize(data_writes));
13114   session_deps_.socket_factory->AddSocketDataProvider(&data);
13115
13116   TestCompletionCallback callback;
13117
13118   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13119   EXPECT_EQ(ERR_IO_PENDING, rv);
13120
13121   rv = callback.WaitForResult();
13122   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13123
13124   const HttpResponseInfo* response = trans->GetResponseInfo();
13125   EXPECT_TRUE(response == NULL);
13126 }
13127
13128 TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13129   ScopedVector<UploadElementReader> element_readers;
13130   element_readers.push_back(new UploadBytesElementReader("foo", 3));
13131   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13132
13133   HttpRequestInfo request;
13134   request.method = "POST";
13135   request.url = GURL("http://www.foo.com/");
13136   request.upload_data_stream = &upload_data_stream;
13137   request.load_flags = 0;
13138
13139   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13140   scoped_ptr<HttpTransaction> trans(
13141       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13142   // Send headers successfully, but get an error while sending the body.
13143   MockWrite data_writes[] = {
13144     MockWrite("POST / HTTP/1.1\r\n"
13145               "Host: www.foo.com\r\n"
13146               "Connection: keep-alive\r\n"
13147               "Content-Length: 3\r\n\r\n"),
13148     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13149   };
13150
13151   MockRead data_reads[] = {
13152     MockRead("HTTP 0.9 rocks!"),
13153     MockRead(SYNCHRONOUS, OK),
13154   };
13155   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13156                                 arraysize(data_writes));
13157   session_deps_.socket_factory->AddSocketDataProvider(&data);
13158
13159   TestCompletionCallback callback;
13160
13161   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13162   EXPECT_EQ(ERR_IO_PENDING, rv);
13163
13164   rv = callback.WaitForResult();
13165   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13166
13167   const HttpResponseInfo* response = trans->GetResponseInfo();
13168   EXPECT_TRUE(response == NULL);
13169 }
13170
13171 TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13172   ScopedVector<UploadElementReader> element_readers;
13173   element_readers.push_back(new UploadBytesElementReader("foo", 3));
13174   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13175
13176   HttpRequestInfo request;
13177   request.method = "POST";
13178   request.url = GURL("http://www.foo.com/");
13179   request.upload_data_stream = &upload_data_stream;
13180   request.load_flags = 0;
13181
13182   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13183   scoped_ptr<HttpTransaction> trans(
13184       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13185   // Send headers successfully, but get an error while sending the body.
13186   MockWrite data_writes[] = {
13187     MockWrite("POST / HTTP/1.1\r\n"
13188               "Host: www.foo.com\r\n"
13189               "Connection: keep-alive\r\n"
13190               "Content-Length: 3\r\n\r\n"),
13191     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13192   };
13193
13194   MockRead data_reads[] = {
13195     MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13196     MockRead(SYNCHRONOUS, OK),
13197   };
13198   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13199                                 arraysize(data_writes));
13200   session_deps_.socket_factory->AddSocketDataProvider(&data);
13201
13202   TestCompletionCallback callback;
13203
13204   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13205   EXPECT_EQ(ERR_IO_PENDING, rv);
13206
13207   rv = callback.WaitForResult();
13208   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13209
13210   const HttpResponseInfo* response = trans->GetResponseInfo();
13211   EXPECT_TRUE(response == NULL);
13212 }
13213
13214 }  // namespace net