- add sources.
[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/strings/string_util.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "base/test/test_file_util.h"
22 #include "net/base/auth.h"
23 #include "net/base/capturing_net_log.h"
24 #include "net/base/completion_callback.h"
25 #include "net/base/load_timing_info.h"
26 #include "net/base/load_timing_info_test_util.h"
27 #include "net/base/net_log.h"
28 #include "net/base/net_log_unittest.h"
29 #include "net/base/request_priority.h"
30 #include "net/base/test_completion_callback.h"
31 #include "net/base/test_data_directory.h"
32 #include "net/base/upload_bytes_element_reader.h"
33 #include "net/base/upload_data_stream.h"
34 #include "net/base/upload_file_element_reader.h"
35 #include "net/cert/mock_cert_verifier.h"
36 #include "net/dns/host_cache.h"
37 #include "net/dns/mock_host_resolver.h"
38 #include "net/http/http_auth_handler_digest.h"
39 #include "net/http/http_auth_handler_mock.h"
40 #include "net/http/http_auth_handler_ntlm.h"
41 #include "net/http/http_basic_stream.h"
42 #include "net/http/http_network_session.h"
43 #include "net/http/http_network_session_peer.h"
44 #include "net/http/http_server_properties_impl.h"
45 #include "net/http/http_stream.h"
46 #include "net/http/http_stream_factory.h"
47 #include "net/http/http_transaction_unittest.h"
48 #include "net/proxy/proxy_config_service_fixed.h"
49 #include "net/proxy/proxy_info.h"
50 #include "net/proxy/proxy_resolver.h"
51 #include "net/proxy/proxy_service.h"
52 #include "net/socket/client_socket_factory.h"
53 #include "net/socket/client_socket_pool_manager.h"
54 #include "net/socket/mock_client_socket_pool_manager.h"
55 #include "net/socket/next_proto.h"
56 #include "net/socket/socket_test_util.h"
57 #include "net/socket/ssl_client_socket.h"
58 #include "net/spdy/spdy_framer.h"
59 #include "net/spdy/spdy_session.h"
60 #include "net/spdy/spdy_session_pool.h"
61 #include "net/spdy/spdy_test_util_common.h"
62 #include "net/ssl/ssl_cert_request_info.h"
63 #include "net/ssl/ssl_config_service.h"
64 #include "net/ssl/ssl_config_service_defaults.h"
65 #include "net/ssl/ssl_info.h"
66 #include "net/test/cert_test_util.h"
67 #include "testing/gtest/include/gtest/gtest.h"
68 #include "testing/platform_test.h"
69 #include "url/gurl.h"
70
71 //-----------------------------------------------------------------------------
72
73 namespace {
74
75 const base::string16 kBar(ASCIIToUTF16("bar"));
76 const base::string16 kBar2(ASCIIToUTF16("bar2"));
77 const base::string16 kBar3(ASCIIToUTF16("bar3"));
78 const base::string16 kBaz(ASCIIToUTF16("baz"));
79 const base::string16 kFirst(ASCIIToUTF16("first"));
80 const base::string16 kFoo(ASCIIToUTF16("foo"));
81 const base::string16 kFoo2(ASCIIToUTF16("foo2"));
82 const base::string16 kFoo3(ASCIIToUTF16("foo3"));
83 const base::string16 kFou(ASCIIToUTF16("fou"));
84 const base::string16 kSecond(ASCIIToUTF16("second"));
85 const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
86 const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
87
88 int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
89   return session->GetTransportSocketPool(
90       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
91 }
92
93 int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
94   return session->GetSSLSocketPool(
95       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
96 }
97
98 bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
99   return session->GetTransportSocketPool(
100       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
101 }
102
103 // Takes in a Value created from a NetLogHttpResponseParameter, and returns
104 // a JSONified list of headers as a single string.  Uses single quotes instead
105 // of double quotes for easier comparison.  Returns false on failure.
106 bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
107   if (!params)
108     return false;
109   base::ListValue* header_list;
110   if (!params->GetList("headers", &header_list))
111     return false;
112   std::string double_quote_headers;
113   base::JSONWriter::Write(header_list, &double_quote_headers);
114   ReplaceChars(double_quote_headers, "\"", "'", headers);
115   return true;
116 }
117
118 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is
119 // used.
120 void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
121   EXPECT_TRUE(load_timing_info.socket_reused);
122   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
123
124   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
125   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
126
127   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
128   EXPECT_FALSE(load_timing_info.send_start.is_null());
129
130   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
131
132   // Set at a higher level.
133   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
134   EXPECT_TRUE(load_timing_info.request_start.is_null());
135   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
136 }
137
138 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is
139 // used.
140 void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
141                              int connect_timing_flags) {
142   EXPECT_FALSE(load_timing_info.socket_reused);
143   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
144
145   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
146   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
147
148   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
149                                    connect_timing_flags);
150   EXPECT_LE(load_timing_info.connect_timing.connect_end,
151             load_timing_info.send_start);
152
153   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
154
155   // Set at a higher level.
156   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
157   EXPECT_TRUE(load_timing_info.request_start.is_null());
158   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
159 }
160
161 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is
162 // used.
163 void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
164   EXPECT_TRUE(load_timing_info.socket_reused);
165   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
166
167   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
168
169   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
170   EXPECT_LE(load_timing_info.proxy_resolve_start,
171             load_timing_info.proxy_resolve_end);
172   EXPECT_LE(load_timing_info.proxy_resolve_end,
173             load_timing_info.send_start);
174   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
175
176   // Set at a higher level.
177   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
178   EXPECT_TRUE(load_timing_info.request_start.is_null());
179   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
180 }
181
182 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is
183 // used.
184 void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
185                                     int connect_timing_flags) {
186   EXPECT_FALSE(load_timing_info.socket_reused);
187   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
188
189   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
190   EXPECT_LE(load_timing_info.proxy_resolve_start,
191             load_timing_info.proxy_resolve_end);
192   EXPECT_LE(load_timing_info.proxy_resolve_end,
193             load_timing_info.connect_timing.connect_start);
194   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
195                                    connect_timing_flags);
196   EXPECT_LE(load_timing_info.connect_timing.connect_end,
197             load_timing_info.send_start);
198
199   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
200
201   // Set at a higher level.
202   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
203   EXPECT_TRUE(load_timing_info.request_start.is_null());
204   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
205 }
206
207 }  // namespace
208
209 namespace net {
210
211 namespace {
212
213 HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
214   return SpdySessionDependencies::SpdyCreateSession(session_deps);
215 }
216
217 }  // namespace
218
219 class HttpNetworkTransactionTest
220     : public PlatformTest,
221       public ::testing::WithParamInterface<NextProto> {
222  public:
223   virtual ~HttpNetworkTransactionTest() {
224     // Important to restore the per-pool limit first, since the pool limit must
225     // always be greater than group limit, and the tests reduce both limits.
226     ClientSocketPoolManager::set_max_sockets_per_pool(
227         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
228     ClientSocketPoolManager::set_max_sockets_per_group(
229         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
230   }
231
232  protected:
233   HttpNetworkTransactionTest()
234       : spdy_util_(GetParam()),
235         session_deps_(GetParam()),
236         old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
237             HttpNetworkSession::NORMAL_SOCKET_POOL)),
238         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
239             HttpNetworkSession::NORMAL_SOCKET_POOL)) {
240   }
241
242   struct SimpleGetHelperResult {
243     int rv;
244     std::string status_line;
245     std::string response_data;
246     LoadTimingInfo load_timing_info;
247   };
248
249   virtual void SetUp() {
250     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
251     base::MessageLoop::current()->RunUntilIdle();
252   }
253
254   virtual void TearDown() {
255     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
256     base::MessageLoop::current()->RunUntilIdle();
257     // Empty the current queue.
258     base::MessageLoop::current()->RunUntilIdle();
259     PlatformTest::TearDown();
260     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
261     base::MessageLoop::current()->RunUntilIdle();
262     HttpStreamFactory::set_use_alternate_protocols(false);
263     HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
264   }
265
266   // This is the expected return from a current server advertising SPDY.
267   std::string GetAlternateProtocolHttpHeader() {
268     return
269         std::string("Alternate-Protocol: 443:") +
270         AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
271         "\r\n\r\n";
272   }
273
274   // Either |write_failure| specifies a write failure or |read_failure|
275   // specifies a read failure when using a reused socket.  In either case, the
276   // failure should cause the network transaction to resend the request, and the
277   // other argument should be NULL.
278   void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
279                                             const MockRead* read_failure);
280
281   SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
282                                                size_t data_count) {
283     SimpleGetHelperResult out;
284
285     HttpRequestInfo request;
286     request.method = "GET";
287     request.url = GURL("http://www.google.com/");
288     request.load_flags = 0;
289
290     CapturingBoundNetLog log;
291     session_deps_.net_log = log.bound().net_log();
292     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
293     scoped_ptr<HttpTransaction> trans(
294         new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
295
296     for (size_t i = 0; i < data_count; ++i) {
297       session_deps_.socket_factory->AddSocketDataProvider(data[i]);
298     }
299
300     TestCompletionCallback callback;
301
302     EXPECT_TRUE(log.bound().IsLoggingAllEvents());
303     int rv = trans->Start(&request, callback.callback(), log.bound());
304     EXPECT_EQ(ERR_IO_PENDING, rv);
305
306     out.rv = callback.WaitForResult();
307
308     // Even in the failure cases that use this function, connections are always
309     // successfully established before the error.
310     EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
311     TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
312
313     if (out.rv != OK)
314       return out;
315
316     const HttpResponseInfo* response = trans->GetResponseInfo();
317     // Can't use ASSERT_* inside helper functions like this, so
318     // return an error.
319     if (response == NULL || response->headers.get() == NULL) {
320       out.rv = ERR_UNEXPECTED;
321       return out;
322     }
323     out.status_line = response->headers->GetStatusLine();
324
325     EXPECT_EQ("127.0.0.1", response->socket_address.host());
326     EXPECT_EQ(80, response->socket_address.port());
327
328     rv = ReadTransaction(trans.get(), &out.response_data);
329     EXPECT_EQ(OK, rv);
330
331     net::CapturingNetLog::CapturedEntryList entries;
332     log.GetEntries(&entries);
333     size_t pos = ExpectLogContainsSomewhere(
334         entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
335         NetLog::PHASE_NONE);
336     ExpectLogContainsSomewhere(
337         entries, pos,
338         NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
339         NetLog::PHASE_NONE);
340
341     std::string line;
342     EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
343     EXPECT_EQ("GET / HTTP/1.1\r\n", line);
344
345     HttpRequestHeaders request_headers;
346     EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
347     std::string value;
348     EXPECT_TRUE(request_headers.GetHeader("Host", &value));
349     EXPECT_EQ("www.google.com", value);
350     EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
351     EXPECT_EQ("keep-alive", value);
352
353     std::string response_headers;
354     EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
355     EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
356               response_headers);
357
358     return out;
359   }
360
361   SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
362                                         size_t reads_count) {
363     StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
364     StaticSocketDataProvider* data[] = { &reads };
365     return SimpleGetHelperForData(data, 1);
366   }
367
368   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
369                                              int expected_status);
370
371   void ConnectStatusHelper(const MockRead& status);
372
373   void BypassHostCacheOnRefreshHelper(int load_flags);
374
375   void CheckErrorIsPassedBack(int error, IoMode mode);
376
377   SpdyTestUtil spdy_util_;
378   SpdySessionDependencies session_deps_;
379
380   // Original socket limits.  Some tests set these.  Safest to always restore
381   // them once each test has been run.
382   int old_max_group_sockets_;
383   int old_max_pool_sockets_;
384 };
385
386 INSTANTIATE_TEST_CASE_P(
387     NextProto,
388     HttpNetworkTransactionTest,
389     testing::Values(kProtoDeprecatedSPDY2,
390                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
391                     kProtoHTTP2Draft04));
392
393 namespace {
394
395 // Fill |str| with a long header list that consumes >= |size| bytes.
396 void FillLargeHeadersString(std::string* str, int size) {
397   const char* row =
398       "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
399   const int sizeof_row = strlen(row);
400   const int num_rows = static_cast<int>(
401       ceil(static_cast<float>(size) / sizeof_row));
402   const int sizeof_data = num_rows * sizeof_row;
403   DCHECK(sizeof_data >= size);
404   str->reserve(sizeof_data);
405
406   for (int i = 0; i < num_rows; ++i)
407     str->append(row, sizeof_row);
408 }
409
410 // Alternative functions that eliminate randomness and dependency on the local
411 // host name so that the generated NTLM messages are reproducible.
412 void MockGenerateRandom1(uint8* output, size_t n) {
413   static const uint8 bytes[] = {
414     0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
415   };
416   static size_t current_byte = 0;
417   for (size_t i = 0; i < n; ++i) {
418     output[i] = bytes[current_byte++];
419     current_byte %= arraysize(bytes);
420   }
421 }
422
423 void MockGenerateRandom2(uint8* output, size_t n) {
424   static const uint8 bytes[] = {
425     0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
426     0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
427   };
428   static size_t current_byte = 0;
429   for (size_t i = 0; i < n; ++i) {
430     output[i] = bytes[current_byte++];
431     current_byte %= arraysize(bytes);
432   }
433 }
434
435 std::string MockGetHostName() {
436   return "WTC-WIN7";
437 }
438
439 template<typename ParentPool>
440 class CaptureGroupNameSocketPool : public ParentPool {
441  public:
442   CaptureGroupNameSocketPool(HostResolver* host_resolver,
443                              CertVerifier* cert_verifier);
444
445   const std::string last_group_name_received() const {
446     return last_group_name_;
447   }
448
449   virtual int RequestSocket(const std::string& group_name,
450                             const void* socket_params,
451                             RequestPriority priority,
452                             ClientSocketHandle* handle,
453                             const CompletionCallback& callback,
454                             const BoundNetLog& net_log) {
455     last_group_name_ = group_name;
456     return ERR_IO_PENDING;
457   }
458   virtual void CancelRequest(const std::string& group_name,
459                              ClientSocketHandle* handle) {}
460   virtual void ReleaseSocket(const std::string& group_name,
461                              scoped_ptr<StreamSocket> socket,
462                              int id) {}
463   virtual void CloseIdleSockets() {}
464   virtual int IdleSocketCount() const {
465     return 0;
466   }
467   virtual int IdleSocketCountInGroup(const std::string& group_name) const {
468     return 0;
469   }
470   virtual LoadState GetLoadState(const std::string& group_name,
471                                  const ClientSocketHandle* handle) const {
472     return LOAD_STATE_IDLE;
473   }
474   virtual base::TimeDelta ConnectionTimeout() const {
475     return base::TimeDelta();
476   }
477
478  private:
479   std::string last_group_name_;
480 };
481
482 typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
483 CaptureGroupNameTransportSocketPool;
484 typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
485 CaptureGroupNameHttpProxySocketPool;
486 typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
487 CaptureGroupNameSOCKSSocketPool;
488 typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
489 CaptureGroupNameSSLSocketPool;
490
491 template<typename ParentPool>
492 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
493     HostResolver* host_resolver,
494     CertVerifier* /* cert_verifier */)
495     : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
496
497 template<>
498 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
499     HostResolver* host_resolver,
500     CertVerifier* /* cert_verifier */)
501     : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
502
503 template <>
504 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
505     HostResolver* host_resolver,
506     CertVerifier* cert_verifier)
507     : SSLClientSocketPool(0,
508                           0,
509                           NULL,
510                           host_resolver,
511                           cert_verifier,
512                           NULL,
513                           NULL,
514                           std::string(),
515                           NULL,
516                           NULL,
517                           NULL,
518                           NULL,
519                           NULL,
520                           NULL) {}
521
522 //-----------------------------------------------------------------------------
523
524 // Helper functions for validating that AuthChallengeInfo's are correctly
525 // configured for common cases.
526 bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
527   if (!auth_challenge)
528     return false;
529   EXPECT_FALSE(auth_challenge->is_proxy);
530   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
531   EXPECT_EQ("MyRealm1", auth_challenge->realm);
532   EXPECT_EQ("basic", auth_challenge->scheme);
533   return true;
534 }
535
536 bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
537   if (!auth_challenge)
538     return false;
539   EXPECT_TRUE(auth_challenge->is_proxy);
540   EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
541   EXPECT_EQ("MyRealm1", auth_challenge->realm);
542   EXPECT_EQ("basic", auth_challenge->scheme);
543   return true;
544 }
545
546 bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
547   if (!auth_challenge)
548     return false;
549   EXPECT_FALSE(auth_challenge->is_proxy);
550   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
551   EXPECT_EQ("digestive", auth_challenge->realm);
552   EXPECT_EQ("digest", auth_challenge->scheme);
553   return true;
554 }
555
556 bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
557   if (!auth_challenge)
558     return false;
559   EXPECT_FALSE(auth_challenge->is_proxy);
560   EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
561   EXPECT_EQ(std::string(), auth_challenge->realm);
562   EXPECT_EQ("ntlm", auth_challenge->scheme);
563   return true;
564 }
565
566 }  // namespace
567
568 TEST_P(HttpNetworkTransactionTest, Basic) {
569   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
570   scoped_ptr<HttpTransaction> trans(
571       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
572 }
573
574 TEST_P(HttpNetworkTransactionTest, SimpleGET) {
575   MockRead data_reads[] = {
576     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
577     MockRead("hello world"),
578     MockRead(SYNCHRONOUS, OK),
579   };
580   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
581                                               arraysize(data_reads));
582   EXPECT_EQ(OK, out.rv);
583   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
584   EXPECT_EQ("hello world", out.response_data);
585 }
586
587 // Response with no status line.
588 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
589   MockRead data_reads[] = {
590     MockRead("hello world"),
591     MockRead(SYNCHRONOUS, OK),
592   };
593   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
594                                               arraysize(data_reads));
595   EXPECT_EQ(OK, out.rv);
596   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
597   EXPECT_EQ("hello world", out.response_data);
598 }
599
600 // Allow up to 4 bytes of junk to precede status line.
601 TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
602   MockRead data_reads[] = {
603     MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
604     MockRead(SYNCHRONOUS, OK),
605   };
606   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
607                                               arraysize(data_reads));
608   EXPECT_EQ(OK, out.rv);
609   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
610   EXPECT_EQ("DATA", out.response_data);
611 }
612
613 // Allow up to 4 bytes of junk to precede status line.
614 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
615   MockRead data_reads[] = {
616     MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
617     MockRead(SYNCHRONOUS, OK),
618   };
619   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
620                                               arraysize(data_reads));
621   EXPECT_EQ(OK, out.rv);
622   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
623   EXPECT_EQ("DATA", out.response_data);
624 }
625
626 // Beyond 4 bytes of slop and it should fail to find a status line.
627 TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
628   MockRead data_reads[] = {
629     MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
630     MockRead(SYNCHRONOUS, OK),
631   };
632   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
633                                               arraysize(data_reads));
634   EXPECT_EQ(OK, out.rv);
635   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
636   EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
637 }
638
639 // Same as StatusLineJunk4Bytes, except the read chunks are smaller.
640 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
641   MockRead data_reads[] = {
642     MockRead("\n"),
643     MockRead("\n"),
644     MockRead("Q"),
645     MockRead("J"),
646     MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
647     MockRead(SYNCHRONOUS, OK),
648   };
649   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
650                                               arraysize(data_reads));
651   EXPECT_EQ(OK, out.rv);
652   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
653   EXPECT_EQ("DATA", out.response_data);
654 }
655
656 // Close the connection before enough bytes to have a status line.
657 TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
658   MockRead data_reads[] = {
659     MockRead("HTT"),
660     MockRead(SYNCHRONOUS, OK),
661   };
662   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
663                                               arraysize(data_reads));
664   EXPECT_EQ(OK, out.rv);
665   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
666   EXPECT_EQ("HTT", out.response_data);
667 }
668
669 // Simulate a 204 response, lacking a Content-Length header, sent over a
670 // persistent connection.  The response should still terminate since a 204
671 // cannot have a response body.
672 TEST_P(HttpNetworkTransactionTest, StopsReading204) {
673   MockRead data_reads[] = {
674     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
675     MockRead("junk"),  // Should not be read!!
676     MockRead(SYNCHRONOUS, OK),
677   };
678   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
679                                               arraysize(data_reads));
680   EXPECT_EQ(OK, out.rv);
681   EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
682   EXPECT_EQ("", out.response_data);
683 }
684
685 // A simple request using chunked encoding with some extra data after.
686 // (Like might be seen in a pipelined response.)
687 TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
688   MockRead data_reads[] = {
689     MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
690     MockRead("5\r\nHello\r\n"),
691     MockRead("1\r\n"),
692     MockRead(" \r\n"),
693     MockRead("5\r\nworld\r\n"),
694     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
695     MockRead(SYNCHRONOUS, OK),
696   };
697   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
698                                               arraysize(data_reads));
699   EXPECT_EQ(OK, out.rv);
700   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
701   EXPECT_EQ("Hello world", out.response_data);
702 }
703
704 // Next tests deal with http://crbug.com/56344.
705
706 TEST_P(HttpNetworkTransactionTest,
707        MultipleContentLengthHeadersNoTransferEncoding) {
708   MockRead data_reads[] = {
709     MockRead("HTTP/1.1 200 OK\r\n"),
710     MockRead("Content-Length: 10\r\n"),
711     MockRead("Content-Length: 5\r\n\r\n"),
712   };
713   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
714                                               arraysize(data_reads));
715   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
716 }
717
718 TEST_P(HttpNetworkTransactionTest,
719        DuplicateContentLengthHeadersNoTransferEncoding) {
720   MockRead data_reads[] = {
721     MockRead("HTTP/1.1 200 OK\r\n"),
722     MockRead("Content-Length: 5\r\n"),
723     MockRead("Content-Length: 5\r\n\r\n"),
724     MockRead("Hello"),
725   };
726   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
727                                               arraysize(data_reads));
728   EXPECT_EQ(OK, out.rv);
729   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
730   EXPECT_EQ("Hello", out.response_data);
731 }
732
733 TEST_P(HttpNetworkTransactionTest,
734        ComplexContentLengthHeadersNoTransferEncoding) {
735   // More than 2 dupes.
736   {
737     MockRead data_reads[] = {
738       MockRead("HTTP/1.1 200 OK\r\n"),
739       MockRead("Content-Length: 5\r\n"),
740       MockRead("Content-Length: 5\r\n"),
741       MockRead("Content-Length: 5\r\n\r\n"),
742       MockRead("Hello"),
743     };
744     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
745                                                 arraysize(data_reads));
746     EXPECT_EQ(OK, out.rv);
747     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
748     EXPECT_EQ("Hello", out.response_data);
749   }
750   // HTTP/1.0
751   {
752     MockRead data_reads[] = {
753       MockRead("HTTP/1.0 200 OK\r\n"),
754       MockRead("Content-Length: 5\r\n"),
755       MockRead("Content-Length: 5\r\n"),
756       MockRead("Content-Length: 5\r\n\r\n"),
757       MockRead("Hello"),
758     };
759     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
760                                                 arraysize(data_reads));
761     EXPECT_EQ(OK, out.rv);
762     EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
763     EXPECT_EQ("Hello", out.response_data);
764   }
765   // 2 dupes and one mismatched.
766   {
767     MockRead data_reads[] = {
768       MockRead("HTTP/1.1 200 OK\r\n"),
769       MockRead("Content-Length: 10\r\n"),
770       MockRead("Content-Length: 10\r\n"),
771       MockRead("Content-Length: 5\r\n\r\n"),
772     };
773     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
774                                                 arraysize(data_reads));
775     EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
776   }
777 }
778
779 TEST_P(HttpNetworkTransactionTest,
780        MultipleContentLengthHeadersTransferEncoding) {
781   MockRead data_reads[] = {
782     MockRead("HTTP/1.1 200 OK\r\n"),
783     MockRead("Content-Length: 666\r\n"),
784     MockRead("Content-Length: 1337\r\n"),
785     MockRead("Transfer-Encoding: chunked\r\n\r\n"),
786     MockRead("5\r\nHello\r\n"),
787     MockRead("1\r\n"),
788     MockRead(" \r\n"),
789     MockRead("5\r\nworld\r\n"),
790     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
791     MockRead(SYNCHRONOUS, OK),
792   };
793   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
794                                               arraysize(data_reads));
795   EXPECT_EQ(OK, out.rv);
796   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
797   EXPECT_EQ("Hello world", out.response_data);
798 }
799
800 // Next tests deal with http://crbug.com/98895.
801
802 // Checks that a single Content-Disposition header results in no error.
803 TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
804   MockRead data_reads[] = {
805     MockRead("HTTP/1.1 200 OK\r\n"),
806     MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
807     MockRead("Content-Length: 5\r\n\r\n"),
808     MockRead("Hello"),
809   };
810   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
811                                               arraysize(data_reads));
812   EXPECT_EQ(OK, out.rv);
813   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
814   EXPECT_EQ("Hello", out.response_data);
815 }
816
817 // Checks that two identical Content-Disposition headers result in no error.
818 TEST_P(HttpNetworkTransactionTest,
819        TwoIdenticalContentDispositionHeaders) {
820   MockRead data_reads[] = {
821     MockRead("HTTP/1.1 200 OK\r\n"),
822     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
823     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
824     MockRead("Content-Length: 5\r\n\r\n"),
825     MockRead("Hello"),
826   };
827   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
828                                               arraysize(data_reads));
829   EXPECT_EQ(OK, out.rv);
830   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
831   EXPECT_EQ("Hello", out.response_data);
832 }
833
834 // Checks that two distinct Content-Disposition headers result in an error.
835 TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
836   MockRead data_reads[] = {
837     MockRead("HTTP/1.1 200 OK\r\n"),
838     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
839     MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
840     MockRead("Content-Length: 5\r\n\r\n"),
841     MockRead("Hello"),
842   };
843   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
844                                               arraysize(data_reads));
845   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
846 }
847
848 // Checks that two identical Location headers result in no error.
849 // Also tests Location header behavior.
850 TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
851   MockRead data_reads[] = {
852     MockRead("HTTP/1.1 302 Redirect\r\n"),
853     MockRead("Location: http://good.com/\r\n"),
854     MockRead("Location: http://good.com/\r\n"),
855     MockRead("Content-Length: 0\r\n\r\n"),
856     MockRead(SYNCHRONOUS, OK),
857   };
858
859   HttpRequestInfo request;
860   request.method = "GET";
861   request.url = GURL("http://redirect.com/");
862   request.load_flags = 0;
863
864   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
865   scoped_ptr<HttpTransaction> trans(
866       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
867
868   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
869   session_deps_.socket_factory->AddSocketDataProvider(&data);
870
871   TestCompletionCallback callback;
872
873   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
874   EXPECT_EQ(ERR_IO_PENDING, rv);
875
876   EXPECT_EQ(OK, callback.WaitForResult());
877
878   const HttpResponseInfo* response = trans->GetResponseInfo();
879   ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
880   EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
881   std::string url;
882   EXPECT_TRUE(response->headers->IsRedirect(&url));
883   EXPECT_EQ("http://good.com/", url);
884 }
885
886 // Checks that two distinct Location headers result in an error.
887 TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
888   MockRead data_reads[] = {
889     MockRead("HTTP/1.1 302 Redirect\r\n"),
890     MockRead("Location: http://good.com/\r\n"),
891     MockRead("Location: http://evil.com/\r\n"),
892     MockRead("Content-Length: 0\r\n\r\n"),
893     MockRead(SYNCHRONOUS, OK),
894   };
895   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
896                                               arraysize(data_reads));
897   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
898 }
899
900 // Do a request using the HEAD method. Verify that we don't try to read the
901 // message body (since HEAD has none).
902 TEST_P(HttpNetworkTransactionTest, Head) {
903   HttpRequestInfo request;
904   request.method = "HEAD";
905   request.url = GURL("http://www.google.com/");
906   request.load_flags = 0;
907
908   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
909   scoped_ptr<HttpTransaction> trans(
910       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
911
912   MockWrite data_writes1[] = {
913     MockWrite("HEAD / HTTP/1.1\r\n"
914               "Host: www.google.com\r\n"
915               "Connection: keep-alive\r\n"
916               "Content-Length: 0\r\n\r\n"),
917   };
918   MockRead data_reads1[] = {
919     MockRead("HTTP/1.1 404 Not Found\r\n"),
920     MockRead("Server: Blah\r\n"),
921     MockRead("Content-Length: 1234\r\n\r\n"),
922
923     // No response body because the test stops reading here.
924     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
925   };
926
927   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
928                                  data_writes1, arraysize(data_writes1));
929   session_deps_.socket_factory->AddSocketDataProvider(&data1);
930
931   TestCompletionCallback callback1;
932
933   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
934   EXPECT_EQ(ERR_IO_PENDING, rv);
935
936   rv = callback1.WaitForResult();
937   EXPECT_EQ(OK, rv);
938
939   const HttpResponseInfo* response = trans->GetResponseInfo();
940   ASSERT_TRUE(response != NULL);
941
942   // Check that the headers got parsed.
943   EXPECT_TRUE(response->headers.get() != NULL);
944   EXPECT_EQ(1234, response->headers->GetContentLength());
945   EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
946
947   std::string server_header;
948   void* iter = NULL;
949   bool has_server_header = response->headers->EnumerateHeader(
950       &iter, "Server", &server_header);
951   EXPECT_TRUE(has_server_header);
952   EXPECT_EQ("Blah", server_header);
953
954   // Reading should give EOF right away, since there is no message body
955   // (despite non-zero content-length).
956   std::string response_data;
957   rv = ReadTransaction(trans.get(), &response_data);
958   EXPECT_EQ(OK, rv);
959   EXPECT_EQ("", response_data);
960 }
961
962 TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
963   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
964
965   MockRead data_reads[] = {
966     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
967     MockRead("hello"),
968     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
969     MockRead("world"),
970     MockRead(SYNCHRONOUS, OK),
971   };
972   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
973   session_deps_.socket_factory->AddSocketDataProvider(&data);
974
975   const char* const kExpectedResponseData[] = {
976     "hello", "world"
977   };
978
979   for (int i = 0; i < 2; ++i) {
980     HttpRequestInfo request;
981     request.method = "GET";
982     request.url = GURL("http://www.google.com/");
983     request.load_flags = 0;
984
985     scoped_ptr<HttpTransaction> trans(
986         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
987
988     TestCompletionCallback callback;
989
990     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
991     EXPECT_EQ(ERR_IO_PENDING, rv);
992
993     rv = callback.WaitForResult();
994     EXPECT_EQ(OK, rv);
995
996     const HttpResponseInfo* response = trans->GetResponseInfo();
997     ASSERT_TRUE(response != NULL);
998
999     EXPECT_TRUE(response->headers.get() != NULL);
1000     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1001
1002     std::string response_data;
1003     rv = ReadTransaction(trans.get(), &response_data);
1004     EXPECT_EQ(OK, rv);
1005     EXPECT_EQ(kExpectedResponseData[i], response_data);
1006   }
1007 }
1008
1009 TEST_P(HttpNetworkTransactionTest, Ignores100) {
1010   ScopedVector<UploadElementReader> element_readers;
1011   element_readers.push_back(new UploadBytesElementReader("foo", 3));
1012   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
1013
1014   HttpRequestInfo request;
1015   request.method = "POST";
1016   request.url = GURL("http://www.foo.com/");
1017   request.upload_data_stream = &upload_data_stream;
1018   request.load_flags = 0;
1019
1020   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1021   scoped_ptr<HttpTransaction> trans(
1022       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1023
1024   MockRead data_reads[] = {
1025     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1026     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1027     MockRead("hello world"),
1028     MockRead(SYNCHRONOUS, OK),
1029   };
1030   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1031   session_deps_.socket_factory->AddSocketDataProvider(&data);
1032
1033   TestCompletionCallback callback;
1034
1035   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1036   EXPECT_EQ(ERR_IO_PENDING, rv);
1037
1038   rv = callback.WaitForResult();
1039   EXPECT_EQ(OK, rv);
1040
1041   const HttpResponseInfo* response = trans->GetResponseInfo();
1042   ASSERT_TRUE(response != NULL);
1043
1044   EXPECT_TRUE(response->headers.get() != NULL);
1045   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
1046
1047   std::string response_data;
1048   rv = ReadTransaction(trans.get(), &response_data);
1049   EXPECT_EQ(OK, rv);
1050   EXPECT_EQ("hello world", response_data);
1051 }
1052
1053 // This test is almost the same as Ignores100 above, but the response contains
1054 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
1055 // HTTP/1.1 and the two status headers are read in one read.
1056 TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
1057   HttpRequestInfo request;
1058   request.method = "GET";
1059   request.url = GURL("http://www.foo.com/");
1060   request.load_flags = 0;
1061
1062   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1063   scoped_ptr<HttpTransaction> trans(
1064       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1065
1066   MockRead data_reads[] = {
1067     MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1068              "HTTP/1.1 200 OK\r\n\r\n"),
1069     MockRead("hello 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   TestCompletionCallback callback;
1076
1077   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1078   EXPECT_EQ(ERR_IO_PENDING, rv);
1079
1080   rv = callback.WaitForResult();
1081   EXPECT_EQ(OK, rv);
1082
1083   const HttpResponseInfo* response = trans->GetResponseInfo();
1084   ASSERT_TRUE(response != NULL);
1085
1086   EXPECT_TRUE(response->headers.get() != NULL);
1087   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1088
1089   std::string response_data;
1090   rv = ReadTransaction(trans.get(), &response_data);
1091   EXPECT_EQ(OK, rv);
1092   EXPECT_EQ("hello world", response_data);
1093 }
1094
1095 TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
1096   HttpRequestInfo request;
1097   request.method = "POST";
1098   request.url = GURL("http://www.foo.com/");
1099   request.load_flags = 0;
1100
1101   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1102   scoped_ptr<HttpTransaction> trans(
1103       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1104
1105   MockRead data_reads[] = {
1106     MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1107     MockRead(ASYNC, 0),
1108   };
1109   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1110   session_deps_.socket_factory->AddSocketDataProvider(&data);
1111
1112   TestCompletionCallback callback;
1113
1114   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1115   EXPECT_EQ(ERR_IO_PENDING, rv);
1116
1117   rv = callback.WaitForResult();
1118   EXPECT_EQ(OK, rv);
1119
1120   std::string response_data;
1121   rv = ReadTransaction(trans.get(), &response_data);
1122   EXPECT_EQ(OK, rv);
1123   EXPECT_EQ("", response_data);
1124 }
1125
1126 TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
1127   HttpRequestInfo request;
1128   request.method = "POST";
1129   request.url = GURL("http://www.foo.com/");
1130   request.load_flags = 0;
1131
1132   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1133   scoped_ptr<HttpTransaction> trans(
1134       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1135
1136
1137   MockRead data_reads[] = {
1138     MockRead(ASYNC, 0),
1139   };
1140   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1141   session_deps_.socket_factory->AddSocketDataProvider(&data);
1142
1143   TestCompletionCallback callback;
1144
1145   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1146   EXPECT_EQ(ERR_IO_PENDING, rv);
1147
1148   rv = callback.WaitForResult();
1149   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1150 }
1151
1152 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
1153     const MockWrite* write_failure,
1154     const MockRead* read_failure) {
1155   HttpRequestInfo request;
1156   request.method = "GET";
1157   request.url = GURL("http://www.foo.com/");
1158   request.load_flags = 0;
1159
1160   CapturingNetLog net_log;
1161   session_deps_.net_log = &net_log;
1162   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1163
1164   // Written data for successfully sending both requests.
1165   MockWrite data1_writes[] = {
1166     MockWrite("GET / HTTP/1.1\r\n"
1167               "Host: www.foo.com\r\n"
1168               "Connection: keep-alive\r\n\r\n"),
1169     MockWrite("GET / HTTP/1.1\r\n"
1170               "Host: www.foo.com\r\n"
1171               "Connection: keep-alive\r\n\r\n")
1172   };
1173
1174   // Read results for the first request.
1175   MockRead data1_reads[] = {
1176     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1177     MockRead("hello"),
1178     MockRead(ASYNC, OK),
1179   };
1180
1181   if (write_failure) {
1182     ASSERT_TRUE(!read_failure);
1183     data1_writes[1] = *write_failure;
1184   } else {
1185     ASSERT_TRUE(read_failure);
1186     data1_reads[2] = *read_failure;
1187   }
1188
1189   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1190                                  data1_writes, arraysize(data1_writes));
1191   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1192
1193   MockRead data2_reads[] = {
1194     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1195     MockRead("world"),
1196     MockRead(ASYNC, OK),
1197   };
1198   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1199   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1200
1201   const char* kExpectedResponseData[] = {
1202     "hello", "world"
1203   };
1204
1205   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
1206   for (int i = 0; i < 2; ++i) {
1207     TestCompletionCallback callback;
1208
1209     scoped_ptr<HttpTransaction> trans(
1210         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1211
1212     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1213     EXPECT_EQ(ERR_IO_PENDING, rv);
1214
1215     rv = callback.WaitForResult();
1216     EXPECT_EQ(OK, rv);
1217
1218     LoadTimingInfo load_timing_info;
1219     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1220     TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1221     if (i == 0) {
1222       first_socket_log_id = load_timing_info.socket_log_id;
1223     } else {
1224       // The second request should be using a new socket.
1225       EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1226     }
1227
1228     const HttpResponseInfo* response = trans->GetResponseInfo();
1229     ASSERT_TRUE(response != NULL);
1230
1231     EXPECT_TRUE(response->headers.get() != NULL);
1232     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1233
1234     std::string response_data;
1235     rv = ReadTransaction(trans.get(), &response_data);
1236     EXPECT_EQ(OK, rv);
1237     EXPECT_EQ(kExpectedResponseData[i], response_data);
1238   }
1239 }
1240
1241 TEST_P(HttpNetworkTransactionTest,
1242        KeepAliveConnectionNotConnectedOnWrite) {
1243   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1244   KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1245 }
1246
1247 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
1248   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1249   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1250 }
1251
1252 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
1253   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1254   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1255 }
1256
1257 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
1258   HttpRequestInfo request;
1259   request.method = "GET";
1260   request.url = GURL("http://www.google.com/");
1261   request.load_flags = 0;
1262
1263   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1264   scoped_ptr<HttpTransaction> trans(
1265       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1266
1267   MockRead data_reads[] = {
1268     MockRead(ASYNC, ERR_CONNECTION_RESET),
1269     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
1270     MockRead("hello world"),
1271     MockRead(SYNCHRONOUS, OK),
1272   };
1273   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1274   session_deps_.socket_factory->AddSocketDataProvider(&data);
1275
1276   TestCompletionCallback callback;
1277
1278   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1279   EXPECT_EQ(ERR_IO_PENDING, rv);
1280
1281   rv = callback.WaitForResult();
1282   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1283
1284   const HttpResponseInfo* response = trans->GetResponseInfo();
1285   EXPECT_TRUE(response == NULL);
1286 }
1287
1288 // What do various browsers do when the server closes a non-keepalive
1289 // connection without sending any response header or body?
1290 //
1291 // IE7: error page
1292 // Safari 3.1.2 (Windows): error page
1293 // Firefox 3.0.1: blank page
1294 // Opera 9.52: after five attempts, blank page
1295 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1296 // Us: error page (EMPTY_RESPONSE)
1297 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
1298   MockRead data_reads[] = {
1299     MockRead(SYNCHRONOUS, OK),  // EOF
1300     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
1301     MockRead("hello world"),
1302     MockRead(SYNCHRONOUS, OK),
1303   };
1304   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1305                                               arraysize(data_reads));
1306   EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
1307 }
1308
1309 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1310 // tests. There was a bug causing HttpNetworkTransaction to hang in the
1311 // destructor in such situations.
1312 // See http://crbug.com/154712 and http://crbug.com/156609.
1313 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
1314   HttpRequestInfo request;
1315   request.method = "GET";
1316   request.url = GURL("http://www.google.com/");
1317   request.load_flags = 0;
1318
1319   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1320   scoped_ptr<HttpTransaction> trans(
1321       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1322
1323   MockRead data_reads[] = {
1324     MockRead("HTTP/1.0 200 OK\r\n"),
1325     MockRead("Connection: keep-alive\r\n"),
1326     MockRead("Content-Length: 100\r\n\r\n"),
1327     MockRead("hello"),
1328     MockRead(SYNCHRONOUS, 0),
1329   };
1330   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1331   session_deps_.socket_factory->AddSocketDataProvider(&data);
1332
1333   TestCompletionCallback callback;
1334
1335   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1336   EXPECT_EQ(ERR_IO_PENDING, rv);
1337
1338   rv = callback.WaitForResult();
1339   EXPECT_EQ(OK, rv);
1340
1341   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1342   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1343   if (rv == ERR_IO_PENDING)
1344     rv = callback.WaitForResult();
1345   EXPECT_EQ(5, rv);
1346   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1347   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1348
1349   trans.reset();
1350   base::MessageLoop::current()->RunUntilIdle();
1351   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1352 }
1353
1354 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
1355   HttpRequestInfo request;
1356   request.method = "GET";
1357   request.url = GURL("http://www.google.com/");
1358   request.load_flags = 0;
1359
1360   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1361   scoped_ptr<HttpTransaction> trans(
1362       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1363
1364   MockRead data_reads[] = {
1365     MockRead("HTTP/1.0 200 OK\r\n"),
1366     MockRead("Connection: keep-alive\r\n"),
1367     MockRead("Content-Length: 100\r\n\r\n"),
1368     MockRead(SYNCHRONOUS, 0),
1369   };
1370   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1371   session_deps_.socket_factory->AddSocketDataProvider(&data);
1372
1373   TestCompletionCallback callback;
1374
1375   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1376   EXPECT_EQ(ERR_IO_PENDING, rv);
1377
1378   rv = callback.WaitForResult();
1379   EXPECT_EQ(OK, rv);
1380
1381   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1382   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1383   if (rv == ERR_IO_PENDING)
1384     rv = callback.WaitForResult();
1385   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1386
1387   trans.reset();
1388   base::MessageLoop::current()->RunUntilIdle();
1389   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1390 }
1391
1392 // Test that we correctly reuse a keep-alive connection after not explicitly
1393 // reading the body.
1394 TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
1395   HttpRequestInfo request;
1396   request.method = "GET";
1397   request.url = GURL("http://www.foo.com/");
1398   request.load_flags = 0;
1399
1400   CapturingNetLog net_log;
1401   session_deps_.net_log = &net_log;
1402   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1403
1404   // Note that because all these reads happen in the same
1405   // StaticSocketDataProvider, it shows that the same socket is being reused for
1406   // all transactions.
1407   MockRead data1_reads[] = {
1408     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1409     MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
1410     MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
1411     MockRead("HTTP/1.1 302 Found\r\n"
1412              "Content-Length: 0\r\n\r\n"),
1413     MockRead("HTTP/1.1 302 Found\r\n"
1414              "Content-Length: 5\r\n\r\n"
1415              "hello"),
1416     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1417              "Content-Length: 0\r\n\r\n"),
1418     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1419              "Content-Length: 5\r\n\r\n"
1420              "hello"),
1421     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1422     MockRead("hello"),
1423   };
1424   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
1425   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1426
1427   MockRead data2_reads[] = {
1428     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
1429   };
1430   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1431   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1432
1433   const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1434   std::string response_lines[kNumUnreadBodies];
1435
1436   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
1437   for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
1438     TestCompletionCallback callback;
1439
1440     scoped_ptr<HttpTransaction> trans(
1441         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1442
1443     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1444     EXPECT_EQ(ERR_IO_PENDING, rv);
1445
1446     rv = callback.WaitForResult();
1447     EXPECT_EQ(OK, rv);
1448
1449     LoadTimingInfo load_timing_info;
1450     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1451     if (i == 0) {
1452       TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1453       first_socket_log_id = load_timing_info.socket_log_id;
1454     } else {
1455       TestLoadTimingReused(load_timing_info);
1456       EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1457     }
1458
1459     const HttpResponseInfo* response = trans->GetResponseInfo();
1460     ASSERT_TRUE(response != NULL);
1461
1462     ASSERT_TRUE(response->headers.get() != NULL);
1463     response_lines[i] = response->headers->GetStatusLine();
1464
1465     // We intentionally don't read the response bodies.
1466   }
1467
1468   const char* const kStatusLines[] = {
1469     "HTTP/1.1 204 No Content",
1470     "HTTP/1.1 205 Reset Content",
1471     "HTTP/1.1 304 Not Modified",
1472     "HTTP/1.1 302 Found",
1473     "HTTP/1.1 302 Found",
1474     "HTTP/1.1 301 Moved Permanently",
1475     "HTTP/1.1 301 Moved Permanently",
1476   };
1477
1478   COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1479                  forgot_to_update_kStatusLines);
1480
1481   for (int i = 0; i < kNumUnreadBodies; ++i)
1482     EXPECT_EQ(kStatusLines[i], response_lines[i]);
1483
1484   TestCompletionCallback callback;
1485   scoped_ptr<HttpTransaction> trans(
1486       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1487   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1488   EXPECT_EQ(ERR_IO_PENDING, rv);
1489   rv = callback.WaitForResult();
1490   EXPECT_EQ(OK, rv);
1491   const HttpResponseInfo* response = trans->GetResponseInfo();
1492   ASSERT_TRUE(response != NULL);
1493   ASSERT_TRUE(response->headers.get() != NULL);
1494   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1495   std::string response_data;
1496   rv = ReadTransaction(trans.get(), &response_data);
1497   EXPECT_EQ(OK, rv);
1498   EXPECT_EQ("hello", response_data);
1499 }
1500
1501 // Test the request-challenge-retry sequence for basic auth.
1502 // (basic auth is the easiest to mock, because it has no randomness).
1503 TEST_P(HttpNetworkTransactionTest, BasicAuth) {
1504   HttpRequestInfo request;
1505   request.method = "GET";
1506   request.url = GURL("http://www.google.com/");
1507   request.load_flags = 0;
1508
1509   CapturingNetLog log;
1510   session_deps_.net_log = &log;
1511   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1512   scoped_ptr<HttpTransaction> trans(
1513       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1514
1515   MockWrite data_writes1[] = {
1516     MockWrite("GET / HTTP/1.1\r\n"
1517               "Host: www.google.com\r\n"
1518               "Connection: keep-alive\r\n\r\n"),
1519   };
1520
1521   MockRead data_reads1[] = {
1522     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1523     // Give a couple authenticate options (only the middle one is actually
1524     // supported).
1525     MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
1526     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1527     MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1528     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1529     // Large content-length -- won't matter, as connection will be reset.
1530     MockRead("Content-Length: 10000\r\n\r\n"),
1531     MockRead(SYNCHRONOUS, ERR_FAILED),
1532   };
1533
1534   // After calling trans->RestartWithAuth(), this is the request we should
1535   // be issuing -- the final header line contains the credentials.
1536   MockWrite data_writes2[] = {
1537     MockWrite("GET / HTTP/1.1\r\n"
1538               "Host: www.google.com\r\n"
1539               "Connection: keep-alive\r\n"
1540               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1541   };
1542
1543   // Lastly, the server responds with the actual content.
1544   MockRead data_reads2[] = {
1545     MockRead("HTTP/1.0 200 OK\r\n"),
1546     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1547     MockRead("Content-Length: 100\r\n\r\n"),
1548     MockRead(SYNCHRONOUS, OK),
1549   };
1550
1551   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1552                                  data_writes1, arraysize(data_writes1));
1553   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1554                                  data_writes2, arraysize(data_writes2));
1555   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1556   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1557
1558   TestCompletionCallback callback1;
1559
1560   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
1561   EXPECT_EQ(ERR_IO_PENDING, rv);
1562
1563   rv = callback1.WaitForResult();
1564   EXPECT_EQ(OK, rv);
1565
1566   LoadTimingInfo load_timing_info1;
1567   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1568   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1569
1570   const HttpResponseInfo* response = trans->GetResponseInfo();
1571   ASSERT_TRUE(response != NULL);
1572   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
1573
1574   TestCompletionCallback callback2;
1575
1576   rv = trans->RestartWithAuth(
1577       AuthCredentials(kFoo, kBar), callback2.callback());
1578   EXPECT_EQ(ERR_IO_PENDING, rv);
1579
1580   rv = callback2.WaitForResult();
1581   EXPECT_EQ(OK, rv);
1582
1583   LoadTimingInfo load_timing_info2;
1584   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1585   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1586   // The load timing after restart should have a new socket ID, and times after
1587   // those of the first load timing.
1588   EXPECT_LE(load_timing_info1.receive_headers_end,
1589             load_timing_info2.connect_timing.connect_start);
1590   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1591
1592   response = trans->GetResponseInfo();
1593   ASSERT_TRUE(response != NULL);
1594   EXPECT_TRUE(response->auth_challenge.get() == NULL);
1595   EXPECT_EQ(100, response->headers->GetContentLength());
1596 }
1597
1598 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
1599   HttpRequestInfo request;
1600   request.method = "GET";
1601   request.url = GURL("http://www.google.com/");
1602   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1603
1604   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1605   scoped_ptr<HttpTransaction> trans(
1606       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1607
1608   MockWrite data_writes[] = {
1609     MockWrite("GET / HTTP/1.1\r\n"
1610               "Host: www.google.com\r\n"
1611               "Connection: keep-alive\r\n\r\n"),
1612   };
1613
1614   MockRead data_reads[] = {
1615     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1616     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1617     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1618     // Large content-length -- won't matter, as connection will be reset.
1619     MockRead("Content-Length: 10000\r\n\r\n"),
1620     MockRead(SYNCHRONOUS, ERR_FAILED),
1621   };
1622
1623   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1624                                 data_writes, arraysize(data_writes));
1625   session_deps_.socket_factory->AddSocketDataProvider(&data);
1626   TestCompletionCallback callback;
1627
1628   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1629   EXPECT_EQ(ERR_IO_PENDING, rv);
1630
1631   rv = callback.WaitForResult();
1632   EXPECT_EQ(0, rv);
1633
1634   const HttpResponseInfo* response = trans->GetResponseInfo();
1635   ASSERT_TRUE(response != NULL);
1636   EXPECT_TRUE(response->auth_challenge.get() == NULL);
1637 }
1638
1639 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
1640 // connection.
1641 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
1642   HttpRequestInfo request;
1643   request.method = "GET";
1644   request.url = GURL("http://www.google.com/");
1645   request.load_flags = 0;
1646
1647   CapturingNetLog log;
1648   session_deps_.net_log = &log;
1649   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1650
1651   MockWrite data_writes1[] = {
1652     MockWrite("GET / HTTP/1.1\r\n"
1653               "Host: www.google.com\r\n"
1654               "Connection: keep-alive\r\n\r\n"),
1655
1656     // After calling trans->RestartWithAuth(), this is the request we should
1657     // be issuing -- the final header line contains the credentials.
1658     MockWrite("GET / HTTP/1.1\r\n"
1659               "Host: www.google.com\r\n"
1660               "Connection: keep-alive\r\n"
1661               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1662   };
1663
1664   MockRead data_reads1[] = {
1665     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1666     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1667     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1668     MockRead("Content-Length: 14\r\n\r\n"),
1669     MockRead("Unauthorized\r\n"),
1670
1671     // Lastly, the server responds with the actual content.
1672     MockRead("HTTP/1.1 200 OK\r\n"),
1673     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1674     MockRead("Content-Length: 5\r\n\r\n"),
1675     MockRead("Hello"),
1676   };
1677
1678   // If there is a regression where we disconnect a Keep-Alive
1679   // connection during an auth roundtrip, we'll end up reading this.
1680   MockRead data_reads2[] = {
1681     MockRead(SYNCHRONOUS, ERR_FAILED),
1682   };
1683
1684   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1685                                  data_writes1, arraysize(data_writes1));
1686   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1687                                  NULL, 0);
1688   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1689   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1690
1691   TestCompletionCallback callback1;
1692
1693   scoped_ptr<HttpTransaction> trans(
1694       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1695   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
1696   EXPECT_EQ(ERR_IO_PENDING, rv);
1697
1698   rv = callback1.WaitForResult();
1699   EXPECT_EQ(OK, rv);
1700
1701   LoadTimingInfo load_timing_info1;
1702   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1703   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1704
1705   const HttpResponseInfo* response = trans->GetResponseInfo();
1706   ASSERT_TRUE(response != NULL);
1707   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
1708
1709   TestCompletionCallback callback2;
1710
1711   rv = trans->RestartWithAuth(
1712       AuthCredentials(kFoo, kBar), callback2.callback());
1713   EXPECT_EQ(ERR_IO_PENDING, rv);
1714
1715   rv = callback2.WaitForResult();
1716   EXPECT_EQ(OK, rv);
1717
1718   LoadTimingInfo load_timing_info2;
1719   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1720   TestLoadTimingReused(load_timing_info2);
1721   // The load timing after restart should have the same socket ID, and times
1722   // those of the first load timing.
1723   EXPECT_LE(load_timing_info1.receive_headers_end,
1724             load_timing_info2.send_start);
1725   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1726
1727   response = trans->GetResponseInfo();
1728   ASSERT_TRUE(response != NULL);
1729   EXPECT_TRUE(response->auth_challenge.get() == NULL);
1730   EXPECT_EQ(5, response->headers->GetContentLength());
1731 }
1732
1733 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
1734 // connection and with no response body to drain.
1735 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
1736   HttpRequestInfo request;
1737   request.method = "GET";
1738   request.url = GURL("http://www.google.com/");
1739   request.load_flags = 0;
1740
1741   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1742
1743   MockWrite data_writes1[] = {
1744     MockWrite("GET / HTTP/1.1\r\n"
1745               "Host: www.google.com\r\n"
1746               "Connection: keep-alive\r\n\r\n"),
1747
1748     // After calling trans->RestartWithAuth(), this is the request we should
1749     // be issuing -- the final header line contains the credentials.
1750     MockWrite("GET / HTTP/1.1\r\n"
1751               "Host: www.google.com\r\n"
1752               "Connection: keep-alive\r\n"
1753               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1754   };
1755
1756   MockRead data_reads1[] = {
1757     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1758     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1759     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
1760
1761     // Lastly, the server responds with the actual content.
1762     MockRead("HTTP/1.1 200 OK\r\n"),
1763     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1764     MockRead("Content-Length: 5\r\n\r\n"),
1765     MockRead("hello"),
1766   };
1767
1768   // An incorrect reconnect would cause this to be read.
1769   MockRead data_reads2[] = {
1770     MockRead(SYNCHRONOUS, ERR_FAILED),
1771   };
1772
1773   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1774                                  data_writes1, arraysize(data_writes1));
1775   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1776                                  NULL, 0);
1777   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1778   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1779
1780   TestCompletionCallback callback1;
1781
1782   scoped_ptr<HttpTransaction> trans(
1783       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1784   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
1785   EXPECT_EQ(ERR_IO_PENDING, rv);
1786
1787   rv = callback1.WaitForResult();
1788   EXPECT_EQ(OK, rv);
1789
1790   const HttpResponseInfo* response = trans->GetResponseInfo();
1791   ASSERT_TRUE(response != NULL);
1792   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
1793
1794   TestCompletionCallback callback2;
1795
1796   rv = trans->RestartWithAuth(
1797       AuthCredentials(kFoo, kBar), callback2.callback());
1798   EXPECT_EQ(ERR_IO_PENDING, rv);
1799
1800   rv = callback2.WaitForResult();
1801   EXPECT_EQ(OK, rv);
1802
1803   response = trans->GetResponseInfo();
1804   ASSERT_TRUE(response != NULL);
1805   EXPECT_TRUE(response->auth_challenge.get() == NULL);
1806   EXPECT_EQ(5, response->headers->GetContentLength());
1807 }
1808
1809 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
1810 // connection and with a large response body to drain.
1811 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
1812   HttpRequestInfo request;
1813   request.method = "GET";
1814   request.url = GURL("http://www.google.com/");
1815   request.load_flags = 0;
1816
1817   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1818
1819   MockWrite data_writes1[] = {
1820     MockWrite("GET / HTTP/1.1\r\n"
1821               "Host: www.google.com\r\n"
1822               "Connection: keep-alive\r\n\r\n"),
1823
1824     // After calling trans->RestartWithAuth(), this is the request we should
1825     // be issuing -- the final header line contains the credentials.
1826     MockWrite("GET / HTTP/1.1\r\n"
1827               "Host: www.google.com\r\n"
1828               "Connection: keep-alive\r\n"
1829               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1830   };
1831
1832   // Respond with 5 kb of response body.
1833   std::string large_body_string("Unauthorized");
1834   large_body_string.append(5 * 1024, ' ');
1835   large_body_string.append("\r\n");
1836
1837   MockRead data_reads1[] = {
1838     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1839     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1840     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1841     // 5134 = 12 + 5 * 1024 + 2
1842     MockRead("Content-Length: 5134\r\n\r\n"),
1843     MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
1844
1845     // Lastly, the server responds with the actual content.
1846     MockRead("HTTP/1.1 200 OK\r\n"),
1847     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1848     MockRead("Content-Length: 5\r\n\r\n"),
1849     MockRead("hello"),
1850   };
1851
1852   // An incorrect reconnect would cause this to be read.
1853   MockRead data_reads2[] = {
1854     MockRead(SYNCHRONOUS, ERR_FAILED),
1855   };
1856
1857   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1858                                  data_writes1, arraysize(data_writes1));
1859   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1860                                  NULL, 0);
1861   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1862   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1863
1864   TestCompletionCallback callback1;
1865
1866   scoped_ptr<HttpTransaction> trans(
1867       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1868   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
1869   EXPECT_EQ(ERR_IO_PENDING, rv);
1870
1871   rv = callback1.WaitForResult();
1872   EXPECT_EQ(OK, rv);
1873
1874   const HttpResponseInfo* response = trans->GetResponseInfo();
1875   ASSERT_TRUE(response != NULL);
1876   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
1877
1878   TestCompletionCallback callback2;
1879
1880   rv = trans->RestartWithAuth(
1881       AuthCredentials(kFoo, kBar), callback2.callback());
1882   EXPECT_EQ(ERR_IO_PENDING, rv);
1883
1884   rv = callback2.WaitForResult();
1885   EXPECT_EQ(OK, rv);
1886
1887   response = trans->GetResponseInfo();
1888   ASSERT_TRUE(response != NULL);
1889   EXPECT_TRUE(response->auth_challenge.get() == NULL);
1890   EXPECT_EQ(5, response->headers->GetContentLength());
1891 }
1892
1893 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
1894 // connection, but the server gets impatient and closes the connection.
1895 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
1896   HttpRequestInfo request;
1897   request.method = "GET";
1898   request.url = GURL("http://www.google.com/");
1899   request.load_flags = 0;
1900
1901   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1902
1903   MockWrite data_writes1[] = {
1904     MockWrite("GET / HTTP/1.1\r\n"
1905               "Host: www.google.com\r\n"
1906               "Connection: keep-alive\r\n\r\n"),
1907     // This simulates the seemingly successful write to a closed connection
1908     // if the bug is not fixed.
1909     MockWrite("GET / HTTP/1.1\r\n"
1910               "Host: www.google.com\r\n"
1911               "Connection: keep-alive\r\n"
1912               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1913   };
1914
1915   MockRead data_reads1[] = {
1916     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1917     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1918     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1919     MockRead("Content-Length: 14\r\n\r\n"),
1920     // Tell MockTCPClientSocket to simulate the server closing the connection.
1921     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1922     MockRead("Unauthorized\r\n"),
1923     MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
1924   };
1925
1926   // After calling trans->RestartWithAuth(), this is the request we should
1927   // be issuing -- the final header line contains the credentials.
1928   MockWrite data_writes2[] = {
1929     MockWrite("GET / HTTP/1.1\r\n"
1930               "Host: www.google.com\r\n"
1931               "Connection: keep-alive\r\n"
1932               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1933   };
1934
1935   // Lastly, the server responds with the actual content.
1936   MockRead data_reads2[] = {
1937     MockRead("HTTP/1.1 200 OK\r\n"),
1938     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1939     MockRead("Content-Length: 5\r\n\r\n"),
1940     MockRead("hello"),
1941   };
1942
1943   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1944                                  data_writes1, arraysize(data_writes1));
1945   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1946                                  data_writes2, arraysize(data_writes2));
1947   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1948   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1949
1950   TestCompletionCallback callback1;
1951
1952   scoped_ptr<HttpTransaction> trans(
1953       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1954   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
1955   EXPECT_EQ(ERR_IO_PENDING, rv);
1956
1957   rv = callback1.WaitForResult();
1958   EXPECT_EQ(OK, rv);
1959
1960   const HttpResponseInfo* response = trans->GetResponseInfo();
1961   ASSERT_TRUE(response != NULL);
1962   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
1963
1964   TestCompletionCallback callback2;
1965
1966   rv = trans->RestartWithAuth(
1967       AuthCredentials(kFoo, kBar), callback2.callback());
1968   EXPECT_EQ(ERR_IO_PENDING, rv);
1969
1970   rv = callback2.WaitForResult();
1971   EXPECT_EQ(OK, rv);
1972
1973   response = trans->GetResponseInfo();
1974   ASSERT_TRUE(response != NULL);
1975   EXPECT_TRUE(response->auth_challenge.get() == NULL);
1976   EXPECT_EQ(5, response->headers->GetContentLength());
1977 }
1978
1979 // Test the request-challenge-retry sequence for basic auth, over a connection
1980 // that requires a restart when setting up an SSL tunnel.
1981 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
1982   HttpRequestInfo request;
1983   request.method = "GET";
1984   request.url = GURL("https://www.google.com/");
1985   // when the no authentication data flag is set.
1986   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1987
1988   // Configure against proxy server "myproxy:70".
1989   session_deps_.proxy_service.reset(
1990       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
1991   CapturingBoundNetLog log;
1992   session_deps_.net_log = log.bound().net_log();
1993   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1994
1995   // Since we have proxy, should try to establish tunnel.
1996   MockWrite data_writes1[] = {
1997     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
1998               "Host: www.google.com\r\n"
1999               "Proxy-Connection: keep-alive\r\n\r\n"),
2000
2001     // After calling trans->RestartWithAuth(), this is the request we should
2002     // be issuing -- the final header line contains the credentials.
2003     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2004               "Host: www.google.com\r\n"
2005               "Proxy-Connection: keep-alive\r\n"
2006               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2007
2008     MockWrite("GET / HTTP/1.1\r\n"
2009               "Host: www.google.com\r\n"
2010               "Connection: keep-alive\r\n\r\n"),
2011   };
2012
2013   // The proxy responds to the connect with a 407, using a persistent
2014   // connection.
2015   MockRead data_reads1[] = {
2016     // No credentials.
2017     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2018     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2019     MockRead("Proxy-Connection: close\r\n\r\n"),
2020
2021     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2022
2023     MockRead("HTTP/1.1 200 OK\r\n"),
2024     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2025     MockRead("Content-Length: 5\r\n\r\n"),
2026     MockRead(SYNCHRONOUS, "hello"),
2027   };
2028
2029   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2030                                  data_writes1, arraysize(data_writes1));
2031   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2032   SSLSocketDataProvider ssl(ASYNC, OK);
2033   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2034
2035   TestCompletionCallback callback1;
2036
2037   scoped_ptr<HttpTransaction> trans(
2038       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2039
2040   int rv = trans->Start(&request, callback1.callback(), log.bound());
2041   EXPECT_EQ(ERR_IO_PENDING, rv);
2042
2043   rv = callback1.WaitForResult();
2044   EXPECT_EQ(OK, rv);
2045   net::CapturingNetLog::CapturedEntryList entries;
2046   log.GetEntries(&entries);
2047   size_t pos = ExpectLogContainsSomewhere(
2048       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2049       NetLog::PHASE_NONE);
2050   ExpectLogContainsSomewhere(
2051       entries, pos,
2052       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2053       NetLog::PHASE_NONE);
2054
2055   const HttpResponseInfo* response = trans->GetResponseInfo();
2056   ASSERT_TRUE(response != NULL);
2057   ASSERT_FALSE(response->headers.get() == NULL);
2058   EXPECT_EQ(407, response->headers->response_code());
2059   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2060   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2061
2062   LoadTimingInfo load_timing_info;
2063   // CONNECT requests and responses are handled at the connect job level, so
2064   // the transaction does not yet have a connection.
2065   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2066
2067   TestCompletionCallback callback2;
2068
2069   rv = trans->RestartWithAuth(
2070       AuthCredentials(kFoo, kBar), callback2.callback());
2071   EXPECT_EQ(ERR_IO_PENDING, rv);
2072
2073   rv = callback2.WaitForResult();
2074   EXPECT_EQ(OK, rv);
2075
2076   response = trans->GetResponseInfo();
2077   ASSERT_TRUE(response != NULL);
2078
2079   EXPECT_TRUE(response->headers->IsKeepAlive());
2080   EXPECT_EQ(200, response->headers->response_code());
2081   EXPECT_EQ(5, response->headers->GetContentLength());
2082   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2083
2084   // The password prompt info should not be set.
2085   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2086
2087   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2088   TestLoadTimingNotReusedWithPac(load_timing_info,
2089                                  CONNECT_TIMING_HAS_SSL_TIMES);
2090
2091   trans.reset();
2092   session->CloseAllConnections();
2093 }
2094
2095 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2096 // proxy connection, when setting up an SSL tunnel.
2097 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
2098   HttpRequestInfo request;
2099   request.method = "GET";
2100   request.url = GURL("https://www.google.com/");
2101   // Ensure that proxy authentication is attempted even
2102   // when the no authentication data flag is set.
2103   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2104
2105   // Configure against proxy server "myproxy:70".
2106   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2107   CapturingBoundNetLog log;
2108   session_deps_.net_log = log.bound().net_log();
2109   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2110
2111   scoped_ptr<HttpTransaction> trans(
2112       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2113
2114   // Since we have proxy, should try to establish tunnel.
2115   MockWrite data_writes1[] = {
2116     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2117               "Host: www.google.com\r\n"
2118               "Proxy-Connection: keep-alive\r\n\r\n"),
2119
2120     // After calling trans->RestartWithAuth(), this is the request we should
2121     // be issuing -- the final header line contains the credentials.
2122     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2123               "Host: www.google.com\r\n"
2124               "Proxy-Connection: keep-alive\r\n"
2125               "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2126   };
2127
2128   // The proxy responds to the connect with a 407, using a persistent
2129   // connection.
2130   MockRead data_reads1[] = {
2131     // No credentials.
2132     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2133     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2134     MockRead("Content-Length: 10\r\n\r\n"),
2135     MockRead("0123456789"),
2136
2137     // Wrong credentials (wrong password).
2138     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2139     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2140     MockRead("Content-Length: 10\r\n\r\n"),
2141     // No response body because the test stops reading here.
2142     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
2143   };
2144
2145   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2146                                  data_writes1, arraysize(data_writes1));
2147   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2148
2149   TestCompletionCallback callback1;
2150
2151   int rv = trans->Start(&request, callback1.callback(), log.bound());
2152   EXPECT_EQ(ERR_IO_PENDING, rv);
2153
2154   rv = callback1.WaitForResult();
2155   EXPECT_EQ(OK, rv);
2156   net::CapturingNetLog::CapturedEntryList entries;
2157   log.GetEntries(&entries);
2158   size_t pos = ExpectLogContainsSomewhere(
2159       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2160       NetLog::PHASE_NONE);
2161   ExpectLogContainsSomewhere(
2162       entries, pos,
2163       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2164       NetLog::PHASE_NONE);
2165
2166   const HttpResponseInfo* response = trans->GetResponseInfo();
2167   ASSERT_TRUE(response != NULL);
2168   ASSERT_FALSE(response->headers.get() == NULL);
2169   EXPECT_TRUE(response->headers->IsKeepAlive());
2170   EXPECT_EQ(407, response->headers->response_code());
2171   EXPECT_EQ(10, response->headers->GetContentLength());
2172   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2173   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2174
2175   TestCompletionCallback callback2;
2176
2177   // Wrong password (should be "bar").
2178   rv = trans->RestartWithAuth(
2179       AuthCredentials(kFoo, kBaz), callback2.callback());
2180   EXPECT_EQ(ERR_IO_PENDING, rv);
2181
2182   rv = callback2.WaitForResult();
2183   EXPECT_EQ(OK, rv);
2184
2185   response = trans->GetResponseInfo();
2186   ASSERT_TRUE(response != NULL);
2187   ASSERT_FALSE(response->headers.get() == NULL);
2188   EXPECT_TRUE(response->headers->IsKeepAlive());
2189   EXPECT_EQ(407, response->headers->response_code());
2190   EXPECT_EQ(10, response->headers->GetContentLength());
2191   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2192   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2193
2194   // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2195   // out of scope.
2196   session->CloseAllConnections();
2197 }
2198
2199 // Test that we don't read the response body when we fail to establish a tunnel,
2200 // even if the user cancels the proxy's auth attempt.
2201 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
2202   HttpRequestInfo request;
2203   request.method = "GET";
2204   request.url = GURL("https://www.google.com/");
2205   request.load_flags = 0;
2206
2207   // Configure against proxy server "myproxy:70".
2208   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2209
2210   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2211
2212   scoped_ptr<HttpTransaction> trans(
2213       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2214
2215   // Since we have proxy, should try to establish tunnel.
2216   MockWrite data_writes[] = {
2217     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2218               "Host: www.google.com\r\n"
2219               "Proxy-Connection: keep-alive\r\n\r\n"),
2220   };
2221
2222   // The proxy responds to the connect with a 407.
2223   MockRead data_reads[] = {
2224     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2225     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2226     MockRead("Content-Length: 10\r\n\r\n"),
2227     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
2228   };
2229
2230   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2231                                 data_writes, arraysize(data_writes));
2232   session_deps_.socket_factory->AddSocketDataProvider(&data);
2233
2234   TestCompletionCallback callback;
2235
2236   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2237   EXPECT_EQ(ERR_IO_PENDING, rv);
2238
2239   rv = callback.WaitForResult();
2240   EXPECT_EQ(OK, rv);
2241
2242   const HttpResponseInfo* response = trans->GetResponseInfo();
2243   ASSERT_TRUE(response != NULL);
2244
2245   EXPECT_TRUE(response->headers->IsKeepAlive());
2246   EXPECT_EQ(407, response->headers->response_code());
2247   EXPECT_EQ(10, response->headers->GetContentLength());
2248   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2249
2250   std::string response_data;
2251   rv = ReadTransaction(trans.get(), &response_data);
2252   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
2253
2254   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
2255   session->CloseAllConnections();
2256 }
2257
2258 // Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2259 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
2260 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
2261   HttpRequestInfo request;
2262   request.method = "GET";
2263   request.url = GURL("http://www.google.com/");
2264   request.load_flags = 0;
2265
2266   // We are using a DIRECT connection (i.e. no proxy) for this session.
2267   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2268   scoped_ptr<HttpTransaction> trans(
2269       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
2270
2271   MockWrite data_writes1[] = {
2272     MockWrite("GET / HTTP/1.1\r\n"
2273               "Host: www.google.com\r\n"
2274               "Connection: keep-alive\r\n\r\n"),
2275   };
2276
2277   MockRead data_reads1[] = {
2278     MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2279     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2280     // Large content-length -- won't matter, as connection will be reset.
2281     MockRead("Content-Length: 10000\r\n\r\n"),
2282     MockRead(SYNCHRONOUS, ERR_FAILED),
2283   };
2284
2285   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2286                                  data_writes1, arraysize(data_writes1));
2287   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2288
2289   TestCompletionCallback callback;
2290
2291   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2292   EXPECT_EQ(ERR_IO_PENDING, rv);
2293
2294   rv = callback.WaitForResult();
2295   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2296 }
2297
2298 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2299 // through a non-authenticating proxy. The request should fail with
2300 // ERR_UNEXPECTED_PROXY_AUTH.
2301 // Note that it is impossible to detect if an HTTP server returns a 407 through
2302 // a non-authenticating proxy - there is nothing to indicate whether the
2303 // response came from the proxy or the server, so it is treated as if the proxy
2304 // issued the challenge.
2305 TEST_P(HttpNetworkTransactionTest,
2306        HttpsServerRequestsProxyAuthThroughProxy) {
2307   HttpRequestInfo request;
2308   request.method = "GET";
2309   request.url = GURL("https://www.google.com/");
2310
2311   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2312   CapturingBoundNetLog log;
2313   session_deps_.net_log = log.bound().net_log();
2314   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2315
2316   // Since we have proxy, should try to establish tunnel.
2317   MockWrite data_writes1[] = {
2318     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2319               "Host: www.google.com\r\n"
2320               "Proxy-Connection: keep-alive\r\n\r\n"),
2321
2322     MockWrite("GET / HTTP/1.1\r\n"
2323               "Host: www.google.com\r\n"
2324               "Connection: keep-alive\r\n\r\n"),
2325   };
2326
2327   MockRead data_reads1[] = {
2328     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2329
2330     MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2331     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2332     MockRead("\r\n"),
2333     MockRead(SYNCHRONOUS, OK),
2334   };
2335
2336   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2337                                  data_writes1, arraysize(data_writes1));
2338   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2339   SSLSocketDataProvider ssl(ASYNC, OK);
2340   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2341
2342   TestCompletionCallback callback1;
2343
2344   scoped_ptr<HttpTransaction> trans(
2345       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2346
2347   int rv = trans->Start(&request, callback1.callback(), log.bound());
2348   EXPECT_EQ(ERR_IO_PENDING, rv);
2349
2350   rv = callback1.WaitForResult();
2351   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2352   net::CapturingNetLog::CapturedEntryList entries;
2353   log.GetEntries(&entries);
2354   size_t pos = ExpectLogContainsSomewhere(
2355       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2356       NetLog::PHASE_NONE);
2357   ExpectLogContainsSomewhere(
2358       entries, pos,
2359       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2360       NetLog::PHASE_NONE);
2361 }
2362
2363 // Test the load timing for HTTPS requests with an HTTP proxy.
2364 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
2365   HttpRequestInfo request1;
2366   request1.method = "GET";
2367   request1.url = GURL("https://www.google.com/1");
2368
2369   HttpRequestInfo request2;
2370   request2.method = "GET";
2371   request2.url = GURL("https://www.google.com/2");
2372
2373   // Configure against proxy server "myproxy:70".
2374   session_deps_.proxy_service.reset(
2375       ProxyService::CreateFixed("PROXY myproxy:70"));
2376   CapturingBoundNetLog log;
2377   session_deps_.net_log = log.bound().net_log();
2378   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2379
2380   // Since we have proxy, should try to establish tunnel.
2381   MockWrite data_writes1[] = {
2382     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2383               "Host: www.google.com\r\n"
2384               "Proxy-Connection: keep-alive\r\n\r\n"),
2385
2386     MockWrite("GET /1 HTTP/1.1\r\n"
2387               "Host: www.google.com\r\n"
2388               "Connection: keep-alive\r\n\r\n"),
2389
2390     MockWrite("GET /2 HTTP/1.1\r\n"
2391               "Host: www.google.com\r\n"
2392               "Connection: keep-alive\r\n\r\n"),
2393   };
2394
2395   // The proxy responds to the connect with a 407, using a persistent
2396   // connection.
2397   MockRead data_reads1[] = {
2398     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2399
2400     MockRead("HTTP/1.1 200 OK\r\n"),
2401     MockRead("Content-Length: 1\r\n\r\n"),
2402     MockRead(SYNCHRONOUS, "1"),
2403
2404     MockRead("HTTP/1.1 200 OK\r\n"),
2405     MockRead("Content-Length: 2\r\n\r\n"),
2406     MockRead(SYNCHRONOUS, "22"),
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   scoped_ptr<HttpTransaction> trans1(
2417       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2418
2419   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2420   EXPECT_EQ(ERR_IO_PENDING, rv);
2421
2422   rv = callback1.WaitForResult();
2423   EXPECT_EQ(OK, rv);
2424
2425   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2426   ASSERT_TRUE(response1 != NULL);
2427   ASSERT_TRUE(response1->headers.get() != NULL);
2428   EXPECT_EQ(1, response1->headers->GetContentLength());
2429
2430   LoadTimingInfo load_timing_info1;
2431   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2432   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2433
2434   trans1.reset();
2435
2436   TestCompletionCallback callback2;
2437   scoped_ptr<HttpTransaction> trans2(
2438       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2439
2440   rv = trans2->Start(&request2, callback2.callback(), log.bound());
2441   EXPECT_EQ(ERR_IO_PENDING, rv);
2442
2443   rv = callback2.WaitForResult();
2444   EXPECT_EQ(OK, rv);
2445
2446   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2447   ASSERT_TRUE(response2 != NULL);
2448   ASSERT_TRUE(response2->headers.get() != NULL);
2449   EXPECT_EQ(2, response2->headers->GetContentLength());
2450
2451   LoadTimingInfo load_timing_info2;
2452   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2453   TestLoadTimingReused(load_timing_info2);
2454
2455   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2456
2457   trans2.reset();
2458   session->CloseAllConnections();
2459 }
2460
2461 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
2462 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
2463   HttpRequestInfo request1;
2464   request1.method = "GET";
2465   request1.url = GURL("https://www.google.com/1");
2466
2467   HttpRequestInfo request2;
2468   request2.method = "GET";
2469   request2.url = GURL("https://www.google.com/2");
2470
2471   // Configure against proxy server "myproxy:70".
2472   session_deps_.proxy_service.reset(
2473       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2474   CapturingBoundNetLog log;
2475   session_deps_.net_log = log.bound().net_log();
2476   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2477
2478   // Since we have proxy, should try to establish tunnel.
2479   MockWrite data_writes1[] = {
2480     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2481               "Host: www.google.com\r\n"
2482               "Proxy-Connection: keep-alive\r\n\r\n"),
2483
2484     MockWrite("GET /1 HTTP/1.1\r\n"
2485               "Host: www.google.com\r\n"
2486               "Connection: keep-alive\r\n\r\n"),
2487
2488     MockWrite("GET /2 HTTP/1.1\r\n"
2489               "Host: www.google.com\r\n"
2490               "Connection: keep-alive\r\n\r\n"),
2491   };
2492
2493   // The proxy responds to the connect with a 407, using a persistent
2494   // connection.
2495   MockRead data_reads1[] = {
2496     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2497
2498     MockRead("HTTP/1.1 200 OK\r\n"),
2499     MockRead("Content-Length: 1\r\n\r\n"),
2500     MockRead(SYNCHRONOUS, "1"),
2501
2502     MockRead("HTTP/1.1 200 OK\r\n"),
2503     MockRead("Content-Length: 2\r\n\r\n"),
2504     MockRead(SYNCHRONOUS, "22"),
2505   };
2506
2507   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2508                                  data_writes1, arraysize(data_writes1));
2509   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2510   SSLSocketDataProvider ssl(ASYNC, OK);
2511   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2512
2513   TestCompletionCallback callback1;
2514   scoped_ptr<HttpTransaction> trans1(
2515       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2516
2517   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2518   EXPECT_EQ(ERR_IO_PENDING, rv);
2519
2520   rv = callback1.WaitForResult();
2521   EXPECT_EQ(OK, rv);
2522
2523   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2524   ASSERT_TRUE(response1 != NULL);
2525   ASSERT_TRUE(response1->headers.get() != NULL);
2526   EXPECT_EQ(1, response1->headers->GetContentLength());
2527
2528   LoadTimingInfo load_timing_info1;
2529   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2530   TestLoadTimingNotReusedWithPac(load_timing_info1,
2531                                  CONNECT_TIMING_HAS_SSL_TIMES);
2532
2533   trans1.reset();
2534
2535   TestCompletionCallback callback2;
2536   scoped_ptr<HttpTransaction> trans2(
2537       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2538
2539   rv = trans2->Start(&request2, callback2.callback(), log.bound());
2540   EXPECT_EQ(ERR_IO_PENDING, rv);
2541
2542   rv = callback2.WaitForResult();
2543   EXPECT_EQ(OK, rv);
2544
2545   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2546   ASSERT_TRUE(response2 != NULL);
2547   ASSERT_TRUE(response2->headers.get() != NULL);
2548   EXPECT_EQ(2, response2->headers->GetContentLength());
2549
2550   LoadTimingInfo load_timing_info2;
2551   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2552   TestLoadTimingReusedWithPac(load_timing_info2);
2553
2554   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2555
2556   trans2.reset();
2557   session->CloseAllConnections();
2558 }
2559
2560 // Test a simple get through an HTTPS Proxy.
2561 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
2562   HttpRequestInfo request;
2563   request.method = "GET";
2564   request.url = GURL("http://www.google.com/");
2565
2566   // Configure against https proxy server "proxy:70".
2567   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
2568       "https://proxy:70"));
2569   CapturingBoundNetLog log;
2570   session_deps_.net_log = log.bound().net_log();
2571   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2572
2573   // Since we have proxy, should use full url
2574   MockWrite data_writes1[] = {
2575     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2576               "Host: www.google.com\r\n"
2577               "Proxy-Connection: keep-alive\r\n\r\n"),
2578   };
2579
2580   MockRead data_reads1[] = {
2581     MockRead("HTTP/1.1 200 OK\r\n"),
2582     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2583     MockRead("Content-Length: 100\r\n\r\n"),
2584     MockRead(SYNCHRONOUS, OK),
2585   };
2586
2587   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2588                                  data_writes1, arraysize(data_writes1));
2589   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2590   SSLSocketDataProvider ssl(ASYNC, OK);
2591   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2592
2593   TestCompletionCallback callback1;
2594
2595   scoped_ptr<HttpTransaction> trans(
2596       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2597
2598   int rv = trans->Start(&request, callback1.callback(), log.bound());
2599   EXPECT_EQ(ERR_IO_PENDING, rv);
2600
2601   rv = callback1.WaitForResult();
2602   EXPECT_EQ(OK, rv);
2603
2604   LoadTimingInfo load_timing_info;
2605   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2606   TestLoadTimingNotReused(load_timing_info,
2607                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2608
2609   const HttpResponseInfo* response = trans->GetResponseInfo();
2610   ASSERT_TRUE(response != NULL);
2611
2612   EXPECT_TRUE(response->headers->IsKeepAlive());
2613   EXPECT_EQ(200, response->headers->response_code());
2614   EXPECT_EQ(100, response->headers->GetContentLength());
2615   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2616
2617   // The password prompt info should not be set.
2618   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2619 }
2620
2621 // Test a SPDY get through an HTTPS Proxy.
2622 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
2623   HttpRequestInfo request;
2624   request.method = "GET";
2625   request.url = GURL("http://www.google.com/");
2626   request.load_flags = 0;
2627
2628   // Configure against https proxy server "proxy:70".
2629   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
2630       "https://proxy:70"));
2631   CapturingBoundNetLog log;
2632   session_deps_.net_log = log.bound().net_log();
2633   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2634
2635   // fetch http://www.google.com/ via SPDY
2636   scoped_ptr<SpdyFrame> req(
2637       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
2638   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2639
2640   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2641   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
2642   MockRead spdy_reads[] = {
2643     CreateMockRead(*resp),
2644     CreateMockRead(*data),
2645     MockRead(ASYNC, 0, 0),
2646   };
2647
2648   DelayedSocketData spdy_data(
2649       1,  // wait for one write to finish before reading.
2650       spdy_reads, arraysize(spdy_reads),
2651       spdy_writes, arraysize(spdy_writes));
2652   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
2653
2654   SSLSocketDataProvider ssl(ASYNC, OK);
2655   ssl.SetNextProto(GetParam());
2656   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2657
2658   TestCompletionCallback callback1;
2659
2660   scoped_ptr<HttpTransaction> trans(
2661       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2662
2663   int rv = trans->Start(&request, callback1.callback(), log.bound());
2664   EXPECT_EQ(ERR_IO_PENDING, rv);
2665
2666   rv = callback1.WaitForResult();
2667   EXPECT_EQ(OK, rv);
2668
2669   LoadTimingInfo load_timing_info;
2670   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2671   TestLoadTimingNotReused(load_timing_info,
2672                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2673
2674   const HttpResponseInfo* response = trans->GetResponseInfo();
2675   ASSERT_TRUE(response != NULL);
2676   ASSERT_TRUE(response->headers.get() != NULL);
2677   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2678
2679   std::string response_data;
2680   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
2681   EXPECT_EQ(kUploadData, response_data);
2682 }
2683
2684 // Test a SPDY get through an HTTPS Proxy.
2685 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
2686   HttpRequestInfo request;
2687   request.method = "GET";
2688   request.url = GURL("http://www.google.com/");
2689   request.load_flags = 0;
2690
2691   // Configure against https proxy server "myproxy:70".
2692   session_deps_.proxy_service.reset(
2693       ProxyService::CreateFixed("https://myproxy:70"));
2694   CapturingBoundNetLog log;
2695   session_deps_.net_log = log.bound().net_log();
2696   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2697
2698   // The first request will be a bare GET, the second request will be a
2699   // GET with a Proxy-Authorization header.
2700   scoped_ptr<SpdyFrame> req_get(
2701       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
2702   const char* const kExtraAuthorizationHeaders[] = {
2703     "proxy-authorization", "Basic Zm9vOmJhcg=="
2704   };
2705   scoped_ptr<SpdyFrame> req_get_authorization(
2706       spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
2707                                   arraysize(kExtraAuthorizationHeaders) / 2,
2708                                   false,
2709                                   3,
2710                                   LOWEST,
2711                                   false));
2712   MockWrite spdy_writes[] = {
2713     CreateMockWrite(*req_get, 1),
2714     CreateMockWrite(*req_get_authorization, 4),
2715   };
2716
2717   // The first response is a 407 proxy authentication challenge, and the second
2718   // response will be a 200 response since the second request includes a valid
2719   // Authorization header.
2720   const char* const kExtraAuthenticationHeaders[] = {
2721     "proxy-authenticate", "Basic realm=\"MyRealm1\""
2722   };
2723   scoped_ptr<SpdyFrame> resp_authentication(
2724       spdy_util_.ConstructSpdySynReplyError(
2725           "407 Proxy Authentication Required",
2726           kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
2727           1));
2728   scoped_ptr<SpdyFrame> body_authentication(
2729       spdy_util_.ConstructSpdyBodyFrame(1, true));
2730   scoped_ptr<SpdyFrame> resp_data(
2731       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
2732   scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
2733   MockRead spdy_reads[] = {
2734     CreateMockRead(*resp_authentication, 2),
2735     CreateMockRead(*body_authentication, 3),
2736     CreateMockRead(*resp_data, 5),
2737     CreateMockRead(*body_data, 6),
2738     MockRead(ASYNC, 0, 7),
2739   };
2740
2741   OrderedSocketData data(
2742       spdy_reads, arraysize(spdy_reads),
2743       spdy_writes, arraysize(spdy_writes));
2744   session_deps_.socket_factory->AddSocketDataProvider(&data);
2745
2746   SSLSocketDataProvider ssl(ASYNC, OK);
2747   ssl.SetNextProto(GetParam());
2748   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2749
2750   TestCompletionCallback callback1;
2751
2752   scoped_ptr<HttpTransaction> trans(
2753       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2754
2755   int rv = trans->Start(&request, callback1.callback(), log.bound());
2756   EXPECT_EQ(ERR_IO_PENDING, rv);
2757
2758   rv = callback1.WaitForResult();
2759   EXPECT_EQ(OK, rv);
2760
2761   const HttpResponseInfo* const response = trans->GetResponseInfo();
2762
2763   ASSERT_TRUE(response != NULL);
2764   ASSERT_TRUE(response->headers.get() != NULL);
2765   EXPECT_EQ(407, response->headers->response_code());
2766   EXPECT_TRUE(response->was_fetched_via_spdy);
2767   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2768
2769   TestCompletionCallback callback2;
2770
2771   rv = trans->RestartWithAuth(
2772       AuthCredentials(kFoo, kBar), callback2.callback());
2773   EXPECT_EQ(ERR_IO_PENDING, rv);
2774
2775   rv = callback2.WaitForResult();
2776   EXPECT_EQ(OK, rv);
2777
2778   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
2779
2780   ASSERT_TRUE(response_restart != NULL);
2781   ASSERT_TRUE(response_restart->headers.get() != NULL);
2782   EXPECT_EQ(200, response_restart->headers->response_code());
2783   // The password prompt info should not be set.
2784   EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
2785 }
2786
2787 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
2788 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
2789   HttpRequestInfo request;
2790   request.method = "GET";
2791   request.url = GURL("https://www.google.com/");
2792   request.load_flags = 0;
2793
2794   // Configure against https proxy server "proxy:70".
2795   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
2796       "https://proxy:70"));
2797   CapturingBoundNetLog log;
2798   session_deps_.net_log = log.bound().net_log();
2799   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2800
2801   scoped_ptr<HttpTransaction> trans(
2802       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2803
2804   // CONNECT to www.google.com:443 via SPDY
2805   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2806                                                                 LOWEST));
2807   // fetch https://www.google.com/ via HTTP
2808
2809   const char get[] = "GET / HTTP/1.1\r\n"
2810     "Host: www.google.com\r\n"
2811     "Connection: keep-alive\r\n\r\n";
2812   scoped_ptr<SpdyFrame> wrapped_get(
2813       spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
2814   scoped_ptr<SpdyFrame> conn_resp(
2815       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2816   const char resp[] = "HTTP/1.1 200 OK\r\n"
2817       "Content-Length: 10\r\n\r\n";
2818   scoped_ptr<SpdyFrame> wrapped_get_resp(
2819       spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
2820   scoped_ptr<SpdyFrame> wrapped_body(
2821       spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
2822   scoped_ptr<SpdyFrame> window_update(
2823       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
2824
2825   MockWrite spdy_writes[] = {
2826       CreateMockWrite(*connect, 1),
2827       CreateMockWrite(*wrapped_get, 3),
2828       CreateMockWrite(*window_update, 5),
2829   };
2830
2831   MockRead spdy_reads[] = {
2832     CreateMockRead(*conn_resp, 2, ASYNC),
2833     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2834     CreateMockRead(*wrapped_body, 6, ASYNC),
2835     CreateMockRead(*wrapped_body, 7, ASYNC),
2836     MockRead(ASYNC, 0, 8),
2837   };
2838
2839   OrderedSocketData spdy_data(
2840       spdy_reads, arraysize(spdy_reads),
2841       spdy_writes, arraysize(spdy_writes));
2842   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
2843
2844   SSLSocketDataProvider ssl(ASYNC, OK);
2845   ssl.SetNextProto(GetParam());
2846   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2847   SSLSocketDataProvider ssl2(ASYNC, OK);
2848   ssl2.was_npn_negotiated = false;
2849   ssl2.protocol_negotiated = kProtoUnknown;
2850   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
2851
2852   TestCompletionCallback callback1;
2853
2854   int rv = trans->Start(&request, callback1.callback(), log.bound());
2855   EXPECT_EQ(ERR_IO_PENDING, rv);
2856
2857   rv = callback1.WaitForResult();
2858   EXPECT_EQ(OK, rv);
2859
2860   LoadTimingInfo load_timing_info;
2861   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2862   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2863
2864   const HttpResponseInfo* response = trans->GetResponseInfo();
2865   ASSERT_TRUE(response != NULL);
2866   ASSERT_TRUE(response->headers.get() != NULL);
2867   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2868
2869   std::string response_data;
2870   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
2871   EXPECT_EQ("1234567890", response_data);
2872 }
2873
2874 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
2875 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
2876   HttpRequestInfo request;
2877   request.method = "GET";
2878   request.url = GURL("https://www.google.com/");
2879   request.load_flags = 0;
2880
2881   // Configure against https proxy server "proxy:70".
2882   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
2883       "https://proxy:70"));
2884   CapturingBoundNetLog log;
2885   session_deps_.net_log = log.bound().net_log();
2886   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2887
2888   scoped_ptr<HttpTransaction> trans(
2889       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2890
2891   // CONNECT to www.google.com:443 via SPDY
2892   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2893                                                                 LOWEST));
2894   // fetch https://www.google.com/ via SPDY
2895   const char* const kMyUrl = "https://www.google.com/";
2896   scoped_ptr<SpdyFrame> get(
2897       spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
2898   scoped_ptr<SpdyFrame> wrapped_get(
2899       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
2900   scoped_ptr<SpdyFrame> conn_resp(
2901       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2902   scoped_ptr<SpdyFrame> get_resp(
2903       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2904   scoped_ptr<SpdyFrame> wrapped_get_resp(
2905       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
2906   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2907   scoped_ptr<SpdyFrame> wrapped_body(
2908       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
2909   scoped_ptr<SpdyFrame> window_update_get_resp(
2910       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
2911   scoped_ptr<SpdyFrame> window_update_body(
2912       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
2913
2914   MockWrite spdy_writes[] = {
2915       CreateMockWrite(*connect, 1),
2916       CreateMockWrite(*wrapped_get, 3),
2917       CreateMockWrite(*window_update_get_resp, 5),
2918       CreateMockWrite(*window_update_body, 7),
2919   };
2920
2921   MockRead spdy_reads[] = {
2922     CreateMockRead(*conn_resp, 2, ASYNC),
2923     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2924     CreateMockRead(*wrapped_body, 6, ASYNC),
2925     MockRead(ASYNC, 0, 8),
2926   };
2927
2928   OrderedSocketData spdy_data(
2929       spdy_reads, arraysize(spdy_reads),
2930       spdy_writes, arraysize(spdy_writes));
2931   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
2932
2933   SSLSocketDataProvider ssl(ASYNC, OK);
2934   ssl.SetNextProto(GetParam());
2935   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2936   SSLSocketDataProvider ssl2(ASYNC, OK);
2937   ssl2.SetNextProto(GetParam());
2938   ssl2.protocol_negotiated = GetParam();
2939   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
2940
2941   TestCompletionCallback callback1;
2942
2943   int rv = trans->Start(&request, callback1.callback(), log.bound());
2944   EXPECT_EQ(ERR_IO_PENDING, rv);
2945
2946   rv = callback1.WaitForResult();
2947   EXPECT_EQ(OK, rv);
2948
2949   LoadTimingInfo load_timing_info;
2950   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2951   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2952
2953   const HttpResponseInfo* response = trans->GetResponseInfo();
2954   ASSERT_TRUE(response != NULL);
2955   ASSERT_TRUE(response->headers.get() != NULL);
2956   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2957
2958   std::string response_data;
2959   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
2960   EXPECT_EQ(kUploadData, response_data);
2961 }
2962
2963 // Test a SPDY CONNECT failure through an HTTPS Proxy.
2964 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
2965   HttpRequestInfo request;
2966   request.method = "GET";
2967   request.url = GURL("https://www.google.com/");
2968   request.load_flags = 0;
2969
2970   // Configure against https proxy server "proxy:70".
2971   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
2972       "https://proxy:70"));
2973   CapturingBoundNetLog log;
2974   session_deps_.net_log = log.bound().net_log();
2975   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2976
2977   scoped_ptr<HttpTransaction> trans(
2978       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2979
2980   // CONNECT to www.google.com:443 via SPDY
2981   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2982                                                                 LOWEST));
2983   scoped_ptr<SpdyFrame> get(
2984       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
2985
2986   MockWrite spdy_writes[] = {
2987       CreateMockWrite(*connect, 1),
2988       CreateMockWrite(*get, 3),
2989   };
2990
2991   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
2992   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
2993   MockRead spdy_reads[] = {
2994     CreateMockRead(*resp, 2, ASYNC),
2995     MockRead(ASYNC, 0, 4),
2996   };
2997
2998   OrderedSocketData spdy_data(
2999       spdy_reads, arraysize(spdy_reads),
3000       spdy_writes, arraysize(spdy_writes));
3001   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3002
3003   SSLSocketDataProvider ssl(ASYNC, OK);
3004   ssl.SetNextProto(GetParam());
3005   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3006   SSLSocketDataProvider ssl2(ASYNC, OK);
3007   ssl2.SetNextProto(GetParam());
3008   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
3009
3010   TestCompletionCallback callback1;
3011
3012   int rv = trans->Start(&request, callback1.callback(), log.bound());
3013   EXPECT_EQ(ERR_IO_PENDING, rv);
3014
3015   rv = callback1.WaitForResult();
3016   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3017
3018   // TODO(ttuttle): Anything else to check here?
3019 }
3020
3021 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3022 // HTTPS Proxy to different servers.
3023 TEST_P(HttpNetworkTransactionTest,
3024        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3025   // Configure against https proxy server "proxy:70".
3026   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3027       "https://proxy:70"));
3028   CapturingBoundNetLog log;
3029   session_deps_.net_log = log.bound().net_log();
3030   scoped_refptr<HttpNetworkSession> session(
3031       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
3032
3033   HttpRequestInfo request1;
3034   request1.method = "GET";
3035   request1.url = GURL("https://www.google.com/");
3036   request1.load_flags = 0;
3037
3038   HttpRequestInfo request2;
3039   request2.method = "GET";
3040   request2.url = GURL("https://news.google.com/");
3041   request2.load_flags = 0;
3042
3043   // CONNECT to www.google.com:443 via SPDY.
3044   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3045                                                                  LOWEST));
3046   scoped_ptr<SpdyFrame> conn_resp1(
3047       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3048
3049   // Fetch https://www.google.com/ via HTTP.
3050   const char get1[] = "GET / HTTP/1.1\r\n"
3051       "Host: www.google.com\r\n"
3052       "Connection: keep-alive\r\n\r\n";
3053   scoped_ptr<SpdyFrame> wrapped_get1(
3054       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
3055   const char resp1[] = "HTTP/1.1 200 OK\r\n"
3056       "Content-Length: 1\r\n\r\n";
3057   scoped_ptr<SpdyFrame> wrapped_get_resp1(
3058       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3059   scoped_ptr<SpdyFrame> wrapped_body1(
3060       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
3061   scoped_ptr<SpdyFrame> window_update(
3062       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
3063
3064   // CONNECT to news.google.com:443 via SPDY.
3065   const char* const kConnectHeaders2[] = {
3066     spdy_util_.GetMethodKey(), "CONNECT",
3067     spdy_util_.GetPathKey(), "news.google.com:443",
3068     spdy_util_.GetHostKey(), "news.google.com",
3069     spdy_util_.GetVersionKey(), "HTTP/1.1",
3070   };
3071   scoped_ptr<SpdyFrame> connect2(
3072       spdy_util_.ConstructSpdyControlFrame(NULL,
3073                                            0,
3074                                            /*compressed*/ false,
3075                                            3,
3076                                            LOWEST,
3077                                            SYN_STREAM,
3078                                            CONTROL_FLAG_NONE,
3079                                            kConnectHeaders2,
3080                                            arraysize(kConnectHeaders2),
3081                                            0));
3082   scoped_ptr<SpdyFrame> conn_resp2(
3083       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3084
3085   // Fetch https://news.google.com/ via HTTP.
3086   const char get2[] = "GET / HTTP/1.1\r\n"
3087       "Host: news.google.com\r\n"
3088       "Connection: keep-alive\r\n\r\n";
3089   scoped_ptr<SpdyFrame> wrapped_get2(
3090       spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
3091   const char resp2[] = "HTTP/1.1 200 OK\r\n"
3092       "Content-Length: 2\r\n\r\n";
3093   scoped_ptr<SpdyFrame> wrapped_get_resp2(
3094       spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
3095   scoped_ptr<SpdyFrame> wrapped_body2(
3096       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
3097
3098   MockWrite spdy_writes[] = {
3099       CreateMockWrite(*connect1, 0),
3100       CreateMockWrite(*wrapped_get1, 2),
3101       CreateMockWrite(*connect2, 5),
3102       CreateMockWrite(*wrapped_get2, 7),
3103   };
3104
3105   MockRead spdy_reads[] = {
3106     CreateMockRead(*conn_resp1, 1, ASYNC),
3107     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3108     CreateMockRead(*wrapped_body1, 4, ASYNC),
3109     CreateMockRead(*conn_resp2, 6, ASYNC),
3110     CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3111     CreateMockRead(*wrapped_body2, 9, ASYNC),
3112     MockRead(ASYNC, 0, 10),
3113   };
3114
3115   DeterministicSocketData spdy_data(
3116       spdy_reads, arraysize(spdy_reads),
3117       spdy_writes, arraysize(spdy_writes));
3118   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
3119
3120   SSLSocketDataProvider ssl(ASYNC, OK);
3121   ssl.SetNextProto(GetParam());
3122   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3123   SSLSocketDataProvider ssl2(ASYNC, OK);
3124   ssl2.was_npn_negotiated = false;
3125   ssl2.protocol_negotiated = kProtoUnknown;
3126   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
3127   SSLSocketDataProvider ssl3(ASYNC, OK);
3128   ssl3.was_npn_negotiated = false;
3129   ssl3.protocol_negotiated = kProtoUnknown;
3130   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
3131
3132   TestCompletionCallback callback;
3133
3134   scoped_ptr<HttpTransaction> trans(
3135       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3136   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3137   EXPECT_EQ(ERR_IO_PENDING, rv);
3138   // The first connect and request, each of their responses, and the body.
3139   spdy_data.RunFor(5);
3140
3141   rv = callback.WaitForResult();
3142   EXPECT_EQ(OK, rv);
3143
3144   LoadTimingInfo load_timing_info;
3145   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3146   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3147
3148   const HttpResponseInfo* response = trans->GetResponseInfo();
3149   ASSERT_TRUE(response != NULL);
3150   ASSERT_TRUE(response->headers.get() != NULL);
3151   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3152
3153   std::string response_data;
3154   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3155   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
3156
3157   scoped_ptr<HttpTransaction> trans2(
3158       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3159   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3160   EXPECT_EQ(ERR_IO_PENDING, rv);
3161
3162   // The second connect and request, each of their responses, and the body.
3163   spdy_data.RunFor(5);
3164   rv = callback.WaitForResult();
3165   EXPECT_EQ(OK, rv);
3166
3167   LoadTimingInfo load_timing_info2;
3168   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3169   // Even though the SPDY connection is reused, a new tunnelled connection has
3170   // to be created, so the socket's load timing looks like a fresh connection.
3171   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3172
3173   // The requests should have different IDs, since they each are using their own
3174   // separate stream.
3175   EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3176
3177   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
3178 }
3179
3180 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3181 // HTTPS Proxy to the same server.
3182 TEST_P(HttpNetworkTransactionTest,
3183        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3184   // Configure against https proxy server "proxy:70".
3185   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3186       "https://proxy:70"));
3187   CapturingBoundNetLog log;
3188   session_deps_.net_log = log.bound().net_log();
3189   scoped_refptr<HttpNetworkSession> session(
3190       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
3191
3192   HttpRequestInfo request1;
3193   request1.method = "GET";
3194   request1.url = GURL("https://www.google.com/");
3195   request1.load_flags = 0;
3196
3197   HttpRequestInfo request2;
3198   request2.method = "GET";
3199   request2.url = GURL("https://www.google.com/2");
3200   request2.load_flags = 0;
3201
3202   // CONNECT to www.google.com:443 via SPDY.
3203   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3204                                                                  LOWEST));
3205   scoped_ptr<SpdyFrame> conn_resp1(
3206       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3207
3208   // Fetch https://www.google.com/ via HTTP.
3209   const char get1[] = "GET / HTTP/1.1\r\n"
3210       "Host: www.google.com\r\n"
3211       "Connection: keep-alive\r\n\r\n";
3212   scoped_ptr<SpdyFrame> wrapped_get1(
3213       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
3214   const char resp1[] = "HTTP/1.1 200 OK\r\n"
3215       "Content-Length: 1\r\n\r\n";
3216   scoped_ptr<SpdyFrame> wrapped_get_resp1(
3217       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3218   scoped_ptr<SpdyFrame> wrapped_body1(
3219       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
3220   scoped_ptr<SpdyFrame> window_update(
3221       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
3222
3223   // Fetch https://www.google.com/2 via HTTP.
3224   const char get2[] = "GET /2 HTTP/1.1\r\n"
3225       "Host: www.google.com\r\n"
3226       "Connection: keep-alive\r\n\r\n";
3227   scoped_ptr<SpdyFrame> wrapped_get2(
3228       spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
3229   const char resp2[] = "HTTP/1.1 200 OK\r\n"
3230       "Content-Length: 2\r\n\r\n";
3231   scoped_ptr<SpdyFrame> wrapped_get_resp2(
3232       spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
3233   scoped_ptr<SpdyFrame> wrapped_body2(
3234       spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
3235
3236   MockWrite spdy_writes[] = {
3237       CreateMockWrite(*connect1, 0),
3238       CreateMockWrite(*wrapped_get1, 2),
3239       CreateMockWrite(*wrapped_get2, 5),
3240   };
3241
3242   MockRead spdy_reads[] = {
3243     CreateMockRead(*conn_resp1, 1, ASYNC),
3244     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3245     CreateMockRead(*wrapped_body1, 4, ASYNC),
3246     CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3247     CreateMockRead(*wrapped_body2, 7, ASYNC),
3248     MockRead(ASYNC, 0, 8),
3249   };
3250
3251   DeterministicSocketData spdy_data(
3252       spdy_reads, arraysize(spdy_reads),
3253       spdy_writes, arraysize(spdy_writes));
3254   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
3255
3256   SSLSocketDataProvider ssl(ASYNC, OK);
3257   ssl.SetNextProto(GetParam());
3258   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3259   SSLSocketDataProvider ssl2(ASYNC, OK);
3260   ssl2.was_npn_negotiated = false;
3261   ssl2.protocol_negotiated = kProtoUnknown;
3262   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
3263
3264   TestCompletionCallback callback;
3265
3266   scoped_ptr<HttpTransaction> trans(
3267       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3268   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3269   EXPECT_EQ(ERR_IO_PENDING, rv);
3270   // The first connect and request, each of their responses, and the body.
3271   spdy_data.RunFor(5);
3272
3273   rv = callback.WaitForResult();
3274   EXPECT_EQ(OK, rv);
3275
3276   LoadTimingInfo load_timing_info;
3277   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3278   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3279
3280   const HttpResponseInfo* response = trans->GetResponseInfo();
3281   ASSERT_TRUE(response != NULL);
3282   ASSERT_TRUE(response->headers.get() != NULL);
3283   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3284
3285   std::string response_data;
3286   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3287   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
3288   trans.reset();
3289
3290   scoped_ptr<HttpTransaction> trans2(
3291       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3292   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3293   EXPECT_EQ(ERR_IO_PENDING, rv);
3294
3295   // The second request, response, and body.  There should not be a second
3296   // connect.
3297   spdy_data.RunFor(3);
3298   rv = callback.WaitForResult();
3299   EXPECT_EQ(OK, rv);
3300
3301   LoadTimingInfo load_timing_info2;
3302   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3303   TestLoadTimingReused(load_timing_info2);
3304
3305   // The requests should have the same ID.
3306   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3307
3308   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
3309 }
3310
3311 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3312 // Proxy to different servers.
3313 TEST_P(HttpNetworkTransactionTest,
3314        HttpsProxySpdyLoadTimingTwoHttpRequests) {
3315   // Configure against https proxy server "proxy:70".
3316   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3317       "https://proxy:70"));
3318   CapturingBoundNetLog log;
3319   session_deps_.net_log = log.bound().net_log();
3320   scoped_refptr<HttpNetworkSession> session(
3321       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
3322
3323   HttpRequestInfo request1;
3324   request1.method = "GET";
3325   request1.url = GURL("http://www.google.com/");
3326   request1.load_flags = 0;
3327
3328   HttpRequestInfo request2;
3329   request2.method = "GET";
3330   request2.url = GURL("http://news.google.com/");
3331   request2.load_flags = 0;
3332
3333   // http://www.google.com/
3334   scoped_ptr<SpdyHeaderBlock> headers(
3335       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
3336   scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
3337       headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3338   scoped_ptr<SpdyFrame> get_resp1(
3339       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3340   scoped_ptr<SpdyFrame> body1(
3341       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
3342
3343   // http://news.google.com/
3344   scoped_ptr<SpdyHeaderBlock> headers2(
3345       spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
3346   scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
3347       headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3348   scoped_ptr<SpdyFrame> get_resp2(
3349       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3350   scoped_ptr<SpdyFrame> body2(
3351       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
3352
3353   MockWrite spdy_writes[] = {
3354       CreateMockWrite(*get1, 0),
3355       CreateMockWrite(*get2, 3),
3356   };
3357
3358   MockRead spdy_reads[] = {
3359     CreateMockRead(*get_resp1, 1, ASYNC),
3360     CreateMockRead(*body1, 2, ASYNC),
3361     CreateMockRead(*get_resp2, 4, ASYNC),
3362     CreateMockRead(*body2, 5, ASYNC),
3363     MockRead(ASYNC, 0, 6),
3364   };
3365
3366   DeterministicSocketData spdy_data(
3367       spdy_reads, arraysize(spdy_reads),
3368       spdy_writes, arraysize(spdy_writes));
3369   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
3370
3371   SSLSocketDataProvider ssl(ASYNC, OK);
3372   ssl.SetNextProto(GetParam());
3373   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3374
3375   TestCompletionCallback callback;
3376
3377   scoped_ptr<HttpTransaction> trans(
3378       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3379   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3380   EXPECT_EQ(ERR_IO_PENDING, rv);
3381   spdy_data.RunFor(2);
3382
3383   rv = callback.WaitForResult();
3384   EXPECT_EQ(OK, rv);
3385
3386   LoadTimingInfo load_timing_info;
3387   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3388   TestLoadTimingNotReused(load_timing_info,
3389                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3390
3391   const HttpResponseInfo* response = trans->GetResponseInfo();
3392   ASSERT_TRUE(response != NULL);
3393   ASSERT_TRUE(response->headers.get() != NULL);
3394   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3395
3396   std::string response_data;
3397   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3398   EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
3399   spdy_data.RunFor(1);
3400   EXPECT_EQ(1, callback.WaitForResult());
3401   // Delete the first request, so the second one can reuse the socket.
3402   trans.reset();
3403
3404   scoped_ptr<HttpTransaction> trans2(
3405       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3406   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3407   EXPECT_EQ(ERR_IO_PENDING, rv);
3408
3409   spdy_data.RunFor(2);
3410   rv = callback.WaitForResult();
3411   EXPECT_EQ(OK, rv);
3412
3413   LoadTimingInfo load_timing_info2;
3414   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3415   TestLoadTimingReused(load_timing_info2);
3416
3417   // The requests should have the same ID.
3418   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3419
3420   EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
3421   spdy_data.RunFor(1);
3422   EXPECT_EQ(2, callback.WaitForResult());
3423 }
3424
3425 // Test the challenge-response-retry sequence through an HTTPS Proxy
3426 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
3427   HttpRequestInfo request;
3428   request.method = "GET";
3429   request.url = GURL("http://www.google.com/");
3430   // when the no authentication data flag is set.
3431   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3432
3433   // Configure against https proxy server "myproxy:70".
3434   session_deps_.proxy_service.reset(
3435       ProxyService::CreateFixed("https://myproxy:70"));
3436   CapturingBoundNetLog log;
3437   session_deps_.net_log = log.bound().net_log();
3438   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3439
3440   // Since we have proxy, should use full url
3441   MockWrite data_writes1[] = {
3442     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3443               "Host: www.google.com\r\n"
3444               "Proxy-Connection: keep-alive\r\n\r\n"),
3445
3446     // After calling trans->RestartWithAuth(), this is the request we should
3447     // be issuing -- the final header line contains the credentials.
3448     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3449               "Host: www.google.com\r\n"
3450               "Proxy-Connection: keep-alive\r\n"
3451               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3452   };
3453
3454   // The proxy responds to the GET with a 407, using a persistent
3455   // connection.
3456   MockRead data_reads1[] = {
3457     // No credentials.
3458     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3459     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3460     MockRead("Proxy-Connection: keep-alive\r\n"),
3461     MockRead("Content-Length: 0\r\n\r\n"),
3462
3463     MockRead("HTTP/1.1 200 OK\r\n"),
3464     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3465     MockRead("Content-Length: 100\r\n\r\n"),
3466     MockRead(SYNCHRONOUS, OK),
3467   };
3468
3469   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3470                                  data_writes1, arraysize(data_writes1));
3471   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3472   SSLSocketDataProvider ssl(ASYNC, OK);
3473   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3474
3475   TestCompletionCallback callback1;
3476
3477   scoped_ptr<HttpTransaction> trans(
3478       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3479
3480   int rv = trans->Start(&request, callback1.callback(), log.bound());
3481   EXPECT_EQ(ERR_IO_PENDING, rv);
3482
3483   rv = callback1.WaitForResult();
3484   EXPECT_EQ(OK, rv);
3485
3486   LoadTimingInfo load_timing_info;
3487   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3488   TestLoadTimingNotReused(load_timing_info,
3489                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3490
3491   const HttpResponseInfo* response = trans->GetResponseInfo();
3492   ASSERT_TRUE(response != NULL);
3493   ASSERT_FALSE(response->headers.get() == NULL);
3494   EXPECT_EQ(407, response->headers->response_code());
3495   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3496   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3497
3498   TestCompletionCallback callback2;
3499
3500   rv = trans->RestartWithAuth(
3501       AuthCredentials(kFoo, kBar), callback2.callback());
3502   EXPECT_EQ(ERR_IO_PENDING, rv);
3503
3504   rv = callback2.WaitForResult();
3505   EXPECT_EQ(OK, rv);
3506
3507   load_timing_info = LoadTimingInfo();
3508   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3509   // Retrying with HTTP AUTH is considered to be reusing a socket.
3510   TestLoadTimingReused(load_timing_info);
3511
3512   response = trans->GetResponseInfo();
3513   ASSERT_TRUE(response != NULL);
3514
3515   EXPECT_TRUE(response->headers->IsKeepAlive());
3516   EXPECT_EQ(200, response->headers->response_code());
3517   EXPECT_EQ(100, response->headers->GetContentLength());
3518   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3519
3520   // The password prompt info should not be set.
3521   EXPECT_TRUE(response->auth_challenge.get() == NULL);
3522 }
3523
3524 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
3525     const MockRead& status, int expected_status) {
3526   HttpRequestInfo request;
3527   request.method = "GET";
3528   request.url = GURL("https://www.google.com/");
3529   request.load_flags = 0;
3530
3531   // Configure against proxy server "myproxy:70".
3532   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3533   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3534
3535   // Since we have proxy, should try to establish tunnel.
3536   MockWrite data_writes[] = {
3537     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
3538               "Host: www.google.com\r\n"
3539               "Proxy-Connection: keep-alive\r\n\r\n"),
3540   };
3541
3542   MockRead data_reads[] = {
3543     status,
3544     MockRead("Content-Length: 10\r\n\r\n"),
3545     // No response body because the test stops reading here.
3546     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
3547   };
3548
3549   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3550                                 data_writes, arraysize(data_writes));
3551   session_deps_.socket_factory->AddSocketDataProvider(&data);
3552
3553   TestCompletionCallback callback;
3554
3555   scoped_ptr<HttpTransaction> trans(
3556       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3557
3558   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3559   EXPECT_EQ(ERR_IO_PENDING, rv);
3560
3561   rv = callback.WaitForResult();
3562   EXPECT_EQ(expected_status, rv);
3563 }
3564
3565 void HttpNetworkTransactionTest::ConnectStatusHelper(
3566     const MockRead& status) {
3567   ConnectStatusHelperWithExpectedStatus(
3568       status, ERR_TUNNEL_CONNECTION_FAILED);
3569 }
3570
3571 TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
3572   ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
3573 }
3574
3575 TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
3576   ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
3577 }
3578
3579 TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
3580   ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
3581 }
3582
3583 TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
3584   ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
3585 }
3586
3587 TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
3588   ConnectStatusHelper(
3589       MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
3590 }
3591
3592 TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
3593   ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
3594 }
3595
3596 TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
3597   ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
3598 }
3599
3600 TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
3601   ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
3602 }
3603
3604 TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
3605   ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
3606 }
3607
3608 TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
3609   ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
3610 }
3611
3612 TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
3613   ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
3614 }
3615
3616 TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
3617   ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
3618 }
3619
3620 TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
3621   ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
3622 }
3623
3624 TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
3625   ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
3626 }
3627
3628 TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
3629   ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
3630 }
3631
3632 TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
3633   ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
3634 }
3635
3636 TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
3637   ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
3638 }
3639
3640 TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
3641   ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
3642 }
3643
3644 TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
3645   ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
3646 }
3647
3648 TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
3649   ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
3650 }
3651
3652 TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
3653   ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
3654 }
3655
3656 TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
3657   ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
3658 }
3659
3660 TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
3661   ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
3662 }
3663
3664 TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
3665   ConnectStatusHelperWithExpectedStatus(
3666       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3667       ERR_PROXY_AUTH_UNSUPPORTED);
3668 }
3669
3670 TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
3671   ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
3672 }
3673
3674 TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
3675   ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
3676 }
3677
3678 TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
3679   ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
3680 }
3681
3682 TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
3683   ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
3684 }
3685
3686 TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
3687   ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
3688 }
3689
3690 TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
3691   ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
3692 }
3693
3694 TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
3695   ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
3696 }
3697
3698 TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
3699   ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
3700 }
3701
3702 TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
3703   ConnectStatusHelper(
3704       MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
3705 }
3706
3707 TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
3708   ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
3709 }
3710
3711 TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
3712   ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
3713 }
3714
3715 TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
3716   ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
3717 }
3718
3719 TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
3720   ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
3721 }
3722
3723 TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
3724   ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
3725 }
3726
3727 TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
3728   ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
3729 }
3730
3731 TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
3732   ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
3733 }
3734
3735 // Test the flow when both the proxy server AND origin server require
3736 // authentication. Again, this uses basic auth for both since that is
3737 // the simplest to mock.
3738 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
3739   HttpRequestInfo request;
3740   request.method = "GET";
3741   request.url = GURL("http://www.google.com/");
3742   request.load_flags = 0;
3743
3744   // Configure against proxy server "myproxy:70".
3745   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3746   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3747
3748   scoped_ptr<HttpTransaction> trans(
3749       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
3750
3751   MockWrite data_writes1[] = {
3752     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3753               "Host: www.google.com\r\n"
3754               "Proxy-Connection: keep-alive\r\n\r\n"),
3755   };
3756
3757   MockRead data_reads1[] = {
3758     MockRead("HTTP/1.0 407 Unauthorized\r\n"),
3759     // Give a couple authenticate options (only the middle one is actually
3760     // supported).
3761     MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
3762     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3763     MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
3764     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3765     // Large content-length -- won't matter, as connection will be reset.
3766     MockRead("Content-Length: 10000\r\n\r\n"),
3767     MockRead(SYNCHRONOUS, ERR_FAILED),
3768   };
3769
3770   // After calling trans->RestartWithAuth() the first time, this is the
3771   // request we should be issuing -- the final header line contains the
3772   // proxy's credentials.
3773   MockWrite data_writes2[] = {
3774     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3775               "Host: www.google.com\r\n"
3776               "Proxy-Connection: keep-alive\r\n"
3777               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3778   };
3779
3780   // Now the proxy server lets the request pass through to origin server.
3781   // The origin server responds with a 401.
3782   MockRead data_reads2[] = {
3783     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3784     // Note: We are using the same realm-name as the proxy server. This is
3785     // completely valid, as realms are unique across hosts.
3786     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3787     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3788     MockRead("Content-Length: 2000\r\n\r\n"),
3789     MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
3790   };
3791
3792   // After calling trans->RestartWithAuth() the second time, we should send
3793   // the credentials for both the proxy and origin server.
3794   MockWrite data_writes3[] = {
3795     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3796               "Host: www.google.com\r\n"
3797               "Proxy-Connection: keep-alive\r\n"
3798               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
3799               "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
3800   };
3801
3802   // Lastly we get the desired content.
3803   MockRead data_reads3[] = {
3804     MockRead("HTTP/1.0 200 OK\r\n"),
3805     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3806     MockRead("Content-Length: 100\r\n\r\n"),
3807     MockRead(SYNCHRONOUS, OK),
3808   };
3809
3810   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3811                                  data_writes1, arraysize(data_writes1));
3812   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3813                                  data_writes2, arraysize(data_writes2));
3814   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
3815                                  data_writes3, arraysize(data_writes3));
3816   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3817   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3818   session_deps_.socket_factory->AddSocketDataProvider(&data3);
3819
3820   TestCompletionCallback callback1;
3821
3822   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
3823   EXPECT_EQ(ERR_IO_PENDING, rv);
3824
3825   rv = callback1.WaitForResult();
3826   EXPECT_EQ(OK, rv);
3827
3828   const HttpResponseInfo* response = trans->GetResponseInfo();
3829   ASSERT_TRUE(response != NULL);
3830   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3831
3832   TestCompletionCallback callback2;
3833
3834   rv = trans->RestartWithAuth(
3835       AuthCredentials(kFoo, kBar), callback2.callback());
3836   EXPECT_EQ(ERR_IO_PENDING, rv);
3837
3838   rv = callback2.WaitForResult();
3839   EXPECT_EQ(OK, rv);
3840
3841   response = trans->GetResponseInfo();
3842   ASSERT_TRUE(response != NULL);
3843   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
3844
3845   TestCompletionCallback callback3;
3846
3847   rv = trans->RestartWithAuth(
3848       AuthCredentials(kFoo2, kBar2), callback3.callback());
3849   EXPECT_EQ(ERR_IO_PENDING, rv);
3850
3851   rv = callback3.WaitForResult();
3852   EXPECT_EQ(OK, rv);
3853
3854   response = trans->GetResponseInfo();
3855   EXPECT_TRUE(response->auth_challenge.get() == NULL);
3856   EXPECT_EQ(100, response->headers->GetContentLength());
3857 }
3858
3859 // For the NTLM implementation using SSPI, we skip the NTLM tests since we
3860 // can't hook into its internals to cause it to generate predictable NTLM
3861 // authorization headers.
3862 #if defined(NTLM_PORTABLE)
3863 // The NTLM authentication unit tests were generated by capturing the HTTP
3864 // requests and responses using Fiddler 2 and inspecting the generated random
3865 // bytes in the debugger.
3866
3867 // Enter the correct password and authenticate successfully.
3868 TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
3869   HttpRequestInfo request;
3870   request.method = "GET";
3871   request.url = GURL("http://172.22.68.17/kids/login.aspx");
3872
3873   // Ensure load is not disrupted by flags which suppress behaviour specific
3874   // to other auth schemes.
3875   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
3876
3877   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
3878                                                     MockGetHostName);
3879   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3880
3881   MockWrite data_writes1[] = {
3882     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3883               "Host: 172.22.68.17\r\n"
3884               "Connection: keep-alive\r\n\r\n"),
3885   };
3886
3887   MockRead data_reads1[] = {
3888     MockRead("HTTP/1.1 401 Access Denied\r\n"),
3889     // Negotiate and NTLM are often requested together.  However, we only want
3890     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
3891     // the header that requests Negotiate for this test.
3892     MockRead("WWW-Authenticate: NTLM\r\n"),
3893     MockRead("Connection: close\r\n"),
3894     MockRead("Content-Length: 42\r\n"),
3895     MockRead("Content-Type: text/html\r\n\r\n"),
3896     // Missing content -- won't matter, as connection will be reset.
3897     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
3898   };
3899
3900   MockWrite data_writes2[] = {
3901     // After restarting with a null identity, this is the
3902     // request we should be issuing -- the final header line contains a Type
3903     // 1 message.
3904     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3905               "Host: 172.22.68.17\r\n"
3906               "Connection: keep-alive\r\n"
3907               "Authorization: NTLM "
3908               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
3909
3910     // After calling trans->RestartWithAuth(), we should send a Type 3 message
3911     // (the credentials for the origin server).  The second request continues
3912     // on the same connection.
3913     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3914               "Host: 172.22.68.17\r\n"
3915               "Connection: keep-alive\r\n"
3916               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
3917               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
3918               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
3919               "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
3920               "ahlhx5I=\r\n\r\n"),
3921   };
3922
3923   MockRead data_reads2[] = {
3924     // The origin server responds with a Type 2 message.
3925     MockRead("HTTP/1.1 401 Access Denied\r\n"),
3926     MockRead("WWW-Authenticate: NTLM "
3927              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
3928              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
3929              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
3930              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
3931              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
3932              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
3933              "BtAAAAAAA=\r\n"),
3934     MockRead("Content-Length: 42\r\n"),
3935     MockRead("Content-Type: text/html\r\n\r\n"),
3936     MockRead("You are not authorized to view this page\r\n"),
3937
3938     // Lastly we get the desired content.
3939     MockRead("HTTP/1.1 200 OK\r\n"),
3940     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
3941     MockRead("Content-Length: 13\r\n\r\n"),
3942     MockRead("Please Login\r\n"),
3943     MockRead(SYNCHRONOUS, OK),
3944   };
3945
3946   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3947                                  data_writes1, arraysize(data_writes1));
3948   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3949                                  data_writes2, arraysize(data_writes2));
3950   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3951   session_deps_.socket_factory->AddSocketDataProvider(&data2);
3952
3953   TestCompletionCallback callback1;
3954
3955   scoped_ptr<HttpTransaction> trans(
3956       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3957
3958   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
3959   EXPECT_EQ(ERR_IO_PENDING, rv);
3960
3961   rv = callback1.WaitForResult();
3962   EXPECT_EQ(OK, rv);
3963
3964   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3965
3966   const HttpResponseInfo* response = trans->GetResponseInfo();
3967   ASSERT_FALSE(response == NULL);
3968   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
3969
3970   TestCompletionCallback callback2;
3971
3972   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
3973                               callback2.callback());
3974   EXPECT_EQ(ERR_IO_PENDING, rv);
3975
3976   rv = callback2.WaitForResult();
3977   EXPECT_EQ(OK, rv);
3978
3979   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3980
3981   response = trans->GetResponseInfo();
3982   ASSERT_TRUE(response != NULL);
3983   EXPECT_TRUE(response->auth_challenge.get() == NULL);
3984
3985   TestCompletionCallback callback3;
3986
3987   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
3988   EXPECT_EQ(ERR_IO_PENDING, rv);
3989
3990   rv = callback3.WaitForResult();
3991   EXPECT_EQ(OK, rv);
3992
3993   response = trans->GetResponseInfo();
3994   ASSERT_TRUE(response != NULL);
3995   EXPECT_TRUE(response->auth_challenge.get() == NULL);
3996   EXPECT_EQ(13, response->headers->GetContentLength());
3997 }
3998
3999 // Enter a wrong password, and then the correct one.
4000 TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
4001   HttpRequestInfo request;
4002   request.method = "GET";
4003   request.url = GURL("http://172.22.68.17/kids/login.aspx");
4004   request.load_flags = 0;
4005
4006   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4007                                                     MockGetHostName);
4008   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4009
4010   MockWrite data_writes1[] = {
4011     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4012               "Host: 172.22.68.17\r\n"
4013               "Connection: keep-alive\r\n\r\n"),
4014   };
4015
4016   MockRead data_reads1[] = {
4017     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4018     // Negotiate and NTLM are often requested together.  However, we only want
4019     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4020     // the header that requests Negotiate for this test.
4021     MockRead("WWW-Authenticate: NTLM\r\n"),
4022     MockRead("Connection: close\r\n"),
4023     MockRead("Content-Length: 42\r\n"),
4024     MockRead("Content-Type: text/html\r\n\r\n"),
4025     // Missing content -- won't matter, as connection will be reset.
4026     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4027   };
4028
4029   MockWrite data_writes2[] = {
4030     // After restarting with a null identity, this is the
4031     // request we should be issuing -- the final header line contains a Type
4032     // 1 message.
4033     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4034               "Host: 172.22.68.17\r\n"
4035               "Connection: keep-alive\r\n"
4036               "Authorization: NTLM "
4037               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4038
4039     // After calling trans->RestartWithAuth(), we should send a Type 3 message
4040     // (the credentials for the origin server).  The second request continues
4041     // on the same connection.
4042     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4043               "Host: 172.22.68.17\r\n"
4044               "Connection: keep-alive\r\n"
4045               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4046               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4047               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4048               "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4049               "4Ww7b7E=\r\n\r\n"),
4050   };
4051
4052   MockRead data_reads2[] = {
4053     // The origin server responds with a Type 2 message.
4054     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4055     MockRead("WWW-Authenticate: NTLM "
4056              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4057              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4058              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4059              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4060              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4061              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4062              "BtAAAAAAA=\r\n"),
4063     MockRead("Content-Length: 42\r\n"),
4064     MockRead("Content-Type: text/html\r\n\r\n"),
4065     MockRead("You are not authorized to view this page\r\n"),
4066
4067     // Wrong password.
4068     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4069     MockRead("WWW-Authenticate: NTLM\r\n"),
4070     MockRead("Connection: close\r\n"),
4071     MockRead("Content-Length: 42\r\n"),
4072     MockRead("Content-Type: text/html\r\n\r\n"),
4073     // Missing content -- won't matter, as connection will be reset.
4074     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4075   };
4076
4077   MockWrite data_writes3[] = {
4078     // After restarting with a null identity, this is the
4079     // request we should be issuing -- the final header line contains a Type
4080     // 1 message.
4081     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4082               "Host: 172.22.68.17\r\n"
4083               "Connection: keep-alive\r\n"
4084               "Authorization: NTLM "
4085               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4086
4087     // After calling trans->RestartWithAuth(), we should send a Type 3 message
4088     // (the credentials for the origin server).  The second request continues
4089     // on the same connection.
4090     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4091               "Host: 172.22.68.17\r\n"
4092               "Connection: keep-alive\r\n"
4093               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4094               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4095               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4096               "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4097               "+4MUm7c=\r\n\r\n"),
4098   };
4099
4100   MockRead data_reads3[] = {
4101     // The origin server responds with a Type 2 message.
4102     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4103     MockRead("WWW-Authenticate: NTLM "
4104              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4105              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4106              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4107              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4108              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4109              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4110              "BtAAAAAAA=\r\n"),
4111     MockRead("Content-Length: 42\r\n"),
4112     MockRead("Content-Type: text/html\r\n\r\n"),
4113     MockRead("You are not authorized to view this page\r\n"),
4114
4115     // Lastly we get the desired content.
4116     MockRead("HTTP/1.1 200 OK\r\n"),
4117     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4118     MockRead("Content-Length: 13\r\n\r\n"),
4119     MockRead("Please Login\r\n"),
4120     MockRead(SYNCHRONOUS, OK),
4121   };
4122
4123   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4124                                  data_writes1, arraysize(data_writes1));
4125   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4126                                  data_writes2, arraysize(data_writes2));
4127   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4128                                  data_writes3, arraysize(data_writes3));
4129   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4130   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4131   session_deps_.socket_factory->AddSocketDataProvider(&data3);
4132
4133   TestCompletionCallback callback1;
4134
4135   scoped_ptr<HttpTransaction> trans(
4136       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4137
4138   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4139   EXPECT_EQ(ERR_IO_PENDING, rv);
4140
4141   rv = callback1.WaitForResult();
4142   EXPECT_EQ(OK, rv);
4143
4144   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4145
4146   const HttpResponseInfo* response = trans->GetResponseInfo();
4147   ASSERT_TRUE(response != NULL);
4148   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
4149
4150   TestCompletionCallback callback2;
4151
4152   // Enter the wrong password.
4153   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
4154                               callback2.callback());
4155   EXPECT_EQ(ERR_IO_PENDING, rv);
4156
4157   rv = callback2.WaitForResult();
4158   EXPECT_EQ(OK, rv);
4159
4160   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4161   TestCompletionCallback callback3;
4162   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
4163   EXPECT_EQ(ERR_IO_PENDING, rv);
4164   rv = callback3.WaitForResult();
4165   EXPECT_EQ(OK, rv);
4166   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4167
4168   response = trans->GetResponseInfo();
4169   ASSERT_FALSE(response == NULL);
4170   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
4171
4172   TestCompletionCallback callback4;
4173
4174   // Now enter the right password.
4175   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
4176                               callback4.callback());
4177   EXPECT_EQ(ERR_IO_PENDING, rv);
4178
4179   rv = callback4.WaitForResult();
4180   EXPECT_EQ(OK, rv);
4181
4182   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4183
4184   TestCompletionCallback callback5;
4185
4186   // One more roundtrip
4187   rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
4188   EXPECT_EQ(ERR_IO_PENDING, rv);
4189
4190   rv = callback5.WaitForResult();
4191   EXPECT_EQ(OK, rv);
4192
4193   response = trans->GetResponseInfo();
4194   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4195   EXPECT_EQ(13, response->headers->GetContentLength());
4196 }
4197 #endif  // NTLM_PORTABLE
4198
4199 // Test reading a server response which has only headers, and no body.
4200 // After some maximum number of bytes is consumed, the transaction should
4201 // fail with ERR_RESPONSE_HEADERS_TOO_BIG.
4202 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
4203   HttpRequestInfo request;
4204   request.method = "GET";
4205   request.url = GURL("http://www.google.com/");
4206   request.load_flags = 0;
4207
4208   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4209   scoped_ptr<HttpTransaction> trans(
4210       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
4211
4212   // Respond with 300 kb of headers (we should fail after 256 kb).
4213   std::string large_headers_string;
4214   FillLargeHeadersString(&large_headers_string, 300 * 1024);
4215
4216   MockRead data_reads[] = {
4217     MockRead("HTTP/1.0 200 OK\r\n"),
4218     MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
4219     MockRead("\r\nBODY"),
4220     MockRead(SYNCHRONOUS, OK),
4221   };
4222   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4223   session_deps_.socket_factory->AddSocketDataProvider(&data);
4224
4225   TestCompletionCallback callback;
4226
4227   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4228   EXPECT_EQ(ERR_IO_PENDING, rv);
4229
4230   rv = callback.WaitForResult();
4231   EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
4232
4233   const HttpResponseInfo* response = trans->GetResponseInfo();
4234   EXPECT_TRUE(response == NULL);
4235 }
4236
4237 // Make sure that we don't try to reuse a TCPClientSocket when failing to
4238 // establish tunnel.
4239 // http://code.google.com/p/chromium/issues/detail?id=3772
4240 TEST_P(HttpNetworkTransactionTest,
4241        DontRecycleTransportSocketForSSLTunnel) {
4242   HttpRequestInfo request;
4243   request.method = "GET";
4244   request.url = GURL("https://www.google.com/");
4245   request.load_flags = 0;
4246
4247   // Configure against proxy server "myproxy:70".
4248   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4249
4250   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4251
4252   scoped_ptr<HttpTransaction> trans(
4253       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4254
4255   // Since we have proxy, should try to establish tunnel.
4256   MockWrite data_writes1[] = {
4257     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
4258               "Host: www.google.com\r\n"
4259               "Proxy-Connection: keep-alive\r\n\r\n"),
4260   };
4261
4262   // The proxy responds to the connect with a 404, using a persistent
4263   // connection. Usually a proxy would return 501 (not implemented),
4264   // or 200 (tunnel established).
4265   MockRead data_reads1[] = {
4266     MockRead("HTTP/1.1 404 Not Found\r\n"),
4267     MockRead("Content-Length: 10\r\n\r\n"),
4268     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
4269   };
4270
4271   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4272                                  data_writes1, arraysize(data_writes1));
4273   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4274
4275   TestCompletionCallback callback1;
4276
4277   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4278   EXPECT_EQ(ERR_IO_PENDING, rv);
4279
4280   rv = callback1.WaitForResult();
4281   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
4282
4283   const HttpResponseInfo* response = trans->GetResponseInfo();
4284   EXPECT_TRUE(response == NULL);
4285
4286   // Empty the current queue.  This is necessary because idle sockets are
4287   // added to the connection pool asynchronously with a PostTask.
4288   base::MessageLoop::current()->RunUntilIdle();
4289
4290   // We now check to make sure the TCPClientSocket was not added back to
4291   // the pool.
4292   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4293   trans.reset();
4294   base::MessageLoop::current()->RunUntilIdle();
4295   // Make sure that the socket didn't get recycled after calling the destructor.
4296   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4297 }
4298
4299 // Make sure that we recycle a socket after reading all of the response body.
4300 TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
4301   HttpRequestInfo request;
4302   request.method = "GET";
4303   request.url = GURL("http://www.google.com/");
4304   request.load_flags = 0;
4305
4306   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4307
4308   scoped_ptr<HttpTransaction> trans(
4309       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4310
4311   MockRead data_reads[] = {
4312     // A part of the response body is received with the response headers.
4313     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4314     // The rest of the response body is received in two parts.
4315     MockRead("lo"),
4316     MockRead(" world"),
4317     MockRead("junk"),  // Should not be read!!
4318     MockRead(SYNCHRONOUS, OK),
4319   };
4320
4321   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4322   session_deps_.socket_factory->AddSocketDataProvider(&data);
4323
4324   TestCompletionCallback callback;
4325
4326   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4327   EXPECT_EQ(ERR_IO_PENDING, rv);
4328
4329   rv = callback.WaitForResult();
4330   EXPECT_EQ(OK, rv);
4331
4332   const HttpResponseInfo* response = trans->GetResponseInfo();
4333   ASSERT_TRUE(response != NULL);
4334
4335   EXPECT_TRUE(response->headers.get() != NULL);
4336   std::string status_line = response->headers->GetStatusLine();
4337   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4338
4339   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4340
4341   std::string response_data;
4342   rv = ReadTransaction(trans.get(), &response_data);
4343   EXPECT_EQ(OK, rv);
4344   EXPECT_EQ("hello world", response_data);
4345
4346   // Empty the current queue.  This is necessary because idle sockets are
4347   // added to the connection pool asynchronously with a PostTask.
4348   base::MessageLoop::current()->RunUntilIdle();
4349
4350   // We now check to make sure the socket was added back to the pool.
4351   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
4352 }
4353
4354 // Make sure that we recycle a SSL socket after reading all of the response
4355 // body.
4356 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
4357   HttpRequestInfo request;
4358   request.method = "GET";
4359   request.url = GURL("https://www.google.com/");
4360   request.load_flags = 0;
4361
4362   MockWrite data_writes[] = {
4363     MockWrite("GET / HTTP/1.1\r\n"
4364               "Host: www.google.com\r\n"
4365               "Connection: keep-alive\r\n\r\n"),
4366   };
4367
4368   MockRead data_reads[] = {
4369     MockRead("HTTP/1.1 200 OK\r\n"),
4370     MockRead("Content-Length: 11\r\n\r\n"),
4371     MockRead("hello world"),
4372     MockRead(SYNCHRONOUS, OK),
4373   };
4374
4375   SSLSocketDataProvider ssl(ASYNC, OK);
4376   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4377
4378   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4379                                 data_writes, arraysize(data_writes));
4380   session_deps_.socket_factory->AddSocketDataProvider(&data);
4381
4382   TestCompletionCallback callback;
4383
4384   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4385   scoped_ptr<HttpTransaction> trans(
4386       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4387
4388   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4389
4390   EXPECT_EQ(ERR_IO_PENDING, rv);
4391   EXPECT_EQ(OK, callback.WaitForResult());
4392
4393   const HttpResponseInfo* response = trans->GetResponseInfo();
4394   ASSERT_TRUE(response != NULL);
4395   ASSERT_TRUE(response->headers.get() != NULL);
4396   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4397
4398   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4399
4400   std::string response_data;
4401   rv = ReadTransaction(trans.get(), &response_data);
4402   EXPECT_EQ(OK, rv);
4403   EXPECT_EQ("hello world", response_data);
4404
4405   // Empty the current queue.  This is necessary because idle sockets are
4406   // added to the connection pool asynchronously with a PostTask.
4407   base::MessageLoop::current()->RunUntilIdle();
4408
4409   // We now check to make sure the socket was added back to the pool.
4410   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
4411 }
4412
4413 // Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
4414 // from the pool and make sure that we recover okay.
4415 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
4416   HttpRequestInfo request;
4417   request.method = "GET";
4418   request.url = GURL("https://www.google.com/");
4419   request.load_flags = 0;
4420
4421   MockWrite data_writes[] = {
4422     MockWrite("GET / HTTP/1.1\r\n"
4423               "Host: www.google.com\r\n"
4424               "Connection: keep-alive\r\n\r\n"),
4425     MockWrite("GET / HTTP/1.1\r\n"
4426               "Host: www.google.com\r\n"
4427               "Connection: keep-alive\r\n\r\n"),
4428   };
4429
4430   MockRead data_reads[] = {
4431     MockRead("HTTP/1.1 200 OK\r\n"),
4432     MockRead("Content-Length: 11\r\n\r\n"),
4433     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4434     MockRead("hello world"),
4435     MockRead(ASYNC, 0, 0)   // EOF
4436   };
4437
4438   SSLSocketDataProvider ssl(ASYNC, OK);
4439   SSLSocketDataProvider ssl2(ASYNC, OK);
4440   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4441   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
4442
4443   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4444                                 data_writes, arraysize(data_writes));
4445   StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4446                                 data_writes, arraysize(data_writes));
4447   session_deps_.socket_factory->AddSocketDataProvider(&data);
4448   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4449
4450   TestCompletionCallback callback;
4451
4452   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4453   scoped_ptr<HttpTransaction> trans(
4454       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4455
4456   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4457
4458   EXPECT_EQ(ERR_IO_PENDING, rv);
4459   EXPECT_EQ(OK, callback.WaitForResult());
4460
4461   const HttpResponseInfo* response = trans->GetResponseInfo();
4462   ASSERT_TRUE(response != NULL);
4463   ASSERT_TRUE(response->headers.get() != NULL);
4464   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4465
4466   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4467
4468   std::string response_data;
4469   rv = ReadTransaction(trans.get(), &response_data);
4470   EXPECT_EQ(OK, rv);
4471   EXPECT_EQ("hello world", response_data);
4472
4473   // Empty the current queue.  This is necessary because idle sockets are
4474   // added to the connection pool asynchronously with a PostTask.
4475   base::MessageLoop::current()->RunUntilIdle();
4476
4477   // We now check to make sure the socket was added back to the pool.
4478   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
4479
4480   // Now start the second transaction, which should reuse the previous socket.
4481
4482   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4483
4484   rv = trans->Start(&request, callback.callback(), BoundNetLog());
4485
4486   EXPECT_EQ(ERR_IO_PENDING, rv);
4487   EXPECT_EQ(OK, callback.WaitForResult());
4488
4489   response = trans->GetResponseInfo();
4490   ASSERT_TRUE(response != NULL);
4491   ASSERT_TRUE(response->headers.get() != NULL);
4492   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4493
4494   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4495
4496   rv = ReadTransaction(trans.get(), &response_data);
4497   EXPECT_EQ(OK, rv);
4498   EXPECT_EQ("hello world", response_data);
4499
4500   // Empty the current queue.  This is necessary because idle sockets are
4501   // added to the connection pool asynchronously with a PostTask.
4502   base::MessageLoop::current()->RunUntilIdle();
4503
4504   // We now check to make sure the socket was added back to the pool.
4505   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
4506 }
4507
4508 // Make sure that we recycle a socket after a zero-length response.
4509 // http://crbug.com/9880
4510 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
4511   HttpRequestInfo request;
4512   request.method = "GET";
4513   request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4514                      "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4515                      "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4516                      "rt=prt.2642,ol.2649,xjs.2951");
4517   request.load_flags = 0;
4518
4519   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4520
4521   scoped_ptr<HttpTransaction> trans(
4522       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4523
4524   MockRead data_reads[] = {
4525     MockRead("HTTP/1.1 204 No Content\r\n"
4526              "Content-Length: 0\r\n"
4527              "Content-Type: text/html\r\n\r\n"),
4528     MockRead("junk"),  // Should not be read!!
4529     MockRead(SYNCHRONOUS, OK),
4530   };
4531
4532   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4533   session_deps_.socket_factory->AddSocketDataProvider(&data);
4534
4535   TestCompletionCallback callback;
4536
4537   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4538   EXPECT_EQ(ERR_IO_PENDING, rv);
4539
4540   rv = callback.WaitForResult();
4541   EXPECT_EQ(OK, rv);
4542
4543   const HttpResponseInfo* response = trans->GetResponseInfo();
4544   ASSERT_TRUE(response != NULL);
4545
4546   EXPECT_TRUE(response->headers.get() != NULL);
4547   std::string status_line = response->headers->GetStatusLine();
4548   EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4549
4550   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4551
4552   std::string response_data;
4553   rv = ReadTransaction(trans.get(), &response_data);
4554   EXPECT_EQ(OK, rv);
4555   EXPECT_EQ("", response_data);
4556
4557   // Empty the current queue.  This is necessary because idle sockets are
4558   // added to the connection pool asynchronously with a PostTask.
4559   base::MessageLoop::current()->RunUntilIdle();
4560
4561   // We now check to make sure the socket was added back to the pool.
4562   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
4563 }
4564
4565 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
4566   ScopedVector<UploadElementReader> element_readers;
4567   element_readers.push_back(new UploadBytesElementReader("foo", 3));
4568   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
4569
4570   HttpRequestInfo request[2];
4571   // Transaction 1: a GET request that succeeds.  The socket is recycled
4572   // after use.
4573   request[0].method = "GET";
4574   request[0].url = GURL("http://www.google.com/");
4575   request[0].load_flags = 0;
4576   // Transaction 2: a POST request.  Reuses the socket kept alive from
4577   // transaction 1.  The first attempts fails when writing the POST data.
4578   // This causes the transaction to retry with a new socket.  The second
4579   // attempt succeeds.
4580   request[1].method = "POST";
4581   request[1].url = GURL("http://www.google.com/login.cgi");
4582   request[1].upload_data_stream = &upload_data_stream;
4583   request[1].load_flags = 0;
4584
4585   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4586
4587   // The first socket is used for transaction 1 and the first attempt of
4588   // transaction 2.
4589
4590   // The response of transaction 1.
4591   MockRead data_reads1[] = {
4592     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
4593     MockRead("hello world"),
4594     MockRead(SYNCHRONOUS, OK),
4595   };
4596   // The mock write results of transaction 1 and the first attempt of
4597   // transaction 2.
4598   MockWrite data_writes1[] = {
4599     MockWrite(SYNCHRONOUS, 64),  // GET
4600     MockWrite(SYNCHRONOUS, 93),  // POST
4601     MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
4602   };
4603   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4604                                  data_writes1, arraysize(data_writes1));
4605
4606   // The second socket is used for the second attempt of transaction 2.
4607
4608   // The response of transaction 2.
4609   MockRead data_reads2[] = {
4610     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
4611     MockRead("welcome"),
4612     MockRead(SYNCHRONOUS, OK),
4613   };
4614   // The mock write results of the second attempt of transaction 2.
4615   MockWrite data_writes2[] = {
4616     MockWrite(SYNCHRONOUS, 93),  // POST
4617     MockWrite(SYNCHRONOUS, 3),  // POST data
4618   };
4619   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4620                                  data_writes2, arraysize(data_writes2));
4621
4622   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4623   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4624
4625   const char* kExpectedResponseData[] = {
4626     "hello world", "welcome"
4627   };
4628
4629   for (int i = 0; i < 2; ++i) {
4630     scoped_ptr<HttpTransaction> trans(
4631         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4632
4633     TestCompletionCallback callback;
4634
4635     int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
4636     EXPECT_EQ(ERR_IO_PENDING, rv);
4637
4638     rv = callback.WaitForResult();
4639     EXPECT_EQ(OK, rv);
4640
4641     const HttpResponseInfo* response = trans->GetResponseInfo();
4642     ASSERT_TRUE(response != NULL);
4643
4644     EXPECT_TRUE(response->headers.get() != NULL);
4645     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4646
4647     std::string response_data;
4648     rv = ReadTransaction(trans.get(), &response_data);
4649     EXPECT_EQ(OK, rv);
4650     EXPECT_EQ(kExpectedResponseData[i], response_data);
4651   }
4652 }
4653
4654 // Test the request-challenge-retry sequence for basic auth when there is
4655 // an identity in the URL. The request should be sent as normal, but when
4656 // it fails the identity from the URL is used to answer the challenge.
4657 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
4658   HttpRequestInfo request;
4659   request.method = "GET";
4660   request.url = GURL("http://foo:b@r@www.google.com/");
4661   request.load_flags = LOAD_NORMAL;
4662
4663   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4664   scoped_ptr<HttpTransaction> trans(
4665       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
4666
4667   // The password contains an escaped character -- for this test to pass it
4668   // will need to be unescaped by HttpNetworkTransaction.
4669   EXPECT_EQ("b%40r", request.url.password());
4670
4671   MockWrite data_writes1[] = {
4672     MockWrite("GET / HTTP/1.1\r\n"
4673               "Host: www.google.com\r\n"
4674               "Connection: keep-alive\r\n\r\n"),
4675   };
4676
4677   MockRead data_reads1[] = {
4678     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4679     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4680     MockRead("Content-Length: 10\r\n\r\n"),
4681     MockRead(SYNCHRONOUS, ERR_FAILED),
4682   };
4683
4684   // After the challenge above, the transaction will be restarted using the
4685   // identity from the url (foo, b@r) to answer the challenge.
4686   MockWrite data_writes2[] = {
4687     MockWrite("GET / HTTP/1.1\r\n"
4688               "Host: www.google.com\r\n"
4689               "Connection: keep-alive\r\n"
4690               "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
4691   };
4692
4693   MockRead data_reads2[] = {
4694     MockRead("HTTP/1.0 200 OK\r\n"),
4695     MockRead("Content-Length: 100\r\n\r\n"),
4696     MockRead(SYNCHRONOUS, OK),
4697   };
4698
4699   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4700                                  data_writes1, arraysize(data_writes1));
4701   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4702                                  data_writes2, arraysize(data_writes2));
4703   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4704   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4705
4706   TestCompletionCallback callback1;
4707   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4708   EXPECT_EQ(ERR_IO_PENDING, rv);
4709   rv = callback1.WaitForResult();
4710   EXPECT_EQ(OK, rv);
4711   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4712
4713   TestCompletionCallback callback2;
4714   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4715   EXPECT_EQ(ERR_IO_PENDING, rv);
4716   rv = callback2.WaitForResult();
4717   EXPECT_EQ(OK, rv);
4718   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4719
4720   const HttpResponseInfo* response = trans->GetResponseInfo();
4721   ASSERT_TRUE(response != NULL);
4722
4723   // There is no challenge info, since the identity in URL worked.
4724   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4725
4726   EXPECT_EQ(100, response->headers->GetContentLength());
4727
4728   // Empty the current queue.
4729   base::MessageLoop::current()->RunUntilIdle();
4730 }
4731
4732 // Test the request-challenge-retry sequence for basic auth when there is an
4733 // incorrect identity in the URL. The identity from the URL should be used only
4734 // once.
4735 TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
4736   HttpRequestInfo request;
4737   request.method = "GET";
4738   // Note: the URL has a username:password in it.  The password "baz" is
4739   // wrong (should be "bar").
4740   request.url = GURL("http://foo:baz@www.google.com/");
4741
4742   request.load_flags = LOAD_NORMAL;
4743
4744   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4745   scoped_ptr<HttpTransaction> trans(
4746       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
4747
4748   MockWrite data_writes1[] = {
4749     MockWrite("GET / HTTP/1.1\r\n"
4750               "Host: www.google.com\r\n"
4751               "Connection: keep-alive\r\n\r\n"),
4752   };
4753
4754   MockRead data_reads1[] = {
4755     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4756     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4757     MockRead("Content-Length: 10\r\n\r\n"),
4758     MockRead(SYNCHRONOUS, ERR_FAILED),
4759   };
4760
4761   // After the challenge above, the transaction will be restarted using the
4762   // identity from the url (foo, baz) to answer the challenge.
4763   MockWrite data_writes2[] = {
4764     MockWrite("GET / HTTP/1.1\r\n"
4765               "Host: www.google.com\r\n"
4766               "Connection: keep-alive\r\n"
4767               "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
4768   };
4769
4770   MockRead data_reads2[] = {
4771     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4772     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4773     MockRead("Content-Length: 10\r\n\r\n"),
4774     MockRead(SYNCHRONOUS, ERR_FAILED),
4775   };
4776
4777   // After the challenge above, the transaction will be restarted using the
4778   // identity supplied by the user (foo, bar) to answer the challenge.
4779   MockWrite data_writes3[] = {
4780     MockWrite("GET / HTTP/1.1\r\n"
4781               "Host: www.google.com\r\n"
4782               "Connection: keep-alive\r\n"
4783               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4784   };
4785
4786   MockRead data_reads3[] = {
4787     MockRead("HTTP/1.0 200 OK\r\n"),
4788     MockRead("Content-Length: 100\r\n\r\n"),
4789     MockRead(SYNCHRONOUS, OK),
4790   };
4791
4792   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4793                                  data_writes1, arraysize(data_writes1));
4794   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4795                                  data_writes2, arraysize(data_writes2));
4796   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4797                                  data_writes3, arraysize(data_writes3));
4798   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4799   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4800   session_deps_.socket_factory->AddSocketDataProvider(&data3);
4801
4802   TestCompletionCallback callback1;
4803
4804   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4805   EXPECT_EQ(ERR_IO_PENDING, rv);
4806
4807   rv = callback1.WaitForResult();
4808   EXPECT_EQ(OK, rv);
4809
4810   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4811   TestCompletionCallback callback2;
4812   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4813   EXPECT_EQ(ERR_IO_PENDING, rv);
4814   rv = callback2.WaitForResult();
4815   EXPECT_EQ(OK, rv);
4816   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4817
4818   const HttpResponseInfo* response = trans->GetResponseInfo();
4819   ASSERT_TRUE(response != NULL);
4820   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4821
4822   TestCompletionCallback callback3;
4823   rv = trans->RestartWithAuth(
4824       AuthCredentials(kFoo, kBar), callback3.callback());
4825   EXPECT_EQ(ERR_IO_PENDING, rv);
4826   rv = callback3.WaitForResult();
4827   EXPECT_EQ(OK, rv);
4828   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4829
4830   response = trans->GetResponseInfo();
4831   ASSERT_TRUE(response != NULL);
4832
4833   // There is no challenge info, since the identity worked.
4834   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4835
4836   EXPECT_EQ(100, response->headers->GetContentLength());
4837
4838   // Empty the current queue.
4839   base::MessageLoop::current()->RunUntilIdle();
4840 }
4841
4842
4843 // Test the request-challenge-retry sequence for basic auth when there is a
4844 // correct identity in the URL, but its use is being suppressed. The identity
4845 // from the URL should never be used.
4846 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
4847   HttpRequestInfo request;
4848   request.method = "GET";
4849   request.url = GURL("http://foo:bar@www.google.com/");
4850   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
4851
4852   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4853   scoped_ptr<HttpTransaction> trans(
4854       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
4855
4856   MockWrite data_writes1[] = {
4857     MockWrite("GET / HTTP/1.1\r\n"
4858               "Host: www.google.com\r\n"
4859               "Connection: keep-alive\r\n\r\n"),
4860   };
4861
4862   MockRead data_reads1[] = {
4863     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4864     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4865     MockRead("Content-Length: 10\r\n\r\n"),
4866     MockRead(SYNCHRONOUS, ERR_FAILED),
4867   };
4868
4869   // After the challenge above, the transaction will be restarted using the
4870   // identity supplied by the user, not the one in the URL, to answer the
4871   // challenge.
4872   MockWrite data_writes3[] = {
4873     MockWrite("GET / HTTP/1.1\r\n"
4874               "Host: www.google.com\r\n"
4875               "Connection: keep-alive\r\n"
4876               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4877   };
4878
4879   MockRead data_reads3[] = {
4880     MockRead("HTTP/1.0 200 OK\r\n"),
4881     MockRead("Content-Length: 100\r\n\r\n"),
4882     MockRead(SYNCHRONOUS, OK),
4883   };
4884
4885   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4886                                  data_writes1, arraysize(data_writes1));
4887   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4888                                  data_writes3, arraysize(data_writes3));
4889   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4890   session_deps_.socket_factory->AddSocketDataProvider(&data3);
4891
4892   TestCompletionCallback callback1;
4893   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4894   EXPECT_EQ(ERR_IO_PENDING, rv);
4895   rv = callback1.WaitForResult();
4896   EXPECT_EQ(OK, rv);
4897   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4898
4899   const HttpResponseInfo* response = trans->GetResponseInfo();
4900   ASSERT_TRUE(response != NULL);
4901   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4902
4903   TestCompletionCallback callback3;
4904   rv = trans->RestartWithAuth(
4905       AuthCredentials(kFoo, kBar), callback3.callback());
4906   EXPECT_EQ(ERR_IO_PENDING, rv);
4907   rv = callback3.WaitForResult();
4908   EXPECT_EQ(OK, rv);
4909   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4910
4911   response = trans->GetResponseInfo();
4912   ASSERT_TRUE(response != NULL);
4913
4914   // There is no challenge info, since the identity worked.
4915   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4916   EXPECT_EQ(100, response->headers->GetContentLength());
4917
4918   // Empty the current queue.
4919   base::MessageLoop::current()->RunUntilIdle();
4920 }
4921
4922 // Test that previously tried username/passwords for a realm get re-used.
4923 TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
4924   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4925
4926   // Transaction 1: authenticate (foo, bar) on MyRealm1
4927   {
4928     HttpRequestInfo request;
4929     request.method = "GET";
4930     request.url = GURL("http://www.google.com/x/y/z");
4931     request.load_flags = 0;
4932
4933     scoped_ptr<HttpTransaction> trans(
4934         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4935
4936     MockWrite data_writes1[] = {
4937       MockWrite("GET /x/y/z HTTP/1.1\r\n"
4938                 "Host: www.google.com\r\n"
4939                 "Connection: keep-alive\r\n\r\n"),
4940     };
4941
4942     MockRead data_reads1[] = {
4943       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4944       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4945       MockRead("Content-Length: 10000\r\n\r\n"),
4946       MockRead(SYNCHRONOUS, ERR_FAILED),
4947     };
4948
4949     // Resend with authorization (username=foo, password=bar)
4950     MockWrite data_writes2[] = {
4951       MockWrite("GET /x/y/z HTTP/1.1\r\n"
4952                 "Host: www.google.com\r\n"
4953                 "Connection: keep-alive\r\n"
4954                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4955     };
4956
4957     // Sever accepts the authorization.
4958     MockRead data_reads2[] = {
4959       MockRead("HTTP/1.0 200 OK\r\n"),
4960       MockRead("Content-Length: 100\r\n\r\n"),
4961       MockRead(SYNCHRONOUS, OK),
4962     };
4963
4964     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4965                                    data_writes1, arraysize(data_writes1));
4966     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4967                                    data_writes2, arraysize(data_writes2));
4968     session_deps_.socket_factory->AddSocketDataProvider(&data1);
4969     session_deps_.socket_factory->AddSocketDataProvider(&data2);
4970
4971     TestCompletionCallback callback1;
4972
4973     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4974     EXPECT_EQ(ERR_IO_PENDING, rv);
4975
4976     rv = callback1.WaitForResult();
4977     EXPECT_EQ(OK, rv);
4978
4979     const HttpResponseInfo* response = trans->GetResponseInfo();
4980     ASSERT_TRUE(response != NULL);
4981     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4982
4983     TestCompletionCallback callback2;
4984
4985     rv = trans->RestartWithAuth(
4986         AuthCredentials(kFoo, kBar), callback2.callback());
4987     EXPECT_EQ(ERR_IO_PENDING, rv);
4988
4989     rv = callback2.WaitForResult();
4990     EXPECT_EQ(OK, rv);
4991
4992     response = trans->GetResponseInfo();
4993     ASSERT_TRUE(response != NULL);
4994     EXPECT_TRUE(response->auth_challenge.get() == NULL);
4995     EXPECT_EQ(100, response->headers->GetContentLength());
4996   }
4997
4998   // ------------------------------------------------------------------------
4999
5000   // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5001   {
5002     HttpRequestInfo request;
5003     request.method = "GET";
5004     // Note that Transaction 1 was at /x/y/z, so this is in the same
5005     // protection space as MyRealm1.
5006     request.url = GURL("http://www.google.com/x/y/a/b");
5007     request.load_flags = 0;
5008
5009     scoped_ptr<HttpTransaction> trans(
5010         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5011
5012     MockWrite data_writes1[] = {
5013       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5014                 "Host: www.google.com\r\n"
5015                 "Connection: keep-alive\r\n"
5016                 // Send preemptive authorization for MyRealm1
5017                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5018     };
5019
5020     // The server didn't like the preemptive authorization, and
5021     // challenges us for a different realm (MyRealm2).
5022     MockRead data_reads1[] = {
5023       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5024       MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5025       MockRead("Content-Length: 10000\r\n\r\n"),
5026       MockRead(SYNCHRONOUS, ERR_FAILED),
5027     };
5028
5029     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5030     MockWrite data_writes2[] = {
5031       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5032                 "Host: www.google.com\r\n"
5033                 "Connection: keep-alive\r\n"
5034                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5035     };
5036
5037     // Sever accepts the authorization.
5038     MockRead data_reads2[] = {
5039       MockRead("HTTP/1.0 200 OK\r\n"),
5040       MockRead("Content-Length: 100\r\n\r\n"),
5041       MockRead(SYNCHRONOUS, OK),
5042     };
5043
5044     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5045                                    data_writes1, arraysize(data_writes1));
5046     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5047                                    data_writes2, arraysize(data_writes2));
5048     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5049     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5050
5051     TestCompletionCallback callback1;
5052
5053     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5054     EXPECT_EQ(ERR_IO_PENDING, rv);
5055
5056     rv = callback1.WaitForResult();
5057     EXPECT_EQ(OK, rv);
5058
5059     const HttpResponseInfo* response = trans->GetResponseInfo();
5060     ASSERT_TRUE(response != NULL);
5061     ASSERT_TRUE(response->auth_challenge.get());
5062     EXPECT_FALSE(response->auth_challenge->is_proxy);
5063     EXPECT_EQ("www.google.com:80",
5064               response->auth_challenge->challenger.ToString());
5065     EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5066     EXPECT_EQ("basic", response->auth_challenge->scheme);
5067
5068     TestCompletionCallback callback2;
5069
5070     rv = trans->RestartWithAuth(
5071         AuthCredentials(kFoo2, kBar2), callback2.callback());
5072     EXPECT_EQ(ERR_IO_PENDING, rv);
5073
5074     rv = callback2.WaitForResult();
5075     EXPECT_EQ(OK, rv);
5076
5077     response = trans->GetResponseInfo();
5078     ASSERT_TRUE(response != NULL);
5079     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5080     EXPECT_EQ(100, response->headers->GetContentLength());
5081   }
5082
5083   // ------------------------------------------------------------------------
5084
5085   // Transaction 3: Resend a request in MyRealm's protection space --
5086   // succeed with preemptive authorization.
5087   {
5088     HttpRequestInfo request;
5089     request.method = "GET";
5090     request.url = GURL("http://www.google.com/x/y/z2");
5091     request.load_flags = 0;
5092
5093     scoped_ptr<HttpTransaction> trans(
5094         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5095
5096     MockWrite data_writes1[] = {
5097       MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5098                 "Host: www.google.com\r\n"
5099                 "Connection: keep-alive\r\n"
5100                 // The authorization for MyRealm1 gets sent preemptively
5101                 // (since the url is in the same protection space)
5102                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5103     };
5104
5105     // Sever accepts the preemptive authorization
5106     MockRead data_reads1[] = {
5107       MockRead("HTTP/1.0 200 OK\r\n"),
5108       MockRead("Content-Length: 100\r\n\r\n"),
5109       MockRead(SYNCHRONOUS, OK),
5110     };
5111
5112     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5113                                    data_writes1, arraysize(data_writes1));
5114     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5115
5116     TestCompletionCallback callback1;
5117
5118     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5119     EXPECT_EQ(ERR_IO_PENDING, rv);
5120
5121     rv = callback1.WaitForResult();
5122     EXPECT_EQ(OK, rv);
5123
5124     const HttpResponseInfo* response = trans->GetResponseInfo();
5125     ASSERT_TRUE(response != NULL);
5126
5127     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5128     EXPECT_EQ(100, response->headers->GetContentLength());
5129   }
5130
5131   // ------------------------------------------------------------------------
5132
5133   // Transaction 4: request another URL in MyRealm (however the
5134   // url is not known to belong to the protection space, so no pre-auth).
5135   {
5136     HttpRequestInfo request;
5137     request.method = "GET";
5138     request.url = GURL("http://www.google.com/x/1");
5139     request.load_flags = 0;
5140
5141     scoped_ptr<HttpTransaction> trans(
5142         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5143
5144     MockWrite data_writes1[] = {
5145       MockWrite("GET /x/1 HTTP/1.1\r\n"
5146                 "Host: www.google.com\r\n"
5147                 "Connection: keep-alive\r\n\r\n"),
5148     };
5149
5150     MockRead data_reads1[] = {
5151       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5152       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5153       MockRead("Content-Length: 10000\r\n\r\n"),
5154       MockRead(SYNCHRONOUS, ERR_FAILED),
5155     };
5156
5157     // Resend with authorization from MyRealm's cache.
5158     MockWrite data_writes2[] = {
5159       MockWrite("GET /x/1 HTTP/1.1\r\n"
5160                 "Host: www.google.com\r\n"
5161                 "Connection: keep-alive\r\n"
5162                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5163     };
5164
5165     // Sever accepts the authorization.
5166     MockRead data_reads2[] = {
5167       MockRead("HTTP/1.0 200 OK\r\n"),
5168       MockRead("Content-Length: 100\r\n\r\n"),
5169       MockRead(SYNCHRONOUS, OK),
5170     };
5171
5172     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5173                                    data_writes1, arraysize(data_writes1));
5174     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5175                                    data_writes2, arraysize(data_writes2));
5176     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5177     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5178
5179     TestCompletionCallback callback1;
5180
5181     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5182     EXPECT_EQ(ERR_IO_PENDING, rv);
5183
5184     rv = callback1.WaitForResult();
5185     EXPECT_EQ(OK, rv);
5186
5187     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5188     TestCompletionCallback callback2;
5189     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5190     EXPECT_EQ(ERR_IO_PENDING, rv);
5191     rv = callback2.WaitForResult();
5192     EXPECT_EQ(OK, rv);
5193     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5194
5195     const HttpResponseInfo* response = trans->GetResponseInfo();
5196     ASSERT_TRUE(response != NULL);
5197     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5198     EXPECT_EQ(100, response->headers->GetContentLength());
5199   }
5200
5201   // ------------------------------------------------------------------------
5202
5203   // Transaction 5: request a URL in MyRealm, but the server rejects the
5204   // cached identity. Should invalidate and re-prompt.
5205   {
5206     HttpRequestInfo request;
5207     request.method = "GET";
5208     request.url = GURL("http://www.google.com/p/q/t");
5209     request.load_flags = 0;
5210
5211     scoped_ptr<HttpTransaction> trans(
5212         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5213
5214     MockWrite data_writes1[] = {
5215       MockWrite("GET /p/q/t HTTP/1.1\r\n"
5216                 "Host: www.google.com\r\n"
5217                 "Connection: keep-alive\r\n\r\n"),
5218     };
5219
5220     MockRead data_reads1[] = {
5221       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5222       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5223       MockRead("Content-Length: 10000\r\n\r\n"),
5224       MockRead(SYNCHRONOUS, ERR_FAILED),
5225     };
5226
5227     // Resend with authorization from cache for MyRealm.
5228     MockWrite data_writes2[] = {
5229       MockWrite("GET /p/q/t HTTP/1.1\r\n"
5230                 "Host: www.google.com\r\n"
5231                 "Connection: keep-alive\r\n"
5232                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5233     };
5234
5235     // Sever rejects the authorization.
5236     MockRead data_reads2[] = {
5237       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5238       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5239       MockRead("Content-Length: 10000\r\n\r\n"),
5240       MockRead(SYNCHRONOUS, ERR_FAILED),
5241     };
5242
5243     // At this point we should prompt for new credentials for MyRealm.
5244     // Restart with username=foo3, password=foo4.
5245     MockWrite data_writes3[] = {
5246       MockWrite("GET /p/q/t HTTP/1.1\r\n"
5247                 "Host: www.google.com\r\n"
5248                 "Connection: keep-alive\r\n"
5249                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5250     };
5251
5252     // Sever accepts the authorization.
5253     MockRead data_reads3[] = {
5254       MockRead("HTTP/1.0 200 OK\r\n"),
5255       MockRead("Content-Length: 100\r\n\r\n"),
5256       MockRead(SYNCHRONOUS, OK),
5257     };
5258
5259     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5260                                    data_writes1, arraysize(data_writes1));
5261     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5262                                    data_writes2, arraysize(data_writes2));
5263     StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5264                                    data_writes3, arraysize(data_writes3));
5265     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5266     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5267     session_deps_.socket_factory->AddSocketDataProvider(&data3);
5268
5269     TestCompletionCallback callback1;
5270
5271     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5272     EXPECT_EQ(ERR_IO_PENDING, rv);
5273
5274     rv = callback1.WaitForResult();
5275     EXPECT_EQ(OK, rv);
5276
5277     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5278     TestCompletionCallback callback2;
5279     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5280     EXPECT_EQ(ERR_IO_PENDING, rv);
5281     rv = callback2.WaitForResult();
5282     EXPECT_EQ(OK, rv);
5283     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5284
5285     const HttpResponseInfo* response = trans->GetResponseInfo();
5286     ASSERT_TRUE(response != NULL);
5287     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5288
5289     TestCompletionCallback callback3;
5290
5291     rv = trans->RestartWithAuth(
5292         AuthCredentials(kFoo3, kBar3), callback3.callback());
5293     EXPECT_EQ(ERR_IO_PENDING, rv);
5294
5295     rv = callback3.WaitForResult();
5296     EXPECT_EQ(OK, rv);
5297
5298     response = trans->GetResponseInfo();
5299     ASSERT_TRUE(response != NULL);
5300     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5301     EXPECT_EQ(100, response->headers->GetContentLength());
5302   }
5303 }
5304
5305 // Tests that nonce count increments when multiple auth attempts
5306 // are started with the same nonce.
5307 TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
5308   HttpAuthHandlerDigest::Factory* digest_factory =
5309       new HttpAuthHandlerDigest::Factory();
5310   HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5311       new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5312   digest_factory->set_nonce_generator(nonce_generator);
5313   session_deps_.http_auth_handler_factory.reset(digest_factory);
5314   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5315
5316   // Transaction 1: authenticate (foo, bar) on MyRealm1
5317   {
5318     HttpRequestInfo request;
5319     request.method = "GET";
5320     request.url = GURL("http://www.google.com/x/y/z");
5321     request.load_flags = 0;
5322
5323     scoped_ptr<HttpTransaction> trans(
5324         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5325
5326     MockWrite data_writes1[] = {
5327       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5328                 "Host: www.google.com\r\n"
5329                 "Connection: keep-alive\r\n\r\n"),
5330     };
5331
5332     MockRead data_reads1[] = {
5333       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5334       MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5335                "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
5336       MockRead(SYNCHRONOUS, OK),
5337     };
5338
5339     // Resend with authorization (username=foo, password=bar)
5340     MockWrite data_writes2[] = {
5341       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5342                 "Host: www.google.com\r\n"
5343                 "Connection: keep-alive\r\n"
5344                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5345                 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5346                 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5347                 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5348     };
5349
5350     // Sever accepts the authorization.
5351     MockRead data_reads2[] = {
5352       MockRead("HTTP/1.0 200 OK\r\n"),
5353       MockRead(SYNCHRONOUS, OK),
5354     };
5355
5356     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5357                                    data_writes1, arraysize(data_writes1));
5358     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5359                                    data_writes2, arraysize(data_writes2));
5360     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5361     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5362
5363     TestCompletionCallback callback1;
5364
5365     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5366     EXPECT_EQ(ERR_IO_PENDING, rv);
5367
5368     rv = callback1.WaitForResult();
5369     EXPECT_EQ(OK, rv);
5370
5371     const HttpResponseInfo* response = trans->GetResponseInfo();
5372     ASSERT_TRUE(response != NULL);
5373     EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
5374
5375     TestCompletionCallback callback2;
5376
5377     rv = trans->RestartWithAuth(
5378         AuthCredentials(kFoo, kBar), callback2.callback());
5379     EXPECT_EQ(ERR_IO_PENDING, rv);
5380
5381     rv = callback2.WaitForResult();
5382     EXPECT_EQ(OK, rv);
5383
5384     response = trans->GetResponseInfo();
5385     ASSERT_TRUE(response != NULL);
5386     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5387   }
5388
5389   // ------------------------------------------------------------------------
5390
5391   // Transaction 2: Request another resource in digestive's protection space.
5392   // This will preemptively add an Authorization header which should have an
5393   // "nc" value of 2 (as compared to 1 in the first use.
5394   {
5395     HttpRequestInfo request;
5396     request.method = "GET";
5397     // Note that Transaction 1 was at /x/y/z, so this is in the same
5398     // protection space as digest.
5399     request.url = GURL("http://www.google.com/x/y/a/b");
5400     request.load_flags = 0;
5401
5402     scoped_ptr<HttpTransaction> trans(
5403         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5404
5405     MockWrite data_writes1[] = {
5406       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5407                 "Host: www.google.com\r\n"
5408                 "Connection: keep-alive\r\n"
5409                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5410                 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5411                 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5412                 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5413     };
5414
5415     // Sever accepts the authorization.
5416     MockRead data_reads1[] = {
5417       MockRead("HTTP/1.0 200 OK\r\n"),
5418       MockRead("Content-Length: 100\r\n\r\n"),
5419       MockRead(SYNCHRONOUS, OK),
5420     };
5421
5422     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5423                                    data_writes1, arraysize(data_writes1));
5424     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5425
5426     TestCompletionCallback callback1;
5427
5428     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5429     EXPECT_EQ(ERR_IO_PENDING, rv);
5430
5431     rv = callback1.WaitForResult();
5432     EXPECT_EQ(OK, rv);
5433
5434     const HttpResponseInfo* response = trans->GetResponseInfo();
5435     ASSERT_TRUE(response != NULL);
5436     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5437   }
5438 }
5439
5440 // Test the ResetStateForRestart() private method.
5441 TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
5442   // Create a transaction (the dependencies aren't important).
5443   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5444   scoped_ptr<HttpNetworkTransaction> trans(
5445       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5446
5447   // Setup some state (which we expect ResetStateForRestart() will clear).
5448   trans->read_buf_ = new IOBuffer(15);
5449   trans->read_buf_len_ = 15;
5450   trans->request_headers_.SetHeader("Authorization", "NTLM");
5451
5452   // Setup state in response_
5453   HttpResponseInfo* response = &trans->response_;
5454   response->auth_challenge = new AuthChallengeInfo();
5455   response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
5456   response->response_time = base::Time::Now();
5457   response->was_cached = true;  // (Wouldn't ever actually be true...)
5458
5459   { // Setup state for response_.vary_data
5460     HttpRequestInfo request;
5461     std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5462     std::replace(temp.begin(), temp.end(), '\n', '\0');
5463     scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
5464     request.extra_headers.SetHeader("Foo", "1");
5465     request.extra_headers.SetHeader("bar", "23");
5466     EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
5467   }
5468
5469   // Cause the above state to be reset.
5470   trans->ResetStateForRestart();
5471
5472   // Verify that the state that needed to be reset, has been reset.
5473   EXPECT_TRUE(trans->read_buf_.get() == NULL);
5474   EXPECT_EQ(0, trans->read_buf_len_);
5475   EXPECT_TRUE(trans->request_headers_.IsEmpty());
5476   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5477   EXPECT_TRUE(response->headers.get() == NULL);
5478   EXPECT_FALSE(response->was_cached);
5479   EXPECT_EQ(0U, response->ssl_info.cert_status);
5480   EXPECT_FALSE(response->vary_data.is_valid());
5481 }
5482
5483 // Test HTTPS connections to a site with a bad certificate
5484 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
5485   HttpRequestInfo request;
5486   request.method = "GET";
5487   request.url = GURL("https://www.google.com/");
5488   request.load_flags = 0;
5489
5490   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5491   scoped_ptr<HttpTransaction> trans(
5492       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5493
5494   MockWrite data_writes[] = {
5495     MockWrite("GET / HTTP/1.1\r\n"
5496               "Host: www.google.com\r\n"
5497               "Connection: keep-alive\r\n\r\n"),
5498   };
5499
5500   MockRead data_reads[] = {
5501     MockRead("HTTP/1.0 200 OK\r\n"),
5502     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5503     MockRead("Content-Length: 100\r\n\r\n"),
5504     MockRead(SYNCHRONOUS, OK),
5505   };
5506
5507   StaticSocketDataProvider ssl_bad_certificate;
5508   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5509                                 data_writes, arraysize(data_writes));
5510   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5511   SSLSocketDataProvider ssl(ASYNC, OK);
5512
5513   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5514   session_deps_.socket_factory->AddSocketDataProvider(&data);
5515   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5516   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5517
5518   TestCompletionCallback callback;
5519
5520   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5521   EXPECT_EQ(ERR_IO_PENDING, rv);
5522
5523   rv = callback.WaitForResult();
5524   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5525
5526   rv = trans->RestartIgnoringLastError(callback.callback());
5527   EXPECT_EQ(ERR_IO_PENDING, rv);
5528
5529   rv = callback.WaitForResult();
5530   EXPECT_EQ(OK, rv);
5531
5532   const HttpResponseInfo* response = trans->GetResponseInfo();
5533
5534   ASSERT_TRUE(response != NULL);
5535   EXPECT_EQ(100, response->headers->GetContentLength());
5536 }
5537
5538 // Test HTTPS connections to a site with a bad certificate, going through a
5539 // proxy
5540 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
5541   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
5542
5543   HttpRequestInfo request;
5544   request.method = "GET";
5545   request.url = GURL("https://www.google.com/");
5546   request.load_flags = 0;
5547
5548   MockWrite proxy_writes[] = {
5549     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5550               "Host: www.google.com\r\n"
5551               "Proxy-Connection: keep-alive\r\n\r\n"),
5552   };
5553
5554   MockRead proxy_reads[] = {
5555     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5556     MockRead(SYNCHRONOUS, OK)
5557   };
5558
5559   MockWrite data_writes[] = {
5560     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5561               "Host: www.google.com\r\n"
5562               "Proxy-Connection: keep-alive\r\n\r\n"),
5563     MockWrite("GET / HTTP/1.1\r\n"
5564               "Host: www.google.com\r\n"
5565               "Connection: keep-alive\r\n\r\n"),
5566   };
5567
5568   MockRead data_reads[] = {
5569     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5570     MockRead("HTTP/1.0 200 OK\r\n"),
5571     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5572     MockRead("Content-Length: 100\r\n\r\n"),
5573     MockRead(SYNCHRONOUS, OK),
5574   };
5575
5576   StaticSocketDataProvider ssl_bad_certificate(
5577       proxy_reads, arraysize(proxy_reads),
5578       proxy_writes, arraysize(proxy_writes));
5579   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5580                                 data_writes, arraysize(data_writes));
5581   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5582   SSLSocketDataProvider ssl(ASYNC, OK);
5583
5584   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5585   session_deps_.socket_factory->AddSocketDataProvider(&data);
5586   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5587   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5588
5589   TestCompletionCallback callback;
5590
5591   for (int i = 0; i < 2; i++) {
5592     session_deps_.socket_factory->ResetNextMockIndexes();
5593
5594     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5595     scoped_ptr<HttpTransaction> trans(
5596         new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5597
5598     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5599     EXPECT_EQ(ERR_IO_PENDING, rv);
5600
5601     rv = callback.WaitForResult();
5602     EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5603
5604     rv = trans->RestartIgnoringLastError(callback.callback());
5605     EXPECT_EQ(ERR_IO_PENDING, rv);
5606
5607     rv = callback.WaitForResult();
5608     EXPECT_EQ(OK, rv);
5609
5610     const HttpResponseInfo* response = trans->GetResponseInfo();
5611
5612     ASSERT_TRUE(response != NULL);
5613     EXPECT_EQ(100, response->headers->GetContentLength());
5614   }
5615 }
5616
5617
5618 // Test HTTPS connections to a site, going through an HTTPS proxy
5619 TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
5620   session_deps_.proxy_service.reset(
5621       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5622   CapturingNetLog net_log;
5623   session_deps_.net_log = &net_log;
5624
5625   HttpRequestInfo request;
5626   request.method = "GET";
5627   request.url = GURL("https://www.google.com/");
5628   request.load_flags = 0;
5629
5630   MockWrite data_writes[] = {
5631     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5632               "Host: www.google.com\r\n"
5633               "Proxy-Connection: keep-alive\r\n\r\n"),
5634     MockWrite("GET / HTTP/1.1\r\n"
5635               "Host: www.google.com\r\n"
5636               "Connection: keep-alive\r\n\r\n"),
5637   };
5638
5639   MockRead data_reads[] = {
5640     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5641     MockRead("HTTP/1.1 200 OK\r\n"),
5642     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5643     MockRead("Content-Length: 100\r\n\r\n"),
5644     MockRead(SYNCHRONOUS, OK),
5645   };
5646
5647   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5648                                 data_writes, arraysize(data_writes));
5649   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
5650   SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
5651
5652   session_deps_.socket_factory->AddSocketDataProvider(&data);
5653   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5654   session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
5655
5656   TestCompletionCallback callback;
5657
5658   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5659   scoped_ptr<HttpTransaction> trans(
5660       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5661
5662   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5663   EXPECT_EQ(ERR_IO_PENDING, rv);
5664
5665   rv = callback.WaitForResult();
5666   EXPECT_EQ(OK, rv);
5667   const HttpResponseInfo* response = trans->GetResponseInfo();
5668
5669   ASSERT_TRUE(response != NULL);
5670
5671   EXPECT_TRUE(response->headers->IsKeepAlive());
5672   EXPECT_EQ(200, response->headers->response_code());
5673   EXPECT_EQ(100, response->headers->GetContentLength());
5674   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5675
5676   LoadTimingInfo load_timing_info;
5677   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5678   TestLoadTimingNotReusedWithPac(load_timing_info,
5679                                  CONNECT_TIMING_HAS_SSL_TIMES);
5680 }
5681
5682 // Test an HTTPS Proxy's ability to redirect a CONNECT request
5683 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
5684   session_deps_.proxy_service.reset(
5685       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5686   CapturingNetLog net_log;
5687   session_deps_.net_log = &net_log;
5688
5689   HttpRequestInfo request;
5690   request.method = "GET";
5691   request.url = GURL("https://www.google.com/");
5692   request.load_flags = 0;
5693
5694   MockWrite data_writes[] = {
5695     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5696               "Host: www.google.com\r\n"
5697               "Proxy-Connection: keep-alive\r\n\r\n"),
5698   };
5699
5700   MockRead data_reads[] = {
5701     MockRead("HTTP/1.1 302 Redirect\r\n"),
5702     MockRead("Location: http://login.example.com/\r\n"),
5703     MockRead("Content-Length: 0\r\n\r\n"),
5704     MockRead(SYNCHRONOUS, OK),
5705   };
5706
5707   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5708                                 data_writes, arraysize(data_writes));
5709   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
5710
5711   session_deps_.socket_factory->AddSocketDataProvider(&data);
5712   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5713
5714   TestCompletionCallback callback;
5715
5716   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5717   scoped_ptr<HttpTransaction> trans(
5718       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5719
5720   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5721   EXPECT_EQ(ERR_IO_PENDING, rv);
5722
5723   rv = callback.WaitForResult();
5724   EXPECT_EQ(OK, rv);
5725   const HttpResponseInfo* response = trans->GetResponseInfo();
5726
5727   ASSERT_TRUE(response != NULL);
5728
5729   EXPECT_EQ(302, response->headers->response_code());
5730   std::string url;
5731   EXPECT_TRUE(response->headers->IsRedirect(&url));
5732   EXPECT_EQ("http://login.example.com/", url);
5733
5734   // In the case of redirects from proxies, HttpNetworkTransaction returns
5735   // timing for the proxy connection instead of the connection to the host,
5736   // and no send / receive times.
5737   // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
5738   LoadTimingInfo load_timing_info;
5739   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5740
5741   EXPECT_FALSE(load_timing_info.socket_reused);
5742   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
5743
5744   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
5745   EXPECT_LE(load_timing_info.proxy_resolve_start,
5746             load_timing_info.proxy_resolve_end);
5747   EXPECT_LE(load_timing_info.proxy_resolve_end,
5748             load_timing_info.connect_timing.connect_start);
5749   ExpectConnectTimingHasTimes(
5750       load_timing_info.connect_timing,
5751       CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
5752
5753   EXPECT_TRUE(load_timing_info.send_start.is_null());
5754   EXPECT_TRUE(load_timing_info.send_end.is_null());
5755   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
5756 }
5757
5758 // Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
5759 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
5760   session_deps_.proxy_service.reset(
5761       ProxyService::CreateFixed("https://proxy:70"));
5762
5763   HttpRequestInfo request;
5764   request.method = "GET";
5765   request.url = GURL("https://www.google.com/");
5766   request.load_flags = 0;
5767
5768   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5769                                                              LOWEST));
5770   scoped_ptr<SpdyFrame> goaway(
5771       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
5772   MockWrite data_writes[] = {
5773     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
5774     CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
5775   };
5776
5777   static const char* const kExtraHeaders[] = {
5778     "location",
5779     "http://login.example.com/",
5780   };
5781   scoped_ptr<SpdyFrame> resp(
5782       spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
5783                                  arraysize(kExtraHeaders)/2, 1));
5784   MockRead data_reads[] = {
5785     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5786     MockRead(ASYNC, 0, 2),  // EOF
5787   };
5788
5789   DelayedSocketData data(
5790       1,  // wait for one write to finish before reading.
5791       data_reads, arraysize(data_reads),
5792       data_writes, arraysize(data_writes));
5793   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
5794   proxy_ssl.SetNextProto(GetParam());
5795
5796   session_deps_.socket_factory->AddSocketDataProvider(&data);
5797   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5798
5799   TestCompletionCallback callback;
5800
5801   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5802   scoped_ptr<HttpTransaction> trans(
5803       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5804
5805   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5806   EXPECT_EQ(ERR_IO_PENDING, rv);
5807
5808   rv = callback.WaitForResult();
5809   EXPECT_EQ(OK, rv);
5810   const HttpResponseInfo* response = trans->GetResponseInfo();
5811
5812   ASSERT_TRUE(response != NULL);
5813
5814   EXPECT_EQ(302, response->headers->response_code());
5815   std::string url;
5816   EXPECT_TRUE(response->headers->IsRedirect(&url));
5817   EXPECT_EQ("http://login.example.com/", url);
5818 }
5819
5820 // Test that an HTTPS proxy's response to a CONNECT request is filtered.
5821 TEST_P(HttpNetworkTransactionTest,
5822        ErrorResponseToHttpsConnectViaHttpsProxy) {
5823   session_deps_.proxy_service.reset(
5824       ProxyService::CreateFixed("https://proxy:70"));
5825
5826   HttpRequestInfo request;
5827   request.method = "GET";
5828   request.url = GURL("https://www.google.com/");
5829   request.load_flags = 0;
5830
5831   MockWrite data_writes[] = {
5832     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5833               "Host: www.google.com\r\n"
5834               "Proxy-Connection: keep-alive\r\n\r\n"),
5835   };
5836
5837   MockRead data_reads[] = {
5838     MockRead("HTTP/1.1 404 Not Found\r\n"),
5839     MockRead("Content-Length: 23\r\n\r\n"),
5840     MockRead("The host does not exist"),
5841     MockRead(SYNCHRONOUS, OK),
5842   };
5843
5844   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5845                                 data_writes, arraysize(data_writes));
5846   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
5847
5848   session_deps_.socket_factory->AddSocketDataProvider(&data);
5849   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5850
5851   TestCompletionCallback callback;
5852
5853   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5854   scoped_ptr<HttpTransaction> trans(
5855       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5856
5857   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5858   EXPECT_EQ(ERR_IO_PENDING, rv);
5859
5860   rv = callback.WaitForResult();
5861   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
5862
5863   // TODO(ttuttle): Anything else to check here?
5864 }
5865
5866 // Test that a SPDY proxy's response to a CONNECT request is filtered.
5867 TEST_P(HttpNetworkTransactionTest,
5868        ErrorResponseToHttpsConnectViaSpdyProxy) {
5869   session_deps_.proxy_service.reset(
5870      ProxyService::CreateFixed("https://proxy:70"));
5871
5872   HttpRequestInfo request;
5873   request.method = "GET";
5874   request.url = GURL("https://www.google.com/");
5875   request.load_flags = 0;
5876
5877   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5878                                                              LOWEST));
5879   scoped_ptr<SpdyFrame> rst(
5880       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
5881   MockWrite data_writes[] = {
5882     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
5883     CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
5884   };
5885
5886   static const char* const kExtraHeaders[] = {
5887     "location",
5888     "http://login.example.com/",
5889   };
5890   scoped_ptr<SpdyFrame> resp(
5891       spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
5892                                  arraysize(kExtraHeaders)/2, 1));
5893   scoped_ptr<SpdyFrame> body(
5894       spdy_util_.ConstructSpdyBodyFrame(
5895           1, "The host does not exist", 23, true));
5896   MockRead data_reads[] = {
5897     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5898     CreateMockRead(*body.get(), 2, SYNCHRONOUS),
5899     MockRead(ASYNC, 0, 4),  // EOF
5900   };
5901
5902   DelayedSocketData data(
5903       1,  // wait for one write to finish before reading.
5904       data_reads, arraysize(data_reads),
5905       data_writes, arraysize(data_writes));
5906   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
5907   proxy_ssl.SetNextProto(GetParam());
5908
5909   session_deps_.socket_factory->AddSocketDataProvider(&data);
5910   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5911
5912   TestCompletionCallback callback;
5913
5914   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5915   scoped_ptr<HttpTransaction> trans(
5916       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5917
5918   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5919   EXPECT_EQ(ERR_IO_PENDING, rv);
5920
5921   rv = callback.WaitForResult();
5922   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
5923
5924   // TODO(ttuttle): Anything else to check here?
5925 }
5926
5927 // Test the request-challenge-retry sequence for basic auth, through
5928 // a SPDY proxy over a single SPDY session.
5929 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
5930   HttpRequestInfo request;
5931   request.method = "GET";
5932   request.url = GURL("https://www.google.com/");
5933   // when the no authentication data flag is set.
5934   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
5935
5936   // Configure against https proxy server "myproxy:70".
5937   session_deps_.proxy_service.reset(
5938       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
5939   CapturingBoundNetLog log;
5940   session_deps_.net_log = log.bound().net_log();
5941   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5942
5943   // Since we have proxy, should try to establish tunnel.
5944   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5945                                                             LOWEST));
5946   scoped_ptr<SpdyFrame> rst(
5947       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
5948
5949   // After calling trans->RestartWithAuth(), this is the request we should
5950   // be issuing -- the final header line contains the credentials.
5951   const char* const kAuthCredentials[] = {
5952       "proxy-authorization", "Basic Zm9vOmJhcg==",
5953   };
5954   scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
5955       kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
5956   // fetch https://www.google.com/ via HTTP
5957   const char get[] = "GET / HTTP/1.1\r\n"
5958     "Host: www.google.com\r\n"
5959     "Connection: keep-alive\r\n\r\n";
5960   scoped_ptr<SpdyFrame> wrapped_get(
5961       spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
5962
5963   MockWrite spdy_writes[] = {
5964     CreateMockWrite(*req, 1, ASYNC),
5965     CreateMockWrite(*rst, 4, ASYNC),
5966     CreateMockWrite(*connect2, 5),
5967     CreateMockWrite(*wrapped_get, 8),
5968   };
5969
5970   // The proxy responds to the connect with a 407, using a persistent
5971   // connection.
5972   const char* const kAuthChallenge[] = {
5973     spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
5974     spdy_util_.GetVersionKey(), "HTTP/1.1",
5975     "proxy-authenticate", "Basic realm=\"MyRealm1\"",
5976   };
5977
5978   scoped_ptr<SpdyFrame> conn_auth_resp(
5979       spdy_util_.ConstructSpdyControlFrame(NULL,
5980                                            0,
5981                                            false,
5982                                            1,
5983                                            LOWEST,
5984                                            SYN_REPLY,
5985                                            CONTROL_FLAG_NONE,
5986                                            kAuthChallenge,
5987                                            arraysize(kAuthChallenge),
5988                                            0));
5989
5990   scoped_ptr<SpdyFrame> conn_resp(
5991       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
5992   const char resp[] = "HTTP/1.1 200 OK\r\n"
5993       "Content-Length: 5\r\n\r\n";
5994
5995   scoped_ptr<SpdyFrame> wrapped_get_resp(
5996       spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
5997   scoped_ptr<SpdyFrame> wrapped_body(
5998       spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
5999   MockRead spdy_reads[] = {
6000     CreateMockRead(*conn_auth_resp, 2, ASYNC),
6001     CreateMockRead(*conn_resp, 6, ASYNC),
6002     CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6003     CreateMockRead(*wrapped_body, 10, ASYNC),
6004     MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
6005   };
6006
6007   OrderedSocketData spdy_data(
6008       spdy_reads, arraysize(spdy_reads),
6009       spdy_writes, arraysize(spdy_writes));
6010   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6011   // Negotiate SPDY to the proxy
6012   SSLSocketDataProvider proxy(ASYNC, OK);
6013   proxy.SetNextProto(GetParam());
6014   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
6015   // Vanilla SSL to the server
6016   SSLSocketDataProvider server(ASYNC, OK);
6017   session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
6018
6019   TestCompletionCallback callback1;
6020
6021   scoped_ptr<HttpTransaction> trans(
6022       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6023
6024   int rv = trans->Start(&request, callback1.callback(), log.bound());
6025   EXPECT_EQ(ERR_IO_PENDING, rv);
6026
6027   rv = callback1.WaitForResult();
6028   EXPECT_EQ(OK, rv);
6029   net::CapturingNetLog::CapturedEntryList entries;
6030   log.GetEntries(&entries);
6031   size_t pos = ExpectLogContainsSomewhere(
6032       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6033       NetLog::PHASE_NONE);
6034   ExpectLogContainsSomewhere(
6035       entries, pos,
6036       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6037       NetLog::PHASE_NONE);
6038
6039   const HttpResponseInfo* response = trans->GetResponseInfo();
6040   ASSERT_TRUE(response != NULL);
6041   ASSERT_FALSE(response->headers.get() == NULL);
6042   EXPECT_EQ(407, response->headers->response_code());
6043   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6044   EXPECT_TRUE(response->auth_challenge.get() != NULL);
6045   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6046
6047   TestCompletionCallback callback2;
6048
6049   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6050                               callback2.callback());
6051   EXPECT_EQ(ERR_IO_PENDING, rv);
6052
6053   rv = callback2.WaitForResult();
6054   EXPECT_EQ(OK, rv);
6055
6056   response = trans->GetResponseInfo();
6057   ASSERT_TRUE(response != NULL);
6058
6059   EXPECT_TRUE(response->headers->IsKeepAlive());
6060   EXPECT_EQ(200, response->headers->response_code());
6061   EXPECT_EQ(5, response->headers->GetContentLength());
6062   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6063
6064   // The password prompt info should not be set.
6065   EXPECT_TRUE(response->auth_challenge.get() == NULL);
6066
6067   LoadTimingInfo load_timing_info;
6068   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6069   TestLoadTimingNotReusedWithPac(load_timing_info,
6070                                  CONNECT_TIMING_HAS_SSL_TIMES);
6071
6072   trans.reset();
6073   session->CloseAllConnections();
6074 }
6075
6076 // Test that an explicitly trusted SPDY proxy can push a resource from an
6077 // origin that is different from that of its associated resource.
6078 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
6079   HttpRequestInfo request;
6080   HttpRequestInfo push_request;
6081
6082   request.method = "GET";
6083   request.url = GURL("http://www.google.com/");
6084   push_request.method = "GET";
6085   push_request.url = GURL("http://www.another-origin.com/foo.dat");
6086
6087   // Configure against https proxy server "myproxy:70".
6088   session_deps_.proxy_service.reset(
6089       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
6090   CapturingBoundNetLog log;
6091   session_deps_.net_log = log.bound().net_log();
6092
6093   // Enable cross-origin push.
6094   session_deps_.trusted_spdy_proxy = "myproxy:70";
6095
6096   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6097
6098   scoped_ptr<SpdyFrame> stream1_syn(
6099       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
6100
6101   MockWrite spdy_writes[] = {
6102     CreateMockWrite(*stream1_syn, 1, ASYNC),
6103   };
6104
6105   scoped_ptr<SpdyFrame>
6106       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
6107
6108   scoped_ptr<SpdyFrame>
6109       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
6110
6111   scoped_ptr<SpdyFrame>
6112       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
6113                                     0,
6114                                     2,
6115                                     1,
6116                                     "http://www.another-origin.com/foo.dat"));
6117   const char kPushedData[] = "pushed";
6118   scoped_ptr<SpdyFrame> stream2_body(
6119       spdy_util_.ConstructSpdyBodyFrame(
6120           2, kPushedData, strlen(kPushedData), true));
6121
6122   MockRead spdy_reads[] = {
6123     CreateMockRead(*stream1_reply, 2, ASYNC),
6124     CreateMockRead(*stream2_syn, 3, ASYNC),
6125     CreateMockRead(*stream1_body, 4, ASYNC),
6126     CreateMockRead(*stream2_body, 5, ASYNC),
6127     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
6128   };
6129
6130   OrderedSocketData spdy_data(
6131       spdy_reads, arraysize(spdy_reads),
6132       spdy_writes, arraysize(spdy_writes));
6133   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6134   // Negotiate SPDY to the proxy
6135   SSLSocketDataProvider proxy(ASYNC, OK);
6136   proxy.SetNextProto(GetParam());
6137   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
6138
6139   scoped_ptr<HttpTransaction> trans(
6140       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6141   TestCompletionCallback callback;
6142   int rv = trans->Start(&request, callback.callback(), log.bound());
6143   EXPECT_EQ(ERR_IO_PENDING, rv);
6144
6145   rv = callback.WaitForResult();
6146   EXPECT_EQ(OK, rv);
6147   const HttpResponseInfo* response = trans->GetResponseInfo();
6148
6149   scoped_ptr<HttpTransaction> push_trans(
6150       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6151   rv = push_trans->Start(&push_request, callback.callback(), log.bound());
6152   EXPECT_EQ(ERR_IO_PENDING, rv);
6153
6154   rv = callback.WaitForResult();
6155   EXPECT_EQ(OK, rv);
6156   const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6157
6158   ASSERT_TRUE(response != NULL);
6159   EXPECT_TRUE(response->headers->IsKeepAlive());
6160
6161   EXPECT_EQ(200, response->headers->response_code());
6162   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6163
6164   std::string response_data;
6165   rv = ReadTransaction(trans.get(), &response_data);
6166   EXPECT_EQ(OK, rv);
6167   EXPECT_EQ("hello!", response_data);
6168
6169   LoadTimingInfo load_timing_info;
6170   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6171   TestLoadTimingNotReusedWithPac(load_timing_info,
6172                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6173
6174   // Verify the pushed stream.
6175   EXPECT_TRUE(push_response->headers.get() != NULL);
6176   EXPECT_EQ(200, push_response->headers->response_code());
6177
6178   rv = ReadTransaction(push_trans.get(), &response_data);
6179   EXPECT_EQ(OK, rv);
6180   EXPECT_EQ("pushed", response_data);
6181
6182   LoadTimingInfo push_load_timing_info;
6183   EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6184   TestLoadTimingReusedWithPac(push_load_timing_info);
6185   // The transactions should share a socket ID, despite being for different
6186   // origins.
6187   EXPECT_EQ(load_timing_info.socket_log_id,
6188             push_load_timing_info.socket_log_id);
6189
6190   trans.reset();
6191   push_trans.reset();
6192   session->CloseAllConnections();
6193 }
6194
6195 // Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
6196 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
6197   HttpRequestInfo request;
6198
6199   request.method = "GET";
6200   request.url = GURL("http://www.google.com/");
6201
6202   // Configure against https proxy server "myproxy:70".
6203   session_deps_.proxy_service.reset(
6204       ProxyService::CreateFixed("https://myproxy:70"));
6205   CapturingBoundNetLog log;
6206   session_deps_.net_log = log.bound().net_log();
6207
6208   // Enable cross-origin push.
6209   session_deps_.trusted_spdy_proxy = "myproxy:70";
6210
6211   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6212
6213   scoped_ptr<SpdyFrame> stream1_syn(
6214       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
6215
6216   scoped_ptr<SpdyFrame> push_rst(
6217       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
6218
6219   MockWrite spdy_writes[] = {
6220     CreateMockWrite(*stream1_syn, 1, ASYNC),
6221     CreateMockWrite(*push_rst, 4),
6222   };
6223
6224   scoped_ptr<SpdyFrame>
6225       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
6226
6227   scoped_ptr<SpdyFrame>
6228       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
6229
6230   scoped_ptr<SpdyFrame>
6231       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
6232                                     0,
6233                                     2,
6234                                     1,
6235                                     "https://www.another-origin.com/foo.dat"));
6236
6237   MockRead spdy_reads[] = {
6238     CreateMockRead(*stream1_reply, 2, ASYNC),
6239     CreateMockRead(*stream2_syn, 3, ASYNC),
6240     CreateMockRead(*stream1_body, 5, ASYNC),
6241     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
6242   };
6243
6244   OrderedSocketData spdy_data(
6245       spdy_reads, arraysize(spdy_reads),
6246       spdy_writes, arraysize(spdy_writes));
6247   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6248   // Negotiate SPDY to the proxy
6249   SSLSocketDataProvider proxy(ASYNC, OK);
6250   proxy.SetNextProto(GetParam());
6251   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
6252
6253   scoped_ptr<HttpTransaction> trans(
6254       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6255   TestCompletionCallback callback;
6256   int rv = trans->Start(&request, callback.callback(), log.bound());
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   EXPECT_TRUE(response->headers->IsKeepAlive());
6265
6266   EXPECT_EQ(200, response->headers->response_code());
6267   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6268
6269   std::string response_data;
6270   rv = ReadTransaction(trans.get(), &response_data);
6271   EXPECT_EQ(OK, rv);
6272   EXPECT_EQ("hello!", response_data);
6273
6274   trans.reset();
6275   session->CloseAllConnections();
6276 }
6277
6278 // Test HTTPS connections to a site with a bad certificate, going through an
6279 // HTTPS proxy
6280 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
6281   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
6282       "https://proxy:70"));
6283
6284   HttpRequestInfo request;
6285   request.method = "GET";
6286   request.url = GURL("https://www.google.com/");
6287   request.load_flags = 0;
6288
6289   // Attempt to fetch the URL from a server with a bad cert
6290   MockWrite bad_cert_writes[] = {
6291     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6292               "Host: www.google.com\r\n"
6293               "Proxy-Connection: keep-alive\r\n\r\n"),
6294   };
6295
6296   MockRead bad_cert_reads[] = {
6297     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6298     MockRead(SYNCHRONOUS, OK)
6299   };
6300
6301   // Attempt to fetch the URL with a good cert
6302   MockWrite good_data_writes[] = {
6303     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6304               "Host: www.google.com\r\n"
6305               "Proxy-Connection: keep-alive\r\n\r\n"),
6306     MockWrite("GET / HTTP/1.1\r\n"
6307               "Host: www.google.com\r\n"
6308               "Connection: keep-alive\r\n\r\n"),
6309   };
6310
6311   MockRead good_cert_reads[] = {
6312     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6313     MockRead("HTTP/1.0 200 OK\r\n"),
6314     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6315     MockRead("Content-Length: 100\r\n\r\n"),
6316     MockRead(SYNCHRONOUS, OK),
6317   };
6318
6319   StaticSocketDataProvider ssl_bad_certificate(
6320       bad_cert_reads, arraysize(bad_cert_reads),
6321       bad_cert_writes, arraysize(bad_cert_writes));
6322   StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6323                                 good_data_writes, arraysize(good_data_writes));
6324   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6325   SSLSocketDataProvider ssl(ASYNC, OK);
6326
6327   // SSL to the proxy, then CONNECT request, then SSL with bad certificate
6328   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6329   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6330   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6331
6332   // SSL to the proxy, then CONNECT request, then valid SSL certificate
6333   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6334   session_deps_.socket_factory->AddSocketDataProvider(&data);
6335   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6336
6337   TestCompletionCallback callback;
6338
6339   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6340   scoped_ptr<HttpTransaction> trans(
6341       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6342
6343   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6344   EXPECT_EQ(ERR_IO_PENDING, rv);
6345
6346   rv = callback.WaitForResult();
6347   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6348
6349   rv = trans->RestartIgnoringLastError(callback.callback());
6350   EXPECT_EQ(ERR_IO_PENDING, rv);
6351
6352   rv = callback.WaitForResult();
6353   EXPECT_EQ(OK, rv);
6354
6355   const HttpResponseInfo* response = trans->GetResponseInfo();
6356
6357   ASSERT_TRUE(response != NULL);
6358   EXPECT_EQ(100, response->headers->GetContentLength());
6359 }
6360
6361 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
6362   HttpRequestInfo request;
6363   request.method = "GET";
6364   request.url = GURL("http://www.google.com/");
6365   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6366                                   "Chromium Ultra Awesome X Edition");
6367
6368   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6369   scoped_ptr<HttpTransaction> trans(
6370       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6371
6372   MockWrite data_writes[] = {
6373     MockWrite("GET / HTTP/1.1\r\n"
6374               "Host: www.google.com\r\n"
6375               "Connection: keep-alive\r\n"
6376               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6377   };
6378
6379   // Lastly, the server responds with the actual content.
6380   MockRead data_reads[] = {
6381     MockRead("HTTP/1.0 200 OK\r\n"),
6382     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6383     MockRead("Content-Length: 100\r\n\r\n"),
6384     MockRead(SYNCHRONOUS, OK),
6385   };
6386
6387   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6388                                 data_writes, arraysize(data_writes));
6389   session_deps_.socket_factory->AddSocketDataProvider(&data);
6390
6391   TestCompletionCallback callback;
6392
6393   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6394   EXPECT_EQ(ERR_IO_PENDING, rv);
6395
6396   rv = callback.WaitForResult();
6397   EXPECT_EQ(OK, rv);
6398 }
6399
6400 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
6401   HttpRequestInfo request;
6402   request.method = "GET";
6403   request.url = GURL("https://www.google.com/");
6404   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6405                                   "Chromium Ultra Awesome X Edition");
6406
6407   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
6408   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6409   scoped_ptr<HttpTransaction> trans(
6410       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6411
6412   MockWrite data_writes[] = {
6413     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6414               "Host: www.google.com\r\n"
6415               "Proxy-Connection: keep-alive\r\n"
6416               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6417   };
6418   MockRead data_reads[] = {
6419     // Return an error, so the transaction stops here (this test isn't
6420     // interested in the rest).
6421     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6422     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6423     MockRead("Proxy-Connection: close\r\n\r\n"),
6424   };
6425
6426   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6427                                 data_writes, arraysize(data_writes));
6428   session_deps_.socket_factory->AddSocketDataProvider(&data);
6429
6430   TestCompletionCallback callback;
6431
6432   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6433   EXPECT_EQ(ERR_IO_PENDING, rv);
6434
6435   rv = callback.WaitForResult();
6436   EXPECT_EQ(OK, rv);
6437 }
6438
6439 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
6440   HttpRequestInfo request;
6441   request.method = "GET";
6442   request.url = GURL("http://www.google.com/");
6443   request.load_flags = 0;
6444   request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6445                                   "http://the.previous.site.com/");
6446
6447   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6448   scoped_ptr<HttpTransaction> trans(
6449       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6450
6451   MockWrite data_writes[] = {
6452     MockWrite("GET / HTTP/1.1\r\n"
6453               "Host: www.google.com\r\n"
6454               "Connection: keep-alive\r\n"
6455               "Referer: http://the.previous.site.com/\r\n\r\n"),
6456   };
6457
6458   // Lastly, the server responds with the actual content.
6459   MockRead data_reads[] = {
6460     MockRead("HTTP/1.0 200 OK\r\n"),
6461     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6462     MockRead("Content-Length: 100\r\n\r\n"),
6463     MockRead(SYNCHRONOUS, OK),
6464   };
6465
6466   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6467                                 data_writes, arraysize(data_writes));
6468   session_deps_.socket_factory->AddSocketDataProvider(&data);
6469
6470   TestCompletionCallback callback;
6471
6472   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6473   EXPECT_EQ(ERR_IO_PENDING, rv);
6474
6475   rv = callback.WaitForResult();
6476   EXPECT_EQ(OK, rv);
6477 }
6478
6479 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
6480   HttpRequestInfo request;
6481   request.method = "POST";
6482   request.url = GURL("http://www.google.com/");
6483
6484   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6485   scoped_ptr<HttpTransaction> trans(
6486       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6487
6488   MockWrite data_writes[] = {
6489     MockWrite("POST / HTTP/1.1\r\n"
6490               "Host: www.google.com\r\n"
6491               "Connection: keep-alive\r\n"
6492               "Content-Length: 0\r\n\r\n"),
6493   };
6494
6495   // Lastly, the server responds with the actual content.
6496   MockRead data_reads[] = {
6497     MockRead("HTTP/1.0 200 OK\r\n"),
6498     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6499     MockRead("Content-Length: 100\r\n\r\n"),
6500     MockRead(SYNCHRONOUS, OK),
6501   };
6502
6503   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6504                                 data_writes, arraysize(data_writes));
6505   session_deps_.socket_factory->AddSocketDataProvider(&data);
6506
6507   TestCompletionCallback callback;
6508
6509   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6510   EXPECT_EQ(ERR_IO_PENDING, rv);
6511
6512   rv = callback.WaitForResult();
6513   EXPECT_EQ(OK, rv);
6514 }
6515
6516 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
6517   HttpRequestInfo request;
6518   request.method = "PUT";
6519   request.url = GURL("http://www.google.com/");
6520
6521   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6522   scoped_ptr<HttpTransaction> trans(
6523       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6524
6525   MockWrite data_writes[] = {
6526     MockWrite("PUT / HTTP/1.1\r\n"
6527               "Host: www.google.com\r\n"
6528               "Connection: keep-alive\r\n"
6529               "Content-Length: 0\r\n\r\n"),
6530   };
6531
6532   // Lastly, the server responds with the actual content.
6533   MockRead data_reads[] = {
6534     MockRead("HTTP/1.0 200 OK\r\n"),
6535     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6536     MockRead("Content-Length: 100\r\n\r\n"),
6537     MockRead(SYNCHRONOUS, OK),
6538   };
6539
6540   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6541                                 data_writes, arraysize(data_writes));
6542   session_deps_.socket_factory->AddSocketDataProvider(&data);
6543
6544   TestCompletionCallback callback;
6545
6546   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6547   EXPECT_EQ(ERR_IO_PENDING, rv);
6548
6549   rv = callback.WaitForResult();
6550   EXPECT_EQ(OK, rv);
6551 }
6552
6553 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
6554   HttpRequestInfo request;
6555   request.method = "HEAD";
6556   request.url = GURL("http://www.google.com/");
6557
6558   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6559   scoped_ptr<HttpTransaction> trans(
6560       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6561
6562   MockWrite data_writes[] = {
6563     MockWrite("HEAD / HTTP/1.1\r\n"
6564               "Host: www.google.com\r\n"
6565               "Connection: keep-alive\r\n"
6566               "Content-Length: 0\r\n\r\n"),
6567   };
6568
6569   // Lastly, the server responds with the actual content.
6570   MockRead data_reads[] = {
6571     MockRead("HTTP/1.0 200 OK\r\n"),
6572     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6573     MockRead("Content-Length: 100\r\n\r\n"),
6574     MockRead(SYNCHRONOUS, OK),
6575   };
6576
6577   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6578                                 data_writes, arraysize(data_writes));
6579   session_deps_.socket_factory->AddSocketDataProvider(&data);
6580
6581   TestCompletionCallback callback;
6582
6583   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6584   EXPECT_EQ(ERR_IO_PENDING, rv);
6585
6586   rv = callback.WaitForResult();
6587   EXPECT_EQ(OK, rv);
6588 }
6589
6590 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
6591   HttpRequestInfo request;
6592   request.method = "GET";
6593   request.url = GURL("http://www.google.com/");
6594   request.load_flags = LOAD_BYPASS_CACHE;
6595
6596   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6597   scoped_ptr<HttpTransaction> trans(
6598       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6599
6600   MockWrite data_writes[] = {
6601     MockWrite("GET / HTTP/1.1\r\n"
6602               "Host: www.google.com\r\n"
6603               "Connection: keep-alive\r\n"
6604               "Pragma: no-cache\r\n"
6605               "Cache-Control: no-cache\r\n\r\n"),
6606   };
6607
6608   // Lastly, the server responds with the actual content.
6609   MockRead data_reads[] = {
6610     MockRead("HTTP/1.0 200 OK\r\n"),
6611     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6612     MockRead("Content-Length: 100\r\n\r\n"),
6613     MockRead(SYNCHRONOUS, OK),
6614   };
6615
6616   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6617                                 data_writes, arraysize(data_writes));
6618   session_deps_.socket_factory->AddSocketDataProvider(&data);
6619
6620   TestCompletionCallback callback;
6621
6622   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6623   EXPECT_EQ(ERR_IO_PENDING, rv);
6624
6625   rv = callback.WaitForResult();
6626   EXPECT_EQ(OK, rv);
6627 }
6628
6629 TEST_P(HttpNetworkTransactionTest,
6630        BuildRequest_CacheControlValidateCache) {
6631   HttpRequestInfo request;
6632   request.method = "GET";
6633   request.url = GURL("http://www.google.com/");
6634   request.load_flags = LOAD_VALIDATE_CACHE;
6635
6636   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6637   scoped_ptr<HttpTransaction> trans(
6638       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6639
6640   MockWrite data_writes[] = {
6641     MockWrite("GET / HTTP/1.1\r\n"
6642               "Host: www.google.com\r\n"
6643               "Connection: keep-alive\r\n"
6644               "Cache-Control: max-age=0\r\n\r\n"),
6645   };
6646
6647   // Lastly, the server responds with the actual content.
6648   MockRead data_reads[] = {
6649     MockRead("HTTP/1.0 200 OK\r\n"),
6650     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6651     MockRead("Content-Length: 100\r\n\r\n"),
6652     MockRead(SYNCHRONOUS, OK),
6653   };
6654
6655   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6656                                 data_writes, arraysize(data_writes));
6657   session_deps_.socket_factory->AddSocketDataProvider(&data);
6658
6659   TestCompletionCallback callback;
6660
6661   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6662   EXPECT_EQ(ERR_IO_PENDING, rv);
6663
6664   rv = callback.WaitForResult();
6665   EXPECT_EQ(OK, rv);
6666 }
6667
6668 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
6669   HttpRequestInfo request;
6670   request.method = "GET";
6671   request.url = GURL("http://www.google.com/");
6672   request.extra_headers.SetHeader("FooHeader", "Bar");
6673
6674   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6675   scoped_ptr<HttpTransaction> trans(
6676       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6677
6678   MockWrite data_writes[] = {
6679     MockWrite("GET / HTTP/1.1\r\n"
6680               "Host: www.google.com\r\n"
6681               "Connection: keep-alive\r\n"
6682               "FooHeader: Bar\r\n\r\n"),
6683   };
6684
6685   // Lastly, the server responds with the actual content.
6686   MockRead data_reads[] = {
6687     MockRead("HTTP/1.0 200 OK\r\n"),
6688     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6689     MockRead("Content-Length: 100\r\n\r\n"),
6690     MockRead(SYNCHRONOUS, OK),
6691   };
6692
6693   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6694                                 data_writes, arraysize(data_writes));
6695   session_deps_.socket_factory->AddSocketDataProvider(&data);
6696
6697   TestCompletionCallback callback;
6698
6699   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6700   EXPECT_EQ(ERR_IO_PENDING, rv);
6701
6702   rv = callback.WaitForResult();
6703   EXPECT_EQ(OK, rv);
6704 }
6705
6706 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
6707   HttpRequestInfo request;
6708   request.method = "GET";
6709   request.url = GURL("http://www.google.com/");
6710   request.extra_headers.SetHeader("referer", "www.foo.com");
6711   request.extra_headers.SetHeader("hEllo", "Kitty");
6712   request.extra_headers.SetHeader("FoO", "bar");
6713
6714   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6715   scoped_ptr<HttpTransaction> trans(
6716       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6717
6718   MockWrite data_writes[] = {
6719     MockWrite("GET / HTTP/1.1\r\n"
6720               "Host: www.google.com\r\n"
6721               "Connection: keep-alive\r\n"
6722               "referer: www.foo.com\r\n"
6723               "hEllo: Kitty\r\n"
6724               "FoO: bar\r\n\r\n"),
6725   };
6726
6727   // Lastly, the server responds with the actual content.
6728   MockRead data_reads[] = {
6729     MockRead("HTTP/1.0 200 OK\r\n"),
6730     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6731     MockRead("Content-Length: 100\r\n\r\n"),
6732     MockRead(SYNCHRONOUS, OK),
6733   };
6734
6735   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6736                                 data_writes, arraysize(data_writes));
6737   session_deps_.socket_factory->AddSocketDataProvider(&data);
6738
6739   TestCompletionCallback callback;
6740
6741   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6742   EXPECT_EQ(ERR_IO_PENDING, rv);
6743
6744   rv = callback.WaitForResult();
6745   EXPECT_EQ(OK, rv);
6746 }
6747
6748 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
6749   HttpRequestInfo request;
6750   request.method = "GET";
6751   request.url = GURL("http://www.google.com/");
6752   request.load_flags = 0;
6753
6754   session_deps_.proxy_service.reset(
6755       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6756   CapturingNetLog net_log;
6757   session_deps_.net_log = &net_log;
6758
6759   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6760   scoped_ptr<HttpTransaction> trans(
6761       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6762
6763   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6764   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6765
6766   MockWrite data_writes[] = {
6767     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
6768     MockWrite("GET / HTTP/1.1\r\n"
6769               "Host: www.google.com\r\n"
6770               "Connection: keep-alive\r\n\r\n")
6771   };
6772
6773   MockRead data_reads[] = {
6774     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
6775     MockRead("HTTP/1.0 200 OK\r\n"),
6776     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6777     MockRead("Payload"),
6778     MockRead(SYNCHRONOUS, OK)
6779   };
6780
6781   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6782                                 data_writes, arraysize(data_writes));
6783   session_deps_.socket_factory->AddSocketDataProvider(&data);
6784
6785   TestCompletionCallback callback;
6786
6787   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6788   EXPECT_EQ(ERR_IO_PENDING, rv);
6789
6790   rv = callback.WaitForResult();
6791   EXPECT_EQ(OK, rv);
6792
6793   const HttpResponseInfo* response = trans->GetResponseInfo();
6794   ASSERT_TRUE(response != NULL);
6795
6796   LoadTimingInfo load_timing_info;
6797   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6798   TestLoadTimingNotReusedWithPac(load_timing_info,
6799                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6800
6801   std::string response_text;
6802   rv = ReadTransaction(trans.get(), &response_text);
6803   EXPECT_EQ(OK, rv);
6804   EXPECT_EQ("Payload", response_text);
6805 }
6806
6807 TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
6808   HttpRequestInfo request;
6809   request.method = "GET";
6810   request.url = GURL("https://www.google.com/");
6811   request.load_flags = 0;
6812
6813   session_deps_.proxy_service.reset(
6814       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6815   CapturingNetLog net_log;
6816   session_deps_.net_log = &net_log;
6817
6818   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6819   scoped_ptr<HttpTransaction> trans(
6820       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6821
6822   unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
6823   unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6824
6825   MockWrite data_writes[] = {
6826     MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
6827               arraysize(write_buffer)),
6828     MockWrite("GET / HTTP/1.1\r\n"
6829               "Host: www.google.com\r\n"
6830               "Connection: keep-alive\r\n\r\n")
6831   };
6832
6833   MockRead data_reads[] = {
6834     MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
6835              arraysize(read_buffer)),
6836     MockRead("HTTP/1.0 200 OK\r\n"),
6837     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6838     MockRead("Payload"),
6839     MockRead(SYNCHRONOUS, OK)
6840   };
6841
6842   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6843                                 data_writes, arraysize(data_writes));
6844   session_deps_.socket_factory->AddSocketDataProvider(&data);
6845
6846   SSLSocketDataProvider ssl(ASYNC, OK);
6847   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6848
6849   TestCompletionCallback callback;
6850
6851   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6852   EXPECT_EQ(ERR_IO_PENDING, rv);
6853
6854   rv = callback.WaitForResult();
6855   EXPECT_EQ(OK, rv);
6856
6857   LoadTimingInfo load_timing_info;
6858   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6859   TestLoadTimingNotReusedWithPac(load_timing_info,
6860                                  CONNECT_TIMING_HAS_SSL_TIMES);
6861
6862   const HttpResponseInfo* response = trans->GetResponseInfo();
6863   ASSERT_TRUE(response != NULL);
6864
6865   std::string response_text;
6866   rv = ReadTransaction(trans.get(), &response_text);
6867   EXPECT_EQ(OK, rv);
6868   EXPECT_EQ("Payload", response_text);
6869 }
6870
6871 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
6872   HttpRequestInfo request;
6873   request.method = "GET";
6874   request.url = GURL("http://www.google.com/");
6875   request.load_flags = 0;
6876
6877   session_deps_.proxy_service.reset(
6878       ProxyService::CreateFixed("socks4://myproxy:1080"));
6879   CapturingNetLog net_log;
6880   session_deps_.net_log = &net_log;
6881
6882   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6883   scoped_ptr<HttpTransaction> trans(
6884       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6885
6886   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6887   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6888
6889   MockWrite data_writes[] = {
6890     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
6891     MockWrite("GET / HTTP/1.1\r\n"
6892               "Host: www.google.com\r\n"
6893               "Connection: keep-alive\r\n\r\n")
6894   };
6895
6896   MockRead data_reads[] = {
6897     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
6898     MockRead("HTTP/1.0 200 OK\r\n"),
6899     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6900     MockRead("Payload"),
6901     MockRead(SYNCHRONOUS, OK)
6902   };
6903
6904   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6905                                 data_writes, arraysize(data_writes));
6906   session_deps_.socket_factory->AddSocketDataProvider(&data);
6907
6908   TestCompletionCallback callback;
6909
6910   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6911   EXPECT_EQ(ERR_IO_PENDING, rv);
6912
6913   rv = callback.WaitForResult();
6914   EXPECT_EQ(OK, rv);
6915
6916   const HttpResponseInfo* response = trans->GetResponseInfo();
6917   ASSERT_TRUE(response != NULL);
6918
6919   LoadTimingInfo load_timing_info;
6920   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6921   TestLoadTimingNotReused(load_timing_info,
6922                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6923
6924   std::string response_text;
6925   rv = ReadTransaction(trans.get(), &response_text);
6926   EXPECT_EQ(OK, rv);
6927   EXPECT_EQ("Payload", response_text);
6928 }
6929
6930 TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
6931   HttpRequestInfo request;
6932   request.method = "GET";
6933   request.url = GURL("http://www.google.com/");
6934   request.load_flags = 0;
6935
6936   session_deps_.proxy_service.reset(
6937       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
6938   CapturingNetLog net_log;
6939   session_deps_.net_log = &net_log;
6940
6941   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6942   scoped_ptr<HttpTransaction> trans(
6943       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6944
6945   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
6946   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
6947   const char kSOCKS5OkRequest[] = {
6948     0x05,  // Version
6949     0x01,  // Command (CONNECT)
6950     0x00,  // Reserved.
6951     0x03,  // Address type (DOMAINNAME).
6952     0x0E,  // Length of domain (14)
6953     // Domain string:
6954     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
6955     0x00, 0x50,  // 16-bit port (80)
6956   };
6957   const char kSOCKS5OkResponse[] =
6958       { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
6959
6960   MockWrite data_writes[] = {
6961     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
6962     MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
6963     MockWrite("GET / HTTP/1.1\r\n"
6964               "Host: www.google.com\r\n"
6965               "Connection: keep-alive\r\n\r\n")
6966   };
6967
6968   MockRead data_reads[] = {
6969     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
6970     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
6971     MockRead("HTTP/1.0 200 OK\r\n"),
6972     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6973     MockRead("Payload"),
6974     MockRead(SYNCHRONOUS, OK)
6975   };
6976
6977   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6978                                 data_writes, arraysize(data_writes));
6979   session_deps_.socket_factory->AddSocketDataProvider(&data);
6980
6981   TestCompletionCallback callback;
6982
6983   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6984   EXPECT_EQ(ERR_IO_PENDING, rv);
6985
6986   rv = callback.WaitForResult();
6987   EXPECT_EQ(OK, rv);
6988
6989   const HttpResponseInfo* response = trans->GetResponseInfo();
6990   ASSERT_TRUE(response != NULL);
6991
6992   LoadTimingInfo load_timing_info;
6993   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6994   TestLoadTimingNotReusedWithPac(load_timing_info,
6995                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6996
6997   std::string response_text;
6998   rv = ReadTransaction(trans.get(), &response_text);
6999   EXPECT_EQ(OK, rv);
7000   EXPECT_EQ("Payload", response_text);
7001 }
7002
7003 TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
7004   HttpRequestInfo request;
7005   request.method = "GET";
7006   request.url = GURL("https://www.google.com/");
7007   request.load_flags = 0;
7008
7009   session_deps_.proxy_service.reset(
7010       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7011   CapturingNetLog net_log;
7012   session_deps_.net_log = &net_log;
7013
7014   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7015   scoped_ptr<HttpTransaction> trans(
7016       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7017
7018   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7019   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
7020   const unsigned char kSOCKS5OkRequest[] = {
7021     0x05,  // Version
7022     0x01,  // Command (CONNECT)
7023     0x00,  // Reserved.
7024     0x03,  // Address type (DOMAINNAME).
7025     0x0E,  // Length of domain (14)
7026     // Domain string:
7027     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7028     0x01, 0xBB,  // 16-bit port (443)
7029   };
7030
7031   const char kSOCKS5OkResponse[] =
7032       { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7033
7034   MockWrite data_writes[] = {
7035     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7036     MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7037               arraysize(kSOCKS5OkRequest)),
7038     MockWrite("GET / HTTP/1.1\r\n"
7039               "Host: www.google.com\r\n"
7040               "Connection: keep-alive\r\n\r\n")
7041   };
7042
7043   MockRead data_reads[] = {
7044     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7045     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
7046     MockRead("HTTP/1.0 200 OK\r\n"),
7047     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7048     MockRead("Payload"),
7049     MockRead(SYNCHRONOUS, OK)
7050   };
7051
7052   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7053                                 data_writes, arraysize(data_writes));
7054   session_deps_.socket_factory->AddSocketDataProvider(&data);
7055
7056   SSLSocketDataProvider ssl(ASYNC, OK);
7057   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7058
7059   TestCompletionCallback callback;
7060
7061   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7062   EXPECT_EQ(ERR_IO_PENDING, rv);
7063
7064   rv = callback.WaitForResult();
7065   EXPECT_EQ(OK, rv);
7066
7067   const HttpResponseInfo* response = trans->GetResponseInfo();
7068   ASSERT_TRUE(response != NULL);
7069
7070   LoadTimingInfo load_timing_info;
7071   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7072   TestLoadTimingNotReusedWithPac(load_timing_info,
7073                                  CONNECT_TIMING_HAS_SSL_TIMES);
7074
7075   std::string response_text;
7076   rv = ReadTransaction(trans.get(), &response_text);
7077   EXPECT_EQ(OK, rv);
7078   EXPECT_EQ("Payload", response_text);
7079 }
7080
7081 namespace {
7082
7083 // Tests that for connection endpoints the group names are correctly set.
7084
7085 struct GroupNameTest {
7086   std::string proxy_server;
7087   std::string url;
7088   std::string expected_group_name;
7089   bool ssl;
7090 };
7091
7092 scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
7093     NextProto next_proto,
7094     SpdySessionDependencies* session_deps_) {
7095   scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
7096
7097   base::WeakPtr<HttpServerProperties> http_server_properties =
7098       session->http_server_properties();
7099   http_server_properties->SetAlternateProtocol(
7100       HostPortPair("host.with.alternate", 80), 443,
7101       AlternateProtocolFromNextProto(next_proto));
7102
7103   return session;
7104 }
7105
7106 int GroupNameTransactionHelper(
7107     const std::string& url,
7108     const scoped_refptr<HttpNetworkSession>& session) {
7109   HttpRequestInfo request;
7110   request.method = "GET";
7111   request.url = GURL(url);
7112   request.load_flags = 0;
7113
7114   scoped_ptr<HttpTransaction> trans(
7115       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7116
7117   TestCompletionCallback callback;
7118
7119   // We do not complete this request, the dtor will clean the transaction up.
7120   return trans->Start(&request, callback.callback(), BoundNetLog());
7121 }
7122
7123 }  // namespace
7124
7125 TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
7126   const GroupNameTest tests[] = {
7127     {
7128       "",  // unused
7129       "http://www.google.com/direct",
7130       "www.google.com:80",
7131       false,
7132     },
7133     {
7134       "",  // unused
7135       "http://[2001:1418:13:1::25]/direct",
7136       "[2001:1418:13:1::25]:80",
7137       false,
7138     },
7139
7140     // SSL Tests
7141     {
7142       "",  // unused
7143       "https://www.google.com/direct_ssl",
7144       "ssl/www.google.com:443",
7145       true,
7146     },
7147     {
7148       "",  // unused
7149       "https://[2001:1418:13:1::25]/direct",
7150       "ssl/[2001:1418:13:1::25]:443",
7151       true,
7152     },
7153     {
7154       "",  // unused
7155       "http://host.with.alternate/direct",
7156       "ssl/host.with.alternate:443",
7157       true,
7158     },
7159   };
7160
7161   HttpStreamFactory::set_use_alternate_protocols(true);
7162
7163   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7164     session_deps_.proxy_service.reset(
7165         ProxyService::CreateFixed(tests[i].proxy_server));
7166     scoped_refptr<HttpNetworkSession> session(
7167         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
7168
7169     HttpNetworkSessionPeer peer(session);
7170     CaptureGroupNameTransportSocketPool* transport_conn_pool =
7171         new CaptureGroupNameTransportSocketPool(NULL, NULL);
7172     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
7173         new CaptureGroupNameSSLSocketPool(NULL, NULL);
7174     MockClientSocketPoolManager* mock_pool_manager =
7175         new MockClientSocketPoolManager;
7176     mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7177     mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
7178     peer.SetClientSocketPoolManager(mock_pool_manager);
7179
7180     EXPECT_EQ(ERR_IO_PENDING,
7181               GroupNameTransactionHelper(tests[i].url, session));
7182     if (tests[i].ssl)
7183       EXPECT_EQ(tests[i].expected_group_name,
7184                 ssl_conn_pool->last_group_name_received());
7185     else
7186       EXPECT_EQ(tests[i].expected_group_name,
7187                 transport_conn_pool->last_group_name_received());
7188   }
7189
7190 }
7191
7192 TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
7193   const GroupNameTest tests[] = {
7194     {
7195       "http_proxy",
7196       "http://www.google.com/http_proxy_normal",
7197       "www.google.com:80",
7198       false,
7199     },
7200
7201     // SSL Tests
7202     {
7203       "http_proxy",
7204       "https://www.google.com/http_connect_ssl",
7205       "ssl/www.google.com:443",
7206       true,
7207     },
7208
7209     {
7210       "http_proxy",
7211       "http://host.with.alternate/direct",
7212       "ssl/host.with.alternate:443",
7213       true,
7214     },
7215
7216     {
7217       "http_proxy",
7218       "ftp://ftp.google.com/http_proxy_normal",
7219       "ftp/ftp.google.com:21",
7220       false,
7221     },
7222   };
7223
7224   HttpStreamFactory::set_use_alternate_protocols(true);
7225
7226   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7227     session_deps_.proxy_service.reset(
7228         ProxyService::CreateFixed(tests[i].proxy_server));
7229     scoped_refptr<HttpNetworkSession> session(
7230         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
7231
7232     HttpNetworkSessionPeer peer(session);
7233
7234     HostPortPair proxy_host("http_proxy", 80);
7235     CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
7236         new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
7237     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
7238         new CaptureGroupNameSSLSocketPool(NULL, NULL);
7239
7240     MockClientSocketPoolManager* mock_pool_manager =
7241         new MockClientSocketPoolManager;
7242     mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7243     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7244     peer.SetClientSocketPoolManager(mock_pool_manager);
7245
7246     EXPECT_EQ(ERR_IO_PENDING,
7247               GroupNameTransactionHelper(tests[i].url, session));
7248     if (tests[i].ssl)
7249       EXPECT_EQ(tests[i].expected_group_name,
7250                 ssl_conn_pool->last_group_name_received());
7251     else
7252       EXPECT_EQ(tests[i].expected_group_name,
7253                 http_proxy_pool->last_group_name_received());
7254   }
7255 }
7256
7257 TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
7258   const GroupNameTest tests[] = {
7259     {
7260       "socks4://socks_proxy:1080",
7261       "http://www.google.com/socks4_direct",
7262       "socks4/www.google.com:80",
7263       false,
7264     },
7265     {
7266       "socks5://socks_proxy:1080",
7267       "http://www.google.com/socks5_direct",
7268       "socks5/www.google.com:80",
7269       false,
7270     },
7271
7272     // SSL Tests
7273     {
7274       "socks4://socks_proxy:1080",
7275       "https://www.google.com/socks4_ssl",
7276       "socks4/ssl/www.google.com:443",
7277       true,
7278     },
7279     {
7280       "socks5://socks_proxy:1080",
7281       "https://www.google.com/socks5_ssl",
7282       "socks5/ssl/www.google.com:443",
7283       true,
7284     },
7285
7286     {
7287       "socks4://socks_proxy:1080",
7288       "http://host.with.alternate/direct",
7289       "socks4/ssl/host.with.alternate:443",
7290       true,
7291     },
7292   };
7293
7294   HttpStreamFactory::set_use_alternate_protocols(true);
7295
7296   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7297     session_deps_.proxy_service.reset(
7298         ProxyService::CreateFixed(tests[i].proxy_server));
7299     scoped_refptr<HttpNetworkSession> session(
7300         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
7301
7302     HttpNetworkSessionPeer peer(session);
7303
7304     HostPortPair proxy_host("socks_proxy", 1080);
7305     CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
7306         new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
7307     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
7308         new CaptureGroupNameSSLSocketPool(NULL, NULL);
7309
7310     MockClientSocketPoolManager* mock_pool_manager =
7311         new MockClientSocketPoolManager;
7312     mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7313     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7314     peer.SetClientSocketPoolManager(mock_pool_manager);
7315
7316     scoped_ptr<HttpTransaction> trans(
7317         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7318
7319     EXPECT_EQ(ERR_IO_PENDING,
7320               GroupNameTransactionHelper(tests[i].url, session));
7321     if (tests[i].ssl)
7322       EXPECT_EQ(tests[i].expected_group_name,
7323                 ssl_conn_pool->last_group_name_received());
7324     else
7325       EXPECT_EQ(tests[i].expected_group_name,
7326                 socks_conn_pool->last_group_name_received());
7327   }
7328 }
7329
7330 TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
7331   HttpRequestInfo request;
7332   request.method = "GET";
7333   request.url = GURL("http://www.google.com/");
7334
7335   session_deps_.proxy_service.reset(
7336       ProxyService::CreateFixed("myproxy:70;foobar:80"));
7337
7338   // This simulates failure resolving all hostnames; that means we will fail
7339   // connecting to both proxies (myproxy:70 and foobar:80).
7340   session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
7341
7342   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7343   scoped_ptr<HttpTransaction> trans(
7344       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7345
7346   TestCompletionCallback callback;
7347
7348   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7349   EXPECT_EQ(ERR_IO_PENDING, rv);
7350
7351   rv = callback.WaitForResult();
7352   EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
7353 }
7354
7355 // Base test to make sure that when the load flags for a request specify to
7356 // bypass the cache, the DNS cache is not used.
7357 void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
7358     int load_flags) {
7359   // Issue a request, asking to bypass the cache(s).
7360   HttpRequestInfo request;
7361   request.method = "GET";
7362   request.load_flags = load_flags;
7363   request.url = GURL("http://www.google.com/");
7364
7365   // Select a host resolver that does caching.
7366   session_deps_.host_resolver.reset(new MockCachingHostResolver);
7367
7368   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7369   scoped_ptr<HttpTransaction> trans(
7370       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7371
7372   // Warm up the host cache so it has an entry for "www.google.com".
7373   AddressList addrlist;
7374   TestCompletionCallback callback;
7375   int rv = session_deps_.host_resolver->Resolve(
7376       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7377       DEFAULT_PRIORITY,
7378       &addrlist,
7379       callback.callback(),
7380       NULL,
7381       BoundNetLog());
7382   EXPECT_EQ(ERR_IO_PENDING, rv);
7383   rv = callback.WaitForResult();
7384   EXPECT_EQ(OK, rv);
7385
7386   // Verify that it was added to host cache, by doing a subsequent async lookup
7387   // and confirming it completes synchronously.
7388   rv = session_deps_.host_resolver->Resolve(
7389       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7390       DEFAULT_PRIORITY,
7391       &addrlist,
7392       callback.callback(),
7393       NULL,
7394       BoundNetLog());
7395   ASSERT_EQ(OK, rv);
7396
7397   // Inject a failure the next time that "www.google.com" is resolved. This way
7398   // we can tell if the next lookup hit the cache, or the "network".
7399   // (cache --> success, "network" --> failure).
7400   session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
7401
7402   // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7403   // first read -- this won't be reached as the host resolution will fail first.
7404   MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
7405   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7406   session_deps_.socket_factory->AddSocketDataProvider(&data);
7407
7408   // Run the request.
7409   rv = trans->Start(&request, callback.callback(), BoundNetLog());
7410   ASSERT_EQ(ERR_IO_PENDING, rv);
7411   rv = callback.WaitForResult();
7412
7413   // If we bypassed the cache, we would have gotten a failure while resolving
7414   // "www.google.com".
7415   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7416 }
7417
7418 // There are multiple load flags that should trigger the host cache bypass.
7419 // Test each in isolation:
7420 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
7421   BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7422 }
7423
7424 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
7425   BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7426 }
7427
7428 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
7429   BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7430 }
7431
7432 // Make sure we can handle an error when writing the request.
7433 TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
7434   HttpRequestInfo request;
7435   request.method = "GET";
7436   request.url = GURL("http://www.foo.com/");
7437   request.load_flags = 0;
7438
7439   MockWrite write_failure[] = {
7440     MockWrite(ASYNC, ERR_CONNECTION_RESET),
7441   };
7442   StaticSocketDataProvider data(NULL, 0,
7443                                 write_failure, arraysize(write_failure));
7444   session_deps_.socket_factory->AddSocketDataProvider(&data);
7445   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7446
7447   TestCompletionCallback callback;
7448
7449   scoped_ptr<HttpTransaction> trans(
7450       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7451
7452   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7453   EXPECT_EQ(ERR_IO_PENDING, rv);
7454
7455   rv = callback.WaitForResult();
7456   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7457 }
7458
7459 // Check that a connection closed after the start of the headers finishes ok.
7460 TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
7461   HttpRequestInfo request;
7462   request.method = "GET";
7463   request.url = GURL("http://www.foo.com/");
7464   request.load_flags = 0;
7465
7466   MockRead data_reads[] = {
7467     MockRead("HTTP/1."),
7468     MockRead(SYNCHRONOUS, OK),
7469   };
7470
7471   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7472   session_deps_.socket_factory->AddSocketDataProvider(&data);
7473   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7474
7475   TestCompletionCallback callback;
7476
7477   scoped_ptr<HttpTransaction> trans(
7478       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7479
7480   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7481   EXPECT_EQ(ERR_IO_PENDING, rv);
7482
7483   rv = callback.WaitForResult();
7484   EXPECT_EQ(OK, rv);
7485
7486   const HttpResponseInfo* response = trans->GetResponseInfo();
7487   ASSERT_TRUE(response != NULL);
7488
7489   EXPECT_TRUE(response->headers.get() != NULL);
7490   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7491
7492   std::string response_data;
7493   rv = ReadTransaction(trans.get(), &response_data);
7494   EXPECT_EQ(OK, rv);
7495   EXPECT_EQ("", response_data);
7496 }
7497
7498 // Make sure that a dropped connection while draining the body for auth
7499 // restart does the right thing.
7500 TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
7501   HttpRequestInfo request;
7502   request.method = "GET";
7503   request.url = GURL("http://www.google.com/");
7504   request.load_flags = 0;
7505
7506   MockWrite data_writes1[] = {
7507     MockWrite("GET / HTTP/1.1\r\n"
7508               "Host: www.google.com\r\n"
7509               "Connection: keep-alive\r\n\r\n"),
7510   };
7511
7512   MockRead data_reads1[] = {
7513     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7514     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7515     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7516     MockRead("Content-Length: 14\r\n\r\n"),
7517     MockRead("Unauth"),
7518     MockRead(ASYNC, ERR_CONNECTION_RESET),
7519   };
7520
7521   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7522                                  data_writes1, arraysize(data_writes1));
7523   session_deps_.socket_factory->AddSocketDataProvider(&data1);
7524
7525   // After calling trans->RestartWithAuth(), this is the request we should
7526   // be issuing -- the final header line contains the credentials.
7527   MockWrite data_writes2[] = {
7528     MockWrite("GET / HTTP/1.1\r\n"
7529               "Host: www.google.com\r\n"
7530               "Connection: keep-alive\r\n"
7531               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7532   };
7533
7534   // Lastly, the server responds with the actual content.
7535   MockRead data_reads2[] = {
7536     MockRead("HTTP/1.1 200 OK\r\n"),
7537     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7538     MockRead("Content-Length: 100\r\n\r\n"),
7539     MockRead(SYNCHRONOUS, OK),
7540   };
7541
7542   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7543                                  data_writes2, arraysize(data_writes2));
7544   session_deps_.socket_factory->AddSocketDataProvider(&data2);
7545   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7546
7547   TestCompletionCallback callback1;
7548
7549   scoped_ptr<HttpTransaction> trans(
7550       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7551
7552   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
7553   EXPECT_EQ(ERR_IO_PENDING, rv);
7554
7555   rv = callback1.WaitForResult();
7556   EXPECT_EQ(OK, rv);
7557
7558   const HttpResponseInfo* response = trans->GetResponseInfo();
7559   ASSERT_TRUE(response != NULL);
7560   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7561
7562   TestCompletionCallback callback2;
7563
7564   rv = trans->RestartWithAuth(
7565       AuthCredentials(kFoo, kBar), callback2.callback());
7566   EXPECT_EQ(ERR_IO_PENDING, rv);
7567
7568   rv = callback2.WaitForResult();
7569   EXPECT_EQ(OK, rv);
7570
7571   response = trans->GetResponseInfo();
7572   ASSERT_TRUE(response != NULL);
7573   EXPECT_TRUE(response->auth_challenge.get() == NULL);
7574   EXPECT_EQ(100, response->headers->GetContentLength());
7575 }
7576
7577 // Test HTTPS connections going through a proxy that sends extra data.
7578 TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
7579   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
7580
7581   HttpRequestInfo request;
7582   request.method = "GET";
7583   request.url = GURL("https://www.google.com/");
7584   request.load_flags = 0;
7585
7586   MockRead proxy_reads[] = {
7587     MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
7588     MockRead(SYNCHRONOUS, OK)
7589   };
7590
7591   StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
7592   SSLSocketDataProvider ssl(ASYNC, OK);
7593
7594   session_deps_.socket_factory->AddSocketDataProvider(&data);
7595   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7596
7597   TestCompletionCallback callback;
7598
7599   session_deps_.socket_factory->ResetNextMockIndexes();
7600
7601   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7602   scoped_ptr<HttpTransaction> trans(
7603       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7604
7605   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7606   EXPECT_EQ(ERR_IO_PENDING, rv);
7607
7608   rv = callback.WaitForResult();
7609   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7610 }
7611
7612 TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
7613   HttpRequestInfo request;
7614   request.method = "GET";
7615   request.url = GURL("http://www.google.com/");
7616   request.load_flags = 0;
7617
7618   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7619   scoped_ptr<HttpTransaction> trans(
7620       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7621
7622   MockRead data_reads[] = {
7623     MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
7624     MockRead(SYNCHRONOUS, OK),
7625   };
7626
7627   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7628   session_deps_.socket_factory->AddSocketDataProvider(&data);
7629
7630   TestCompletionCallback callback;
7631
7632   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7633   EXPECT_EQ(ERR_IO_PENDING, rv);
7634
7635   EXPECT_EQ(OK, callback.WaitForResult());
7636
7637   const HttpResponseInfo* response = trans->GetResponseInfo();
7638   ASSERT_TRUE(response != NULL);
7639
7640   EXPECT_TRUE(response->headers.get() != NULL);
7641   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7642
7643   std::string response_data;
7644   rv = ReadTransaction(trans.get(), &response_data);
7645   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
7646 }
7647
7648 TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
7649   base::FilePath temp_file_path;
7650   ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
7651   const uint64 kFakeSize = 100000;  // file is actually blank
7652   UploadFileElementReader::ScopedOverridingContentLengthForTests
7653       overriding_content_length(kFakeSize);
7654
7655   ScopedVector<UploadElementReader> element_readers;
7656   element_readers.push_back(
7657       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7658                                   temp_file_path,
7659                                   0,
7660                                   kuint64max,
7661                                   base::Time()));
7662   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
7663
7664   HttpRequestInfo request;
7665   request.method = "POST";
7666   request.url = GURL("http://www.google.com/upload");
7667   request.upload_data_stream = &upload_data_stream;
7668   request.load_flags = 0;
7669
7670   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7671   scoped_ptr<HttpTransaction> trans(
7672       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7673
7674   MockRead data_reads[] = {
7675     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
7676     MockRead("hello world"),
7677     MockRead(SYNCHRONOUS, OK),
7678   };
7679   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7680   session_deps_.socket_factory->AddSocketDataProvider(&data);
7681
7682   TestCompletionCallback callback;
7683
7684   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7685   EXPECT_EQ(ERR_IO_PENDING, rv);
7686
7687   rv = callback.WaitForResult();
7688   EXPECT_EQ(OK, rv);
7689
7690   const HttpResponseInfo* response = trans->GetResponseInfo();
7691   ASSERT_TRUE(response != NULL);
7692
7693   EXPECT_TRUE(response->headers.get() != NULL);
7694   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7695
7696   std::string response_data;
7697   rv = ReadTransaction(trans.get(), &response_data);
7698   EXPECT_EQ(OK, rv);
7699   EXPECT_EQ("hello world", response_data);
7700
7701   base::DeleteFile(temp_file_path, false);
7702 }
7703
7704 TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
7705   base::FilePath temp_file;
7706   ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
7707   std::string temp_file_content("Unreadable file.");
7708   ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
7709                                    temp_file_content.length()));
7710   ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7711
7712   ScopedVector<UploadElementReader> element_readers;
7713   element_readers.push_back(
7714       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7715                                   temp_file,
7716                                   0,
7717                                   kuint64max,
7718                                   base::Time()));
7719   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
7720
7721   HttpRequestInfo request;
7722   request.method = "POST";
7723   request.url = GURL("http://www.google.com/upload");
7724   request.upload_data_stream = &upload_data_stream;
7725   request.load_flags = 0;
7726
7727   // If we try to upload an unreadable file, the network stack should report
7728   // the file size as zero and upload zero bytes for that file.
7729   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7730   scoped_ptr<HttpTransaction> trans(
7731       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7732
7733   MockRead data_reads[] = {
7734     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
7735     MockRead(SYNCHRONOUS, OK),
7736   };
7737   MockWrite data_writes[] = {
7738     MockWrite("POST /upload HTTP/1.1\r\n"
7739               "Host: www.google.com\r\n"
7740               "Connection: keep-alive\r\n"
7741               "Content-Length: 0\r\n\r\n"),
7742     MockWrite(SYNCHRONOUS, OK),
7743   };
7744   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7745                                 arraysize(data_writes));
7746   session_deps_.socket_factory->AddSocketDataProvider(&data);
7747
7748   TestCompletionCallback callback;
7749
7750   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7751   EXPECT_EQ(ERR_IO_PENDING, rv);
7752
7753   rv = callback.WaitForResult();
7754   EXPECT_EQ(OK, rv);
7755
7756   const HttpResponseInfo* response = trans->GetResponseInfo();
7757   ASSERT_TRUE(response != NULL);
7758   EXPECT_TRUE(response->headers.get() != NULL);
7759   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7760
7761   base::DeleteFile(temp_file, false);
7762 }
7763
7764 TEST_P(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) {
7765   base::FilePath temp_file;
7766   ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
7767   std::string temp_file_contents("Unreadable file.");
7768   std::string unreadable_contents(temp_file_contents.length(), '\0');
7769   ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_contents.c_str(),
7770                                    temp_file_contents.length()));
7771
7772   ScopedVector<UploadElementReader> element_readers;
7773   element_readers.push_back(
7774       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7775                                   temp_file,
7776                                   0,
7777                                   kuint64max,
7778                                   base::Time()));
7779   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
7780
7781   HttpRequestInfo request;
7782   request.method = "POST";
7783   request.url = GURL("http://www.google.com/upload");
7784   request.upload_data_stream = &upload_data_stream;
7785   request.load_flags = 0;
7786
7787   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7788   scoped_ptr<HttpTransaction> trans(
7789       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7790
7791   MockRead data_reads[] = {
7792     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7793     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7794     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
7795
7796     MockRead("HTTP/1.1 200 OK\r\n"),
7797     MockRead("Content-Length: 0\r\n\r\n"),
7798     MockRead(SYNCHRONOUS, OK),
7799   };
7800   MockWrite data_writes[] = {
7801     MockWrite("POST /upload HTTP/1.1\r\n"
7802               "Host: www.google.com\r\n"
7803               "Connection: keep-alive\r\n"
7804               "Content-Length: 16\r\n\r\n"),
7805     MockWrite(SYNCHRONOUS, temp_file_contents.c_str()),
7806
7807     MockWrite("POST /upload HTTP/1.1\r\n"
7808               "Host: www.google.com\r\n"
7809               "Connection: keep-alive\r\n"
7810               "Content-Length: 0\r\n"
7811               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7812     MockWrite(SYNCHRONOUS, unreadable_contents.c_str(),
7813               temp_file_contents.length()),
7814     MockWrite(SYNCHRONOUS, OK),
7815   };
7816   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7817                                 arraysize(data_writes));
7818   session_deps_.socket_factory->AddSocketDataProvider(&data);
7819
7820   TestCompletionCallback callback1;
7821
7822   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
7823   EXPECT_EQ(ERR_IO_PENDING, rv);
7824
7825   rv = callback1.WaitForResult();
7826   EXPECT_EQ(OK, rv);
7827
7828   const HttpResponseInfo* response = trans->GetResponseInfo();
7829   ASSERT_TRUE(response != NULL);
7830   ASSERT_TRUE(response->headers.get() != NULL);
7831   EXPECT_EQ("HTTP/1.1 401 Unauthorized", response->headers->GetStatusLine());
7832   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7833
7834   // Now make the file unreadable and try again.
7835   ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7836
7837   TestCompletionCallback callback2;
7838
7839   rv = trans->RestartWithAuth(
7840       AuthCredentials(kFoo, kBar), callback2.callback());
7841   EXPECT_EQ(ERR_IO_PENDING, rv);
7842
7843   rv = callback2.WaitForResult();
7844   EXPECT_EQ(OK, rv);
7845
7846   response = trans->GetResponseInfo();
7847   ASSERT_TRUE(response != NULL);
7848   EXPECT_TRUE(response->headers.get() != NULL);
7849   EXPECT_TRUE(response->auth_challenge.get() == NULL);
7850   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7851
7852   base::DeleteFile(temp_file, false);
7853 }
7854
7855 TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
7856   class FakeUploadElementReader : public UploadElementReader {
7857    public:
7858     FakeUploadElementReader() {}
7859     virtual ~FakeUploadElementReader() {}
7860
7861     const CompletionCallback& callback() const { return callback_; }
7862
7863     // UploadElementReader overrides:
7864     virtual int Init(const CompletionCallback& callback) OVERRIDE {
7865       callback_ = callback;
7866       return ERR_IO_PENDING;
7867     }
7868     virtual uint64 GetContentLength() const OVERRIDE { return 0; }
7869     virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
7870     virtual int Read(IOBuffer* buf,
7871                      int buf_length,
7872                      const CompletionCallback& callback) OVERRIDE {
7873       return ERR_FAILED;
7874     }
7875
7876    private:
7877     CompletionCallback callback_;
7878   };
7879
7880   FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
7881   ScopedVector<UploadElementReader> element_readers;
7882   element_readers.push_back(fake_reader);
7883   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
7884
7885   HttpRequestInfo request;
7886   request.method = "POST";
7887   request.url = GURL("http://www.google.com/upload");
7888   request.upload_data_stream = &upload_data_stream;
7889   request.load_flags = 0;
7890
7891   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7892   scoped_ptr<HttpTransaction> trans(
7893       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7894
7895   StaticSocketDataProvider data;
7896   session_deps_.socket_factory->AddSocketDataProvider(&data);
7897
7898   TestCompletionCallback callback;
7899   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7900   EXPECT_EQ(ERR_IO_PENDING, rv);
7901   base::MessageLoop::current()->RunUntilIdle();
7902
7903   // Transaction is pending on request body initialization.
7904   ASSERT_FALSE(fake_reader->callback().is_null());
7905
7906   // Return Init()'s result after the transaction gets destroyed.
7907   trans.reset();
7908   fake_reader->callback().Run(OK);  // Should not crash.
7909 }
7910
7911 // Tests that changes to Auth realms are treated like auth rejections.
7912 TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
7913
7914   HttpRequestInfo request;
7915   request.method = "GET";
7916   request.url = GURL("http://www.google.com/");
7917   request.load_flags = 0;
7918
7919   // First transaction will request a resource and receive a Basic challenge
7920   // with realm="first_realm".
7921   MockWrite data_writes1[] = {
7922     MockWrite("GET / HTTP/1.1\r\n"
7923               "Host: www.google.com\r\n"
7924               "Connection: keep-alive\r\n"
7925               "\r\n"),
7926   };
7927   MockRead data_reads1[] = {
7928     MockRead("HTTP/1.1 401 Unauthorized\r\n"
7929              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7930              "\r\n"),
7931   };
7932
7933   // After calling trans->RestartWithAuth(), provide an Authentication header
7934   // for first_realm. The server will reject and provide a challenge with
7935   // second_realm.
7936   MockWrite data_writes2[] = {
7937     MockWrite("GET / HTTP/1.1\r\n"
7938               "Host: www.google.com\r\n"
7939               "Connection: keep-alive\r\n"
7940               "Authorization: Basic Zmlyc3Q6YmF6\r\n"
7941               "\r\n"),
7942   };
7943   MockRead data_reads2[] = {
7944     MockRead("HTTP/1.1 401 Unauthorized\r\n"
7945              "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
7946              "\r\n"),
7947   };
7948
7949   // This again fails, and goes back to first_realm. Make sure that the
7950   // entry is removed from cache.
7951   MockWrite data_writes3[] = {
7952     MockWrite("GET / HTTP/1.1\r\n"
7953               "Host: www.google.com\r\n"
7954               "Connection: keep-alive\r\n"
7955               "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
7956               "\r\n"),
7957   };
7958   MockRead data_reads3[] = {
7959     MockRead("HTTP/1.1 401 Unauthorized\r\n"
7960              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7961              "\r\n"),
7962   };
7963
7964   // Try one last time (with the correct password) and get the resource.
7965   MockWrite data_writes4[] = {
7966     MockWrite("GET / HTTP/1.1\r\n"
7967               "Host: www.google.com\r\n"
7968               "Connection: keep-alive\r\n"
7969               "Authorization: Basic Zmlyc3Q6YmFy\r\n"
7970               "\r\n"),
7971   };
7972   MockRead data_reads4[] = {
7973     MockRead("HTTP/1.1 200 OK\r\n"
7974              "Content-Type: text/html; charset=iso-8859-1\r\n"
7975              "Content-Length: 5\r\n"
7976              "\r\n"
7977              "hello"),
7978   };
7979
7980   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7981                                  data_writes1, arraysize(data_writes1));
7982   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7983                                  data_writes2, arraysize(data_writes2));
7984   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7985                                  data_writes3, arraysize(data_writes3));
7986   StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
7987                                  data_writes4, arraysize(data_writes4));
7988   session_deps_.socket_factory->AddSocketDataProvider(&data1);
7989   session_deps_.socket_factory->AddSocketDataProvider(&data2);
7990   session_deps_.socket_factory->AddSocketDataProvider(&data3);
7991   session_deps_.socket_factory->AddSocketDataProvider(&data4);
7992
7993   TestCompletionCallback callback1;
7994
7995   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7996   scoped_ptr<HttpTransaction> trans(
7997       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7998
7999   // Issue the first request with Authorize headers. There should be a
8000   // password prompt for first_realm waiting to be filled in after the
8001   // transaction completes.
8002   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
8003   EXPECT_EQ(ERR_IO_PENDING, rv);
8004   rv = callback1.WaitForResult();
8005   EXPECT_EQ(OK, rv);
8006   const HttpResponseInfo* response = trans->GetResponseInfo();
8007   ASSERT_TRUE(response != NULL);
8008   const AuthChallengeInfo* challenge = response->auth_challenge.get();
8009   ASSERT_FALSE(challenge == NULL);
8010   EXPECT_FALSE(challenge->is_proxy);
8011   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8012   EXPECT_EQ("first_realm", challenge->realm);
8013   EXPECT_EQ("basic", challenge->scheme);
8014
8015   // Issue the second request with an incorrect password. There should be a
8016   // password prompt for second_realm waiting to be filled in after the
8017   // transaction completes.
8018   TestCompletionCallback callback2;
8019   rv = trans->RestartWithAuth(
8020       AuthCredentials(kFirst, kBaz), callback2.callback());
8021   EXPECT_EQ(ERR_IO_PENDING, rv);
8022   rv = callback2.WaitForResult();
8023   EXPECT_EQ(OK, rv);
8024   response = trans->GetResponseInfo();
8025   ASSERT_TRUE(response != NULL);
8026   challenge = response->auth_challenge.get();
8027   ASSERT_FALSE(challenge == NULL);
8028   EXPECT_FALSE(challenge->is_proxy);
8029   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8030   EXPECT_EQ("second_realm", challenge->realm);
8031   EXPECT_EQ("basic", challenge->scheme);
8032
8033   // Issue the third request with another incorrect password. There should be
8034   // a password prompt for first_realm waiting to be filled in. If the password
8035   // prompt is not present, it indicates that the HttpAuthCacheEntry for
8036   // first_realm was not correctly removed.
8037   TestCompletionCallback callback3;
8038   rv = trans->RestartWithAuth(
8039       AuthCredentials(kSecond, kFou), callback3.callback());
8040   EXPECT_EQ(ERR_IO_PENDING, rv);
8041   rv = callback3.WaitForResult();
8042   EXPECT_EQ(OK, rv);
8043   response = trans->GetResponseInfo();
8044   ASSERT_TRUE(response != NULL);
8045   challenge = response->auth_challenge.get();
8046   ASSERT_FALSE(challenge == NULL);
8047   EXPECT_FALSE(challenge->is_proxy);
8048   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8049   EXPECT_EQ("first_realm", challenge->realm);
8050   EXPECT_EQ("basic", challenge->scheme);
8051
8052   // Issue the fourth request with the correct password and username.
8053   TestCompletionCallback callback4;
8054   rv = trans->RestartWithAuth(
8055       AuthCredentials(kFirst, kBar), callback4.callback());
8056   EXPECT_EQ(ERR_IO_PENDING, rv);
8057   rv = callback4.WaitForResult();
8058   EXPECT_EQ(OK, rv);
8059   response = trans->GetResponseInfo();
8060   ASSERT_TRUE(response != NULL);
8061   EXPECT_TRUE(response->auth_challenge.get() == NULL);
8062 }
8063
8064 TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
8065   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
8066   HttpStreamFactory::set_use_alternate_protocols(true);
8067
8068   std::string alternate_protocol_http_header =
8069       GetAlternateProtocolHttpHeader();
8070
8071   MockRead data_reads[] = {
8072     MockRead("HTTP/1.1 200 OK\r\n"),
8073     MockRead(alternate_protocol_http_header.c_str()),
8074     MockRead("hello world"),
8075     MockRead(SYNCHRONOUS, OK),
8076   };
8077
8078   HttpRequestInfo request;
8079   request.method = "GET";
8080   request.url = GURL("http://www.google.com/");
8081   request.load_flags = 0;
8082
8083   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8084
8085   session_deps_.socket_factory->AddSocketDataProvider(&data);
8086
8087   TestCompletionCallback callback;
8088
8089   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8090   scoped_ptr<HttpTransaction> trans(
8091       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8092
8093   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8094   EXPECT_EQ(ERR_IO_PENDING, rv);
8095
8096   HostPortPair http_host_port_pair("www.google.com", 80);
8097   const HttpServerProperties& http_server_properties =
8098       *session->http_server_properties();
8099   EXPECT_FALSE(
8100       http_server_properties.HasAlternateProtocol(http_host_port_pair));
8101
8102   EXPECT_EQ(OK, callback.WaitForResult());
8103
8104   const HttpResponseInfo* response = trans->GetResponseInfo();
8105   ASSERT_TRUE(response != NULL);
8106   ASSERT_TRUE(response->headers.get() != NULL);
8107   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8108   EXPECT_FALSE(response->was_fetched_via_spdy);
8109   EXPECT_FALSE(response->was_npn_negotiated);
8110
8111   std::string response_data;
8112   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8113   EXPECT_EQ("hello world", response_data);
8114
8115   ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8116   const PortAlternateProtocolPair alternate =
8117       http_server_properties.GetAlternateProtocol(http_host_port_pair);
8118   PortAlternateProtocolPair expected_alternate;
8119   expected_alternate.port = 443;
8120   expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
8121   EXPECT_TRUE(expected_alternate.Equals(alternate));
8122 }
8123
8124 TEST_P(HttpNetworkTransactionTest,
8125        MarkBrokenAlternateProtocolAndFallback) {
8126   HttpStreamFactory::set_use_alternate_protocols(true);
8127
8128   HttpRequestInfo request;
8129   request.method = "GET";
8130   request.url = GURL("http://www.google.com/");
8131   request.load_flags = 0;
8132
8133   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8134   StaticSocketDataProvider first_data;
8135   first_data.set_connect_data(mock_connect);
8136   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8137
8138   MockRead data_reads[] = {
8139     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8140     MockRead("hello world"),
8141     MockRead(ASYNC, OK),
8142   };
8143   StaticSocketDataProvider second_data(
8144       data_reads, arraysize(data_reads), NULL, 0);
8145   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8146
8147   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8148
8149   base::WeakPtr<HttpServerProperties> http_server_properties =
8150       session->http_server_properties();
8151   // Port must be < 1024, or the header will be ignored (since initial port was
8152   // port 80 (another restricted port).
8153   http_server_properties->SetAlternateProtocol(
8154       HostPortPair::FromURL(request.url),
8155       666 /* port is ignored by MockConnect anyway */,
8156       AlternateProtocolFromNextProto(GetParam()));
8157
8158   scoped_ptr<HttpTransaction> trans(
8159       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8160   TestCompletionCallback callback;
8161
8162   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8163   EXPECT_EQ(ERR_IO_PENDING, rv);
8164   EXPECT_EQ(OK, callback.WaitForResult());
8165
8166   const HttpResponseInfo* response = trans->GetResponseInfo();
8167   ASSERT_TRUE(response != NULL);
8168   ASSERT_TRUE(response->headers.get() != NULL);
8169   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8170
8171   std::string response_data;
8172   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8173   EXPECT_EQ("hello world", response_data);
8174
8175   ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
8176       HostPortPair::FromURL(request.url)));
8177   const PortAlternateProtocolPair alternate =
8178       http_server_properties->GetAlternateProtocol(
8179           HostPortPair::FromURL(request.url));
8180   EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
8181 }
8182
8183 TEST_P(HttpNetworkTransactionTest,
8184        AlternateProtocolPortRestrictedBlocked) {
8185   // Ensure that we're not allowed to redirect traffic via an alternate
8186   // protocol to an unrestricted (port >= 1024) when the original traffic was
8187   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8188   // other cases.
8189   HttpStreamFactory::set_use_alternate_protocols(true);
8190
8191   HttpRequestInfo restricted_port_request;
8192   restricted_port_request.method = "GET";
8193   restricted_port_request.url = GURL("http://www.google.com:1023/");
8194   restricted_port_request.load_flags = 0;
8195
8196   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8197   StaticSocketDataProvider first_data;
8198   first_data.set_connect_data(mock_connect);
8199   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8200
8201   MockRead data_reads[] = {
8202     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8203     MockRead("hello world"),
8204     MockRead(ASYNC, OK),
8205   };
8206   StaticSocketDataProvider second_data(
8207       data_reads, arraysize(data_reads), NULL, 0);
8208   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8209
8210   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8211
8212   base::WeakPtr<HttpServerProperties> http_server_properties =
8213       session->http_server_properties();
8214   const int kUnrestrictedAlternatePort = 1024;
8215   http_server_properties->SetAlternateProtocol(
8216       HostPortPair::FromURL(restricted_port_request.url),
8217       kUnrestrictedAlternatePort,
8218       AlternateProtocolFromNextProto(GetParam()));
8219
8220   scoped_ptr<HttpTransaction> trans(
8221       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8222   TestCompletionCallback callback;
8223
8224   int rv = trans->Start(
8225       &restricted_port_request,
8226       callback.callback(), BoundNetLog());
8227   EXPECT_EQ(ERR_IO_PENDING, rv);
8228   // Invalid change to unrestricted port should fail.
8229   EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
8230 }
8231
8232 TEST_P(HttpNetworkTransactionTest,
8233        AlternateProtocolPortRestrictedPermitted) {
8234   // Ensure that we're allowed to redirect traffic via an alternate
8235   // protocol to an unrestricted (port >= 1024) when the original traffic was
8236   // on a restricted port (port < 1024) if we set
8237   // enable_user_alternate_protocol_ports.
8238
8239   HttpStreamFactory::set_use_alternate_protocols(true);
8240   session_deps_.enable_user_alternate_protocol_ports = true;
8241
8242   HttpRequestInfo restricted_port_request;
8243   restricted_port_request.method = "GET";
8244   restricted_port_request.url = GURL("http://www.google.com:1023/");
8245   restricted_port_request.load_flags = 0;
8246
8247   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8248   StaticSocketDataProvider first_data;
8249   first_data.set_connect_data(mock_connect);
8250   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8251
8252   MockRead data_reads[] = {
8253     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8254     MockRead("hello world"),
8255     MockRead(ASYNC, OK),
8256   };
8257   StaticSocketDataProvider second_data(
8258       data_reads, arraysize(data_reads), NULL, 0);
8259   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8260
8261   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8262
8263   base::WeakPtr<HttpServerProperties> http_server_properties =
8264       session->http_server_properties();
8265   const int kUnrestrictedAlternatePort = 1024;
8266   http_server_properties->SetAlternateProtocol(
8267       HostPortPair::FromURL(restricted_port_request.url),
8268       kUnrestrictedAlternatePort,
8269       AlternateProtocolFromNextProto(GetParam()));
8270
8271   scoped_ptr<HttpTransaction> trans(
8272       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8273   TestCompletionCallback callback;
8274
8275   EXPECT_EQ(ERR_IO_PENDING, trans->Start(
8276       &restricted_port_request,
8277       callback.callback(), BoundNetLog()));
8278   // Change to unrestricted port should succeed.
8279   EXPECT_EQ(OK, callback.WaitForResult());
8280 }
8281
8282 TEST_P(HttpNetworkTransactionTest,
8283        AlternateProtocolPortRestrictedAllowed) {
8284   // Ensure that we're not allowed to redirect traffic via an alternate
8285   // protocol to an unrestricted (port >= 1024) when the original traffic was
8286   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8287   // other cases.
8288   HttpStreamFactory::set_use_alternate_protocols(true);
8289
8290   HttpRequestInfo restricted_port_request;
8291   restricted_port_request.method = "GET";
8292   restricted_port_request.url = GURL("http://www.google.com:1023/");
8293   restricted_port_request.load_flags = 0;
8294
8295   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8296   StaticSocketDataProvider first_data;
8297   first_data.set_connect_data(mock_connect);
8298   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8299
8300   MockRead data_reads[] = {
8301     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8302     MockRead("hello world"),
8303     MockRead(ASYNC, OK),
8304   };
8305   StaticSocketDataProvider second_data(
8306       data_reads, arraysize(data_reads), NULL, 0);
8307   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8308
8309   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8310
8311   base::WeakPtr<HttpServerProperties> http_server_properties =
8312       session->http_server_properties();
8313   const int kRestrictedAlternatePort = 80;
8314   http_server_properties->SetAlternateProtocol(
8315       HostPortPair::FromURL(restricted_port_request.url),
8316       kRestrictedAlternatePort,
8317       AlternateProtocolFromNextProto(GetParam()));
8318
8319   scoped_ptr<HttpTransaction> trans(
8320       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8321   TestCompletionCallback callback;
8322
8323   int rv = trans->Start(
8324       &restricted_port_request,
8325       callback.callback(), BoundNetLog());
8326   EXPECT_EQ(ERR_IO_PENDING, rv);
8327   // Valid change to restricted port should pass.
8328   EXPECT_EQ(OK, callback.WaitForResult());
8329 }
8330
8331 TEST_P(HttpNetworkTransactionTest,
8332        AlternateProtocolPortUnrestrictedAllowed1) {
8333   // Ensure that we're not allowed to redirect traffic via an alternate
8334   // protocol to an unrestricted (port >= 1024) when the original traffic was
8335   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8336   // other cases.
8337   HttpStreamFactory::set_use_alternate_protocols(true);
8338
8339   HttpRequestInfo unrestricted_port_request;
8340   unrestricted_port_request.method = "GET";
8341   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8342   unrestricted_port_request.load_flags = 0;
8343
8344   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8345   StaticSocketDataProvider first_data;
8346   first_data.set_connect_data(mock_connect);
8347   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8348
8349   MockRead data_reads[] = {
8350     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8351     MockRead("hello world"),
8352     MockRead(ASYNC, OK),
8353   };
8354   StaticSocketDataProvider second_data(
8355       data_reads, arraysize(data_reads), NULL, 0);
8356   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8357
8358   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8359
8360   base::WeakPtr<HttpServerProperties> http_server_properties =
8361       session->http_server_properties();
8362   const int kRestrictedAlternatePort = 80;
8363   http_server_properties->SetAlternateProtocol(
8364       HostPortPair::FromURL(unrestricted_port_request.url),
8365       kRestrictedAlternatePort,
8366       AlternateProtocolFromNextProto(GetParam()));
8367
8368   scoped_ptr<HttpTransaction> trans(
8369       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8370   TestCompletionCallback callback;
8371
8372   int rv = trans->Start(
8373       &unrestricted_port_request, callback.callback(), BoundNetLog());
8374   EXPECT_EQ(ERR_IO_PENDING, rv);
8375   // Valid change to restricted port should pass.
8376   EXPECT_EQ(OK, callback.WaitForResult());
8377 }
8378
8379 TEST_P(HttpNetworkTransactionTest,
8380        AlternateProtocolPortUnrestrictedAllowed2) {
8381   // Ensure that we're not allowed to redirect traffic via an alternate
8382   // protocol to an unrestricted (port >= 1024) when the original traffic was
8383   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8384   // other cases.
8385   HttpStreamFactory::set_use_alternate_protocols(true);
8386
8387   HttpRequestInfo unrestricted_port_request;
8388   unrestricted_port_request.method = "GET";
8389   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8390   unrestricted_port_request.load_flags = 0;
8391
8392   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8393   StaticSocketDataProvider first_data;
8394   first_data.set_connect_data(mock_connect);
8395   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8396
8397   MockRead data_reads[] = {
8398     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8399     MockRead("hello world"),
8400     MockRead(ASYNC, OK),
8401   };
8402   StaticSocketDataProvider second_data(
8403       data_reads, arraysize(data_reads), NULL, 0);
8404   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8405
8406   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8407
8408   base::WeakPtr<HttpServerProperties> http_server_properties =
8409       session->http_server_properties();
8410   const int kUnrestrictedAlternatePort = 1024;
8411   http_server_properties->SetAlternateProtocol(
8412       HostPortPair::FromURL(unrestricted_port_request.url),
8413       kUnrestrictedAlternatePort,
8414       AlternateProtocolFromNextProto(GetParam()));
8415
8416   scoped_ptr<HttpTransaction> trans(
8417       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8418   TestCompletionCallback callback;
8419
8420   int rv = trans->Start(
8421       &unrestricted_port_request, callback.callback(), BoundNetLog());
8422   EXPECT_EQ(ERR_IO_PENDING, rv);
8423   // Valid change to an unrestricted port should pass.
8424   EXPECT_EQ(OK, callback.WaitForResult());
8425 }
8426
8427 TEST_P(HttpNetworkTransactionTest,
8428        AlternateProtocolUnsafeBlocked) {
8429   // Ensure that we're not allowed to redirect traffic via an alternate
8430   // protocol to an unsafe port, and that we resume the second
8431   // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8432   HttpStreamFactory::set_use_alternate_protocols(true);
8433
8434   HttpRequestInfo request;
8435   request.method = "GET";
8436   request.url = GURL("http://www.google.com/");
8437   request.load_flags = 0;
8438
8439   // The alternate protocol request will error out before we attempt to connect,
8440   // so only the standard HTTP request will try to connect.
8441   MockRead data_reads[] = {
8442     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8443     MockRead("hello world"),
8444     MockRead(ASYNC, OK),
8445   };
8446   StaticSocketDataProvider data(
8447       data_reads, arraysize(data_reads), NULL, 0);
8448   session_deps_.socket_factory->AddSocketDataProvider(&data);
8449
8450   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8451
8452   base::WeakPtr<HttpServerProperties> http_server_properties =
8453       session->http_server_properties();
8454   const int kUnsafePort = 7;
8455   http_server_properties->SetAlternateProtocol(
8456       HostPortPair::FromURL(request.url),
8457       kUnsafePort,
8458       AlternateProtocolFromNextProto(GetParam()));
8459
8460   scoped_ptr<HttpTransaction> trans(
8461       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8462   TestCompletionCallback callback;
8463
8464   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8465   EXPECT_EQ(ERR_IO_PENDING, rv);
8466   // The HTTP request should succeed.
8467   EXPECT_EQ(OK, callback.WaitForResult());
8468
8469   // Disable alternate protocol before the asserts.
8470   HttpStreamFactory::set_use_alternate_protocols(false);
8471
8472   const HttpResponseInfo* response = trans->GetResponseInfo();
8473   ASSERT_TRUE(response != NULL);
8474   ASSERT_TRUE(response->headers.get() != NULL);
8475   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8476
8477   std::string response_data;
8478   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8479   EXPECT_EQ("hello world", response_data);
8480 }
8481
8482 TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
8483   HttpStreamFactory::set_use_alternate_protocols(true);
8484   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
8485
8486   HttpRequestInfo request;
8487   request.method = "GET";
8488   request.url = GURL("http://www.google.com/");
8489   request.load_flags = 0;
8490
8491   std::string alternate_protocol_http_header =
8492       GetAlternateProtocolHttpHeader();
8493
8494   MockRead data_reads[] = {
8495     MockRead("HTTP/1.1 200 OK\r\n"),
8496     MockRead(alternate_protocol_http_header.c_str()),
8497     MockRead("hello world"),
8498     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8499     MockRead(ASYNC, OK)
8500   };
8501
8502   StaticSocketDataProvider first_transaction(
8503       data_reads, arraysize(data_reads), NULL, 0);
8504   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
8505
8506   SSLSocketDataProvider ssl(ASYNC, OK);
8507   ssl.SetNextProto(GetParam());
8508   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8509
8510   scoped_ptr<SpdyFrame> req(
8511       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8512   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
8513
8514   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8515   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
8516   MockRead spdy_reads[] = {
8517     CreateMockRead(*resp),
8518     CreateMockRead(*data),
8519     MockRead(ASYNC, 0, 0),
8520   };
8521
8522   DelayedSocketData spdy_data(
8523       1,  // wait for one write to finish before reading.
8524       spdy_reads, arraysize(spdy_reads),
8525       spdy_writes, arraysize(spdy_writes));
8526   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8527
8528   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
8529   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8530       NULL, 0, NULL, 0);
8531   hanging_non_alternate_protocol_socket.set_connect_data(
8532       never_finishing_connect);
8533   session_deps_.socket_factory->AddSocketDataProvider(
8534       &hanging_non_alternate_protocol_socket);
8535
8536   TestCompletionCallback callback;
8537
8538   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8539   scoped_ptr<HttpTransaction> trans(
8540       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8541
8542   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8543   EXPECT_EQ(ERR_IO_PENDING, rv);
8544   EXPECT_EQ(OK, callback.WaitForResult());
8545
8546   const HttpResponseInfo* response = trans->GetResponseInfo();
8547   ASSERT_TRUE(response != NULL);
8548   ASSERT_TRUE(response->headers.get() != NULL);
8549   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8550
8551   std::string response_data;
8552   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8553   EXPECT_EQ("hello world", response_data);
8554
8555   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8556
8557   rv = trans->Start(&request, callback.callback(), BoundNetLog());
8558   EXPECT_EQ(ERR_IO_PENDING, rv);
8559   EXPECT_EQ(OK, callback.WaitForResult());
8560
8561   response = trans->GetResponseInfo();
8562   ASSERT_TRUE(response != NULL);
8563   ASSERT_TRUE(response->headers.get() != NULL);
8564   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8565   EXPECT_TRUE(response->was_fetched_via_spdy);
8566   EXPECT_TRUE(response->was_npn_negotiated);
8567
8568   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8569   EXPECT_EQ("hello!", response_data);
8570 }
8571
8572 TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
8573   HttpStreamFactory::set_use_alternate_protocols(true);
8574   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
8575
8576   HttpRequestInfo request;
8577   request.method = "GET";
8578   request.url = GURL("http://www.google.com/");
8579   request.load_flags = 0;
8580
8581   std::string alternate_protocol_http_header =
8582       GetAlternateProtocolHttpHeader();
8583
8584   MockRead data_reads[] = {
8585     MockRead("HTTP/1.1 200 OK\r\n"),
8586     MockRead(alternate_protocol_http_header.c_str()),
8587     MockRead("hello world"),
8588     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8589     MockRead(ASYNC, OK),
8590   };
8591
8592   StaticSocketDataProvider first_transaction(
8593       data_reads, arraysize(data_reads), NULL, 0);
8594   // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
8595   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
8596
8597   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
8598   StaticSocketDataProvider hanging_socket(
8599       NULL, 0, NULL, 0);
8600   hanging_socket.set_connect_data(never_finishing_connect);
8601   // Socket 2 and 3 are the hanging Alternate-Protocol and
8602   // non-Alternate-Protocol jobs from the 2nd transaction.
8603   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8604   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8605
8606   SSLSocketDataProvider ssl(ASYNC, OK);
8607   ssl.SetNextProto(GetParam());
8608   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8609
8610   scoped_ptr<SpdyFrame> req1(
8611       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8612   scoped_ptr<SpdyFrame> req2(
8613       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
8614   MockWrite spdy_writes[] = {
8615     CreateMockWrite(*req1),
8616     CreateMockWrite(*req2),
8617   };
8618   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8619   scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8620   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8621   scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
8622   MockRead spdy_reads[] = {
8623     CreateMockRead(*resp1),
8624     CreateMockRead(*data1),
8625     CreateMockRead(*resp2),
8626     CreateMockRead(*data2),
8627     MockRead(ASYNC, 0, 0),
8628   };
8629
8630   DelayedSocketData spdy_data(
8631       2,  // wait for writes to finish before reading.
8632       spdy_reads, arraysize(spdy_reads),
8633       spdy_writes, arraysize(spdy_writes));
8634   // Socket 4 is the successful Alternate-Protocol for transaction 3.
8635   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8636
8637   // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
8638   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8639
8640   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8641   TestCompletionCallback callback1;
8642   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
8643
8644   int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
8645   EXPECT_EQ(ERR_IO_PENDING, rv);
8646   EXPECT_EQ(OK, callback1.WaitForResult());
8647
8648   const HttpResponseInfo* response = trans1.GetResponseInfo();
8649   ASSERT_TRUE(response != NULL);
8650   ASSERT_TRUE(response->headers.get() != NULL);
8651   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8652
8653   std::string response_data;
8654   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8655   EXPECT_EQ("hello world", response_data);
8656
8657   TestCompletionCallback callback2;
8658   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
8659   rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
8660   EXPECT_EQ(ERR_IO_PENDING, rv);
8661
8662   TestCompletionCallback callback3;
8663   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
8664   rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
8665   EXPECT_EQ(ERR_IO_PENDING, rv);
8666
8667   EXPECT_EQ(OK, callback2.WaitForResult());
8668   EXPECT_EQ(OK, callback3.WaitForResult());
8669
8670   response = trans2.GetResponseInfo();
8671   ASSERT_TRUE(response != NULL);
8672   ASSERT_TRUE(response->headers.get() != NULL);
8673   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8674   EXPECT_TRUE(response->was_fetched_via_spdy);
8675   EXPECT_TRUE(response->was_npn_negotiated);
8676   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
8677   EXPECT_EQ("hello!", response_data);
8678
8679   response = trans3.GetResponseInfo();
8680   ASSERT_TRUE(response != NULL);
8681   ASSERT_TRUE(response->headers.get() != NULL);
8682   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8683   EXPECT_TRUE(response->was_fetched_via_spdy);
8684   EXPECT_TRUE(response->was_npn_negotiated);
8685   ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
8686   EXPECT_EQ("hello!", response_data);
8687 }
8688
8689 TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
8690   HttpStreamFactory::set_use_alternate_protocols(true);
8691   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
8692
8693   HttpRequestInfo request;
8694   request.method = "GET";
8695   request.url = GURL("http://www.google.com/");
8696   request.load_flags = 0;
8697
8698   std::string alternate_protocol_http_header =
8699       GetAlternateProtocolHttpHeader();
8700
8701   MockRead data_reads[] = {
8702     MockRead("HTTP/1.1 200 OK\r\n"),
8703     MockRead(alternate_protocol_http_header.c_str()),
8704     MockRead("hello world"),
8705     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8706     MockRead(ASYNC, OK),
8707   };
8708
8709   StaticSocketDataProvider first_transaction(
8710       data_reads, arraysize(data_reads), NULL, 0);
8711   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
8712
8713   SSLSocketDataProvider ssl(ASYNC, OK);
8714   ssl.SetNextProto(GetParam());
8715   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8716
8717   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
8718   StaticSocketDataProvider hanging_alternate_protocol_socket(
8719       NULL, 0, NULL, 0);
8720   hanging_alternate_protocol_socket.set_connect_data(
8721       never_finishing_connect);
8722   session_deps_.socket_factory->AddSocketDataProvider(
8723       &hanging_alternate_protocol_socket);
8724
8725   // 2nd request is just a copy of the first one, over HTTP again.
8726   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
8727
8728   TestCompletionCallback callback;
8729
8730   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8731   scoped_ptr<HttpTransaction> trans(
8732       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8733
8734   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8735   EXPECT_EQ(ERR_IO_PENDING, rv);
8736   EXPECT_EQ(OK, callback.WaitForResult());
8737
8738   const HttpResponseInfo* response = trans->GetResponseInfo();
8739   ASSERT_TRUE(response != NULL);
8740   ASSERT_TRUE(response->headers.get() != NULL);
8741   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8742
8743   std::string response_data;
8744   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8745   EXPECT_EQ("hello world", response_data);
8746
8747   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8748
8749   rv = trans->Start(&request, callback.callback(), BoundNetLog());
8750   EXPECT_EQ(ERR_IO_PENDING, rv);
8751   EXPECT_EQ(OK, callback.WaitForResult());
8752
8753   response = trans->GetResponseInfo();
8754   ASSERT_TRUE(response != NULL);
8755   ASSERT_TRUE(response->headers.get() != NULL);
8756   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8757   EXPECT_FALSE(response->was_fetched_via_spdy);
8758   EXPECT_FALSE(response->was_npn_negotiated);
8759
8760   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8761   EXPECT_EQ("hello world", response_data);
8762 }
8763
8764 class CapturingProxyResolver : public ProxyResolver {
8765  public:
8766   CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
8767   virtual ~CapturingProxyResolver() {}
8768
8769   virtual int GetProxyForURL(const GURL& url,
8770                              ProxyInfo* results,
8771                              const CompletionCallback& callback,
8772                              RequestHandle* request,
8773                              const BoundNetLog& net_log) OVERRIDE {
8774     ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
8775                              HostPortPair("myproxy", 80));
8776     results->UseProxyServer(proxy_server);
8777     resolved_.push_back(url);
8778     return OK;
8779   }
8780
8781   virtual void CancelRequest(RequestHandle request) OVERRIDE {
8782     NOTREACHED();
8783   }
8784
8785   virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
8786     NOTREACHED();
8787     return LOAD_STATE_IDLE;
8788   }
8789
8790   virtual void CancelSetPacScript() OVERRIDE {
8791     NOTREACHED();
8792   }
8793
8794   virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
8795                            const CompletionCallback& /*callback*/) OVERRIDE {
8796     return OK;
8797   }
8798
8799   const std::vector<GURL>& resolved() const { return resolved_; }
8800
8801  private:
8802   std::vector<GURL> resolved_;
8803
8804   DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
8805 };
8806
8807 TEST_P(HttpNetworkTransactionTest,
8808        UseAlternateProtocolForTunneledNpnSpdy) {
8809   HttpStreamFactory::set_use_alternate_protocols(true);
8810   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
8811
8812   ProxyConfig proxy_config;
8813   proxy_config.set_auto_detect(true);
8814   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
8815
8816   CapturingProxyResolver* capturing_proxy_resolver =
8817       new CapturingProxyResolver();
8818   session_deps_.proxy_service.reset(new ProxyService(
8819       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
8820       NULL));
8821   CapturingNetLog net_log;
8822   session_deps_.net_log = &net_log;
8823
8824   HttpRequestInfo request;
8825   request.method = "GET";
8826   request.url = GURL("http://www.google.com/");
8827   request.load_flags = 0;
8828
8829   std::string alternate_protocol_http_header =
8830       GetAlternateProtocolHttpHeader();
8831
8832   MockRead data_reads[] = {
8833     MockRead("HTTP/1.1 200 OK\r\n"),
8834     MockRead(alternate_protocol_http_header.c_str()),
8835     MockRead("hello world"),
8836     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8837     MockRead(ASYNC, OK),
8838   };
8839
8840   StaticSocketDataProvider first_transaction(
8841       data_reads, arraysize(data_reads), NULL, 0);
8842   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
8843
8844   SSLSocketDataProvider ssl(ASYNC, OK);
8845   ssl.SetNextProto(GetParam());
8846   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8847
8848   scoped_ptr<SpdyFrame> req(
8849       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8850   MockWrite spdy_writes[] = {
8851     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
8852               "Host: www.google.com\r\n"
8853               "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
8854     CreateMockWrite(*req),                              // 3
8855   };
8856
8857   const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
8858
8859   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8860   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
8861   MockRead spdy_reads[] = {
8862     MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
8863     CreateMockRead(*resp.get(), 4),  // 2, 4
8864     CreateMockRead(*data.get(), 4),  // 5
8865     MockRead(ASYNC, 0, 0, 4),  // 6
8866   };
8867
8868   OrderedSocketData spdy_data(
8869       spdy_reads, arraysize(spdy_reads),
8870       spdy_writes, arraysize(spdy_writes));
8871   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8872
8873   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
8874   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8875       NULL, 0, NULL, 0);
8876   hanging_non_alternate_protocol_socket.set_connect_data(
8877       never_finishing_connect);
8878   session_deps_.socket_factory->AddSocketDataProvider(
8879       &hanging_non_alternate_protocol_socket);
8880
8881   TestCompletionCallback callback;
8882
8883   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8884   scoped_ptr<HttpTransaction> trans(
8885       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8886
8887   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8888   EXPECT_EQ(ERR_IO_PENDING, rv);
8889   EXPECT_EQ(OK, callback.WaitForResult());
8890
8891   const HttpResponseInfo* response = trans->GetResponseInfo();
8892   ASSERT_TRUE(response != NULL);
8893   ASSERT_TRUE(response->headers.get() != NULL);
8894   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8895   EXPECT_FALSE(response->was_fetched_via_spdy);
8896   EXPECT_FALSE(response->was_npn_negotiated);
8897
8898   std::string response_data;
8899   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8900   EXPECT_EQ("hello world", response_data);
8901
8902   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8903
8904   rv = trans->Start(&request, callback.callback(), BoundNetLog());
8905   EXPECT_EQ(ERR_IO_PENDING, rv);
8906   EXPECT_EQ(OK, callback.WaitForResult());
8907
8908   response = trans->GetResponseInfo();
8909   ASSERT_TRUE(response != NULL);
8910   ASSERT_TRUE(response->headers.get() != NULL);
8911   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8912   EXPECT_TRUE(response->was_fetched_via_spdy);
8913   EXPECT_TRUE(response->was_npn_negotiated);
8914
8915   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8916   EXPECT_EQ("hello!", response_data);
8917   ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
8918   EXPECT_EQ("http://www.google.com/",
8919             capturing_proxy_resolver->resolved()[0].spec());
8920   EXPECT_EQ("https://www.google.com/",
8921             capturing_proxy_resolver->resolved()[1].spec());
8922
8923   LoadTimingInfo load_timing_info;
8924   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8925   TestLoadTimingNotReusedWithPac(load_timing_info,
8926                                  CONNECT_TIMING_HAS_SSL_TIMES);
8927 }
8928
8929 TEST_P(HttpNetworkTransactionTest,
8930        UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
8931   HttpStreamFactory::set_use_alternate_protocols(true);
8932   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
8933
8934   HttpRequestInfo request;
8935   request.method = "GET";
8936   request.url = GURL("http://www.google.com/");
8937   request.load_flags = 0;
8938
8939   std::string alternate_protocol_http_header =
8940       GetAlternateProtocolHttpHeader();
8941
8942   MockRead data_reads[] = {
8943     MockRead("HTTP/1.1 200 OK\r\n"),
8944     MockRead(alternate_protocol_http_header.c_str()),
8945     MockRead("hello world"),
8946     MockRead(ASYNC, OK),
8947   };
8948
8949   StaticSocketDataProvider first_transaction(
8950       data_reads, arraysize(data_reads), NULL, 0);
8951   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
8952
8953   SSLSocketDataProvider ssl(ASYNC, OK);
8954   ssl.SetNextProto(GetParam());
8955   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8956
8957   scoped_ptr<SpdyFrame> req(
8958       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8959   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
8960
8961   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8962   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
8963   MockRead spdy_reads[] = {
8964     CreateMockRead(*resp),
8965     CreateMockRead(*data),
8966     MockRead(ASYNC, 0, 0),
8967   };
8968
8969   DelayedSocketData spdy_data(
8970       1,  // wait for one write to finish before reading.
8971       spdy_reads, arraysize(spdy_reads),
8972       spdy_writes, arraysize(spdy_writes));
8973   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8974
8975   TestCompletionCallback callback;
8976
8977   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8978
8979   scoped_ptr<HttpTransaction> trans(
8980       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8981
8982   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8983   EXPECT_EQ(ERR_IO_PENDING, rv);
8984   EXPECT_EQ(OK, callback.WaitForResult());
8985
8986   const HttpResponseInfo* response = trans->GetResponseInfo();
8987   ASSERT_TRUE(response != NULL);
8988   ASSERT_TRUE(response->headers.get() != NULL);
8989   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8990
8991   std::string response_data;
8992   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8993   EXPECT_EQ("hello world", response_data);
8994
8995   // Set up an initial SpdySession in the pool to reuse.
8996   HostPortPair host_port_pair("www.google.com", 443);
8997   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
8998                      kPrivacyModeDisabled);
8999   base::WeakPtr<SpdySession> spdy_session =
9000       CreateSecureSpdySession(session, key, BoundNetLog());
9001
9002   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9003
9004   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9005   EXPECT_EQ(ERR_IO_PENDING, rv);
9006   EXPECT_EQ(OK, callback.WaitForResult());
9007
9008   response = trans->GetResponseInfo();
9009   ASSERT_TRUE(response != NULL);
9010   ASSERT_TRUE(response->headers.get() != NULL);
9011   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9012   EXPECT_TRUE(response->was_fetched_via_spdy);
9013   EXPECT_TRUE(response->was_npn_negotiated);
9014
9015   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9016   EXPECT_EQ("hello!", response_data);
9017 }
9018
9019 // GenerateAuthToken is a mighty big test.
9020 // It tests all permutation of GenerateAuthToken behavior:
9021 //   - Synchronous and Asynchronous completion.
9022 //   - OK or error on completion.
9023 //   - Direct connection, non-authenticating proxy, and authenticating proxy.
9024 //   - HTTP or HTTPS backend (to include proxy tunneling).
9025 //   - Non-authenticating and authenticating backend.
9026 //
9027 // In all, there are 44 reasonable permuations (for example, if there are
9028 // problems generating an auth token for an authenticating proxy, we don't
9029 // need to test all permutations of the backend server).
9030 //
9031 // The test proceeds by going over each of the configuration cases, and
9032 // potentially running up to three rounds in each of the tests. The TestConfig
9033 // specifies both the configuration for the test as well as the expectations
9034 // for the results.
9035 TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
9036   static const char kServer[] = "http://www.example.com";
9037   static const char kSecureServer[] = "https://www.example.com";
9038   static const char kProxy[] = "myproxy:70";
9039   const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9040
9041   enum AuthTiming {
9042     AUTH_NONE,
9043     AUTH_SYNC,
9044     AUTH_ASYNC,
9045   };
9046
9047   const MockWrite kGet(
9048       "GET / HTTP/1.1\r\n"
9049       "Host: www.example.com\r\n"
9050       "Connection: keep-alive\r\n\r\n");
9051   const MockWrite kGetProxy(
9052       "GET http://www.example.com/ HTTP/1.1\r\n"
9053       "Host: www.example.com\r\n"
9054       "Proxy-Connection: keep-alive\r\n\r\n");
9055   const MockWrite kGetAuth(
9056       "GET / HTTP/1.1\r\n"
9057       "Host: www.example.com\r\n"
9058       "Connection: keep-alive\r\n"
9059       "Authorization: auth_token\r\n\r\n");
9060   const MockWrite kGetProxyAuth(
9061       "GET http://www.example.com/ HTTP/1.1\r\n"
9062       "Host: www.example.com\r\n"
9063       "Proxy-Connection: keep-alive\r\n"
9064       "Proxy-Authorization: auth_token\r\n\r\n");
9065   const MockWrite kGetAuthThroughProxy(
9066       "GET http://www.example.com/ HTTP/1.1\r\n"
9067       "Host: www.example.com\r\n"
9068       "Proxy-Connection: keep-alive\r\n"
9069       "Authorization: auth_token\r\n\r\n");
9070   const MockWrite kGetAuthWithProxyAuth(
9071       "GET http://www.example.com/ HTTP/1.1\r\n"
9072       "Host: www.example.com\r\n"
9073       "Proxy-Connection: keep-alive\r\n"
9074       "Proxy-Authorization: auth_token\r\n"
9075       "Authorization: auth_token\r\n\r\n");
9076   const MockWrite kConnect(
9077       "CONNECT www.example.com:443 HTTP/1.1\r\n"
9078       "Host: www.example.com\r\n"
9079       "Proxy-Connection: keep-alive\r\n\r\n");
9080   const MockWrite kConnectProxyAuth(
9081       "CONNECT www.example.com:443 HTTP/1.1\r\n"
9082       "Host: www.example.com\r\n"
9083       "Proxy-Connection: keep-alive\r\n"
9084       "Proxy-Authorization: auth_token\r\n\r\n");
9085
9086   const MockRead kSuccess(
9087       "HTTP/1.1 200 OK\r\n"
9088       "Content-Type: text/html; charset=iso-8859-1\r\n"
9089       "Content-Length: 3\r\n\r\n"
9090       "Yes");
9091   const MockRead kFailure(
9092       "Should not be called.");
9093   const MockRead kServerChallenge(
9094       "HTTP/1.1 401 Unauthorized\r\n"
9095       "WWW-Authenticate: Mock realm=server\r\n"
9096       "Content-Type: text/html; charset=iso-8859-1\r\n"
9097       "Content-Length: 14\r\n\r\n"
9098       "Unauthorized\r\n");
9099   const MockRead kProxyChallenge(
9100       "HTTP/1.1 407 Unauthorized\r\n"
9101       "Proxy-Authenticate: Mock realm=proxy\r\n"
9102       "Proxy-Connection: close\r\n"
9103       "Content-Type: text/html; charset=iso-8859-1\r\n"
9104       "Content-Length: 14\r\n\r\n"
9105       "Unauthorized\r\n");
9106   const MockRead kProxyConnected(
9107       "HTTP/1.1 200 Connection Established\r\n\r\n");
9108
9109   // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9110   // no constructors, but the C++ compiler on Windows warns about
9111   // unspecified data in compound literals. So, moved to using constructors,
9112   // and TestRound's created with the default constructor should not be used.
9113   struct TestRound {
9114     TestRound()
9115         : expected_rv(ERR_UNEXPECTED),
9116           extra_write(NULL),
9117           extra_read(NULL) {
9118     }
9119     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9120               int expected_rv_arg)
9121         : write(write_arg),
9122           read(read_arg),
9123           expected_rv(expected_rv_arg),
9124           extra_write(NULL),
9125           extra_read(NULL) {
9126     }
9127     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9128               int expected_rv_arg, const MockWrite* extra_write_arg,
9129               const MockRead* extra_read_arg)
9130         : write(write_arg),
9131           read(read_arg),
9132           expected_rv(expected_rv_arg),
9133           extra_write(extra_write_arg),
9134           extra_read(extra_read_arg) {
9135     }
9136     MockWrite write;
9137     MockRead read;
9138     int expected_rv;
9139     const MockWrite* extra_write;
9140     const MockRead* extra_read;
9141   };
9142
9143   static const int kNoSSL = 500;
9144
9145   struct TestConfig {
9146     const char* proxy_url;
9147     AuthTiming proxy_auth_timing;
9148     int proxy_auth_rv;
9149     const char* server_url;
9150     AuthTiming server_auth_timing;
9151     int server_auth_rv;
9152     int num_auth_rounds;
9153     int first_ssl_round;
9154     TestRound rounds[3];
9155   } test_configs[] = {
9156     // Non-authenticating HTTP server with a direct connection.
9157     { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9158       { TestRound(kGet, kSuccess, OK)}},
9159     // Authenticating HTTP server with a direct connection.
9160     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9161       { TestRound(kGet, kServerChallenge, OK),
9162         TestRound(kGetAuth, kSuccess, OK)}},
9163     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9164       { TestRound(kGet, kServerChallenge, OK),
9165         TestRound(kGetAuth, kFailure, kAuthErr)}},
9166     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9167       { TestRound(kGet, kServerChallenge, OK),
9168         TestRound(kGetAuth, kSuccess, OK)}},
9169     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9170       { TestRound(kGet, kServerChallenge, OK),
9171         TestRound(kGetAuth, kFailure, kAuthErr)}},
9172     // Non-authenticating HTTP server through a non-authenticating proxy.
9173     { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9174       { TestRound(kGetProxy, kSuccess, OK)}},
9175     // Authenticating HTTP server through a non-authenticating proxy.
9176     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9177       { TestRound(kGetProxy, kServerChallenge, OK),
9178         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9179     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9180       { TestRound(kGetProxy, kServerChallenge, OK),
9181         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9182     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9183       { TestRound(kGetProxy, kServerChallenge, OK),
9184         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9185     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9186       { TestRound(kGetProxy, kServerChallenge, OK),
9187         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9188     // Non-authenticating HTTP server through an authenticating proxy.
9189     { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9190       { TestRound(kGetProxy, kProxyChallenge, OK),
9191         TestRound(kGetProxyAuth, kSuccess, OK)}},
9192     { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9193       { TestRound(kGetProxy, kProxyChallenge, OK),
9194         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9195     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9196       { TestRound(kGetProxy, kProxyChallenge, OK),
9197         TestRound(kGetProxyAuth, kSuccess, OK)}},
9198     { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9199       { TestRound(kGetProxy, kProxyChallenge, OK),
9200         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9201     // Authenticating HTTP server through an authenticating proxy.
9202     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9203       { TestRound(kGetProxy, kProxyChallenge, OK),
9204         TestRound(kGetProxyAuth, kServerChallenge, OK),
9205         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9206     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9207       { TestRound(kGetProxy, kProxyChallenge, OK),
9208         TestRound(kGetProxyAuth, kServerChallenge, OK),
9209         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9210     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9211       { TestRound(kGetProxy, kProxyChallenge, OK),
9212         TestRound(kGetProxyAuth, kServerChallenge, OK),
9213         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9214     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9215       { TestRound(kGetProxy, kProxyChallenge, OK),
9216         TestRound(kGetProxyAuth, kServerChallenge, OK),
9217         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9218     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9219       { TestRound(kGetProxy, kProxyChallenge, OK),
9220         TestRound(kGetProxyAuth, kServerChallenge, OK),
9221         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9222     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9223       { TestRound(kGetProxy, kProxyChallenge, OK),
9224         TestRound(kGetProxyAuth, kServerChallenge, OK),
9225         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9226     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9227       { TestRound(kGetProxy, kProxyChallenge, OK),
9228         TestRound(kGetProxyAuth, kServerChallenge, OK),
9229         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9230     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9231       { TestRound(kGetProxy, kProxyChallenge, OK),
9232         TestRound(kGetProxyAuth, kServerChallenge, OK),
9233         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9234     // Non-authenticating HTTPS server with a direct connection.
9235     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9236       { TestRound(kGet, kSuccess, OK)}},
9237     // Authenticating HTTPS server with a direct connection.
9238     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9239       { TestRound(kGet, kServerChallenge, OK),
9240         TestRound(kGetAuth, kSuccess, OK)}},
9241     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9242       { TestRound(kGet, kServerChallenge, OK),
9243         TestRound(kGetAuth, kFailure, kAuthErr)}},
9244     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9245       { TestRound(kGet, kServerChallenge, OK),
9246         TestRound(kGetAuth, kSuccess, OK)}},
9247     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9248       { TestRound(kGet, kServerChallenge, OK),
9249         TestRound(kGetAuth, kFailure, kAuthErr)}},
9250     // Non-authenticating HTTPS server with a non-authenticating proxy.
9251     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9252       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9253     // Authenticating HTTPS server through a non-authenticating proxy.
9254     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9255       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9256         TestRound(kGetAuth, kSuccess, OK)}},
9257     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9258       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9259         TestRound(kGetAuth, kFailure, kAuthErr)}},
9260     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9261       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9262         TestRound(kGetAuth, kSuccess, OK)}},
9263     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9264       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9265         TestRound(kGetAuth, kFailure, kAuthErr)}},
9266     // Non-Authenticating HTTPS server through an authenticating proxy.
9267     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9268       { TestRound(kConnect, kProxyChallenge, OK),
9269         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9270     { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9271       { TestRound(kConnect, kProxyChallenge, OK),
9272         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9273     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9274       { TestRound(kConnect, kProxyChallenge, OK),
9275         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9276     { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9277       { TestRound(kConnect, kProxyChallenge, OK),
9278         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9279     // Authenticating HTTPS server through an authenticating proxy.
9280     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9281       { TestRound(kConnect, kProxyChallenge, OK),
9282         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9283                   &kGet, &kServerChallenge),
9284         TestRound(kGetAuth, kSuccess, OK)}},
9285     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9286       { TestRound(kConnect, kProxyChallenge, OK),
9287         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9288                   &kGet, &kServerChallenge),
9289         TestRound(kGetAuth, kFailure, kAuthErr)}},
9290     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9291       { TestRound(kConnect, kProxyChallenge, OK),
9292         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9293                   &kGet, &kServerChallenge),
9294         TestRound(kGetAuth, kSuccess, OK)}},
9295     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9296       { TestRound(kConnect, kProxyChallenge, OK),
9297         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9298                   &kGet, &kServerChallenge),
9299         TestRound(kGetAuth, kFailure, kAuthErr)}},
9300     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9301       { TestRound(kConnect, kProxyChallenge, OK),
9302         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9303                   &kGet, &kServerChallenge),
9304         TestRound(kGetAuth, kSuccess, OK)}},
9305     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9306       { TestRound(kConnect, kProxyChallenge, OK),
9307         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9308                   &kGet, &kServerChallenge),
9309         TestRound(kGetAuth, kFailure, kAuthErr)}},
9310     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9311       { TestRound(kConnect, kProxyChallenge, OK),
9312         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9313                   &kGet, &kServerChallenge),
9314         TestRound(kGetAuth, kSuccess, OK)}},
9315     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9316       { TestRound(kConnect, kProxyChallenge, OK),
9317         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9318                   &kGet, &kServerChallenge),
9319         TestRound(kGetAuth, kFailure, kAuthErr)}},
9320   };
9321
9322   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
9323     HttpAuthHandlerMock::Factory* auth_factory(
9324         new HttpAuthHandlerMock::Factory());
9325     session_deps_.http_auth_handler_factory.reset(auth_factory);
9326     const TestConfig& test_config = test_configs[i];
9327
9328     // Set up authentication handlers as necessary.
9329     if (test_config.proxy_auth_timing != AUTH_NONE) {
9330       for (int n = 0; n < 2; n++) {
9331         HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9332         std::string auth_challenge = "Mock realm=proxy";
9333         GURL origin(test_config.proxy_url);
9334         HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9335                                                auth_challenge.end());
9336         auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9337                                         origin, BoundNetLog());
9338         auth_handler->SetGenerateExpectation(
9339             test_config.proxy_auth_timing == AUTH_ASYNC,
9340             test_config.proxy_auth_rv);
9341         auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9342       }
9343     }
9344     if (test_config.server_auth_timing != AUTH_NONE) {
9345       HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9346       std::string auth_challenge = "Mock realm=server";
9347       GURL origin(test_config.server_url);
9348       HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9349                                              auth_challenge.end());
9350       auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9351                                       origin, BoundNetLog());
9352       auth_handler->SetGenerateExpectation(
9353           test_config.server_auth_timing == AUTH_ASYNC,
9354           test_config.server_auth_rv);
9355       auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
9356     }
9357     if (test_config.proxy_url) {
9358       session_deps_.proxy_service.reset(
9359           ProxyService::CreateFixed(test_config.proxy_url));
9360     } else {
9361       session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9362     }
9363
9364     HttpRequestInfo request;
9365     request.method = "GET";
9366     request.url = GURL(test_config.server_url);
9367     request.load_flags = 0;
9368
9369     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9370     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
9371
9372     for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9373       const TestRound& read_write_round = test_config.rounds[round];
9374
9375       // Set up expected reads and writes.
9376       MockRead reads[2];
9377       reads[0] = read_write_round.read;
9378       size_t length_reads = 1;
9379       if (read_write_round.extra_read) {
9380         reads[1] = *read_write_round.extra_read;
9381         length_reads = 2;
9382       }
9383
9384       MockWrite writes[2];
9385       writes[0] = read_write_round.write;
9386       size_t length_writes = 1;
9387       if (read_write_round.extra_write) {
9388         writes[1] = *read_write_round.extra_write;
9389         length_writes = 2;
9390       }
9391       StaticSocketDataProvider data_provider(
9392           reads, length_reads, writes, length_writes);
9393       session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
9394
9395       // Add an SSL sequence if necessary.
9396       SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
9397       if (round >= test_config.first_ssl_round)
9398         session_deps_.socket_factory->AddSSLSocketDataProvider(
9399             &ssl_socket_data_provider);
9400
9401       // Start or restart the transaction.
9402       TestCompletionCallback callback;
9403       int rv;
9404       if (round == 0) {
9405         rv = trans.Start(&request, callback.callback(), BoundNetLog());
9406       } else {
9407         rv = trans.RestartWithAuth(
9408             AuthCredentials(kFoo, kBar), callback.callback());
9409       }
9410       if (rv == ERR_IO_PENDING)
9411         rv = callback.WaitForResult();
9412
9413       // Compare results with expected data.
9414       EXPECT_EQ(read_write_round.expected_rv, rv);
9415       const HttpResponseInfo* response = trans.GetResponseInfo();
9416       if (read_write_round.expected_rv == OK) {
9417         ASSERT_TRUE(response != NULL);
9418       } else {
9419         EXPECT_TRUE(response == NULL);
9420         EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9421         continue;
9422       }
9423       if (round + 1 < test_config.num_auth_rounds) {
9424         EXPECT_FALSE(response->auth_challenge.get() == NULL);
9425       } else {
9426         EXPECT_TRUE(response->auth_challenge.get() == NULL);
9427       }
9428     }
9429   }
9430 }
9431
9432 TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
9433   // Do multi-round authentication and make sure it works correctly.
9434   HttpAuthHandlerMock::Factory* auth_factory(
9435       new HttpAuthHandlerMock::Factory());
9436   session_deps_.http_auth_handler_factory.reset(auth_factory);
9437   session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9438   session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9439   session_deps_.host_resolver->set_synchronous_mode(true);
9440
9441   HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9442   auth_handler->set_connection_based(true);
9443   std::string auth_challenge = "Mock realm=server";
9444   GURL origin("http://www.example.com");
9445   HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9446                                          auth_challenge.end());
9447   auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9448                                   origin, BoundNetLog());
9449   auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
9450
9451   int rv = OK;
9452   const HttpResponseInfo* response = NULL;
9453   HttpRequestInfo request;
9454   request.method = "GET";
9455   request.url = origin;
9456   request.load_flags = 0;
9457
9458   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9459
9460   // Use a TCP Socket Pool with only one connection per group. This is used
9461   // to validate that the TCP socket is not released to the pool between
9462   // each round of multi-round authentication.
9463   HttpNetworkSessionPeer session_peer(session);
9464   ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9465   TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
9466       50,  // Max sockets for pool
9467       1,   // Max sockets per group
9468       &transport_pool_histograms,
9469       session_deps_.host_resolver.get(),
9470       session_deps_.socket_factory.get(),
9471       session_deps_.net_log);
9472   MockClientSocketPoolManager* mock_pool_manager =
9473       new MockClientSocketPoolManager;
9474   mock_pool_manager->SetTransportSocketPool(transport_pool);
9475   session_peer.SetClientSocketPoolManager(mock_pool_manager);
9476
9477   scoped_ptr<HttpTransaction> trans(
9478       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9479   TestCompletionCallback callback;
9480
9481   const MockWrite kGet(
9482       "GET / HTTP/1.1\r\n"
9483       "Host: www.example.com\r\n"
9484       "Connection: keep-alive\r\n\r\n");
9485   const MockWrite kGetAuth(
9486       "GET / HTTP/1.1\r\n"
9487       "Host: www.example.com\r\n"
9488       "Connection: keep-alive\r\n"
9489       "Authorization: auth_token\r\n\r\n");
9490
9491   const MockRead kServerChallenge(
9492       "HTTP/1.1 401 Unauthorized\r\n"
9493       "WWW-Authenticate: Mock realm=server\r\n"
9494       "Content-Type: text/html; charset=iso-8859-1\r\n"
9495       "Content-Length: 14\r\n\r\n"
9496       "Unauthorized\r\n");
9497   const MockRead kSuccess(
9498       "HTTP/1.1 200 OK\r\n"
9499       "Content-Type: text/html; charset=iso-8859-1\r\n"
9500       "Content-Length: 3\r\n\r\n"
9501       "Yes");
9502
9503   MockWrite writes[] = {
9504     // First round
9505     kGet,
9506     // Second round
9507     kGetAuth,
9508     // Third round
9509     kGetAuth,
9510     // Fourth round
9511     kGetAuth,
9512     // Competing request
9513     kGet,
9514   };
9515   MockRead reads[] = {
9516     // First round
9517     kServerChallenge,
9518     // Second round
9519     kServerChallenge,
9520     // Third round
9521     kServerChallenge,
9522     // Fourth round
9523     kSuccess,
9524     // Competing response
9525     kSuccess,
9526   };
9527   StaticSocketDataProvider data_provider(reads, arraysize(reads),
9528                                          writes, arraysize(writes));
9529   session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
9530
9531   const char* const kSocketGroup = "www.example.com:80";
9532
9533   // First round of authentication.
9534   auth_handler->SetGenerateExpectation(false, OK);
9535   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9536   if (rv == ERR_IO_PENDING)
9537     rv = callback.WaitForResult();
9538   EXPECT_EQ(OK, rv);
9539   response = trans->GetResponseInfo();
9540   ASSERT_TRUE(response != NULL);
9541   EXPECT_FALSE(response->auth_challenge.get() == NULL);
9542   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9543
9544   // In between rounds, another request comes in for the same domain.
9545   // It should not be able to grab the TCP socket that trans has already
9546   // claimed.
9547   scoped_ptr<HttpTransaction> trans_compete(
9548       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9549   TestCompletionCallback callback_compete;
9550   rv = trans_compete->Start(
9551       &request, callback_compete.callback(), BoundNetLog());
9552   EXPECT_EQ(ERR_IO_PENDING, rv);
9553   // callback_compete.WaitForResult at this point would stall forever,
9554   // since the HttpNetworkTransaction does not release the request back to
9555   // the pool until after authentication completes.
9556
9557   // Second round of authentication.
9558   auth_handler->SetGenerateExpectation(false, OK);
9559   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
9560   if (rv == ERR_IO_PENDING)
9561     rv = callback.WaitForResult();
9562   EXPECT_EQ(OK, rv);
9563   response = trans->GetResponseInfo();
9564   ASSERT_TRUE(response != NULL);
9565   EXPECT_TRUE(response->auth_challenge.get() == NULL);
9566   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9567
9568   // Third round of authentication.
9569   auth_handler->SetGenerateExpectation(false, OK);
9570   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
9571   if (rv == ERR_IO_PENDING)
9572     rv = callback.WaitForResult();
9573   EXPECT_EQ(OK, rv);
9574   response = trans->GetResponseInfo();
9575   ASSERT_TRUE(response != NULL);
9576   EXPECT_TRUE(response->auth_challenge.get() == NULL);
9577   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9578
9579   // Fourth round of authentication, which completes successfully.
9580   auth_handler->SetGenerateExpectation(false, OK);
9581   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
9582   if (rv == ERR_IO_PENDING)
9583     rv = callback.WaitForResult();
9584   EXPECT_EQ(OK, rv);
9585   response = trans->GetResponseInfo();
9586   ASSERT_TRUE(response != NULL);
9587   EXPECT_TRUE(response->auth_challenge.get() == NULL);
9588   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9589
9590   // Read the body since the fourth round was successful. This will also
9591   // release the socket back to the pool.
9592   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
9593   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
9594   if (rv == ERR_IO_PENDING)
9595     rv = callback.WaitForResult();
9596   EXPECT_EQ(3, rv);
9597   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
9598   EXPECT_EQ(0, rv);
9599   // There are still 0 idle sockets, since the trans_compete transaction
9600   // will be handed it immediately after trans releases it to the group.
9601   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9602
9603   // The competing request can now finish. Wait for the headers and then
9604   // read the body.
9605   rv = callback_compete.WaitForResult();
9606   EXPECT_EQ(OK, rv);
9607   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
9608   if (rv == ERR_IO_PENDING)
9609     rv = callback.WaitForResult();
9610   EXPECT_EQ(3, rv);
9611   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
9612   EXPECT_EQ(0, rv);
9613
9614   // Finally, the socket is released to the group.
9615   EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9616 }
9617
9618 // This tests the case that a request is issued via http instead of spdy after
9619 // npn is negotiated.
9620 TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
9621   HttpStreamFactory::set_use_alternate_protocols(true);
9622   std::vector<NextProto> next_protos;
9623   next_protos.push_back(kProtoHTTP11);
9624   HttpStreamFactory::SetNextProtos(next_protos);
9625   HttpRequestInfo request;
9626   request.method = "GET";
9627   request.url = GURL("https://www.google.com/");
9628   request.load_flags = 0;
9629
9630   MockWrite data_writes[] = {
9631     MockWrite("GET / HTTP/1.1\r\n"
9632               "Host: www.google.com\r\n"
9633               "Connection: keep-alive\r\n\r\n"),
9634   };
9635
9636   std::string alternate_protocol_http_header =
9637       GetAlternateProtocolHttpHeader();
9638
9639   MockRead data_reads[] = {
9640     MockRead("HTTP/1.1 200 OK\r\n"),
9641     MockRead(alternate_protocol_http_header.c_str()),
9642     MockRead("hello world"),
9643     MockRead(SYNCHRONOUS, OK),
9644   };
9645
9646   SSLSocketDataProvider ssl(ASYNC, OK);
9647   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9648   ssl.next_proto = "http/1.1";
9649   ssl.protocol_negotiated = kProtoHTTP11;
9650
9651   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9652
9653   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9654                                 data_writes, arraysize(data_writes));
9655   session_deps_.socket_factory->AddSocketDataProvider(&data);
9656
9657   TestCompletionCallback callback;
9658
9659   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9660   scoped_ptr<HttpTransaction> trans(
9661       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9662
9663   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9664
9665   EXPECT_EQ(ERR_IO_PENDING, rv);
9666   EXPECT_EQ(OK, callback.WaitForResult());
9667
9668   const HttpResponseInfo* response = trans->GetResponseInfo();
9669   ASSERT_TRUE(response != NULL);
9670   ASSERT_TRUE(response->headers.get() != NULL);
9671   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9672
9673   std::string response_data;
9674   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9675   EXPECT_EQ("hello world", response_data);
9676
9677   EXPECT_FALSE(response->was_fetched_via_spdy);
9678   EXPECT_TRUE(response->was_npn_negotiated);
9679 }
9680
9681 TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
9682   // Simulate the SSL handshake completing with an NPN negotiation
9683   // followed by an immediate server closing of the socket.
9684   // Fix crash:  http://crbug.com/46369
9685   HttpStreamFactory::set_use_alternate_protocols(true);
9686   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
9687
9688   HttpRequestInfo request;
9689   request.method = "GET";
9690   request.url = GURL("https://www.google.com/");
9691   request.load_flags = 0;
9692
9693   SSLSocketDataProvider ssl(ASYNC, OK);
9694   ssl.SetNextProto(GetParam());
9695   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9696
9697   scoped_ptr<SpdyFrame> req(
9698       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9699   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
9700
9701   MockRead spdy_reads[] = {
9702     MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
9703   };
9704
9705   DelayedSocketData spdy_data(
9706       0,  // don't wait in this case, immediate hangup.
9707       spdy_reads, arraysize(spdy_reads),
9708       spdy_writes, arraysize(spdy_writes));
9709   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9710
9711   TestCompletionCallback callback;
9712
9713   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9714   scoped_ptr<HttpTransaction> trans(
9715       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9716
9717   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9718   EXPECT_EQ(ERR_IO_PENDING, rv);
9719   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
9720 }
9721
9722 // A subclass of HttpAuthHandlerMock that records the request URL when
9723 // it gets it. This is needed since the auth handler may get destroyed
9724 // before we get a chance to query it.
9725 class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
9726  public:
9727   explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
9728
9729   virtual ~UrlRecordingHttpAuthHandlerMock() {}
9730
9731  protected:
9732   virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
9733                                     const HttpRequestInfo* request,
9734                                     const CompletionCallback& callback,
9735                                     std::string* auth_token) OVERRIDE {
9736     *url_ = request->url;
9737     return HttpAuthHandlerMock::GenerateAuthTokenImpl(
9738         credentials, request, callback, auth_token);
9739   }
9740
9741  private:
9742   GURL* url_;
9743 };
9744
9745 TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
9746   // This test ensures that the URL passed into the proxy is upgraded
9747   // to https when doing an Alternate Protocol upgrade.
9748   HttpStreamFactory::set_use_alternate_protocols(true);
9749   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
9750
9751   session_deps_.proxy_service.reset(
9752       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
9753   CapturingNetLog net_log;
9754   session_deps_.net_log = &net_log;
9755   GURL request_url;
9756   {
9757     HttpAuthHandlerMock::Factory* auth_factory =
9758         new HttpAuthHandlerMock::Factory();
9759     UrlRecordingHttpAuthHandlerMock* auth_handler =
9760         new UrlRecordingHttpAuthHandlerMock(&request_url);
9761     auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9762     auth_factory->set_do_init_from_challenge(true);
9763     session_deps_.http_auth_handler_factory.reset(auth_factory);
9764   }
9765
9766   HttpRequestInfo request;
9767   request.method = "GET";
9768   request.url = GURL("http://www.google.com");
9769   request.load_flags = 0;
9770
9771   // First round goes unauthenticated through the proxy.
9772   MockWrite data_writes_1[] = {
9773     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9774               "Host: www.google.com\r\n"
9775               "Proxy-Connection: keep-alive\r\n"
9776               "\r\n"),
9777   };
9778   MockRead data_reads_1[] = {
9779     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9780     MockRead("HTTP/1.1 200 OK\r\n"
9781              "Alternate-Protocol: 443:npn-spdy/2\r\n"
9782              "Proxy-Connection: close\r\n"
9783              "\r\n"),
9784   };
9785   StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
9786                                   data_writes_1, arraysize(data_writes_1));
9787
9788   // Second round tries to tunnel to www.google.com due to the
9789   // Alternate-Protocol announcement in the first round. It fails due
9790   // to a proxy authentication challenge.
9791   // After the failure, a tunnel is established to www.google.com using
9792   // Proxy-Authorization headers. There is then a SPDY request round.
9793   //
9794   // NOTE: Despite the "Proxy-Connection: Close", these are done on the
9795   // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
9796   // does a Disconnect and Connect on the same socket, rather than trying
9797   // to obtain a new one.
9798   //
9799   // NOTE: Originally, the proxy response to the second CONNECT request
9800   // simply returned another 407 so the unit test could skip the SSL connection
9801   // establishment and SPDY framing issues. Alas, the
9802   // retry-http-when-alternate-protocol fails logic kicks in, which was more
9803   // complicated to set up expectations for than the SPDY session.
9804
9805   scoped_ptr<SpdyFrame> req(
9806       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9807   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9808   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
9809
9810   MockWrite data_writes_2[] = {
9811     // First connection attempt without Proxy-Authorization.
9812     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9813               "Host: www.google.com\r\n"
9814               "Proxy-Connection: keep-alive\r\n"
9815               "\r\n"),
9816
9817     // Second connection attempt with Proxy-Authorization.
9818     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9819               "Host: www.google.com\r\n"
9820               "Proxy-Connection: keep-alive\r\n"
9821               "Proxy-Authorization: auth_token\r\n"
9822               "\r\n"),
9823
9824     // SPDY request
9825     CreateMockWrite(*req),
9826   };
9827   const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
9828                                          "Proxy-Authenticate: Mock\r\n"
9829                                          "Proxy-Connection: close\r\n"
9830                                          "\r\n");
9831   const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9832   MockRead data_reads_2[] = {
9833     // First connection attempt fails
9834     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
9835     MockRead(ASYNC, kRejectConnectResponse,
9836              arraysize(kRejectConnectResponse) - 1, 1),
9837
9838     // Second connection attempt passes
9839     MockRead(ASYNC, kAcceptConnectResponse,
9840              arraysize(kAcceptConnectResponse) -1, 4),
9841
9842     // SPDY response
9843     CreateMockRead(*resp.get(), 6),
9844     CreateMockRead(*data.get(), 6),
9845     MockRead(ASYNC, 0, 0, 6),
9846   };
9847   OrderedSocketData data_2(
9848       data_reads_2, arraysize(data_reads_2),
9849       data_writes_2, arraysize(data_writes_2));
9850
9851   SSLSocketDataProvider ssl(ASYNC, OK);
9852   ssl.SetNextProto(GetParam());
9853
9854   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
9855   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9856       NULL, 0, NULL, 0);
9857   hanging_non_alternate_protocol_socket.set_connect_data(
9858       never_finishing_connect);
9859
9860   session_deps_.socket_factory->AddSocketDataProvider(&data_1);
9861   session_deps_.socket_factory->AddSocketDataProvider(&data_2);
9862   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9863   session_deps_.socket_factory->AddSocketDataProvider(
9864       &hanging_non_alternate_protocol_socket);
9865   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9866
9867   // First round should work and provide the Alternate-Protocol state.
9868   TestCompletionCallback callback_1;
9869   scoped_ptr<HttpTransaction> trans_1(
9870       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9871   int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
9872   EXPECT_EQ(ERR_IO_PENDING, rv);
9873   EXPECT_EQ(OK, callback_1.WaitForResult());
9874
9875   // Second round should attempt a tunnel connect and get an auth challenge.
9876   TestCompletionCallback callback_2;
9877   scoped_ptr<HttpTransaction> trans_2(
9878       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9879   rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
9880   EXPECT_EQ(ERR_IO_PENDING, rv);
9881   EXPECT_EQ(OK, callback_2.WaitForResult());
9882   const HttpResponseInfo* response = trans_2->GetResponseInfo();
9883   ASSERT_TRUE(response != NULL);
9884   ASSERT_FALSE(response->auth_challenge.get() == NULL);
9885
9886   // Restart with auth. Tunnel should work and response received.
9887   TestCompletionCallback callback_3;
9888   rv = trans_2->RestartWithAuth(
9889       AuthCredentials(kFoo, kBar), callback_3.callback());
9890   EXPECT_EQ(ERR_IO_PENDING, rv);
9891   EXPECT_EQ(OK, callback_3.WaitForResult());
9892
9893   // After all that work, these two lines (or actually, just the scheme) are
9894   // what this test is all about. Make sure it happens correctly.
9895   EXPECT_EQ("https", request_url.scheme());
9896   EXPECT_EQ("www.google.com", request_url.host());
9897
9898   LoadTimingInfo load_timing_info;
9899   EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
9900   TestLoadTimingNotReusedWithPac(load_timing_info,
9901                                  CONNECT_TIMING_HAS_SSL_TIMES);
9902 }
9903
9904 // Test that if we cancel the transaction as the connection is completing, that
9905 // everything tears down correctly.
9906 TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
9907   // Setup everything about the connection to complete synchronously, so that
9908   // after calling HttpNetworkTransaction::Start, the only thing we're waiting
9909   // for is the callback from the HttpStreamRequest.
9910   // Then cancel the transaction.
9911   // Verify that we don't crash.
9912   MockConnect mock_connect(SYNCHRONOUS, OK);
9913   MockRead data_reads[] = {
9914     MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
9915     MockRead(SYNCHRONOUS, "hello world"),
9916     MockRead(SYNCHRONOUS, OK),
9917   };
9918
9919   HttpRequestInfo request;
9920   request.method = "GET";
9921   request.url = GURL("http://www.google.com/");
9922   request.load_flags = 0;
9923
9924   session_deps_.host_resolver->set_synchronous_mode(true);
9925   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9926   scoped_ptr<HttpTransaction> trans(
9927       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
9928
9929   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9930   data.set_connect_data(mock_connect);
9931   session_deps_.socket_factory->AddSocketDataProvider(&data);
9932
9933   TestCompletionCallback callback;
9934
9935   CapturingBoundNetLog log;
9936   int rv = trans->Start(&request, callback.callback(), log.bound());
9937   EXPECT_EQ(ERR_IO_PENDING, rv);
9938   trans.reset();  // Cancel the transaction here.
9939
9940   base::MessageLoop::current()->RunUntilIdle();
9941 }
9942
9943 // Test a basic GET request through a proxy.
9944 TEST_P(HttpNetworkTransactionTest, ProxyGet) {
9945   session_deps_.proxy_service.reset(
9946       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
9947   CapturingBoundNetLog log;
9948   session_deps_.net_log = log.bound().net_log();
9949   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9950
9951   HttpRequestInfo request;
9952   request.method = "GET";
9953   request.url = GURL("http://www.google.com/");
9954
9955   MockWrite data_writes1[] = {
9956     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9957               "Host: www.google.com\r\n"
9958               "Proxy-Connection: keep-alive\r\n\r\n"),
9959   };
9960
9961   MockRead data_reads1[] = {
9962     MockRead("HTTP/1.1 200 OK\r\n"),
9963     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9964     MockRead("Content-Length: 100\r\n\r\n"),
9965     MockRead(SYNCHRONOUS, OK),
9966   };
9967
9968   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9969                                  data_writes1, arraysize(data_writes1));
9970   session_deps_.socket_factory->AddSocketDataProvider(&data1);
9971
9972   TestCompletionCallback callback1;
9973
9974   scoped_ptr<HttpTransaction> trans(
9975       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9976
9977   int rv = trans->Start(&request, callback1.callback(), log.bound());
9978   EXPECT_EQ(ERR_IO_PENDING, rv);
9979
9980   rv = callback1.WaitForResult();
9981   EXPECT_EQ(OK, rv);
9982
9983   const HttpResponseInfo* response = trans->GetResponseInfo();
9984   ASSERT_TRUE(response != NULL);
9985
9986   EXPECT_TRUE(response->headers->IsKeepAlive());
9987   EXPECT_EQ(200, response->headers->response_code());
9988   EXPECT_EQ(100, response->headers->GetContentLength());
9989   EXPECT_TRUE(response->was_fetched_via_proxy);
9990   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9991
9992   LoadTimingInfo load_timing_info;
9993   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9994   TestLoadTimingNotReusedWithPac(load_timing_info,
9995                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9996 }
9997
9998 // Test a basic HTTPS GET request through a proxy.
9999 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
10000   session_deps_.proxy_service.reset(
10001       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10002   CapturingBoundNetLog log;
10003   session_deps_.net_log = log.bound().net_log();
10004   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10005
10006   HttpRequestInfo request;
10007   request.method = "GET";
10008   request.url = GURL("https://www.google.com/");
10009
10010   // Since we have proxy, should try to establish tunnel.
10011   MockWrite data_writes1[] = {
10012     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10013               "Host: www.google.com\r\n"
10014               "Proxy-Connection: keep-alive\r\n\r\n"),
10015
10016     MockWrite("GET / HTTP/1.1\r\n"
10017               "Host: www.google.com\r\n"
10018               "Connection: keep-alive\r\n\r\n"),
10019   };
10020
10021   MockRead data_reads1[] = {
10022     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10023
10024     MockRead("HTTP/1.1 200 OK\r\n"),
10025     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10026     MockRead("Content-Length: 100\r\n\r\n"),
10027     MockRead(SYNCHRONOUS, OK),
10028   };
10029
10030   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10031                                  data_writes1, arraysize(data_writes1));
10032   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10033   SSLSocketDataProvider ssl(ASYNC, OK);
10034   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10035
10036   TestCompletionCallback callback1;
10037
10038   scoped_ptr<HttpTransaction> trans(
10039       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10040
10041   int rv = trans->Start(&request, callback1.callback(), log.bound());
10042   EXPECT_EQ(ERR_IO_PENDING, rv);
10043
10044   rv = callback1.WaitForResult();
10045   EXPECT_EQ(OK, rv);
10046   net::CapturingNetLog::CapturedEntryList entries;
10047   log.GetEntries(&entries);
10048   size_t pos = ExpectLogContainsSomewhere(
10049       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10050       NetLog::PHASE_NONE);
10051   ExpectLogContainsSomewhere(
10052       entries, pos,
10053       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10054       NetLog::PHASE_NONE);
10055
10056   const HttpResponseInfo* response = trans->GetResponseInfo();
10057   ASSERT_TRUE(response != NULL);
10058
10059   EXPECT_TRUE(response->headers->IsKeepAlive());
10060   EXPECT_EQ(200, response->headers->response_code());
10061   EXPECT_EQ(100, response->headers->GetContentLength());
10062   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10063   EXPECT_TRUE(response->was_fetched_via_proxy);
10064
10065   LoadTimingInfo load_timing_info;
10066   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10067   TestLoadTimingNotReusedWithPac(load_timing_info,
10068                                  CONNECT_TIMING_HAS_SSL_TIMES);
10069 }
10070
10071 // Test a basic HTTPS GET request through a proxy, but the server hangs up
10072 // while establishing the tunnel.
10073 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
10074   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
10075   CapturingBoundNetLog log;
10076   session_deps_.net_log = log.bound().net_log();
10077   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10078
10079   HttpRequestInfo request;
10080   request.method = "GET";
10081   request.url = GURL("https://www.google.com/");
10082
10083   // Since we have proxy, should try to establish tunnel.
10084   MockWrite data_writes1[] = {
10085     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10086               "Host: www.google.com\r\n"
10087               "Proxy-Connection: keep-alive\r\n\r\n"),
10088
10089     MockWrite("GET / HTTP/1.1\r\n"
10090               "Host: www.google.com\r\n"
10091               "Connection: keep-alive\r\n\r\n"),
10092   };
10093
10094   MockRead data_reads1[] = {
10095     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10096     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10097     MockRead(ASYNC, 0, 0),  // EOF
10098   };
10099
10100   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10101                                  data_writes1, arraysize(data_writes1));
10102   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10103   SSLSocketDataProvider ssl(ASYNC, OK);
10104   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10105
10106   TestCompletionCallback callback1;
10107
10108   scoped_ptr<HttpTransaction> trans(
10109       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10110
10111   int rv = trans->Start(&request, callback1.callback(), log.bound());
10112   EXPECT_EQ(ERR_IO_PENDING, rv);
10113
10114   rv = callback1.WaitForResult();
10115   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
10116   net::CapturingNetLog::CapturedEntryList entries;
10117   log.GetEntries(&entries);
10118   size_t pos = ExpectLogContainsSomewhere(
10119       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10120       NetLog::PHASE_NONE);
10121   ExpectLogContainsSomewhere(
10122       entries, pos,
10123       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10124       NetLog::PHASE_NONE);
10125 }
10126
10127 // Test for crbug.com/55424.
10128 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
10129   scoped_ptr<SpdyFrame> req(
10130       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10131   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10132
10133   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10134   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
10135   MockRead spdy_reads[] = {
10136     CreateMockRead(*resp),
10137     CreateMockRead(*data),
10138     MockRead(ASYNC, 0, 0),
10139   };
10140
10141   DelayedSocketData spdy_data(
10142       1,  // wait for one write to finish before reading.
10143       spdy_reads, arraysize(spdy_reads),
10144       spdy_writes, arraysize(spdy_writes));
10145   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10146
10147   SSLSocketDataProvider ssl(ASYNC, OK);
10148   ssl.SetNextProto(GetParam());
10149   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10150
10151   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10152
10153   // Set up an initial SpdySession in the pool to reuse.
10154   HostPortPair host_port_pair("www.google.com", 443);
10155   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10156                      kPrivacyModeDisabled);
10157   base::WeakPtr<SpdySession> spdy_session =
10158       CreateInsecureSpdySession(session, key, BoundNetLog());
10159
10160   HttpRequestInfo request;
10161   request.method = "GET";
10162   request.url = GURL("https://www.google.com/");
10163   request.load_flags = 0;
10164
10165   // This is the important line that marks this as a preconnect.
10166   request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10167
10168   scoped_ptr<HttpTransaction> trans(
10169       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10170
10171   TestCompletionCallback callback;
10172   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10173   EXPECT_EQ(ERR_IO_PENDING, rv);
10174   EXPECT_EQ(OK, callback.WaitForResult());
10175 }
10176
10177 // Given a net error, cause that error to be returned from the first Write()
10178 // call and verify that the HttpTransaction fails with that error.
10179 void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
10180     int error, IoMode mode) {
10181   net::HttpRequestInfo request_info;
10182   request_info.url = GURL("https://www.example.com/");
10183   request_info.method = "GET";
10184   request_info.load_flags = net::LOAD_NORMAL;
10185
10186   SSLSocketDataProvider ssl_data(mode, OK);
10187   net::MockWrite data_writes[] = {
10188     net::MockWrite(mode, error),
10189   };
10190   net::StaticSocketDataProvider data(NULL, 0,
10191                                      data_writes, arraysize(data_writes));
10192   session_deps_.socket_factory->AddSocketDataProvider(&data);
10193   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
10194
10195   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10196   scoped_ptr<HttpTransaction> trans(
10197       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10198
10199   TestCompletionCallback callback;
10200   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
10201   if (rv == net::ERR_IO_PENDING)
10202     rv = callback.WaitForResult();
10203   ASSERT_EQ(error, rv);
10204 }
10205
10206 TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
10207   // Just check a grab bag of cert errors.
10208   static const int kErrors[] = {
10209     ERR_CERT_COMMON_NAME_INVALID,
10210     ERR_CERT_AUTHORITY_INVALID,
10211     ERR_CERT_DATE_INVALID,
10212   };
10213   for (size_t i = 0; i < arraysize(kErrors); i++) {
10214     CheckErrorIsPassedBack(kErrors[i], ASYNC);
10215     CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
10216   }
10217 }
10218
10219 // Ensure that a client certificate is removed from the SSL client auth
10220 // cache when:
10221 //  1) No proxy is involved.
10222 //  2) TLS False Start is disabled.
10223 //  3) The initial TLS handshake requests a client certificate.
10224 //  4) The client supplies an invalid/unacceptable certificate.
10225 TEST_P(HttpNetworkTransactionTest,
10226        ClientAuthCertCache_Direct_NoFalseStart) {
10227   net::HttpRequestInfo request_info;
10228   request_info.url = GURL("https://www.example.com/");
10229   request_info.method = "GET";
10230   request_info.load_flags = net::LOAD_NORMAL;
10231
10232   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10233   cert_request->host_and_port = "www.example.com:443";
10234
10235   // [ssl_]data1 contains the data for the first SSL handshake. When a
10236   // CertificateRequest is received for the first time, the handshake will
10237   // be aborted to allow the caller to provide a certificate.
10238   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
10239   ssl_data1.cert_request_info = cert_request.get();
10240   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
10241   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10242   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10243
10244   // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10245   // False Start is not being used, the result of the SSL handshake will be
10246   // returned as part of the SSLClientSocket::Connect() call. This test
10247   // matches the result of a server sending a handshake_failure alert,
10248   // rather than a Finished message, because it requires a client
10249   // certificate and none was supplied.
10250   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10251   ssl_data2.cert_request_info = cert_request.get();
10252   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
10253   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10254   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10255
10256   // [ssl_]data3 contains the data for the third SSL handshake. When a
10257   // connection to a server fails during an SSL handshake,
10258   // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10259   // connection was attempted with TLSv1.1. This is transparent to the caller
10260   // of the HttpNetworkTransaction. Because this test failure is due to
10261   // requiring a client certificate, this fallback handshake should also
10262   // fail.
10263   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10264   ssl_data3.cert_request_info = cert_request.get();
10265   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
10266   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10267   session_deps_.socket_factory->AddSocketDataProvider(&data3);
10268
10269   // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10270   // connection to a server fails during an SSL handshake,
10271   // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10272   // connection was attempted with TLSv1. This is transparent to the caller
10273   // of the HttpNetworkTransaction. Because this test failure is due to
10274   // requiring a client certificate, this fallback handshake should also
10275   // fail.
10276   SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10277   ssl_data4.cert_request_info = cert_request.get();
10278   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
10279   net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
10280   session_deps_.socket_factory->AddSocketDataProvider(&data4);
10281
10282   // Need one more if TLSv1.2 is enabled.
10283   SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10284   ssl_data5.cert_request_info = cert_request.get();
10285   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10286   net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10287   session_deps_.socket_factory->AddSocketDataProvider(&data5);
10288
10289   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10290   scoped_ptr<HttpTransaction> trans(
10291       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10292
10293   // Begin the SSL handshake with the peer. This consumes ssl_data1.
10294   TestCompletionCallback callback;
10295   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
10296   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10297
10298   // Complete the SSL handshake, which should abort due to requiring a
10299   // client certificate.
10300   rv = callback.WaitForResult();
10301   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10302
10303   // Indicate that no certificate should be supplied. From the perspective
10304   // of SSLClientCertCache, NULL is just as meaningful as a real
10305   // certificate, so this is the same as supply a
10306   // legitimate-but-unacceptable certificate.
10307   rv = trans->RestartWithCertificate(NULL, callback.callback());
10308   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10309
10310   // Ensure the certificate was added to the client auth cache before
10311   // allowing the connection to continue restarting.
10312   scoped_refptr<X509Certificate> client_cert;
10313   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10314                                                        &client_cert));
10315   ASSERT_EQ(NULL, client_cert.get());
10316
10317   // Restart the handshake. This will consume ssl_data2, which fails, and
10318   // then consume ssl_data3 and ssl_data4, both of which should also fail.
10319   // The result code is checked against what ssl_data4 should return.
10320   rv = callback.WaitForResult();
10321   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10322
10323   // Ensure that the client certificate is removed from the cache on a
10324   // handshake failure.
10325   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10326                                                         &client_cert));
10327 }
10328
10329 // Ensure that a client certificate is removed from the SSL client auth
10330 // cache when:
10331 //  1) No proxy is involved.
10332 //  2) TLS False Start is enabled.
10333 //  3) The initial TLS handshake requests a client certificate.
10334 //  4) The client supplies an invalid/unacceptable certificate.
10335 TEST_P(HttpNetworkTransactionTest,
10336        ClientAuthCertCache_Direct_FalseStart) {
10337   net::HttpRequestInfo request_info;
10338   request_info.url = GURL("https://www.example.com/");
10339   request_info.method = "GET";
10340   request_info.load_flags = net::LOAD_NORMAL;
10341
10342   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10343   cert_request->host_and_port = "www.example.com:443";
10344
10345   // When TLS False Start is used, SSLClientSocket::Connect() calls will
10346   // return successfully after reading up to the peer's Certificate message.
10347   // This is to allow the caller to call SSLClientSocket::Write(), which can
10348   // enqueue application data to be sent in the same packet as the
10349   // ChangeCipherSpec and Finished messages.
10350   // The actual handshake will be finished when SSLClientSocket::Read() is
10351   // called, which expects to process the peer's ChangeCipherSpec and
10352   // Finished messages. If there was an error negotiating with the peer,
10353   // such as due to the peer requiring a client certificate when none was
10354   // supplied, the alert sent by the peer won't be processed until Read() is
10355   // called.
10356
10357   // Like the non-False Start case, when a client certificate is requested by
10358   // the peer, the handshake is aborted during the Connect() call.
10359   // [ssl_]data1 represents the initial SSL handshake with the peer.
10360   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
10361   ssl_data1.cert_request_info = cert_request.get();
10362   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
10363   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10364   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10365
10366   // When a client certificate is supplied, Connect() will not be aborted
10367   // when the peer requests the certificate. Instead, the handshake will
10368   // artificially succeed, allowing the caller to write the HTTP request to
10369   // the socket. The handshake messages are not processed until Read() is
10370   // called, which then detects that the handshake was aborted, due to the
10371   // peer sending a handshake_failure because it requires a client
10372   // certificate.
10373   SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
10374   ssl_data2.cert_request_info = cert_request.get();
10375   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
10376   net::MockRead data2_reads[] = {
10377     net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
10378   };
10379   net::StaticSocketDataProvider data2(
10380       data2_reads, arraysize(data2_reads), NULL, 0);
10381   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10382
10383   // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
10384   // the data for the SSL handshake once the TLSv1.1 connection falls back to
10385   // TLSv1. It has the same behaviour as [ssl_]data2.
10386   SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
10387   ssl_data3.cert_request_info = cert_request.get();
10388   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
10389   net::StaticSocketDataProvider data3(
10390       data2_reads, arraysize(data2_reads), NULL, 0);
10391   session_deps_.socket_factory->AddSocketDataProvider(&data3);
10392
10393   // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10394   // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10395   SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10396   ssl_data4.cert_request_info = cert_request.get();
10397   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
10398   net::StaticSocketDataProvider data4(
10399       data2_reads, arraysize(data2_reads), NULL, 0);
10400   session_deps_.socket_factory->AddSocketDataProvider(&data4);
10401
10402   // Need one more if TLSv1.2 is enabled.
10403   SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10404   ssl_data5.cert_request_info = cert_request.get();
10405   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10406   net::StaticSocketDataProvider data5(
10407       data2_reads, arraysize(data2_reads), NULL, 0);
10408   session_deps_.socket_factory->AddSocketDataProvider(&data5);
10409
10410   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10411   scoped_ptr<HttpTransaction> trans(
10412       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10413
10414   // Begin the initial SSL handshake.
10415   TestCompletionCallback callback;
10416   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
10417   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10418
10419   // Complete the SSL handshake, which should abort due to requiring a
10420   // client certificate.
10421   rv = callback.WaitForResult();
10422   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10423
10424   // Indicate that no certificate should be supplied. From the perspective
10425   // of SSLClientCertCache, NULL is just as meaningful as a real
10426   // certificate, so this is the same as supply a
10427   // legitimate-but-unacceptable certificate.
10428   rv = trans->RestartWithCertificate(NULL, callback.callback());
10429   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10430
10431   // Ensure the certificate was added to the client auth cache before
10432   // allowing the connection to continue restarting.
10433   scoped_refptr<X509Certificate> client_cert;
10434   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10435                                                        &client_cert));
10436   ASSERT_EQ(NULL, client_cert.get());
10437
10438   // Restart the handshake. This will consume ssl_data2, which fails, and
10439   // then consume ssl_data3 and ssl_data4, both of which should also fail.
10440   // The result code is checked against what ssl_data4 should return.
10441   rv = callback.WaitForResult();
10442   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10443
10444   // Ensure that the client certificate is removed from the cache on a
10445   // handshake failure.
10446   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10447                                                         &client_cert));
10448 }
10449
10450 // Ensure that a client certificate is removed from the SSL client auth
10451 // cache when:
10452 //  1) An HTTPS proxy is involved.
10453 //  3) The HTTPS proxy requests a client certificate.
10454 //  4) The client supplies an invalid/unacceptable certificate for the
10455 //     proxy.
10456 // The test is repeated twice, first for connecting to an HTTPS endpoint,
10457 // then for connecting to an HTTP endpoint.
10458 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
10459   session_deps_.proxy_service.reset(
10460       ProxyService::CreateFixed("https://proxy:70"));
10461   CapturingBoundNetLog log;
10462   session_deps_.net_log = log.bound().net_log();
10463
10464   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10465   cert_request->host_and_port = "proxy:70";
10466
10467   // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10468   // [ssl_]data[1-3]. Rather than represending the endpoint
10469   // (www.example.com:443), they represent failures with the HTTPS proxy
10470   // (proxy:70).
10471   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
10472   ssl_data1.cert_request_info = cert_request.get();
10473   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
10474   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10475   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10476
10477   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10478   ssl_data2.cert_request_info = cert_request.get();
10479   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
10480   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10481   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10482
10483   // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10484 #if 0
10485   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10486   ssl_data3.cert_request_info = cert_request.get();
10487   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
10488   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10489   session_deps_.socket_factory->AddSocketDataProvider(&data3);
10490 #endif
10491
10492   net::HttpRequestInfo requests[2];
10493   requests[0].url = GURL("https://www.example.com/");
10494   requests[0].method = "GET";
10495   requests[0].load_flags = net::LOAD_NORMAL;
10496
10497   requests[1].url = GURL("http://www.example.com/");
10498   requests[1].method = "GET";
10499   requests[1].load_flags = net::LOAD_NORMAL;
10500
10501   for (size_t i = 0; i < arraysize(requests); ++i) {
10502     session_deps_.socket_factory->ResetNextMockIndexes();
10503     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10504     scoped_ptr<HttpNetworkTransaction> trans(
10505         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10506
10507     // Begin the SSL handshake with the proxy.
10508     TestCompletionCallback callback;
10509     int rv = trans->Start(
10510         &requests[i], callback.callback(), net::BoundNetLog());
10511     ASSERT_EQ(net::ERR_IO_PENDING, rv);
10512
10513     // Complete the SSL handshake, which should abort due to requiring a
10514     // client certificate.
10515     rv = callback.WaitForResult();
10516     ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10517
10518     // Indicate that no certificate should be supplied. From the perspective
10519     // of SSLClientCertCache, NULL is just as meaningful as a real
10520     // certificate, so this is the same as supply a
10521     // legitimate-but-unacceptable certificate.
10522     rv = trans->RestartWithCertificate(NULL, callback.callback());
10523     ASSERT_EQ(net::ERR_IO_PENDING, rv);
10524
10525     // Ensure the certificate was added to the client auth cache before
10526     // allowing the connection to continue restarting.
10527     scoped_refptr<X509Certificate> client_cert;
10528     ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10529                                                          &client_cert));
10530     ASSERT_EQ(NULL, client_cert.get());
10531     // Ensure the certificate was NOT cached for the endpoint. This only
10532     // applies to HTTPS requests, but is fine to check for HTTP requests.
10533     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10534                                                           &client_cert));
10535
10536     // Restart the handshake. This will consume ssl_data2, which fails, and
10537     // then consume ssl_data3, which should also fail. The result code is
10538     // checked against what ssl_data3 should return.
10539     rv = callback.WaitForResult();
10540     ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10541
10542     // Now that the new handshake has failed, ensure that the client
10543     // certificate was removed from the client auth cache.
10544     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10545                                                           &client_cert));
10546     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10547                                                           &client_cert));
10548   }
10549 }
10550
10551 // Unlike TEST/TEST_F, which are macros that expand to further macros,
10552 // TEST_P is a macro that expands directly to code that stringizes the
10553 // arguments. As a result, macros passed as parameters (such as prefix
10554 // or test_case_name) will not be expanded by the preprocessor. To
10555 // work around this, indirect the macro for TEST_P, so that the
10556 // pre-processor will expand macros such as MAYBE_test_name before
10557 // instantiating the test.
10558 #define WRAPPED_TEST_P(test_case_name, test_name) \
10559   TEST_P(test_case_name, test_name)
10560
10561 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
10562 #if defined(OS_WIN)
10563 #define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10564 #else
10565 #define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10566 #endif
10567 WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
10568   HttpStreamFactory::set_use_alternate_protocols(true);
10569   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10570
10571   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
10572   session_deps_.host_resolver.reset(new MockCachingHostResolver());
10573   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10574   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10575   pool_peer.DisableDomainAuthenticationVerification();
10576
10577   SSLSocketDataProvider ssl(ASYNC, OK);
10578   ssl.SetNextProto(GetParam());
10579   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10580
10581   scoped_ptr<SpdyFrame> host1_req(
10582       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10583   scoped_ptr<SpdyFrame> host2_req(
10584       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
10585   MockWrite spdy_writes[] = {
10586     CreateMockWrite(*host1_req, 1),
10587     CreateMockWrite(*host2_req, 4),
10588   };
10589   scoped_ptr<SpdyFrame> host1_resp(
10590       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10591   scoped_ptr<SpdyFrame> host1_resp_body(
10592       spdy_util_.ConstructSpdyBodyFrame(1, true));
10593   scoped_ptr<SpdyFrame> host2_resp(
10594       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10595   scoped_ptr<SpdyFrame> host2_resp_body(
10596       spdy_util_.ConstructSpdyBodyFrame(3, true));
10597   MockRead spdy_reads[] = {
10598     CreateMockRead(*host1_resp, 2),
10599     CreateMockRead(*host1_resp_body, 3),
10600     CreateMockRead(*host2_resp, 5),
10601     CreateMockRead(*host2_resp_body, 6),
10602     MockRead(ASYNC, 0, 7),
10603   };
10604
10605   IPAddressNumber ip;
10606   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10607   IPEndPoint peer_addr = IPEndPoint(ip, 443);
10608   MockConnect connect(ASYNC, OK, peer_addr);
10609   OrderedSocketData spdy_data(
10610       connect,
10611       spdy_reads, arraysize(spdy_reads),
10612       spdy_writes, arraysize(spdy_writes));
10613   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10614
10615   TestCompletionCallback callback;
10616   HttpRequestInfo request1;
10617   request1.method = "GET";
10618   request1.url = GURL("https://www.google.com/");
10619   request1.load_flags = 0;
10620   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
10621
10622   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10623   EXPECT_EQ(ERR_IO_PENDING, rv);
10624   EXPECT_EQ(OK, callback.WaitForResult());
10625
10626   const HttpResponseInfo* response = trans1.GetResponseInfo();
10627   ASSERT_TRUE(response != NULL);
10628   ASSERT_TRUE(response->headers.get() != NULL);
10629   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10630
10631   std::string response_data;
10632   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10633   EXPECT_EQ("hello!", response_data);
10634
10635   // Preload www.gmail.com into HostCache.
10636   HostPortPair host_port("www.gmail.com", 443);
10637   HostResolver::RequestInfo resolve_info(host_port);
10638   AddressList ignored;
10639   rv = session_deps_.host_resolver->Resolve(resolve_info,
10640                                             DEFAULT_PRIORITY,
10641                                             &ignored,
10642                                             callback.callback(),
10643                                             NULL,
10644                                             BoundNetLog());
10645   EXPECT_EQ(ERR_IO_PENDING, rv);
10646   rv = callback.WaitForResult();
10647   EXPECT_EQ(OK, rv);
10648
10649   HttpRequestInfo request2;
10650   request2.method = "GET";
10651   request2.url = GURL("https://www.gmail.com/");
10652   request2.load_flags = 0;
10653   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
10654
10655   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10656   EXPECT_EQ(ERR_IO_PENDING, rv);
10657   EXPECT_EQ(OK, callback.WaitForResult());
10658
10659   response = trans2.GetResponseInfo();
10660   ASSERT_TRUE(response != NULL);
10661   ASSERT_TRUE(response->headers.get() != NULL);
10662   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10663   EXPECT_TRUE(response->was_fetched_via_spdy);
10664   EXPECT_TRUE(response->was_npn_negotiated);
10665   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10666   EXPECT_EQ("hello!", response_data);
10667 }
10668 #undef MAYBE_UseIPConnectionPooling
10669
10670 TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
10671   HttpStreamFactory::set_use_alternate_protocols(true);
10672   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10673
10674   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
10675   session_deps_.host_resolver.reset(new MockCachingHostResolver());
10676   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10677   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10678   pool_peer.DisableDomainAuthenticationVerification();
10679
10680   SSLSocketDataProvider ssl(ASYNC, OK);
10681   ssl.SetNextProto(GetParam());
10682   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10683
10684   scoped_ptr<SpdyFrame> host1_req(
10685       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10686   scoped_ptr<SpdyFrame> host2_req(
10687       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
10688   MockWrite spdy_writes[] = {
10689     CreateMockWrite(*host1_req, 1),
10690     CreateMockWrite(*host2_req, 4),
10691   };
10692   scoped_ptr<SpdyFrame> host1_resp(
10693       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10694   scoped_ptr<SpdyFrame> host1_resp_body(
10695       spdy_util_.ConstructSpdyBodyFrame(1, true));
10696   scoped_ptr<SpdyFrame> host2_resp(
10697       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10698   scoped_ptr<SpdyFrame> host2_resp_body(
10699       spdy_util_.ConstructSpdyBodyFrame(3, true));
10700   MockRead spdy_reads[] = {
10701     CreateMockRead(*host1_resp, 2),
10702     CreateMockRead(*host1_resp_body, 3),
10703     CreateMockRead(*host2_resp, 5),
10704     CreateMockRead(*host2_resp_body, 6),
10705     MockRead(ASYNC, 0, 7),
10706   };
10707
10708   IPAddressNumber ip;
10709   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10710   IPEndPoint peer_addr = IPEndPoint(ip, 443);
10711   MockConnect connect(ASYNC, OK, peer_addr);
10712   OrderedSocketData spdy_data(
10713       connect,
10714       spdy_reads, arraysize(spdy_reads),
10715       spdy_writes, arraysize(spdy_writes));
10716   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10717
10718   TestCompletionCallback callback;
10719   HttpRequestInfo request1;
10720   request1.method = "GET";
10721   request1.url = GURL("https://www.google.com/");
10722   request1.load_flags = 0;
10723   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
10724
10725   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10726   EXPECT_EQ(ERR_IO_PENDING, rv);
10727   EXPECT_EQ(OK, callback.WaitForResult());
10728
10729   const HttpResponseInfo* response = trans1.GetResponseInfo();
10730   ASSERT_TRUE(response != NULL);
10731   ASSERT_TRUE(response->headers.get() != NULL);
10732   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10733
10734   std::string response_data;
10735   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10736   EXPECT_EQ("hello!", response_data);
10737
10738   HttpRequestInfo request2;
10739   request2.method = "GET";
10740   request2.url = GURL("https://www.gmail.com/");
10741   request2.load_flags = 0;
10742   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
10743
10744   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10745   EXPECT_EQ(ERR_IO_PENDING, rv);
10746   EXPECT_EQ(OK, callback.WaitForResult());
10747
10748   response = trans2.GetResponseInfo();
10749   ASSERT_TRUE(response != NULL);
10750   ASSERT_TRUE(response->headers.get() != NULL);
10751   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10752   EXPECT_TRUE(response->was_fetched_via_spdy);
10753   EXPECT_TRUE(response->was_npn_negotiated);
10754   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10755   EXPECT_EQ("hello!", response_data);
10756 }
10757
10758 class OneTimeCachingHostResolver : public net::HostResolver {
10759  public:
10760   explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
10761       : host_port_(host_port) {}
10762   virtual ~OneTimeCachingHostResolver() {}
10763
10764   RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
10765
10766   // HostResolver methods:
10767   virtual int Resolve(const RequestInfo& info,
10768                       RequestPriority priority,
10769                       AddressList* addresses,
10770                       const CompletionCallback& callback,
10771                       RequestHandle* out_req,
10772                       const BoundNetLog& net_log) OVERRIDE {
10773     return host_resolver_.Resolve(
10774         info, priority, addresses, callback, out_req, net_log);
10775   }
10776
10777   virtual int ResolveFromCache(const RequestInfo& info,
10778                                AddressList* addresses,
10779                                const BoundNetLog& net_log) OVERRIDE {
10780     int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
10781     if (rv == OK && info.host_port_pair().Equals(host_port_))
10782       host_resolver_.GetHostCache()->clear();
10783     return rv;
10784   }
10785
10786   virtual void CancelRequest(RequestHandle req) OVERRIDE {
10787     host_resolver_.CancelRequest(req);
10788   }
10789
10790   MockCachingHostResolver* GetMockHostResolver() {
10791     return &host_resolver_;
10792   }
10793
10794  private:
10795   MockCachingHostResolver host_resolver_;
10796   const HostPortPair host_port_;
10797 };
10798
10799 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
10800 #if defined(OS_WIN)
10801 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10802     DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
10803 #else
10804 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10805     UseIPConnectionPoolingWithHostCacheExpiration
10806 #endif
10807 WRAPPED_TEST_P(HttpNetworkTransactionTest,
10808                MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
10809 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
10810 // prefix doesn't work with parametrized tests).
10811 #if defined(OS_WIN)
10812   return;
10813 #endif
10814
10815   HttpStreamFactory::set_use_alternate_protocols(true);
10816   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10817
10818   // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
10819   OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
10820   HttpNetworkSession::Params params =
10821       SpdySessionDependencies::CreateSessionParams(&session_deps_);
10822   params.host_resolver = &host_resolver;
10823   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10824   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10825   pool_peer.DisableDomainAuthenticationVerification();
10826
10827   SSLSocketDataProvider ssl(ASYNC, OK);
10828   ssl.SetNextProto(GetParam());
10829   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10830
10831   scoped_ptr<SpdyFrame> host1_req(
10832       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10833   scoped_ptr<SpdyFrame> host2_req(
10834       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
10835   MockWrite spdy_writes[] = {
10836     CreateMockWrite(*host1_req, 1),
10837     CreateMockWrite(*host2_req, 4),
10838   };
10839   scoped_ptr<SpdyFrame> host1_resp(
10840       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10841   scoped_ptr<SpdyFrame> host1_resp_body(
10842       spdy_util_.ConstructSpdyBodyFrame(1, true));
10843   scoped_ptr<SpdyFrame> host2_resp(
10844       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10845   scoped_ptr<SpdyFrame> host2_resp_body(
10846       spdy_util_.ConstructSpdyBodyFrame(3, true));
10847   MockRead spdy_reads[] = {
10848     CreateMockRead(*host1_resp, 2),
10849     CreateMockRead(*host1_resp_body, 3),
10850     CreateMockRead(*host2_resp, 5),
10851     CreateMockRead(*host2_resp_body, 6),
10852     MockRead(ASYNC, 0, 7),
10853   };
10854
10855   IPAddressNumber ip;
10856   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10857   IPEndPoint peer_addr = IPEndPoint(ip, 443);
10858   MockConnect connect(ASYNC, OK, peer_addr);
10859   OrderedSocketData spdy_data(
10860       connect,
10861       spdy_reads, arraysize(spdy_reads),
10862       spdy_writes, arraysize(spdy_writes));
10863   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10864
10865   TestCompletionCallback callback;
10866   HttpRequestInfo request1;
10867   request1.method = "GET";
10868   request1.url = GURL("https://www.google.com/");
10869   request1.load_flags = 0;
10870   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
10871
10872   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10873   EXPECT_EQ(ERR_IO_PENDING, rv);
10874   EXPECT_EQ(OK, callback.WaitForResult());
10875
10876   const HttpResponseInfo* response = trans1.GetResponseInfo();
10877   ASSERT_TRUE(response != NULL);
10878   ASSERT_TRUE(response->headers.get() != NULL);
10879   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10880
10881   std::string response_data;
10882   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10883   EXPECT_EQ("hello!", response_data);
10884
10885   // Preload cache entries into HostCache.
10886   HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
10887   AddressList ignored;
10888   rv = host_resolver.Resolve(resolve_info,
10889                              DEFAULT_PRIORITY,
10890                              &ignored,
10891                              callback.callback(),
10892                              NULL,
10893                              BoundNetLog());
10894   EXPECT_EQ(ERR_IO_PENDING, rv);
10895   rv = callback.WaitForResult();
10896   EXPECT_EQ(OK, rv);
10897
10898   HttpRequestInfo request2;
10899   request2.method = "GET";
10900   request2.url = GURL("https://www.gmail.com/");
10901   request2.load_flags = 0;
10902   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
10903
10904   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10905   EXPECT_EQ(ERR_IO_PENDING, rv);
10906   EXPECT_EQ(OK, callback.WaitForResult());
10907
10908   response = trans2.GetResponseInfo();
10909   ASSERT_TRUE(response != NULL);
10910   ASSERT_TRUE(response->headers.get() != NULL);
10911   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10912   EXPECT_TRUE(response->was_fetched_via_spdy);
10913   EXPECT_TRUE(response->was_npn_negotiated);
10914   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10915   EXPECT_EQ("hello!", response_data);
10916 }
10917 #undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
10918
10919 TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
10920   MockRead data_reads1[] = {
10921     MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
10922   };
10923   MockRead data_reads2[] = {
10924     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10925     MockRead("hello world"),
10926     MockRead(SYNCHRONOUS, OK),
10927   };
10928   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
10929   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
10930   StaticSocketDataProvider* data[] = { &data1, &data2 };
10931
10932   SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10933
10934   EXPECT_EQ(OK, out.rv);
10935   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10936   EXPECT_EQ("hello world", out.response_data);
10937 }
10938
10939 TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
10940   MockWrite data_writes1[] = {
10941     MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
10942   };
10943   MockWrite data_writes2[] = {
10944     MockWrite("GET / HTTP/1.1\r\n"
10945               "Host: www.google.com\r\n"
10946               "Connection: keep-alive\r\n\r\n"),
10947   };
10948   MockRead data_reads2[] = {
10949     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10950     MockRead("hello world"),
10951     MockRead(SYNCHRONOUS, OK),
10952   };
10953   StaticSocketDataProvider data1(NULL, 0,
10954                                  data_writes1, arraysize(data_writes1));
10955   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10956                                  data_writes2, arraysize(data_writes2));
10957   StaticSocketDataProvider* data[] = { &data1, &data2 };
10958
10959   SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10960
10961   EXPECT_EQ(OK, out.rv);
10962   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10963   EXPECT_EQ("hello world", out.response_data);
10964 }
10965
10966 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
10967   const std::string https_url = "https://www.google.com/";
10968   const std::string http_url = "http://www.google.com:443/";
10969
10970   // SPDY GET for HTTPS URL
10971   scoped_ptr<SpdyFrame> req1(
10972       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
10973
10974   MockWrite writes1[] = {
10975     CreateMockWrite(*req1, 0),
10976   };
10977
10978   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10979   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
10980   MockRead reads1[] = {
10981     CreateMockRead(*resp1, 1),
10982     CreateMockRead(*body1, 2),
10983     MockRead(ASYNC, ERR_IO_PENDING, 3)
10984   };
10985
10986   DelayedSocketData data1(
10987       1, reads1, arraysize(reads1),
10988       writes1, arraysize(writes1));
10989   MockConnect connect_data1(ASYNC, OK);
10990   data1.set_connect_data(connect_data1);
10991
10992   // HTTP GET for the HTTP URL
10993   MockWrite writes2[] = {
10994     MockWrite(ASYNC, 4,
10995               "GET / HTTP/1.1\r\n"
10996               "Host: www.google.com:443\r\n"
10997               "Connection: keep-alive\r\n\r\n"),
10998   };
10999
11000   MockRead reads2[] = {
11001     MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11002     MockRead(ASYNC, 6, "hello"),
11003     MockRead(ASYNC, 7, OK),
11004   };
11005
11006   DelayedSocketData data2(
11007       1, reads2, arraysize(reads2),
11008       writes2, arraysize(writes2));
11009
11010   SSLSocketDataProvider ssl(ASYNC, OK);
11011   ssl.SetNextProto(GetParam());
11012   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11013   session_deps_.socket_factory->AddSocketDataProvider(&data1);
11014   session_deps_.socket_factory->AddSocketDataProvider(&data2);
11015
11016   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11017
11018   // Start the first transaction to set up the SpdySession
11019   HttpRequestInfo request1;
11020   request1.method = "GET";
11021   request1.url = GURL(https_url);
11022   request1.load_flags = 0;
11023   HttpNetworkTransaction trans1(LOWEST, session.get());
11024   TestCompletionCallback callback1;
11025   EXPECT_EQ(ERR_IO_PENDING,
11026             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11027   base::MessageLoop::current()->RunUntilIdle();
11028
11029   EXPECT_EQ(OK, callback1.WaitForResult());
11030   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11031
11032   // Now, start the HTTP request
11033   HttpRequestInfo request2;
11034   request2.method = "GET";
11035   request2.url = GURL(http_url);
11036   request2.load_flags = 0;
11037   HttpNetworkTransaction trans2(MEDIUM, session.get());
11038   TestCompletionCallback callback2;
11039   EXPECT_EQ(ERR_IO_PENDING,
11040             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11041   base::MessageLoop::current()->RunUntilIdle();
11042
11043   EXPECT_EQ(OK, callback2.WaitForResult());
11044   EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11045 }
11046
11047 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
11048   const std::string https_url = "https://www.google.com/";
11049   const std::string http_url = "http://www.google.com:443/";
11050
11051   // SPDY GET for HTTPS URL (through CONNECT tunnel)
11052   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
11053                                                                 LOWEST));
11054   scoped_ptr<SpdyFrame> req1(
11055       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
11056
11057   // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
11058   scoped_ptr<SpdyFrame> wrapped_req1(
11059       spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
11060   const char* const headers[] = {
11061     spdy_util_.GetMethodKey(), "GET",
11062     spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
11063     spdy_util_.GetHostKey(),  "www.google.com:443",
11064     spdy_util_.GetSchemeKey(), "http",
11065     spdy_util_.GetVersionKey(), "HTTP/1.1"
11066   };
11067   scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
11068       NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
11069       headers, arraysize(headers), 0));
11070
11071   MockWrite writes1[] = {
11072     CreateMockWrite(*connect, 0),
11073     CreateMockWrite(*wrapped_req1, 2),
11074     CreateMockWrite(*req2, 5),
11075   };
11076
11077   scoped_ptr<SpdyFrame> conn_resp(
11078       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11079   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11080   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11081   scoped_ptr<SpdyFrame> wrapped_resp1(
11082       spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11083   scoped_ptr<SpdyFrame> wrapped_body1(
11084       spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11085   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11086   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
11087   MockRead reads1[] = {
11088     CreateMockRead(*conn_resp, 1),
11089     CreateMockRead(*wrapped_resp1, 3),
11090     CreateMockRead(*wrapped_body1, 4),
11091     CreateMockRead(*resp2, 6),
11092     CreateMockRead(*body2, 7),
11093     MockRead(ASYNC, ERR_IO_PENDING, 8)
11094   };
11095
11096   DeterministicSocketData data1(reads1, arraysize(reads1),
11097                                 writes1, arraysize(writes1));
11098   MockConnect connect_data1(ASYNC, OK);
11099   data1.set_connect_data(connect_data1);
11100
11101   session_deps_.proxy_service.reset(
11102       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11103   CapturingNetLog log;
11104   session_deps_.net_log = &log;
11105   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
11106   ssl1.SetNextProto(GetParam());
11107   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11108   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
11109   ssl2.SetNextProto(GetParam());
11110   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11111   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
11112
11113   scoped_refptr<HttpNetworkSession> session(
11114       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11115
11116   // Start the first transaction to set up the SpdySession
11117   HttpRequestInfo request1;
11118   request1.method = "GET";
11119   request1.url = GURL(https_url);
11120   request1.load_flags = 0;
11121   HttpNetworkTransaction trans1(LOWEST, session.get());
11122   TestCompletionCallback callback1;
11123   EXPECT_EQ(ERR_IO_PENDING,
11124             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11125   base::MessageLoop::current()->RunUntilIdle();
11126   data1.RunFor(4);
11127
11128   EXPECT_EQ(OK, callback1.WaitForResult());
11129   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11130
11131   LoadTimingInfo load_timing_info1;
11132   EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11133   TestLoadTimingNotReusedWithPac(load_timing_info1,
11134                                  CONNECT_TIMING_HAS_SSL_TIMES);
11135
11136   // Now, start the HTTP request
11137   HttpRequestInfo request2;
11138   request2.method = "GET";
11139   request2.url = GURL(http_url);
11140   request2.load_flags = 0;
11141   HttpNetworkTransaction trans2(MEDIUM, session.get());
11142   TestCompletionCallback callback2;
11143   EXPECT_EQ(ERR_IO_PENDING,
11144             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11145   base::MessageLoop::current()->RunUntilIdle();
11146   data1.RunFor(3);
11147
11148   EXPECT_EQ(OK, callback2.WaitForResult());
11149   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11150
11151   LoadTimingInfo load_timing_info2;
11152   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11153   // The established SPDY sessions is considered reused by the HTTP request.
11154   TestLoadTimingReusedWithPac(load_timing_info2);
11155   // HTTP requests over a SPDY session should have a different connection
11156   // socket_log_id than requests over a tunnel.
11157   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
11158 }
11159
11160 TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
11161   HttpStreamFactory::set_force_spdy_always(true);
11162   const std::string https_url = "https://www.google.com/";
11163   const std::string http_url = "http://www.google.com:443/";
11164
11165   // SPDY GET for HTTPS URL
11166   scoped_ptr<SpdyFrame> req1(
11167       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
11168   // SPDY GET for the HTTP URL
11169   scoped_ptr<SpdyFrame> req2(
11170       spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
11171
11172   MockWrite writes[] = {
11173     CreateMockWrite(*req1, 1),
11174     CreateMockWrite(*req2, 4),
11175   };
11176
11177   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11178   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11179   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11180   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
11181   MockRead reads[] = {
11182     CreateMockRead(*resp1, 2),
11183     CreateMockRead(*body1, 3),
11184     CreateMockRead(*resp2, 5),
11185     CreateMockRead(*body2, 6),
11186     MockRead(ASYNC, ERR_IO_PENDING, 7)
11187   };
11188
11189   OrderedSocketData data(reads, arraysize(reads),
11190                          writes, arraysize(writes));
11191
11192   SSLSocketDataProvider ssl(ASYNC, OK);
11193   ssl.SetNextProto(GetParam());
11194   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11195   session_deps_.socket_factory->AddSocketDataProvider(&data);
11196
11197   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11198
11199   // Start the first transaction to set up the SpdySession
11200   HttpRequestInfo request1;
11201   request1.method = "GET";
11202   request1.url = GURL(https_url);
11203   request1.load_flags = 0;
11204   HttpNetworkTransaction trans1(LOWEST, session.get());
11205   TestCompletionCallback callback1;
11206   EXPECT_EQ(ERR_IO_PENDING,
11207             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11208   base::MessageLoop::current()->RunUntilIdle();
11209
11210   EXPECT_EQ(OK, callback1.WaitForResult());
11211   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11212
11213   // Now, start the HTTP request
11214   HttpRequestInfo request2;
11215   request2.method = "GET";
11216   request2.url = GURL(http_url);
11217   request2.load_flags = 0;
11218   HttpNetworkTransaction trans2(MEDIUM, session.get());
11219   TestCompletionCallback callback2;
11220   EXPECT_EQ(ERR_IO_PENDING,
11221             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11222   base::MessageLoop::current()->RunUntilIdle();
11223
11224   EXPECT_EQ(OK, callback2.WaitForResult());
11225   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11226 }
11227
11228 // Test that in the case where we have a SPDY session to a SPDY proxy
11229 // that we do not pool other origins that resolve to the same IP when
11230 // the certificate does not match the new origin.
11231 // http://crbug.com/134690
11232 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
11233   const std::string url1 = "http://www.google.com/";
11234   const std::string url2 = "https://mail.google.com/";
11235   const std::string ip_addr = "1.2.3.4";
11236
11237   // SPDY GET for HTTP URL (through SPDY proxy)
11238   scoped_ptr<SpdyHeaderBlock> headers(
11239       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
11240   scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
11241       headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
11242
11243   MockWrite writes1[] = {
11244     CreateMockWrite(*req1, 0),
11245   };
11246
11247   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11248   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11249   MockRead reads1[] = {
11250     CreateMockRead(*resp1, 1),
11251     CreateMockRead(*body1, 2),
11252     MockRead(ASYNC, OK, 3) // EOF
11253   };
11254
11255   scoped_ptr<DeterministicSocketData> data1(
11256       new DeterministicSocketData(reads1, arraysize(reads1),
11257                                   writes1, arraysize(writes1)));
11258   IPAddressNumber ip;
11259   ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11260   IPEndPoint peer_addr = IPEndPoint(ip, 443);
11261   MockConnect connect_data1(ASYNC, OK, peer_addr);
11262   data1->set_connect_data(connect_data1);
11263
11264   // SPDY GET for HTTPS URL (direct)
11265   scoped_ptr<SpdyFrame> req2(
11266       spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
11267
11268   MockWrite writes2[] = {
11269     CreateMockWrite(*req2, 0),
11270   };
11271
11272   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11273   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11274   MockRead reads2[] = {
11275     CreateMockRead(*resp2, 1),
11276     CreateMockRead(*body2, 2),
11277     MockRead(ASYNC, OK, 3) // EOF
11278   };
11279
11280   scoped_ptr<DeterministicSocketData> data2(
11281       new DeterministicSocketData(reads2, arraysize(reads2),
11282                                   writes2, arraysize(writes2)));
11283   MockConnect connect_data2(ASYNC, OK);
11284   data2->set_connect_data(connect_data2);
11285
11286   // Set up a proxy config that sends HTTP requests to a proxy, and
11287   // all others direct.
11288   ProxyConfig proxy_config;
11289   proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11290   CapturingProxyResolver* capturing_proxy_resolver =
11291       new CapturingProxyResolver();
11292   session_deps_.proxy_service.reset(new ProxyService(
11293       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11294       NULL));
11295
11296   // Load a valid cert.  Note, that this does not need to
11297   // be valid for proxy because the MockSSLClientSocket does
11298   // not actually verify it.  But SpdySession will use this
11299   // to see if it is valid for the new origin
11300   base::FilePath certs_dir = GetTestCertsDirectory();
11301   scoped_refptr<X509Certificate> server_cert(
11302       ImportCertFromFile(certs_dir, "ok_cert.pem"));
11303   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11304
11305   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
11306   ssl1.SetNextProto(GetParam());
11307   ssl1.cert = server_cert;
11308   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11309   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11310       data1.get());
11311
11312   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
11313   ssl2.SetNextProto(GetParam());
11314   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11315   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11316       data2.get());
11317
11318   session_deps_.host_resolver.reset(new MockCachingHostResolver());
11319   session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11320   session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
11321
11322   scoped_refptr<HttpNetworkSession> session(
11323       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11324
11325   // Start the first transaction to set up the SpdySession
11326   HttpRequestInfo request1;
11327   request1.method = "GET";
11328   request1.url = GURL(url1);
11329   request1.load_flags = 0;
11330   HttpNetworkTransaction trans1(LOWEST, session.get());
11331   TestCompletionCallback callback1;
11332   ASSERT_EQ(ERR_IO_PENDING,
11333             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11334   data1->RunFor(3);
11335
11336   ASSERT_TRUE(callback1.have_result());
11337   EXPECT_EQ(OK, callback1.WaitForResult());
11338   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11339
11340   // Now, start the HTTP request
11341   HttpRequestInfo request2;
11342   request2.method = "GET";
11343   request2.url = GURL(url2);
11344   request2.load_flags = 0;
11345   HttpNetworkTransaction trans2(MEDIUM, session.get());
11346   TestCompletionCallback callback2;
11347   EXPECT_EQ(ERR_IO_PENDING,
11348             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11349   base::MessageLoop::current()->RunUntilIdle();
11350   data2->RunFor(3);
11351
11352   ASSERT_TRUE(callback2.have_result());
11353   EXPECT_EQ(OK, callback2.WaitForResult());
11354   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11355 }
11356
11357 // Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11358 // error) in SPDY session, removes the socket from pool and closes the SPDY
11359 // session. Verify that new url's from the same HttpNetworkSession (and a new
11360 // SpdySession) do work. http://crbug.com/224701
11361 TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
11362   const std::string https_url = "https://www.google.com/";
11363
11364   MockRead reads1[] = {
11365     MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11366   };
11367
11368   scoped_ptr<DeterministicSocketData> data1(
11369       new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11370   data1->SetStop(1);
11371
11372   scoped_ptr<SpdyFrame> req2(
11373       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
11374   MockWrite writes2[] = {
11375     CreateMockWrite(*req2, 0),
11376   };
11377
11378   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11379   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11380   MockRead reads2[] = {
11381     CreateMockRead(*resp2, 1),
11382     CreateMockRead(*body2, 2),
11383     MockRead(ASYNC, OK, 3)  // EOF
11384   };
11385
11386   scoped_ptr<DeterministicSocketData> data2(
11387       new DeterministicSocketData(reads2, arraysize(reads2),
11388                                   writes2, arraysize(writes2)));
11389
11390   SSLSocketDataProvider ssl1(ASYNC, OK);
11391   ssl1.SetNextProto(GetParam());
11392   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11393   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11394       data1.get());
11395
11396   SSLSocketDataProvider ssl2(ASYNC, OK);
11397   ssl2.SetNextProto(GetParam());
11398   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11399   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11400       data2.get());
11401
11402   scoped_refptr<HttpNetworkSession> session(
11403       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11404
11405   // Start the first transaction to set up the SpdySession and verify that
11406   // connection was closed.
11407   HttpRequestInfo request1;
11408   request1.method = "GET";
11409   request1.url = GURL(https_url);
11410   request1.load_flags = 0;
11411   HttpNetworkTransaction trans1(MEDIUM, session.get());
11412   TestCompletionCallback callback1;
11413   EXPECT_EQ(ERR_IO_PENDING,
11414             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11415   base::MessageLoop::current()->RunUntilIdle();
11416   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11417
11418   // Now, start the second request and make sure it succeeds.
11419   HttpRequestInfo request2;
11420   request2.method = "GET";
11421   request2.url = GURL(https_url);
11422   request2.load_flags = 0;
11423   HttpNetworkTransaction trans2(MEDIUM, session.get());
11424   TestCompletionCallback callback2;
11425   EXPECT_EQ(ERR_IO_PENDING,
11426             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11427   base::MessageLoop::current()->RunUntilIdle();
11428   data2->RunFor(3);
11429
11430   ASSERT_TRUE(callback2.have_result());
11431   EXPECT_EQ(OK, callback2.WaitForResult());
11432   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11433 }
11434
11435 TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
11436   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11437   ClientSocketPoolManager::set_max_sockets_per_group(
11438       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11439   ClientSocketPoolManager::set_max_sockets_per_pool(
11440       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11441
11442   // Use two different hosts with different IPs so they don't get pooled.
11443   session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11444   session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11445   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11446
11447   SSLSocketDataProvider ssl1(ASYNC, OK);
11448   ssl1.SetNextProto(GetParam());
11449   SSLSocketDataProvider ssl2(ASYNC, OK);
11450   ssl2.SetNextProto(GetParam());
11451   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11452   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11453
11454   scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
11455       "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11456   MockWrite spdy1_writes[] = {
11457     CreateMockWrite(*host1_req, 1),
11458   };
11459   scoped_ptr<SpdyFrame> host1_resp(
11460       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11461   scoped_ptr<SpdyFrame> host1_resp_body(
11462       spdy_util_.ConstructSpdyBodyFrame(1, true));
11463   MockRead spdy1_reads[] = {
11464     CreateMockRead(*host1_resp, 2),
11465     CreateMockRead(*host1_resp_body, 3),
11466     MockRead(ASYNC, ERR_IO_PENDING, 4),
11467   };
11468
11469   scoped_ptr<OrderedSocketData> spdy1_data(
11470       new OrderedSocketData(
11471           spdy1_reads, arraysize(spdy1_reads),
11472           spdy1_writes, arraysize(spdy1_writes)));
11473   session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11474
11475   scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
11476       "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11477   MockWrite spdy2_writes[] = {
11478     CreateMockWrite(*host2_req, 1),
11479   };
11480   scoped_ptr<SpdyFrame> host2_resp(
11481       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11482   scoped_ptr<SpdyFrame> host2_resp_body(
11483       spdy_util_.ConstructSpdyBodyFrame(1, true));
11484   MockRead spdy2_reads[] = {
11485     CreateMockRead(*host2_resp, 2),
11486     CreateMockRead(*host2_resp_body, 3),
11487     MockRead(ASYNC, ERR_IO_PENDING, 4),
11488   };
11489
11490   scoped_ptr<OrderedSocketData> spdy2_data(
11491       new OrderedSocketData(
11492           spdy2_reads, arraysize(spdy2_reads),
11493           spdy2_writes, arraysize(spdy2_writes)));
11494   session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11495
11496   MockWrite http_write[] = {
11497     MockWrite("GET / HTTP/1.1\r\n"
11498               "Host: www.a.com\r\n"
11499               "Connection: keep-alive\r\n\r\n"),
11500   };
11501
11502   MockRead http_read[] = {
11503     MockRead("HTTP/1.1 200 OK\r\n"),
11504     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11505     MockRead("Content-Length: 6\r\n\r\n"),
11506     MockRead("hello!"),
11507   };
11508   StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11509                                      http_write, arraysize(http_write));
11510   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11511
11512   HostPortPair host_port_pair_a("www.a.com", 443);
11513   SpdySessionKey spdy_session_key_a(
11514       host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
11515   EXPECT_FALSE(
11516       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11517
11518   TestCompletionCallback callback;
11519   HttpRequestInfo request1;
11520   request1.method = "GET";
11521   request1.url = GURL("https://www.a.com/");
11522   request1.load_flags = 0;
11523   scoped_ptr<HttpNetworkTransaction> trans(
11524       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11525
11526   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11527   EXPECT_EQ(ERR_IO_PENDING, rv);
11528   EXPECT_EQ(OK, callback.WaitForResult());
11529
11530   const HttpResponseInfo* response = trans->GetResponseInfo();
11531   ASSERT_TRUE(response != NULL);
11532   ASSERT_TRUE(response->headers.get() != NULL);
11533   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11534   EXPECT_TRUE(response->was_fetched_via_spdy);
11535   EXPECT_TRUE(response->was_npn_negotiated);
11536
11537   std::string response_data;
11538   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11539   EXPECT_EQ("hello!", response_data);
11540   trans.reset();
11541   EXPECT_TRUE(
11542       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11543
11544   HostPortPair host_port_pair_b("www.b.com", 443);
11545   SpdySessionKey spdy_session_key_b(
11546       host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
11547   EXPECT_FALSE(
11548       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11549   HttpRequestInfo request2;
11550   request2.method = "GET";
11551   request2.url = GURL("https://www.b.com/");
11552   request2.load_flags = 0;
11553   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11554
11555   rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11556   EXPECT_EQ(ERR_IO_PENDING, rv);
11557   EXPECT_EQ(OK, callback.WaitForResult());
11558
11559   response = trans->GetResponseInfo();
11560   ASSERT_TRUE(response != NULL);
11561   ASSERT_TRUE(response->headers.get() != NULL);
11562   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11563   EXPECT_TRUE(response->was_fetched_via_spdy);
11564   EXPECT_TRUE(response->was_npn_negotiated);
11565   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11566   EXPECT_EQ("hello!", response_data);
11567   EXPECT_FALSE(
11568       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11569   EXPECT_TRUE(
11570       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11571
11572   HostPortPair host_port_pair_a1("www.a.com", 80);
11573   SpdySessionKey spdy_session_key_a1(
11574       host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
11575   EXPECT_FALSE(
11576       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
11577   HttpRequestInfo request3;
11578   request3.method = "GET";
11579   request3.url = GURL("http://www.a.com/");
11580   request3.load_flags = 0;
11581   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11582
11583   rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11584   EXPECT_EQ(ERR_IO_PENDING, rv);
11585   EXPECT_EQ(OK, callback.WaitForResult());
11586
11587   response = trans->GetResponseInfo();
11588   ASSERT_TRUE(response != NULL);
11589   ASSERT_TRUE(response->headers.get() != NULL);
11590   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11591   EXPECT_FALSE(response->was_fetched_via_spdy);
11592   EXPECT_FALSE(response->was_npn_negotiated);
11593   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11594   EXPECT_EQ("hello!", response_data);
11595   EXPECT_FALSE(
11596       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11597   EXPECT_FALSE(
11598       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11599 }
11600
11601 TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11602   HttpRequestInfo request;
11603   request.method = "GET";
11604   request.url = GURL("http://www.google.com/");
11605   request.load_flags = 0;
11606
11607   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11608   scoped_ptr<HttpTransaction> trans(
11609       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11610
11611   MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11612   StaticSocketDataProvider data;
11613   data.set_connect_data(mock_connect);
11614   session_deps_.socket_factory->AddSocketDataProvider(&data);
11615
11616   TestCompletionCallback callback;
11617
11618   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11619   EXPECT_EQ(ERR_IO_PENDING, rv);
11620
11621   rv = callback.WaitForResult();
11622   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11623
11624   EXPECT_EQ(NULL, trans->GetResponseInfo());
11625
11626   // We don't care whether this succeeds or fails, but it shouldn't crash.
11627   HttpRequestHeaders request_headers;
11628   trans->GetFullRequestHeaders(&request_headers);
11629 }
11630
11631 TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11632   HttpRequestInfo request;
11633   request.method = "GET";
11634   request.url = GURL("http://www.google.com/");
11635   request.load_flags = 0;
11636
11637   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11638   scoped_ptr<HttpTransaction> trans(
11639       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11640
11641   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11642   StaticSocketDataProvider data;
11643   data.set_connect_data(mock_connect);
11644   session_deps_.socket_factory->AddSocketDataProvider(&data);
11645
11646   TestCompletionCallback callback;
11647
11648   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11649   EXPECT_EQ(ERR_IO_PENDING, rv);
11650
11651   rv = callback.WaitForResult();
11652   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11653
11654   EXPECT_EQ(NULL, trans->GetResponseInfo());
11655
11656   // We don't care whether this succeeds or fails, but it shouldn't crash.
11657   HttpRequestHeaders request_headers;
11658   trans->GetFullRequestHeaders(&request_headers);
11659 }
11660
11661 TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11662   HttpRequestInfo request;
11663   request.method = "GET";
11664   request.url = GURL("http://www.google.com/");
11665   request.load_flags = 0;
11666
11667   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11668   scoped_ptr<HttpTransaction> trans(
11669       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11670
11671   MockWrite data_writes[] = {
11672     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11673   };
11674   MockRead data_reads[] = {
11675     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
11676   };
11677
11678   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11679                                 data_writes, arraysize(data_writes));
11680   session_deps_.socket_factory->AddSocketDataProvider(&data);
11681
11682   TestCompletionCallback callback;
11683
11684   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11685   EXPECT_EQ(ERR_IO_PENDING, rv);
11686
11687   rv = callback.WaitForResult();
11688   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11689
11690   EXPECT_EQ(NULL, trans->GetResponseInfo());
11691
11692   HttpRequestHeaders request_headers;
11693   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11694   EXPECT_TRUE(request_headers.HasHeader("Host"));
11695 }
11696
11697 TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11698   HttpRequestInfo request;
11699   request.method = "GET";
11700   request.url = GURL("http://www.google.com/");
11701   request.load_flags = 0;
11702
11703   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11704   scoped_ptr<HttpTransaction> trans(
11705       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11706
11707   MockWrite data_writes[] = {
11708     MockWrite(ASYNC, ERR_CONNECTION_RESET),
11709   };
11710   MockRead data_reads[] = {
11711     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
11712   };
11713
11714   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11715                                 data_writes, arraysize(data_writes));
11716   session_deps_.socket_factory->AddSocketDataProvider(&data);
11717
11718   TestCompletionCallback callback;
11719
11720   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11721   EXPECT_EQ(ERR_IO_PENDING, rv);
11722
11723   rv = callback.WaitForResult();
11724   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11725
11726   EXPECT_EQ(NULL, trans->GetResponseInfo());
11727
11728   HttpRequestHeaders request_headers;
11729   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11730   EXPECT_TRUE(request_headers.HasHeader("Host"));
11731 }
11732
11733 TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
11734   HttpRequestInfo request;
11735   request.method = "GET";
11736   request.url = GURL("http://www.google.com/");
11737   request.load_flags = 0;
11738
11739   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11740   scoped_ptr<HttpTransaction> trans(
11741       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11742
11743   MockWrite data_writes[] = {
11744     MockWrite("GET / HTTP/1.1\r\n"
11745               "Host: www.google.com\r\n"
11746               "Connection: keep-alive\r\n\r\n"),
11747   };
11748   MockRead data_reads[] = {
11749     MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11750   };
11751
11752   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11753                                 data_writes, arraysize(data_writes));
11754   session_deps_.socket_factory->AddSocketDataProvider(&data);
11755
11756   TestCompletionCallback callback;
11757
11758   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11759   EXPECT_EQ(ERR_IO_PENDING, rv);
11760
11761   rv = callback.WaitForResult();
11762   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11763
11764   EXPECT_EQ(NULL, trans->GetResponseInfo());
11765
11766   HttpRequestHeaders request_headers;
11767   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11768   EXPECT_TRUE(request_headers.HasHeader("Host"));
11769 }
11770
11771 TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11772   HttpRequestInfo request;
11773   request.method = "GET";
11774   request.url = GURL("http://www.google.com/");
11775   request.load_flags = 0;
11776
11777   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11778   scoped_ptr<HttpTransaction> trans(
11779       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11780
11781   MockWrite data_writes[] = {
11782     MockWrite("GET / HTTP/1.1\r\n"
11783               "Host: www.google.com\r\n"
11784               "Connection: keep-alive\r\n\r\n"),
11785   };
11786   MockRead data_reads[] = {
11787     MockRead(ASYNC, ERR_CONNECTION_RESET),
11788   };
11789
11790   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11791                                 data_writes, arraysize(data_writes));
11792   session_deps_.socket_factory->AddSocketDataProvider(&data);
11793
11794   TestCompletionCallback callback;
11795
11796   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11797   EXPECT_EQ(ERR_IO_PENDING, rv);
11798
11799   rv = callback.WaitForResult();
11800   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11801
11802   EXPECT_EQ(NULL, trans->GetResponseInfo());
11803
11804   HttpRequestHeaders request_headers;
11805   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11806   EXPECT_TRUE(request_headers.HasHeader("Host"));
11807 }
11808
11809 TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
11810   HttpRequestInfo request;
11811   request.method = "GET";
11812   request.url = GURL("http://www.google.com/");
11813   request.load_flags = 0;
11814   request.extra_headers.SetHeader("X-Foo", "bar");
11815
11816   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11817   scoped_ptr<HttpTransaction> trans(
11818       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11819
11820   MockWrite data_writes[] = {
11821     MockWrite("GET / HTTP/1.1\r\n"
11822               "Host: www.google.com\r\n"
11823               "Connection: keep-alive\r\n"
11824               "X-Foo: bar\r\n\r\n"),
11825   };
11826   MockRead data_reads[] = {
11827     MockRead("HTTP/1.1 200 OK\r\n"
11828              "Content-Length: 5\r\n\r\n"
11829              "hello"),
11830     MockRead(ASYNC, ERR_UNEXPECTED),
11831   };
11832
11833   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11834                                 data_writes, arraysize(data_writes));
11835   session_deps_.socket_factory->AddSocketDataProvider(&data);
11836
11837   TestCompletionCallback callback;
11838
11839   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11840   EXPECT_EQ(ERR_IO_PENDING, rv);
11841
11842   rv = callback.WaitForResult();
11843   EXPECT_EQ(OK, rv);
11844
11845   HttpRequestHeaders request_headers;
11846   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11847   std::string foo;
11848   EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
11849   EXPECT_EQ("bar", foo);
11850 }
11851
11852 namespace {
11853
11854 // Fake HttpStreamBase that simply records calls to SetPriority().
11855 class FakeStream : public HttpStreamBase,
11856                    public base::SupportsWeakPtr<FakeStream> {
11857  public:
11858   explicit FakeStream(RequestPriority priority) : priority_(priority) {}
11859   virtual ~FakeStream() {}
11860
11861   RequestPriority priority() const { return priority_; }
11862
11863   virtual int InitializeStream(const HttpRequestInfo* request_info,
11864                                RequestPriority priority,
11865                                const BoundNetLog& net_log,
11866                                const CompletionCallback& callback) OVERRIDE {
11867     return ERR_IO_PENDING;
11868   }
11869
11870   virtual int SendRequest(const HttpRequestHeaders& request_headers,
11871                           HttpResponseInfo* response,
11872                           const CompletionCallback& callback) OVERRIDE {
11873     ADD_FAILURE();
11874     return ERR_UNEXPECTED;
11875   }
11876
11877   virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
11878     ADD_FAILURE();
11879     return ERR_UNEXPECTED;
11880   }
11881
11882   virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
11883     ADD_FAILURE();
11884     return NULL;
11885   }
11886
11887   virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
11888                                const CompletionCallback& callback) OVERRIDE {
11889     ADD_FAILURE();
11890     return ERR_UNEXPECTED;
11891   }
11892
11893   virtual void Close(bool not_reusable) OVERRIDE {}
11894
11895   virtual bool IsResponseBodyComplete() const OVERRIDE {
11896     ADD_FAILURE();
11897     return false;
11898   }
11899
11900   virtual bool CanFindEndOfResponse() const OVERRIDE {
11901     return false;
11902   }
11903
11904   virtual bool IsConnectionReused() const OVERRIDE {
11905     ADD_FAILURE();
11906     return false;
11907   }
11908
11909   virtual void SetConnectionReused() OVERRIDE {
11910     ADD_FAILURE();
11911   }
11912
11913   virtual bool IsConnectionReusable() const OVERRIDE {
11914     ADD_FAILURE();
11915     return false;
11916   }
11917
11918   virtual bool GetLoadTimingInfo(
11919       LoadTimingInfo* load_timing_info) const OVERRIDE {
11920     ADD_FAILURE();
11921     return false;
11922   }
11923
11924   virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
11925     ADD_FAILURE();
11926   }
11927
11928   virtual void GetSSLCertRequestInfo(
11929       SSLCertRequestInfo* cert_request_info) OVERRIDE {
11930     ADD_FAILURE();
11931   }
11932
11933   virtual bool IsSpdyHttpStream() const OVERRIDE {
11934     ADD_FAILURE();
11935     return false;
11936   }
11937
11938   virtual void Drain(HttpNetworkSession* session) OVERRIDE {
11939     ADD_FAILURE();
11940   }
11941
11942   virtual void SetPriority(RequestPriority priority) OVERRIDE {
11943     priority_ = priority;
11944   }
11945
11946  private:
11947   RequestPriority priority_;
11948
11949   DISALLOW_COPY_AND_ASSIGN(FakeStream);
11950 };
11951
11952 // Fake HttpStreamRequest that simply records calls to SetPriority()
11953 // and vends FakeStreams with its current priority.
11954 class FakeStreamRequest : public HttpStreamRequest,
11955                           public base::SupportsWeakPtr<FakeStreamRequest> {
11956  public:
11957   FakeStreamRequest(RequestPriority priority,
11958                     HttpStreamRequest::Delegate* delegate)
11959       : priority_(priority),
11960         delegate_(delegate) {}
11961
11962   virtual ~FakeStreamRequest() {}
11963
11964   RequestPriority priority() const { return priority_; }
11965
11966   // Create a new FakeStream and pass it to the request's
11967   // delegate. Returns a weak pointer to the FakeStream.
11968   base::WeakPtr<FakeStream> FinishStreamRequest() {
11969     FakeStream* fake_stream = new FakeStream(priority_);
11970     // Do this before calling OnStreamReady() as OnStreamReady() may
11971     // immediately delete |fake_stream|.
11972     base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
11973     delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
11974     return weak_stream;
11975   }
11976
11977   virtual int RestartTunnelWithProxyAuth(
11978       const AuthCredentials& credentials) OVERRIDE {
11979     ADD_FAILURE();
11980     return ERR_UNEXPECTED;
11981   }
11982
11983   virtual LoadState GetLoadState() const OVERRIDE {
11984     ADD_FAILURE();
11985     return LoadState();
11986   }
11987
11988   virtual void SetPriority(RequestPriority priority) OVERRIDE {
11989     priority_ = priority;
11990   }
11991
11992   virtual bool was_npn_negotiated() const OVERRIDE {
11993     return false;
11994   }
11995
11996   virtual NextProto protocol_negotiated() const OVERRIDE {
11997     return kProtoUnknown;
11998   }
11999
12000   virtual bool using_spdy() const OVERRIDE {
12001     return false;
12002   }
12003
12004  private:
12005   RequestPriority priority_;
12006   HttpStreamRequest::Delegate* const delegate_;
12007
12008   DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12009 };
12010
12011 // Fake HttpStreamFactory that vends FakeStreamRequests.
12012 class FakeStreamFactory : public HttpStreamFactory {
12013  public:
12014   FakeStreamFactory() {}
12015   virtual ~FakeStreamFactory() {}
12016
12017   // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12018   // RequestStream() (which may be NULL if it was destroyed already).
12019   base::WeakPtr<FakeStreamRequest> last_stream_request() {
12020     return last_stream_request_;
12021   }
12022
12023   virtual HttpStreamRequest* RequestStream(
12024       const HttpRequestInfo& info,
12025       RequestPriority priority,
12026       const SSLConfig& server_ssl_config,
12027       const SSLConfig& proxy_ssl_config,
12028       HttpStreamRequest::Delegate* delegate,
12029       const BoundNetLog& net_log) OVERRIDE {
12030     FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
12031     last_stream_request_ = fake_request->AsWeakPtr();
12032     return fake_request;
12033   }
12034
12035   virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
12036       const HttpRequestInfo& info,
12037       RequestPriority priority,
12038       const SSLConfig& server_ssl_config,
12039       const SSLConfig& proxy_ssl_config,
12040       HttpStreamRequest::Delegate* delegate,
12041       WebSocketHandshakeStreamBase::Factory* factory,
12042       const BoundNetLog& net_log) OVERRIDE {
12043     ADD_FAILURE();
12044     return NULL;
12045   }
12046
12047   virtual void PreconnectStreams(int num_streams,
12048                                  const HttpRequestInfo& info,
12049                                  RequestPriority priority,
12050                                  const SSLConfig& server_ssl_config,
12051                                  const SSLConfig& proxy_ssl_config) OVERRIDE {
12052     ADD_FAILURE();
12053   }
12054
12055   virtual base::Value* PipelineInfoToValue() const OVERRIDE {
12056     ADD_FAILURE();
12057     return NULL;
12058   }
12059
12060   virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
12061     ADD_FAILURE();
12062     return NULL;
12063   }
12064
12065  private:
12066   base::WeakPtr<FakeStreamRequest> last_stream_request_;
12067
12068   DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12069 };
12070
12071 }  // namespace
12072
12073 // Make sure that HttpNetworkTransaction passes on its priority to its
12074 // stream request on start.
12075 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12076   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12077   HttpNetworkSessionPeer peer(session);
12078   FakeStreamFactory* fake_factory = new FakeStreamFactory();
12079   peer.SetHttpStreamFactory(fake_factory);
12080
12081   HttpNetworkTransaction trans(LOW, session);
12082
12083   ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12084
12085   HttpRequestInfo request;
12086   TestCompletionCallback callback;
12087   EXPECT_EQ(ERR_IO_PENDING,
12088             trans.Start(&request, callback.callback(), BoundNetLog()));
12089
12090   base::WeakPtr<FakeStreamRequest> fake_request =
12091       fake_factory->last_stream_request();
12092   ASSERT_TRUE(fake_request != NULL);
12093   EXPECT_EQ(LOW, fake_request->priority());
12094 }
12095
12096 // Make sure that HttpNetworkTransaction passes on its priority
12097 // updates to its stream request.
12098 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12099   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12100   HttpNetworkSessionPeer peer(session);
12101   FakeStreamFactory* fake_factory = new FakeStreamFactory();
12102   peer.SetHttpStreamFactory(fake_factory);
12103
12104   HttpNetworkTransaction trans(LOW, session);
12105
12106   HttpRequestInfo request;
12107   TestCompletionCallback callback;
12108   EXPECT_EQ(ERR_IO_PENDING,
12109             trans.Start(&request, callback.callback(), BoundNetLog()));
12110
12111   base::WeakPtr<FakeStreamRequest> fake_request =
12112       fake_factory->last_stream_request();
12113   ASSERT_TRUE(fake_request != NULL);
12114   EXPECT_EQ(LOW, fake_request->priority());
12115
12116   trans.SetPriority(LOWEST);
12117   ASSERT_TRUE(fake_request != NULL);
12118   EXPECT_EQ(LOWEST, fake_request->priority());
12119 }
12120
12121 // Make sure that HttpNetworkTransaction passes on its priority
12122 // updates to its stream.
12123 TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12124   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12125   HttpNetworkSessionPeer peer(session);
12126   FakeStreamFactory* fake_factory = new FakeStreamFactory();
12127   peer.SetHttpStreamFactory(fake_factory);
12128
12129   HttpNetworkTransaction trans(LOW, session);
12130
12131   HttpRequestInfo request;
12132   TestCompletionCallback callback;
12133   EXPECT_EQ(ERR_IO_PENDING,
12134             trans.Start(&request, callback.callback(), BoundNetLog()));
12135
12136   base::WeakPtr<FakeStreamRequest> fake_request =
12137       fake_factory->last_stream_request();
12138   ASSERT_TRUE(fake_request != NULL);
12139   base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12140   ASSERT_TRUE(fake_stream != NULL);
12141   EXPECT_EQ(LOW, fake_stream->priority());
12142
12143   trans.SetPriority(LOWEST);
12144   EXPECT_EQ(LOWEST, fake_stream->priority());
12145 }
12146
12147 // Tests that when a used socket is returned to the SSL socket pool, it's closed
12148 // if the transport socket pool is stalled on the global socket limit.
12149 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12150   ClientSocketPoolManager::set_max_sockets_per_group(
12151       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12152   ClientSocketPoolManager::set_max_sockets_per_pool(
12153       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12154
12155   // Set up SSL request.
12156
12157   HttpRequestInfo ssl_request;
12158   ssl_request.method = "GET";
12159   ssl_request.url = GURL("https://www.google.com/");
12160
12161   MockWrite ssl_writes[] = {
12162     MockWrite("GET / HTTP/1.1\r\n"
12163               "Host: www.google.com\r\n"
12164               "Connection: keep-alive\r\n\r\n"),
12165   };
12166   MockRead ssl_reads[] = {
12167     MockRead("HTTP/1.1 200 OK\r\n"),
12168     MockRead("Content-Length: 11\r\n\r\n"),
12169     MockRead("hello world"),
12170     MockRead(SYNCHRONOUS, OK),
12171   };
12172   StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12173                                     ssl_writes, arraysize(ssl_writes));
12174   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12175
12176   SSLSocketDataProvider ssl(ASYNC, OK);
12177   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12178
12179   // Set up HTTP request.
12180
12181   HttpRequestInfo http_request;
12182   http_request.method = "GET";
12183   http_request.url = GURL("http://www.google.com/");
12184
12185   MockWrite http_writes[] = {
12186     MockWrite("GET / HTTP/1.1\r\n"
12187               "Host: www.google.com\r\n"
12188               "Connection: keep-alive\r\n\r\n"),
12189   };
12190   MockRead http_reads[] = {
12191     MockRead("HTTP/1.1 200 OK\r\n"),
12192     MockRead("Content-Length: 7\r\n\r\n"),
12193     MockRead("falafel"),
12194     MockRead(SYNCHRONOUS, OK),
12195   };
12196   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12197                                      http_writes, arraysize(http_writes));
12198   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12199
12200   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12201
12202   // Start the SSL request.
12203   TestCompletionCallback ssl_callback;
12204   scoped_ptr<HttpTransaction> ssl_trans(
12205       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12206   ASSERT_EQ(ERR_IO_PENDING,
12207             ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12208             BoundNetLog()));
12209
12210   // Start the HTTP request.  Pool should stall.
12211   TestCompletionCallback http_callback;
12212   scoped_ptr<HttpTransaction> http_trans(
12213       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12214   ASSERT_EQ(ERR_IO_PENDING,
12215             http_trans->Start(&http_request, http_callback.callback(),
12216                               BoundNetLog()));
12217   EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12218
12219   // Wait for response from SSL request.
12220   ASSERT_EQ(OK, ssl_callback.WaitForResult());
12221   std::string response_data;
12222   ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12223   EXPECT_EQ("hello world", response_data);
12224
12225   // The SSL socket should automatically be closed, so the HTTP request can
12226   // start.
12227   EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12228   ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12229
12230   // The HTTP request can now complete.
12231   ASSERT_EQ(OK, http_callback.WaitForResult());
12232   ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12233   EXPECT_EQ("falafel", response_data);
12234
12235   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12236 }
12237
12238 // Tests that when a SSL connection is established but there's no corresponding
12239 // request that needs it, the new socket is closed if the transport socket pool
12240 // is stalled on the global socket limit.
12241 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12242   ClientSocketPoolManager::set_max_sockets_per_group(
12243       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12244   ClientSocketPoolManager::set_max_sockets_per_pool(
12245       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12246
12247   // Set up an ssl request.
12248
12249   HttpRequestInfo ssl_request;
12250   ssl_request.method = "GET";
12251   ssl_request.url = GURL("https://www.foopy.com/");
12252
12253   // No data will be sent on the SSL socket.
12254   StaticSocketDataProvider ssl_data;
12255   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12256
12257   SSLSocketDataProvider ssl(ASYNC, OK);
12258   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12259
12260   // Set up HTTP request.
12261
12262   HttpRequestInfo http_request;
12263   http_request.method = "GET";
12264   http_request.url = GURL("http://www.google.com/");
12265
12266   MockWrite http_writes[] = {
12267     MockWrite("GET / HTTP/1.1\r\n"
12268               "Host: www.google.com\r\n"
12269               "Connection: keep-alive\r\n\r\n"),
12270   };
12271   MockRead http_reads[] = {
12272     MockRead("HTTP/1.1 200 OK\r\n"),
12273     MockRead("Content-Length: 7\r\n\r\n"),
12274     MockRead("falafel"),
12275     MockRead(SYNCHRONOUS, OK),
12276   };
12277   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12278                                      http_writes, arraysize(http_writes));
12279   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12280
12281   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12282
12283   // Preconnect an SSL socket.  A preconnect is needed because connect jobs are
12284   // cancelled when a normal transaction is cancelled.
12285   net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12286   net::SSLConfig ssl_config;
12287   session->ssl_config_service()->GetSSLConfig(&ssl_config);
12288   http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12289                                          ssl_config, ssl_config);
12290   EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12291
12292   // Start the HTTP request.  Pool should stall.
12293   TestCompletionCallback http_callback;
12294   scoped_ptr<HttpTransaction> http_trans(
12295       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12296   ASSERT_EQ(ERR_IO_PENDING,
12297             http_trans->Start(&http_request, http_callback.callback(),
12298                               BoundNetLog()));
12299   EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12300
12301   // The SSL connection will automatically be closed once the connection is
12302   // established, to let the HTTP request start.
12303   ASSERT_EQ(OK, http_callback.WaitForResult());
12304   std::string response_data;
12305   ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12306   EXPECT_EQ("falafel", response_data);
12307
12308   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12309 }
12310
12311 }  // namespace net