• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/http/http_network_transaction.h"
6 
7 #include <math.h>  // ceil
8 #include <stdarg.h>
9 #include <string>
10 #include <vector>
11 
12 #include "base/basictypes.h"
13 #include "base/compiler_specific.h"
14 #include "base/file_util.h"
15 #include "base/files/file_path.h"
16 #include "base/json/json_writer.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/run_loop.h"
20 #include "base/strings/string_util.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "base/test/test_file_util.h"
23 #include "net/base/auth.h"
24 #include "net/base/capturing_net_log.h"
25 #include "net/base/completion_callback.h"
26 #include "net/base/load_timing_info.h"
27 #include "net/base/load_timing_info_test_util.h"
28 #include "net/base/net_log.h"
29 #include "net/base/net_log_unittest.h"
30 #include "net/base/request_priority.h"
31 #include "net/base/test_completion_callback.h"
32 #include "net/base/test_data_directory.h"
33 #include "net/base/upload_bytes_element_reader.h"
34 #include "net/base/upload_data_stream.h"
35 #include "net/base/upload_file_element_reader.h"
36 #include "net/cert/mock_cert_verifier.h"
37 #include "net/dns/host_cache.h"
38 #include "net/dns/mock_host_resolver.h"
39 #include "net/http/http_auth_challenge_tokenizer.h"
40 #include "net/http/http_auth_handler_digest.h"
41 #include "net/http/http_auth_handler_mock.h"
42 #include "net/http/http_auth_handler_ntlm.h"
43 #include "net/http/http_basic_stream.h"
44 #include "net/http/http_network_session.h"
45 #include "net/http/http_network_session_peer.h"
46 #include "net/http/http_server_properties_impl.h"
47 #include "net/http/http_stream.h"
48 #include "net/http/http_stream_factory.h"
49 #include "net/http/http_transaction_test_util.h"
50 #include "net/proxy/proxy_config_service_fixed.h"
51 #include "net/proxy/proxy_info.h"
52 #include "net/proxy/proxy_resolver.h"
53 #include "net/proxy/proxy_service.h"
54 #include "net/socket/client_socket_factory.h"
55 #include "net/socket/client_socket_pool_manager.h"
56 #include "net/socket/mock_client_socket_pool_manager.h"
57 #include "net/socket/next_proto.h"
58 #include "net/socket/socket_test_util.h"
59 #include "net/socket/ssl_client_socket.h"
60 #include "net/spdy/spdy_framer.h"
61 #include "net/spdy/spdy_session.h"
62 #include "net/spdy/spdy_session_pool.h"
63 #include "net/spdy/spdy_test_util_common.h"
64 #include "net/ssl/ssl_cert_request_info.h"
65 #include "net/ssl/ssl_config_service.h"
66 #include "net/ssl/ssl_config_service_defaults.h"
67 #include "net/ssl/ssl_info.h"
68 #include "net/test/cert_test_util.h"
69 #include "net/websockets/websocket_handshake_stream_base.h"
70 #include "testing/gtest/include/gtest/gtest.h"
71 #include "testing/platform_test.h"
72 #include "url/gurl.h"
73 
74 using base::ASCIIToUTF16;
75 
76 //-----------------------------------------------------------------------------
77 
78 namespace {
79 
80 const base::string16 kBar(ASCIIToUTF16("bar"));
81 const base::string16 kBar2(ASCIIToUTF16("bar2"));
82 const base::string16 kBar3(ASCIIToUTF16("bar3"));
83 const base::string16 kBaz(ASCIIToUTF16("baz"));
84 const base::string16 kFirst(ASCIIToUTF16("first"));
85 const base::string16 kFoo(ASCIIToUTF16("foo"));
86 const base::string16 kFoo2(ASCIIToUTF16("foo2"));
87 const base::string16 kFoo3(ASCIIToUTF16("foo3"));
88 const base::string16 kFou(ASCIIToUTF16("fou"));
89 const base::string16 kSecond(ASCIIToUTF16("second"));
90 const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
91 const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
92 
GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession * session)93 int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
94   return session->GetTransportSocketPool(
95       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
96 }
97 
GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession * session)98 int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
99   return session->GetSSLSocketPool(
100       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
101 }
102 
IsTransportSocketPoolStalled(net::HttpNetworkSession * session)103 bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
104   return session->GetTransportSocketPool(
105       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
106 }
107 
108 // Takes in a Value created from a NetLogHttpResponseParameter, and returns
109 // a JSONified list of headers as a single string.  Uses single quotes instead
110 // of double quotes for easier comparison.  Returns false on failure.
GetHeaders(base::DictionaryValue * params,std::string * headers)111 bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
112   if (!params)
113     return false;
114   base::ListValue* header_list;
115   if (!params->GetList("headers", &header_list))
116     return false;
117   std::string double_quote_headers;
118   base::JSONWriter::Write(header_list, &double_quote_headers);
119   base::ReplaceChars(double_quote_headers, "\"", "'", headers);
120   return true;
121 }
122 
123 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is
124 // used.
TestLoadTimingReused(const net::LoadTimingInfo & load_timing_info)125 void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
126   EXPECT_TRUE(load_timing_info.socket_reused);
127   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
128 
129   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
130   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
131 
132   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
133   EXPECT_FALSE(load_timing_info.send_start.is_null());
134 
135   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
136 
137   // Set at a higher level.
138   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
139   EXPECT_TRUE(load_timing_info.request_start.is_null());
140   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
141 }
142 
143 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is
144 // used.
TestLoadTimingNotReused(const net::LoadTimingInfo & load_timing_info,int connect_timing_flags)145 void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
146                              int connect_timing_flags) {
147   EXPECT_FALSE(load_timing_info.socket_reused);
148   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
149 
150   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
151   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
152 
153   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
154                                    connect_timing_flags);
155   EXPECT_LE(load_timing_info.connect_timing.connect_end,
156             load_timing_info.send_start);
157 
158   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
159 
160   // Set at a higher level.
161   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
162   EXPECT_TRUE(load_timing_info.request_start.is_null());
163   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
164 }
165 
166 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is
167 // used.
TestLoadTimingReusedWithPac(const net::LoadTimingInfo & load_timing_info)168 void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
169   EXPECT_TRUE(load_timing_info.socket_reused);
170   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
171 
172   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
173 
174   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
175   EXPECT_LE(load_timing_info.proxy_resolve_start,
176             load_timing_info.proxy_resolve_end);
177   EXPECT_LE(load_timing_info.proxy_resolve_end,
178             load_timing_info.send_start);
179   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
180 
181   // Set at a higher level.
182   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
183   EXPECT_TRUE(load_timing_info.request_start.is_null());
184   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
185 }
186 
187 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is
188 // used.
TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo & load_timing_info,int connect_timing_flags)189 void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
190                                     int connect_timing_flags) {
191   EXPECT_FALSE(load_timing_info.socket_reused);
192   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
193 
194   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
195   EXPECT_LE(load_timing_info.proxy_resolve_start,
196             load_timing_info.proxy_resolve_end);
197   EXPECT_LE(load_timing_info.proxy_resolve_end,
198             load_timing_info.connect_timing.connect_start);
199   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
200                                    connect_timing_flags);
201   EXPECT_LE(load_timing_info.connect_timing.connect_end,
202             load_timing_info.send_start);
203 
204   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
205 
206   // Set at a higher level.
207   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
208   EXPECT_TRUE(load_timing_info.request_start.is_null());
209   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
210 }
211 
212 }  // namespace
213 
214 namespace net {
215 
216 namespace {
217 
CreateSession(SpdySessionDependencies * session_deps)218 HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
219   return SpdySessionDependencies::SpdyCreateSession(session_deps);
220 }
221 
222 }  // namespace
223 
224 class HttpNetworkTransactionTest
225     : public PlatformTest,
226       public ::testing::WithParamInterface<NextProto> {
227  public:
~HttpNetworkTransactionTest()228   virtual ~HttpNetworkTransactionTest() {
229     // Important to restore the per-pool limit first, since the pool limit must
230     // always be greater than group limit, and the tests reduce both limits.
231     ClientSocketPoolManager::set_max_sockets_per_pool(
232         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
233     ClientSocketPoolManager::set_max_sockets_per_group(
234         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
235   }
236 
237  protected:
HttpNetworkTransactionTest()238   HttpNetworkTransactionTest()
239       : spdy_util_(GetParam()),
240         session_deps_(GetParam()),
241         old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
242             HttpNetworkSession::NORMAL_SOCKET_POOL)),
243         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
244             HttpNetworkSession::NORMAL_SOCKET_POOL)) {
245   }
246 
247   struct SimpleGetHelperResult {
248     int rv;
249     std::string status_line;
250     std::string response_data;
251     int64 totalReceivedBytes;
252     LoadTimingInfo load_timing_info;
253   };
254 
SetUp()255   virtual void SetUp() {
256     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
257     base::MessageLoop::current()->RunUntilIdle();
258   }
259 
TearDown()260   virtual void TearDown() {
261     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
262     base::MessageLoop::current()->RunUntilIdle();
263     // Empty the current queue.
264     base::MessageLoop::current()->RunUntilIdle();
265     PlatformTest::TearDown();
266     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
267     base::MessageLoop::current()->RunUntilIdle();
268   }
269 
270   // This is the expected return from a current server advertising SPDY.
GetAlternateProtocolHttpHeader()271   std::string GetAlternateProtocolHttpHeader() {
272     return
273         std::string("Alternate-Protocol: 443:") +
274         AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
275         "\r\n\r\n";
276   }
277 
278   // Either |write_failure| specifies a write failure or |read_failure|
279   // specifies a read failure when using a reused socket.  In either case, the
280   // failure should cause the network transaction to resend the request, and the
281   // other argument should be NULL.
282   void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
283                                             const MockRead* read_failure);
284 
285   // Either |write_failure| specifies a write failure or |read_failure|
286   // specifies a read failure when using a reused socket.  In either case, the
287   // failure should cause the network transaction to resend the request, and the
288   // other argument should be NULL.
289   void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
290                                         const MockRead* read_failure,
291                                         bool use_spdy);
292 
SimpleGetHelperForData(StaticSocketDataProvider * data[],size_t data_count)293   SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
294                                                size_t data_count) {
295     SimpleGetHelperResult out;
296 
297     HttpRequestInfo request;
298     request.method = "GET";
299     request.url = GURL("http://www.google.com/");
300     request.load_flags = 0;
301 
302     CapturingBoundNetLog log;
303     session_deps_.net_log = log.bound().net_log();
304     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
305     scoped_ptr<HttpTransaction> trans(
306         new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
307 
308     for (size_t i = 0; i < data_count; ++i) {
309       session_deps_.socket_factory->AddSocketDataProvider(data[i]);
310     }
311 
312     TestCompletionCallback callback;
313 
314     EXPECT_TRUE(log.bound().IsLogging());
315     int rv = trans->Start(&request, callback.callback(), log.bound());
316     EXPECT_EQ(ERR_IO_PENDING, rv);
317 
318     out.rv = callback.WaitForResult();
319 
320     // Even in the failure cases that use this function, connections are always
321     // successfully established before the error.
322     EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
323     TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
324 
325     if (out.rv != OK)
326       return out;
327 
328     const HttpResponseInfo* response = trans->GetResponseInfo();
329     // Can't use ASSERT_* inside helper functions like this, so
330     // return an error.
331     if (response == NULL || response->headers.get() == NULL) {
332       out.rv = ERR_UNEXPECTED;
333       return out;
334     }
335     out.status_line = response->headers->GetStatusLine();
336 
337     EXPECT_EQ("127.0.0.1", response->socket_address.host());
338     EXPECT_EQ(80, response->socket_address.port());
339 
340     rv = ReadTransaction(trans.get(), &out.response_data);
341     EXPECT_EQ(OK, rv);
342 
343     net::CapturingNetLog::CapturedEntryList entries;
344     log.GetEntries(&entries);
345     size_t pos = ExpectLogContainsSomewhere(
346         entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
347         NetLog::PHASE_NONE);
348     ExpectLogContainsSomewhere(
349         entries, pos,
350         NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
351         NetLog::PHASE_NONE);
352 
353     std::string line;
354     EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
355     EXPECT_EQ("GET / HTTP/1.1\r\n", line);
356 
357     HttpRequestHeaders request_headers;
358     EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
359     std::string value;
360     EXPECT_TRUE(request_headers.GetHeader("Host", &value));
361     EXPECT_EQ("www.google.com", value);
362     EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
363     EXPECT_EQ("keep-alive", value);
364 
365     std::string response_headers;
366     EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
367     EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
368               response_headers);
369 
370     out.totalReceivedBytes = trans->GetTotalReceivedBytes();
371     return out;
372   }
373 
SimpleGetHelper(MockRead data_reads[],size_t reads_count)374   SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
375                                         size_t reads_count) {
376     StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
377     StaticSocketDataProvider* data[] = { &reads };
378     return SimpleGetHelperForData(data, 1);
379   }
380 
ReadsSize(MockRead data_reads[],size_t reads_count)381   int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
382     int64 size = 0;
383     for (size_t i = 0; i < reads_count; ++i)
384       size += data_reads[i].data_len;
385     return size;
386   }
387 
388   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
389                                              int expected_status);
390 
391   void ConnectStatusHelper(const MockRead& status);
392 
393   void BypassHostCacheOnRefreshHelper(int load_flags);
394 
395   void CheckErrorIsPassedBack(int error, IoMode mode);
396 
397   SpdyTestUtil spdy_util_;
398   SpdySessionDependencies session_deps_;
399 
400   // Original socket limits.  Some tests set these.  Safest to always restore
401   // them once each test has been run.
402   int old_max_group_sockets_;
403   int old_max_pool_sockets_;
404 };
405 
406 INSTANTIATE_TEST_CASE_P(
407     NextProto,
408     HttpNetworkTransactionTest,
409     testing::Values(kProtoDeprecatedSPDY2,
410                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
411 
412 namespace {
413 
414 class BeforeNetworkStartHandler {
415  public:
BeforeNetworkStartHandler(bool defer)416   explicit BeforeNetworkStartHandler(bool defer)
417       : defer_on_before_network_start_(defer),
418         observed_before_network_start_(false) {}
419 
OnBeforeNetworkStart(bool * defer)420   void OnBeforeNetworkStart(bool* defer) {
421     *defer = defer_on_before_network_start_;
422     observed_before_network_start_ = true;
423   }
424 
observed_before_network_start() const425   bool observed_before_network_start() const {
426     return observed_before_network_start_;
427   }
428 
429  private:
430   const bool defer_on_before_network_start_;
431   bool observed_before_network_start_;
432 
433   DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
434 };
435 
436 // Fill |str| with a long header list that consumes >= |size| bytes.
FillLargeHeadersString(std::string * str,int size)437 void FillLargeHeadersString(std::string* str, int size) {
438   const char* row =
439       "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
440   const int sizeof_row = strlen(row);
441   const int num_rows = static_cast<int>(
442       ceil(static_cast<float>(size) / sizeof_row));
443   const int sizeof_data = num_rows * sizeof_row;
444   DCHECK(sizeof_data >= size);
445   str->reserve(sizeof_data);
446 
447   for (int i = 0; i < num_rows; ++i)
448     str->append(row, sizeof_row);
449 }
450 
451 // Alternative functions that eliminate randomness and dependency on the local
452 // host name so that the generated NTLM messages are reproducible.
MockGenerateRandom1(uint8 * output,size_t n)453 void MockGenerateRandom1(uint8* output, size_t n) {
454   static const uint8 bytes[] = {
455     0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
456   };
457   static size_t current_byte = 0;
458   for (size_t i = 0; i < n; ++i) {
459     output[i] = bytes[current_byte++];
460     current_byte %= arraysize(bytes);
461   }
462 }
463 
MockGenerateRandom2(uint8 * output,size_t n)464 void MockGenerateRandom2(uint8* output, size_t n) {
465   static const uint8 bytes[] = {
466     0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
467     0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
468   };
469   static size_t current_byte = 0;
470   for (size_t i = 0; i < n; ++i) {
471     output[i] = bytes[current_byte++];
472     current_byte %= arraysize(bytes);
473   }
474 }
475 
MockGetHostName()476 std::string MockGetHostName() {
477   return "WTC-WIN7";
478 }
479 
480 template<typename ParentPool>
481 class CaptureGroupNameSocketPool : public ParentPool {
482  public:
483   CaptureGroupNameSocketPool(HostResolver* host_resolver,
484                              CertVerifier* cert_verifier);
485 
last_group_name_received() const486   const std::string last_group_name_received() const {
487     return last_group_name_;
488   }
489 
RequestSocket(const std::string & group_name,const void * socket_params,RequestPriority priority,ClientSocketHandle * handle,const CompletionCallback & callback,const BoundNetLog & net_log)490   virtual int RequestSocket(const std::string& group_name,
491                             const void* socket_params,
492                             RequestPriority priority,
493                             ClientSocketHandle* handle,
494                             const CompletionCallback& callback,
495                             const BoundNetLog& net_log) {
496     last_group_name_ = group_name;
497     return ERR_IO_PENDING;
498   }
CancelRequest(const std::string & group_name,ClientSocketHandle * handle)499   virtual void CancelRequest(const std::string& group_name,
500                              ClientSocketHandle* handle) {}
ReleaseSocket(const std::string & group_name,scoped_ptr<StreamSocket> socket,int id)501   virtual void ReleaseSocket(const std::string& group_name,
502                              scoped_ptr<StreamSocket> socket,
503                              int id) {}
CloseIdleSockets()504   virtual void CloseIdleSockets() {}
IdleSocketCount() const505   virtual int IdleSocketCount() const {
506     return 0;
507   }
IdleSocketCountInGroup(const std::string & group_name) const508   virtual int IdleSocketCountInGroup(const std::string& group_name) const {
509     return 0;
510   }
GetLoadState(const std::string & group_name,const ClientSocketHandle * handle) const511   virtual LoadState GetLoadState(const std::string& group_name,
512                                  const ClientSocketHandle* handle) const {
513     return LOAD_STATE_IDLE;
514   }
ConnectionTimeout() const515   virtual base::TimeDelta ConnectionTimeout() const {
516     return base::TimeDelta();
517   }
518 
519  private:
520   std::string last_group_name_;
521 };
522 
523 typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
524 CaptureGroupNameTransportSocketPool;
525 typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
526 CaptureGroupNameHttpProxySocketPool;
527 typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
528 CaptureGroupNameSOCKSSocketPool;
529 typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
530 CaptureGroupNameSSLSocketPool;
531 
532 template<typename ParentPool>
CaptureGroupNameSocketPool(HostResolver * host_resolver,CertVerifier *)533 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
534     HostResolver* host_resolver,
535     CertVerifier* /* cert_verifier */)
536     : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
537 
538 template<>
CaptureGroupNameSocketPool(HostResolver * host_resolver,CertVerifier *)539 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
540     HostResolver* host_resolver,
541     CertVerifier* /* cert_verifier */)
542     : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
543 
544 template <>
CaptureGroupNameSocketPool(HostResolver * host_resolver,CertVerifier * cert_verifier)545 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
546     HostResolver* host_resolver,
547     CertVerifier* cert_verifier)
548     : SSLClientSocketPool(0,
549                           0,
550                           NULL,
551                           host_resolver,
552                           cert_verifier,
553                           NULL,
554                           NULL,
555                           NULL,
556                           std::string(),
557                           NULL,
558                           NULL,
559                           NULL,
560                           NULL,
561                           NULL,
562                           NULL) {}
563 
564 //-----------------------------------------------------------------------------
565 
566 // Helper functions for validating that AuthChallengeInfo's are correctly
567 // configured for common cases.
CheckBasicServerAuth(const AuthChallengeInfo * auth_challenge)568 bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
569   if (!auth_challenge)
570     return false;
571   EXPECT_FALSE(auth_challenge->is_proxy);
572   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
573   EXPECT_EQ("MyRealm1", auth_challenge->realm);
574   EXPECT_EQ("basic", auth_challenge->scheme);
575   return true;
576 }
577 
CheckBasicProxyAuth(const AuthChallengeInfo * auth_challenge)578 bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
579   if (!auth_challenge)
580     return false;
581   EXPECT_TRUE(auth_challenge->is_proxy);
582   EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
583   EXPECT_EQ("MyRealm1", auth_challenge->realm);
584   EXPECT_EQ("basic", auth_challenge->scheme);
585   return true;
586 }
587 
CheckDigestServerAuth(const AuthChallengeInfo * auth_challenge)588 bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
589   if (!auth_challenge)
590     return false;
591   EXPECT_FALSE(auth_challenge->is_proxy);
592   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
593   EXPECT_EQ("digestive", auth_challenge->realm);
594   EXPECT_EQ("digest", auth_challenge->scheme);
595   return true;
596 }
597 
CheckNTLMServerAuth(const AuthChallengeInfo * auth_challenge)598 bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
599   if (!auth_challenge)
600     return false;
601   EXPECT_FALSE(auth_challenge->is_proxy);
602   EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
603   EXPECT_EQ(std::string(), auth_challenge->realm);
604   EXPECT_EQ("ntlm", auth_challenge->scheme);
605   return true;
606 }
607 
608 }  // namespace
609 
TEST_P(HttpNetworkTransactionTest,Basic)610 TEST_P(HttpNetworkTransactionTest, Basic) {
611   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
612   scoped_ptr<HttpTransaction> trans(
613       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
614 }
615 
TEST_P(HttpNetworkTransactionTest,SimpleGET)616 TEST_P(HttpNetworkTransactionTest, SimpleGET) {
617   MockRead data_reads[] = {
618     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
619     MockRead("hello world"),
620     MockRead(SYNCHRONOUS, OK),
621   };
622   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
623                                               arraysize(data_reads));
624   EXPECT_EQ(OK, out.rv);
625   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
626   EXPECT_EQ("hello world", out.response_data);
627   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
628   EXPECT_EQ(reads_size, out.totalReceivedBytes);
629 }
630 
631 // Response with no status line.
TEST_P(HttpNetworkTransactionTest,SimpleGETNoHeaders)632 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
633   MockRead data_reads[] = {
634     MockRead("hello world"),
635     MockRead(SYNCHRONOUS, OK),
636   };
637   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
638                                               arraysize(data_reads));
639   EXPECT_EQ(OK, out.rv);
640   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
641   EXPECT_EQ("hello world", out.response_data);
642   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
643   EXPECT_EQ(reads_size, out.totalReceivedBytes);
644 }
645 
646 // Allow up to 4 bytes of junk to precede status line.
TEST_P(HttpNetworkTransactionTest,StatusLineJunk3Bytes)647 TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
648   MockRead data_reads[] = {
649     MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
650     MockRead(SYNCHRONOUS, OK),
651   };
652   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
653                                               arraysize(data_reads));
654   EXPECT_EQ(OK, out.rv);
655   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
656   EXPECT_EQ("DATA", out.response_data);
657   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
658   EXPECT_EQ(reads_size, out.totalReceivedBytes);
659 }
660 
661 // Allow up to 4 bytes of junk to precede status line.
TEST_P(HttpNetworkTransactionTest,StatusLineJunk4Bytes)662 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
663   MockRead data_reads[] = {
664     MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
665     MockRead(SYNCHRONOUS, OK),
666   };
667   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
668                                               arraysize(data_reads));
669   EXPECT_EQ(OK, out.rv);
670   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
671   EXPECT_EQ("DATA", out.response_data);
672   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
673   EXPECT_EQ(reads_size, out.totalReceivedBytes);
674 }
675 
676 // Beyond 4 bytes of slop and it should fail to find a status line.
TEST_P(HttpNetworkTransactionTest,StatusLineJunk5Bytes)677 TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
678   MockRead data_reads[] = {
679     MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
680     MockRead(SYNCHRONOUS, OK),
681   };
682   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
683                                               arraysize(data_reads));
684   EXPECT_EQ(OK, out.rv);
685   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
686   EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
687   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
688   EXPECT_EQ(reads_size, out.totalReceivedBytes);
689 }
690 
691 // Same as StatusLineJunk4Bytes, except the read chunks are smaller.
TEST_P(HttpNetworkTransactionTest,StatusLineJunk4Bytes_Slow)692 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
693   MockRead data_reads[] = {
694     MockRead("\n"),
695     MockRead("\n"),
696     MockRead("Q"),
697     MockRead("J"),
698     MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
699     MockRead(SYNCHRONOUS, OK),
700   };
701   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
702                                               arraysize(data_reads));
703   EXPECT_EQ(OK, out.rv);
704   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
705   EXPECT_EQ("DATA", out.response_data);
706   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
707   EXPECT_EQ(reads_size, out.totalReceivedBytes);
708 }
709 
710 // Close the connection before enough bytes to have a status line.
TEST_P(HttpNetworkTransactionTest,StatusLinePartial)711 TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
712   MockRead data_reads[] = {
713     MockRead("HTT"),
714     MockRead(SYNCHRONOUS, OK),
715   };
716   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
717                                               arraysize(data_reads));
718   EXPECT_EQ(OK, out.rv);
719   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
720   EXPECT_EQ("HTT", out.response_data);
721   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
722   EXPECT_EQ(reads_size, out.totalReceivedBytes);
723 }
724 
725 // Simulate a 204 response, lacking a Content-Length header, sent over a
726 // persistent connection.  The response should still terminate since a 204
727 // cannot have a response body.
TEST_P(HttpNetworkTransactionTest,StopsReading204)728 TEST_P(HttpNetworkTransactionTest, StopsReading204) {
729   char junk[] = "junk";
730   MockRead data_reads[] = {
731     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
732     MockRead(junk),  // Should not be read!!
733     MockRead(SYNCHRONOUS, OK),
734   };
735   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
736                                               arraysize(data_reads));
737   EXPECT_EQ(OK, out.rv);
738   EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
739   EXPECT_EQ("", out.response_data);
740   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
741   int64 response_size = reads_size - strlen(junk);
742   EXPECT_EQ(response_size, out.totalReceivedBytes);
743 }
744 
745 // A simple request using chunked encoding with some extra data after.
TEST_P(HttpNetworkTransactionTest,ChunkedEncoding)746 TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
747   std::string final_chunk = "0\r\n\r\n";
748   std::string extra_data = "HTTP/1.1 200 OK\r\n";
749   std::string last_read = final_chunk + extra_data;
750   MockRead data_reads[] = {
751     MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
752     MockRead("5\r\nHello\r\n"),
753     MockRead("1\r\n"),
754     MockRead(" \r\n"),
755     MockRead("5\r\nworld\r\n"),
756     MockRead(last_read.data()),
757     MockRead(SYNCHRONOUS, OK),
758   };
759   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
760                                               arraysize(data_reads));
761   EXPECT_EQ(OK, out.rv);
762   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
763   EXPECT_EQ("Hello world", out.response_data);
764   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
765   int64 response_size = reads_size - extra_data.size();
766   EXPECT_EQ(response_size, out.totalReceivedBytes);
767 }
768 
769 // Next tests deal with http://crbug.com/56344.
770 
TEST_P(HttpNetworkTransactionTest,MultipleContentLengthHeadersNoTransferEncoding)771 TEST_P(HttpNetworkTransactionTest,
772        MultipleContentLengthHeadersNoTransferEncoding) {
773   MockRead data_reads[] = {
774     MockRead("HTTP/1.1 200 OK\r\n"),
775     MockRead("Content-Length: 10\r\n"),
776     MockRead("Content-Length: 5\r\n\r\n"),
777   };
778   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
779                                               arraysize(data_reads));
780   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
781 }
782 
TEST_P(HttpNetworkTransactionTest,DuplicateContentLengthHeadersNoTransferEncoding)783 TEST_P(HttpNetworkTransactionTest,
784        DuplicateContentLengthHeadersNoTransferEncoding) {
785   MockRead data_reads[] = {
786     MockRead("HTTP/1.1 200 OK\r\n"),
787     MockRead("Content-Length: 5\r\n"),
788     MockRead("Content-Length: 5\r\n\r\n"),
789     MockRead("Hello"),
790   };
791   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
792                                               arraysize(data_reads));
793   EXPECT_EQ(OK, out.rv);
794   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
795   EXPECT_EQ("Hello", out.response_data);
796 }
797 
TEST_P(HttpNetworkTransactionTest,ComplexContentLengthHeadersNoTransferEncoding)798 TEST_P(HttpNetworkTransactionTest,
799        ComplexContentLengthHeadersNoTransferEncoding) {
800   // More than 2 dupes.
801   {
802     MockRead data_reads[] = {
803       MockRead("HTTP/1.1 200 OK\r\n"),
804       MockRead("Content-Length: 5\r\n"),
805       MockRead("Content-Length: 5\r\n"),
806       MockRead("Content-Length: 5\r\n\r\n"),
807       MockRead("Hello"),
808     };
809     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
810                                                 arraysize(data_reads));
811     EXPECT_EQ(OK, out.rv);
812     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
813     EXPECT_EQ("Hello", out.response_data);
814   }
815   // HTTP/1.0
816   {
817     MockRead data_reads[] = {
818       MockRead("HTTP/1.0 200 OK\r\n"),
819       MockRead("Content-Length: 5\r\n"),
820       MockRead("Content-Length: 5\r\n"),
821       MockRead("Content-Length: 5\r\n\r\n"),
822       MockRead("Hello"),
823     };
824     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
825                                                 arraysize(data_reads));
826     EXPECT_EQ(OK, out.rv);
827     EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
828     EXPECT_EQ("Hello", out.response_data);
829   }
830   // 2 dupes and one mismatched.
831   {
832     MockRead data_reads[] = {
833       MockRead("HTTP/1.1 200 OK\r\n"),
834       MockRead("Content-Length: 10\r\n"),
835       MockRead("Content-Length: 10\r\n"),
836       MockRead("Content-Length: 5\r\n\r\n"),
837     };
838     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
839                                                 arraysize(data_reads));
840     EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
841   }
842 }
843 
TEST_P(HttpNetworkTransactionTest,MultipleContentLengthHeadersTransferEncoding)844 TEST_P(HttpNetworkTransactionTest,
845        MultipleContentLengthHeadersTransferEncoding) {
846   MockRead data_reads[] = {
847     MockRead("HTTP/1.1 200 OK\r\n"),
848     MockRead("Content-Length: 666\r\n"),
849     MockRead("Content-Length: 1337\r\n"),
850     MockRead("Transfer-Encoding: chunked\r\n\r\n"),
851     MockRead("5\r\nHello\r\n"),
852     MockRead("1\r\n"),
853     MockRead(" \r\n"),
854     MockRead("5\r\nworld\r\n"),
855     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
856     MockRead(SYNCHRONOUS, OK),
857   };
858   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
859                                               arraysize(data_reads));
860   EXPECT_EQ(OK, out.rv);
861   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
862   EXPECT_EQ("Hello world", out.response_data);
863 }
864 
865 // Next tests deal with http://crbug.com/98895.
866 
867 // Checks that a single Content-Disposition header results in no error.
TEST_P(HttpNetworkTransactionTest,SingleContentDispositionHeader)868 TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
869   MockRead data_reads[] = {
870     MockRead("HTTP/1.1 200 OK\r\n"),
871     MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
872     MockRead("Content-Length: 5\r\n\r\n"),
873     MockRead("Hello"),
874   };
875   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
876                                               arraysize(data_reads));
877   EXPECT_EQ(OK, out.rv);
878   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
879   EXPECT_EQ("Hello", out.response_data);
880 }
881 
882 // Checks that two identical Content-Disposition headers result in no error.
TEST_P(HttpNetworkTransactionTest,TwoIdenticalContentDispositionHeaders)883 TEST_P(HttpNetworkTransactionTest,
884        TwoIdenticalContentDispositionHeaders) {
885   MockRead data_reads[] = {
886     MockRead("HTTP/1.1 200 OK\r\n"),
887     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
888     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
889     MockRead("Content-Length: 5\r\n\r\n"),
890     MockRead("Hello"),
891   };
892   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
893                                               arraysize(data_reads));
894   EXPECT_EQ(OK, out.rv);
895   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
896   EXPECT_EQ("Hello", out.response_data);
897 }
898 
899 // Checks that two distinct Content-Disposition headers result in an error.
TEST_P(HttpNetworkTransactionTest,TwoDistinctContentDispositionHeaders)900 TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
901   MockRead data_reads[] = {
902     MockRead("HTTP/1.1 200 OK\r\n"),
903     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
904     MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
905     MockRead("Content-Length: 5\r\n\r\n"),
906     MockRead("Hello"),
907   };
908   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
909                                               arraysize(data_reads));
910   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
911 }
912 
913 // Checks that two identical Location headers result in no error.
914 // Also tests Location header behavior.
TEST_P(HttpNetworkTransactionTest,TwoIdenticalLocationHeaders)915 TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
916   MockRead data_reads[] = {
917     MockRead("HTTP/1.1 302 Redirect\r\n"),
918     MockRead("Location: http://good.com/\r\n"),
919     MockRead("Location: http://good.com/\r\n"),
920     MockRead("Content-Length: 0\r\n\r\n"),
921     MockRead(SYNCHRONOUS, OK),
922   };
923 
924   HttpRequestInfo request;
925   request.method = "GET";
926   request.url = GURL("http://redirect.com/");
927   request.load_flags = 0;
928 
929   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
930   scoped_ptr<HttpTransaction> trans(
931       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
932 
933   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
934   session_deps_.socket_factory->AddSocketDataProvider(&data);
935 
936   TestCompletionCallback callback;
937 
938   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
939   EXPECT_EQ(ERR_IO_PENDING, rv);
940 
941   EXPECT_EQ(OK, callback.WaitForResult());
942 
943   const HttpResponseInfo* response = trans->GetResponseInfo();
944   ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
945   EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
946   std::string url;
947   EXPECT_TRUE(response->headers->IsRedirect(&url));
948   EXPECT_EQ("http://good.com/", url);
949   EXPECT_TRUE(response->proxy_server.IsEmpty());
950 }
951 
952 // Checks that two distinct Location headers result in an error.
TEST_P(HttpNetworkTransactionTest,TwoDistinctLocationHeaders)953 TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
954   MockRead data_reads[] = {
955     MockRead("HTTP/1.1 302 Redirect\r\n"),
956     MockRead("Location: http://good.com/\r\n"),
957     MockRead("Location: http://evil.com/\r\n"),
958     MockRead("Content-Length: 0\r\n\r\n"),
959     MockRead(SYNCHRONOUS, OK),
960   };
961   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
962                                               arraysize(data_reads));
963   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
964 }
965 
966 // Do a request using the HEAD method. Verify that we don't try to read the
967 // message body (since HEAD has none).
TEST_P(HttpNetworkTransactionTest,Head)968 TEST_P(HttpNetworkTransactionTest, Head) {
969   HttpRequestInfo request;
970   request.method = "HEAD";
971   request.url = GURL("http://www.google.com/");
972   request.load_flags = 0;
973 
974   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
975   scoped_ptr<HttpTransaction> trans(
976       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
977 
978   MockWrite data_writes1[] = {
979     MockWrite("HEAD / HTTP/1.1\r\n"
980               "Host: www.google.com\r\n"
981               "Connection: keep-alive\r\n"
982               "Content-Length: 0\r\n\r\n"),
983   };
984   MockRead data_reads1[] = {
985     MockRead("HTTP/1.1 404 Not Found\r\n"),
986     MockRead("Server: Blah\r\n"),
987     MockRead("Content-Length: 1234\r\n\r\n"),
988 
989     // No response body because the test stops reading here.
990     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
991   };
992 
993   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
994                                  data_writes1, arraysize(data_writes1));
995   session_deps_.socket_factory->AddSocketDataProvider(&data1);
996 
997   TestCompletionCallback callback1;
998 
999   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
1000   EXPECT_EQ(ERR_IO_PENDING, rv);
1001 
1002   rv = callback1.WaitForResult();
1003   EXPECT_EQ(OK, rv);
1004 
1005   const HttpResponseInfo* response = trans->GetResponseInfo();
1006   ASSERT_TRUE(response != NULL);
1007 
1008   // Check that the headers got parsed.
1009   EXPECT_TRUE(response->headers.get() != NULL);
1010   EXPECT_EQ(1234, response->headers->GetContentLength());
1011   EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
1012   EXPECT_TRUE(response->proxy_server.IsEmpty());
1013 
1014   std::string server_header;
1015   void* iter = NULL;
1016   bool has_server_header = response->headers->EnumerateHeader(
1017       &iter, "Server", &server_header);
1018   EXPECT_TRUE(has_server_header);
1019   EXPECT_EQ("Blah", server_header);
1020 
1021   // Reading should give EOF right away, since there is no message body
1022   // (despite non-zero content-length).
1023   std::string response_data;
1024   rv = ReadTransaction(trans.get(), &response_data);
1025   EXPECT_EQ(OK, rv);
1026   EXPECT_EQ("", response_data);
1027 }
1028 
TEST_P(HttpNetworkTransactionTest,ReuseConnection)1029 TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
1030   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1031 
1032   MockRead data_reads[] = {
1033     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1034     MockRead("hello"),
1035     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1036     MockRead("world"),
1037     MockRead(SYNCHRONOUS, OK),
1038   };
1039   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1040   session_deps_.socket_factory->AddSocketDataProvider(&data);
1041 
1042   const char* const kExpectedResponseData[] = {
1043     "hello", "world"
1044   };
1045 
1046   for (int i = 0; i < 2; ++i) {
1047     HttpRequestInfo request;
1048     request.method = "GET";
1049     request.url = GURL("http://www.google.com/");
1050     request.load_flags = 0;
1051 
1052     scoped_ptr<HttpTransaction> trans(
1053         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1054 
1055     TestCompletionCallback callback;
1056 
1057     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1058     EXPECT_EQ(ERR_IO_PENDING, rv);
1059 
1060     rv = callback.WaitForResult();
1061     EXPECT_EQ(OK, rv);
1062 
1063     const HttpResponseInfo* response = trans->GetResponseInfo();
1064     ASSERT_TRUE(response != NULL);
1065 
1066     EXPECT_TRUE(response->headers.get() != NULL);
1067     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1068     EXPECT_TRUE(response->proxy_server.IsEmpty());
1069 
1070     std::string response_data;
1071     rv = ReadTransaction(trans.get(), &response_data);
1072     EXPECT_EQ(OK, rv);
1073     EXPECT_EQ(kExpectedResponseData[i], response_data);
1074   }
1075 }
1076 
TEST_P(HttpNetworkTransactionTest,Ignores100)1077 TEST_P(HttpNetworkTransactionTest, Ignores100) {
1078   ScopedVector<UploadElementReader> element_readers;
1079   element_readers.push_back(new UploadBytesElementReader("foo", 3));
1080   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
1081 
1082   HttpRequestInfo request;
1083   request.method = "POST";
1084   request.url = GURL("http://www.foo.com/");
1085   request.upload_data_stream = &upload_data_stream;
1086   request.load_flags = 0;
1087 
1088   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1089   scoped_ptr<HttpTransaction> trans(
1090       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1091 
1092   MockRead data_reads[] = {
1093     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1094     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1095     MockRead("hello world"),
1096     MockRead(SYNCHRONOUS, OK),
1097   };
1098   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1099   session_deps_.socket_factory->AddSocketDataProvider(&data);
1100 
1101   TestCompletionCallback callback;
1102 
1103   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1104   EXPECT_EQ(ERR_IO_PENDING, rv);
1105 
1106   rv = callback.WaitForResult();
1107   EXPECT_EQ(OK, rv);
1108 
1109   const HttpResponseInfo* response = trans->GetResponseInfo();
1110   ASSERT_TRUE(response != NULL);
1111 
1112   EXPECT_TRUE(response->headers.get() != NULL);
1113   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
1114 
1115   std::string response_data;
1116   rv = ReadTransaction(trans.get(), &response_data);
1117   EXPECT_EQ(OK, rv);
1118   EXPECT_EQ("hello world", response_data);
1119 }
1120 
1121 // This test is almost the same as Ignores100 above, but the response contains
1122 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
1123 // HTTP/1.1 and the two status headers are read in one read.
TEST_P(HttpNetworkTransactionTest,Ignores1xx)1124 TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
1125   HttpRequestInfo request;
1126   request.method = "GET";
1127   request.url = GURL("http://www.foo.com/");
1128   request.load_flags = 0;
1129 
1130   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1131   scoped_ptr<HttpTransaction> trans(
1132       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1133 
1134   MockRead data_reads[] = {
1135     MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1136              "HTTP/1.1 200 OK\r\n\r\n"),
1137     MockRead("hello world"),
1138     MockRead(SYNCHRONOUS, OK),
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(OK, rv);
1150 
1151   const HttpResponseInfo* response = trans->GetResponseInfo();
1152   ASSERT_TRUE(response != NULL);
1153 
1154   EXPECT_TRUE(response->headers.get() != NULL);
1155   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1156 
1157   std::string response_data;
1158   rv = ReadTransaction(trans.get(), &response_data);
1159   EXPECT_EQ(OK, rv);
1160   EXPECT_EQ("hello world", response_data);
1161 }
1162 
TEST_P(HttpNetworkTransactionTest,Incomplete100ThenEOF)1163 TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
1164   HttpRequestInfo request;
1165   request.method = "POST";
1166   request.url = GURL("http://www.foo.com/");
1167   request.load_flags = 0;
1168 
1169   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1170   scoped_ptr<HttpTransaction> trans(
1171       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1172 
1173   MockRead data_reads[] = {
1174     MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1175     MockRead(ASYNC, 0),
1176   };
1177   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1178   session_deps_.socket_factory->AddSocketDataProvider(&data);
1179 
1180   TestCompletionCallback callback;
1181 
1182   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1183   EXPECT_EQ(ERR_IO_PENDING, rv);
1184 
1185   rv = callback.WaitForResult();
1186   EXPECT_EQ(OK, rv);
1187 
1188   std::string response_data;
1189   rv = ReadTransaction(trans.get(), &response_data);
1190   EXPECT_EQ(OK, rv);
1191   EXPECT_EQ("", response_data);
1192 }
1193 
TEST_P(HttpNetworkTransactionTest,EmptyResponse)1194 TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
1195   HttpRequestInfo request;
1196   request.method = "POST";
1197   request.url = GURL("http://www.foo.com/");
1198   request.load_flags = 0;
1199 
1200   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1201   scoped_ptr<HttpTransaction> trans(
1202       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1203 
1204 
1205   MockRead data_reads[] = {
1206     MockRead(ASYNC, 0),
1207   };
1208   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1209   session_deps_.socket_factory->AddSocketDataProvider(&data);
1210 
1211   TestCompletionCallback callback;
1212 
1213   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1214   EXPECT_EQ(ERR_IO_PENDING, rv);
1215 
1216   rv = callback.WaitForResult();
1217   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1218 }
1219 
KeepAliveConnectionResendRequestTest(const MockWrite * write_failure,const MockRead * read_failure)1220 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
1221     const MockWrite* write_failure,
1222     const MockRead* read_failure) {
1223   HttpRequestInfo request;
1224   request.method = "GET";
1225   request.url = GURL("http://www.foo.com/");
1226   request.load_flags = 0;
1227 
1228   CapturingNetLog net_log;
1229   session_deps_.net_log = &net_log;
1230   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1231 
1232   // Written data for successfully sending both requests.
1233   MockWrite data1_writes[] = {
1234     MockWrite("GET / HTTP/1.1\r\n"
1235               "Host: www.foo.com\r\n"
1236               "Connection: keep-alive\r\n\r\n"),
1237     MockWrite("GET / HTTP/1.1\r\n"
1238               "Host: www.foo.com\r\n"
1239               "Connection: keep-alive\r\n\r\n")
1240   };
1241 
1242   // Read results for the first request.
1243   MockRead data1_reads[] = {
1244     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1245     MockRead("hello"),
1246     MockRead(ASYNC, OK),
1247   };
1248 
1249   if (write_failure) {
1250     ASSERT_FALSE(read_failure);
1251     data1_writes[1] = *write_failure;
1252   } else {
1253     ASSERT_TRUE(read_failure);
1254     data1_reads[2] = *read_failure;
1255   }
1256 
1257   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1258                                  data1_writes, arraysize(data1_writes));
1259   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1260 
1261   MockRead data2_reads[] = {
1262     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1263     MockRead("world"),
1264     MockRead(ASYNC, OK),
1265   };
1266   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1267   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1268 
1269   const char* kExpectedResponseData[] = {
1270     "hello", "world"
1271   };
1272 
1273   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
1274   for (int i = 0; i < 2; ++i) {
1275     TestCompletionCallback callback;
1276 
1277     scoped_ptr<HttpTransaction> trans(
1278         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1279 
1280     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1281     EXPECT_EQ(ERR_IO_PENDING, rv);
1282 
1283     rv = callback.WaitForResult();
1284     EXPECT_EQ(OK, rv);
1285 
1286     LoadTimingInfo load_timing_info;
1287     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1288     TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1289     if (i == 0) {
1290       first_socket_log_id = load_timing_info.socket_log_id;
1291     } else {
1292       // The second request should be using a new socket.
1293       EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1294     }
1295 
1296     const HttpResponseInfo* response = trans->GetResponseInfo();
1297     ASSERT_TRUE(response != NULL);
1298 
1299     EXPECT_TRUE(response->headers.get() != NULL);
1300     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1301 
1302     std::string response_data;
1303     rv = ReadTransaction(trans.get(), &response_data);
1304     EXPECT_EQ(OK, rv);
1305     EXPECT_EQ(kExpectedResponseData[i], response_data);
1306   }
1307 }
1308 
PreconnectErrorResendRequestTest(const MockWrite * write_failure,const MockRead * read_failure,bool use_spdy)1309 void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1310     const MockWrite* write_failure,
1311     const MockRead* read_failure,
1312     bool use_spdy) {
1313   HttpRequestInfo request;
1314   request.method = "GET";
1315   request.url = GURL("https://www.foo.com/");
1316   request.load_flags = 0;
1317 
1318   CapturingNetLog net_log;
1319   session_deps_.net_log = &net_log;
1320   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1321 
1322   SSLSocketDataProvider ssl1(ASYNC, OK);
1323   SSLSocketDataProvider ssl2(ASYNC, OK);
1324   if (use_spdy) {
1325     ssl1.SetNextProto(GetParam());
1326     ssl2.SetNextProto(GetParam());
1327   }
1328   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1329   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
1330 
1331   // SPDY versions of the request and response.
1332   scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1333       request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1334   scoped_ptr<SpdyFrame> spdy_response(
1335       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1336   scoped_ptr<SpdyFrame> spdy_data(
1337       spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
1338 
1339   // HTTP/1.1 versions of the request and response.
1340   const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1341       "Host: www.foo.com\r\n"
1342       "Connection: keep-alive\r\n\r\n";
1343   const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1344   const char kHttpData[] = "hello";
1345 
1346   std::vector<MockRead> data1_reads;
1347   std::vector<MockWrite> data1_writes;
1348   if (write_failure) {
1349     ASSERT_FALSE(read_failure);
1350     data1_writes.push_back(*write_failure);
1351     data1_reads.push_back(MockRead(ASYNC, OK));
1352   } else {
1353     ASSERT_TRUE(read_failure);
1354     if (use_spdy) {
1355       data1_writes.push_back(CreateMockWrite(*spdy_request));
1356     } else {
1357       data1_writes.push_back(MockWrite(kHttpRequest));
1358     }
1359     data1_reads.push_back(*read_failure);
1360   }
1361 
1362   StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1363                                  &data1_writes[0], data1_writes.size());
1364   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1365 
1366   std::vector<MockRead> data2_reads;
1367   std::vector<MockWrite> data2_writes;
1368 
1369   if (use_spdy) {
1370     data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1371 
1372     data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1373     data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1374     data2_reads.push_back(MockRead(ASYNC, OK, 3));
1375   } else {
1376     data2_writes.push_back(
1377         MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1378 
1379     data2_reads.push_back(
1380         MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1381     data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1382     data2_reads.push_back(MockRead(ASYNC, OK, 3));
1383   }
1384   OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1385                           &data2_writes[0], data2_writes.size());
1386   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1387 
1388   // Preconnect a socket.
1389   net::SSLConfig ssl_config;
1390   session->ssl_config_service()->GetSSLConfig(&ssl_config);
1391   session->GetNextProtos(&ssl_config.next_protos);
1392   session->http_stream_factory()->PreconnectStreams(
1393       1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1394   // Wait for the preconnect to complete.
1395   // TODO(davidben): Some way to wait for an idle socket count might be handy.
1396   base::RunLoop().RunUntilIdle();
1397   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
1398 
1399   // Make the request.
1400   TestCompletionCallback callback;
1401 
1402   scoped_ptr<HttpTransaction> trans(
1403       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1404 
1405   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1406   EXPECT_EQ(ERR_IO_PENDING, rv);
1407 
1408   rv = callback.WaitForResult();
1409   EXPECT_EQ(OK, rv);
1410 
1411   LoadTimingInfo load_timing_info;
1412   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1413   TestLoadTimingNotReused(
1414       load_timing_info,
1415       CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
1416 
1417   const HttpResponseInfo* response = trans->GetResponseInfo();
1418   ASSERT_TRUE(response != NULL);
1419 
1420   EXPECT_TRUE(response->headers.get() != NULL);
1421   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1422 
1423   std::string response_data;
1424   rv = ReadTransaction(trans.get(), &response_data);
1425   EXPECT_EQ(OK, rv);
1426   EXPECT_EQ(kHttpData, response_data);
1427 }
1428 
TEST_P(HttpNetworkTransactionTest,KeepAliveConnectionNotConnectedOnWrite)1429 TEST_P(HttpNetworkTransactionTest,
1430        KeepAliveConnectionNotConnectedOnWrite) {
1431   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1432   KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1433 }
1434 
TEST_P(HttpNetworkTransactionTest,KeepAliveConnectionReset)1435 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
1436   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1437   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1438 }
1439 
TEST_P(HttpNetworkTransactionTest,KeepAliveConnectionEOF)1440 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
1441   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1442   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1443 }
1444 
1445 // Make sure that on a 408 response (Request Timeout), the request is retried,
1446 // if the socket was a reused keep alive socket.
TEST_P(HttpNetworkTransactionTest,KeepAlive408)1447 TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1448   MockRead read_failure(SYNCHRONOUS,
1449                         "HTTP/1.1 408 Request Timeout\r\n"
1450                         "Connection: Keep-Alive\r\n"
1451                         "Content-Length: 6\r\n\r\n"
1452                         "Pickle");
1453   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1454 }
1455 
TEST_P(HttpNetworkTransactionTest,PreconnectErrorNotConnectedOnWrite)1456 TEST_P(HttpNetworkTransactionTest,
1457        PreconnectErrorNotConnectedOnWrite) {
1458   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1459   PreconnectErrorResendRequestTest(&write_failure, NULL, false);
1460 }
1461 
TEST_P(HttpNetworkTransactionTest,PreconnectErrorReset)1462 TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1463   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1464   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1465 }
1466 
TEST_P(HttpNetworkTransactionTest,PreconnectErrorEOF)1467 TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1468   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1469   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1470 }
1471 
TEST_P(HttpNetworkTransactionTest,PreconnectErrorAsyncEOF)1472 TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1473   MockRead read_failure(ASYNC, OK);  // EOF
1474   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1475 }
1476 
1477 // Make sure that on a 408 response (Request Timeout), the request is retried,
1478 // if the socket was a preconnected (UNUSED_IDLE) socket.
TEST_P(HttpNetworkTransactionTest,RetryOnIdle408)1479 TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1480   MockRead read_failure(SYNCHRONOUS,
1481                         "HTTP/1.1 408 Request Timeout\r\n"
1482                         "Connection: Keep-Alive\r\n"
1483                         "Content-Length: 6\r\n\r\n"
1484                         "Pickle");
1485   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1486   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1487 }
1488 
TEST_P(HttpNetworkTransactionTest,SpdyPreconnectErrorNotConnectedOnWrite)1489 TEST_P(HttpNetworkTransactionTest,
1490        SpdyPreconnectErrorNotConnectedOnWrite) {
1491   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1492   PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1493 }
1494 
TEST_P(HttpNetworkTransactionTest,SpdyPreconnectErrorReset)1495 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1496   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1497   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1498 }
1499 
TEST_P(HttpNetworkTransactionTest,SpdyPreconnectErrorEOF)1500 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1501   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1502   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1503 }
1504 
TEST_P(HttpNetworkTransactionTest,SpdyPreconnectErrorAsyncEOF)1505 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1506   MockRead read_failure(ASYNC, OK);  // EOF
1507   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1508 }
1509 
TEST_P(HttpNetworkTransactionTest,NonKeepAliveConnectionReset)1510 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
1511   HttpRequestInfo request;
1512   request.method = "GET";
1513   request.url = GURL("http://www.google.com/");
1514   request.load_flags = 0;
1515 
1516   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1517   scoped_ptr<HttpTransaction> trans(
1518       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1519 
1520   MockRead data_reads[] = {
1521     MockRead(ASYNC, ERR_CONNECTION_RESET),
1522     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
1523     MockRead("hello world"),
1524     MockRead(SYNCHRONOUS, OK),
1525   };
1526   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1527   session_deps_.socket_factory->AddSocketDataProvider(&data);
1528 
1529   TestCompletionCallback callback;
1530 
1531   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1532   EXPECT_EQ(ERR_IO_PENDING, rv);
1533 
1534   rv = callback.WaitForResult();
1535   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1536 
1537   const HttpResponseInfo* response = trans->GetResponseInfo();
1538   EXPECT_TRUE(response == NULL);
1539 }
1540 
1541 // What do various browsers do when the server closes a non-keepalive
1542 // connection without sending any response header or body?
1543 //
1544 // IE7: error page
1545 // Safari 3.1.2 (Windows): error page
1546 // Firefox 3.0.1: blank page
1547 // Opera 9.52: after five attempts, blank page
1548 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1549 // Us: error page (EMPTY_RESPONSE)
TEST_P(HttpNetworkTransactionTest,NonKeepAliveConnectionEOF)1550 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
1551   MockRead data_reads[] = {
1552     MockRead(SYNCHRONOUS, OK),  // EOF
1553     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
1554     MockRead("hello world"),
1555     MockRead(SYNCHRONOUS, OK),
1556   };
1557   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1558                                               arraysize(data_reads));
1559   EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
1560 }
1561 
1562 // Test that network access can be deferred and resumed.
TEST_P(HttpNetworkTransactionTest,ThrottleBeforeNetworkStart)1563 TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1564   HttpRequestInfo request;
1565   request.method = "GET";
1566   request.url = GURL("http://www.google.com/");
1567   request.load_flags = 0;
1568 
1569   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1570   scoped_ptr<HttpTransaction> trans(
1571       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1572 
1573   // Defer on OnBeforeNetworkStart.
1574   BeforeNetworkStartHandler net_start_handler(true);  // defer
1575   trans->SetBeforeNetworkStartCallback(
1576       base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1577                  base::Unretained(&net_start_handler)));
1578 
1579   MockRead data_reads[] = {
1580     MockRead("HTTP/1.0 200 OK\r\n"),
1581     MockRead("Content-Length: 5\r\n\r\n"),
1582     MockRead("hello"),
1583     MockRead(SYNCHRONOUS, 0),
1584   };
1585   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1586   session_deps_.socket_factory->AddSocketDataProvider(&data);
1587 
1588   TestCompletionCallback callback;
1589 
1590   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1591   EXPECT_EQ(ERR_IO_PENDING, rv);
1592   base::MessageLoop::current()->RunUntilIdle();
1593 
1594   // Should have deferred for network start.
1595   EXPECT_TRUE(net_start_handler.observed_before_network_start());
1596   EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1597   EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1598 
1599   trans->ResumeNetworkStart();
1600   rv = callback.WaitForResult();
1601   EXPECT_EQ(OK, rv);
1602   EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1603 
1604   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1605   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1606   if (rv == ERR_IO_PENDING)
1607     rv = callback.WaitForResult();
1608   EXPECT_EQ(5, rv);
1609   trans.reset();
1610 }
1611 
1612 // Test that network use can be deferred and canceled.
TEST_P(HttpNetworkTransactionTest,ThrottleAndCancelBeforeNetworkStart)1613 TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1614   HttpRequestInfo request;
1615   request.method = "GET";
1616   request.url = GURL("http://www.google.com/");
1617   request.load_flags = 0;
1618 
1619   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1620   scoped_ptr<HttpTransaction> trans(
1621       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1622 
1623   // Defer on OnBeforeNetworkStart.
1624   BeforeNetworkStartHandler net_start_handler(true);  // defer
1625   trans->SetBeforeNetworkStartCallback(
1626       base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1627                  base::Unretained(&net_start_handler)));
1628 
1629   TestCompletionCallback callback;
1630 
1631   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1632   EXPECT_EQ(ERR_IO_PENDING, rv);
1633   base::MessageLoop::current()->RunUntilIdle();
1634 
1635   // Should have deferred for network start.
1636   EXPECT_TRUE(net_start_handler.observed_before_network_start());
1637   EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1638   EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1639 }
1640 
1641 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1642 // tests. There was a bug causing HttpNetworkTransaction to hang in the
1643 // destructor in such situations.
1644 // See http://crbug.com/154712 and http://crbug.com/156609.
TEST_P(HttpNetworkTransactionTest,KeepAliveEarlyClose)1645 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
1646   HttpRequestInfo request;
1647   request.method = "GET";
1648   request.url = GURL("http://www.google.com/");
1649   request.load_flags = 0;
1650 
1651   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1652   scoped_ptr<HttpTransaction> trans(
1653       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1654 
1655   MockRead data_reads[] = {
1656     MockRead("HTTP/1.0 200 OK\r\n"),
1657     MockRead("Connection: keep-alive\r\n"),
1658     MockRead("Content-Length: 100\r\n\r\n"),
1659     MockRead("hello"),
1660     MockRead(SYNCHRONOUS, 0),
1661   };
1662   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1663   session_deps_.socket_factory->AddSocketDataProvider(&data);
1664 
1665   TestCompletionCallback callback;
1666 
1667   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1668   EXPECT_EQ(ERR_IO_PENDING, rv);
1669 
1670   rv = callback.WaitForResult();
1671   EXPECT_EQ(OK, rv);
1672 
1673   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1674   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1675   if (rv == ERR_IO_PENDING)
1676     rv = callback.WaitForResult();
1677   EXPECT_EQ(5, rv);
1678   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1679   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1680 
1681   trans.reset();
1682   base::MessageLoop::current()->RunUntilIdle();
1683   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1684 }
1685 
TEST_P(HttpNetworkTransactionTest,KeepAliveEarlyClose2)1686 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
1687   HttpRequestInfo request;
1688   request.method = "GET";
1689   request.url = GURL("http://www.google.com/");
1690   request.load_flags = 0;
1691 
1692   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1693   scoped_ptr<HttpTransaction> trans(
1694       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1695 
1696   MockRead data_reads[] = {
1697     MockRead("HTTP/1.0 200 OK\r\n"),
1698     MockRead("Connection: keep-alive\r\n"),
1699     MockRead("Content-Length: 100\r\n\r\n"),
1700     MockRead(SYNCHRONOUS, 0),
1701   };
1702   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1703   session_deps_.socket_factory->AddSocketDataProvider(&data);
1704 
1705   TestCompletionCallback callback;
1706 
1707   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1708   EXPECT_EQ(ERR_IO_PENDING, rv);
1709 
1710   rv = callback.WaitForResult();
1711   EXPECT_EQ(OK, rv);
1712 
1713   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1714   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1715   if (rv == ERR_IO_PENDING)
1716     rv = callback.WaitForResult();
1717   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1718 
1719   trans.reset();
1720   base::MessageLoop::current()->RunUntilIdle();
1721   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1722 }
1723 
1724 // Test that we correctly reuse a keep-alive connection after not explicitly
1725 // reading the body.
TEST_P(HttpNetworkTransactionTest,KeepAliveAfterUnreadBody)1726 TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
1727   HttpRequestInfo request;
1728   request.method = "GET";
1729   request.url = GURL("http://www.foo.com/");
1730   request.load_flags = 0;
1731 
1732   CapturingNetLog net_log;
1733   session_deps_.net_log = &net_log;
1734   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1735 
1736   // Note that because all these reads happen in the same
1737   // StaticSocketDataProvider, it shows that the same socket is being reused for
1738   // all transactions.
1739   MockRead data1_reads[] = {
1740     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1741     MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
1742     MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
1743     MockRead("HTTP/1.1 302 Found\r\n"
1744              "Content-Length: 0\r\n\r\n"),
1745     MockRead("HTTP/1.1 302 Found\r\n"
1746              "Content-Length: 5\r\n\r\n"
1747              "hello"),
1748     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1749              "Content-Length: 0\r\n\r\n"),
1750     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1751              "Content-Length: 5\r\n\r\n"
1752              "hello"),
1753     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1754     MockRead("hello"),
1755   };
1756   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
1757   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1758 
1759   MockRead data2_reads[] = {
1760     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
1761   };
1762   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1763   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1764 
1765   const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1766   std::string response_lines[kNumUnreadBodies];
1767 
1768   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
1769   for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
1770     TestCompletionCallback callback;
1771 
1772     scoped_ptr<HttpTransaction> trans(
1773         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1774 
1775     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1776     EXPECT_EQ(ERR_IO_PENDING, rv);
1777 
1778     rv = callback.WaitForResult();
1779     EXPECT_EQ(OK, rv);
1780 
1781     LoadTimingInfo load_timing_info;
1782     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1783     if (i == 0) {
1784       TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1785       first_socket_log_id = load_timing_info.socket_log_id;
1786     } else {
1787       TestLoadTimingReused(load_timing_info);
1788       EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1789     }
1790 
1791     const HttpResponseInfo* response = trans->GetResponseInfo();
1792     ASSERT_TRUE(response != NULL);
1793 
1794     ASSERT_TRUE(response->headers.get() != NULL);
1795     response_lines[i] = response->headers->GetStatusLine();
1796 
1797     // We intentionally don't read the response bodies.
1798   }
1799 
1800   const char* const kStatusLines[] = {
1801     "HTTP/1.1 204 No Content",
1802     "HTTP/1.1 205 Reset Content",
1803     "HTTP/1.1 304 Not Modified",
1804     "HTTP/1.1 302 Found",
1805     "HTTP/1.1 302 Found",
1806     "HTTP/1.1 301 Moved Permanently",
1807     "HTTP/1.1 301 Moved Permanently",
1808   };
1809 
1810   COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1811                  forgot_to_update_kStatusLines);
1812 
1813   for (int i = 0; i < kNumUnreadBodies; ++i)
1814     EXPECT_EQ(kStatusLines[i], response_lines[i]);
1815 
1816   TestCompletionCallback callback;
1817   scoped_ptr<HttpTransaction> trans(
1818       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1819   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1820   EXPECT_EQ(ERR_IO_PENDING, rv);
1821   rv = callback.WaitForResult();
1822   EXPECT_EQ(OK, rv);
1823   const HttpResponseInfo* response = trans->GetResponseInfo();
1824   ASSERT_TRUE(response != NULL);
1825   ASSERT_TRUE(response->headers.get() != NULL);
1826   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1827   std::string response_data;
1828   rv = ReadTransaction(trans.get(), &response_data);
1829   EXPECT_EQ(OK, rv);
1830   EXPECT_EQ("hello", response_data);
1831 }
1832 
1833 // Test the request-challenge-retry sequence for basic auth.
1834 // (basic auth is the easiest to mock, because it has no randomness).
TEST_P(HttpNetworkTransactionTest,BasicAuth)1835 TEST_P(HttpNetworkTransactionTest, BasicAuth) {
1836   HttpRequestInfo request;
1837   request.method = "GET";
1838   request.url = GURL("http://www.google.com/");
1839   request.load_flags = 0;
1840 
1841   CapturingNetLog log;
1842   session_deps_.net_log = &log;
1843   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1844   scoped_ptr<HttpTransaction> trans(
1845       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1846 
1847   MockWrite data_writes1[] = {
1848     MockWrite("GET / HTTP/1.1\r\n"
1849               "Host: www.google.com\r\n"
1850               "Connection: keep-alive\r\n\r\n"),
1851   };
1852 
1853   MockRead data_reads1[] = {
1854     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1855     // Give a couple authenticate options (only the middle one is actually
1856     // supported).
1857     MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
1858     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1859     MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1860     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1861     // Large content-length -- won't matter, as connection will be reset.
1862     MockRead("Content-Length: 10000\r\n\r\n"),
1863     MockRead(SYNCHRONOUS, ERR_FAILED),
1864   };
1865 
1866   // After calling trans->RestartWithAuth(), this is the request we should
1867   // be issuing -- the final header line contains the credentials.
1868   MockWrite data_writes2[] = {
1869     MockWrite("GET / HTTP/1.1\r\n"
1870               "Host: www.google.com\r\n"
1871               "Connection: keep-alive\r\n"
1872               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1873   };
1874 
1875   // Lastly, the server responds with the actual content.
1876   MockRead data_reads2[] = {
1877     MockRead("HTTP/1.0 200 OK\r\n"),
1878     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1879     MockRead("Content-Length: 100\r\n\r\n"),
1880     MockRead(SYNCHRONOUS, OK),
1881   };
1882 
1883   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1884                                  data_writes1, arraysize(data_writes1));
1885   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1886                                  data_writes2, arraysize(data_writes2));
1887   session_deps_.socket_factory->AddSocketDataProvider(&data1);
1888   session_deps_.socket_factory->AddSocketDataProvider(&data2);
1889 
1890   TestCompletionCallback callback1;
1891 
1892   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
1893   EXPECT_EQ(ERR_IO_PENDING, rv);
1894 
1895   rv = callback1.WaitForResult();
1896   EXPECT_EQ(OK, rv);
1897 
1898   LoadTimingInfo load_timing_info1;
1899   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1900   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1901 
1902   int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1903   EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1904 
1905   const HttpResponseInfo* response = trans->GetResponseInfo();
1906   ASSERT_TRUE(response != NULL);
1907   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
1908 
1909   TestCompletionCallback callback2;
1910 
1911   rv = trans->RestartWithAuth(
1912       AuthCredentials(kFoo, kBar), callback2.callback());
1913   EXPECT_EQ(ERR_IO_PENDING, rv);
1914 
1915   rv = callback2.WaitForResult();
1916   EXPECT_EQ(OK, rv);
1917 
1918   LoadTimingInfo load_timing_info2;
1919   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1920   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1921   // The load timing after restart should have a new socket ID, and times after
1922   // those of the first load timing.
1923   EXPECT_LE(load_timing_info1.receive_headers_end,
1924             load_timing_info2.connect_timing.connect_start);
1925   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1926 
1927   int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1928   EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1929 
1930   response = trans->GetResponseInfo();
1931   ASSERT_TRUE(response != NULL);
1932   EXPECT_TRUE(response->auth_challenge.get() == NULL);
1933   EXPECT_EQ(100, response->headers->GetContentLength());
1934 }
1935 
TEST_P(HttpNetworkTransactionTest,DoNotSendAuth)1936 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
1937   HttpRequestInfo request;
1938   request.method = "GET";
1939   request.url = GURL("http://www.google.com/");
1940   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1941 
1942   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1943   scoped_ptr<HttpTransaction> trans(
1944       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1945 
1946   MockWrite data_writes[] = {
1947     MockWrite("GET / HTTP/1.1\r\n"
1948               "Host: www.google.com\r\n"
1949               "Connection: keep-alive\r\n\r\n"),
1950   };
1951 
1952   MockRead data_reads[] = {
1953     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1954     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1955     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1956     // Large content-length -- won't matter, as connection will be reset.
1957     MockRead("Content-Length: 10000\r\n\r\n"),
1958     MockRead(SYNCHRONOUS, ERR_FAILED),
1959   };
1960 
1961   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1962                                 data_writes, arraysize(data_writes));
1963   session_deps_.socket_factory->AddSocketDataProvider(&data);
1964   TestCompletionCallback callback;
1965 
1966   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1967   EXPECT_EQ(ERR_IO_PENDING, rv);
1968 
1969   rv = callback.WaitForResult();
1970   EXPECT_EQ(0, rv);
1971 
1972   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
1973   EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
1974 
1975   const HttpResponseInfo* response = trans->GetResponseInfo();
1976   ASSERT_TRUE(response != NULL);
1977   EXPECT_TRUE(response->auth_challenge.get() == NULL);
1978 }
1979 
1980 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
1981 // connection.
TEST_P(HttpNetworkTransactionTest,BasicAuthKeepAlive)1982 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
1983   HttpRequestInfo request;
1984   request.method = "GET";
1985   request.url = GURL("http://www.google.com/");
1986   request.load_flags = 0;
1987 
1988   CapturingNetLog log;
1989   session_deps_.net_log = &log;
1990   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1991 
1992   MockWrite data_writes1[] = {
1993     MockWrite("GET / HTTP/1.1\r\n"
1994               "Host: www.google.com\r\n"
1995               "Connection: keep-alive\r\n\r\n"),
1996 
1997     // After calling trans->RestartWithAuth(), this is the request we should
1998     // be issuing -- the final header line contains the credentials.
1999     MockWrite("GET / HTTP/1.1\r\n"
2000               "Host: www.google.com\r\n"
2001               "Connection: keep-alive\r\n"
2002               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2003   };
2004 
2005   MockRead data_reads1[] = {
2006     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2007     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2008     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2009     MockRead("Content-Length: 14\r\n\r\n"),
2010     MockRead("Unauthorized\r\n"),
2011 
2012     // Lastly, the server responds with the actual content.
2013     MockRead("HTTP/1.1 200 OK\r\n"),
2014     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2015     MockRead("Content-Length: 5\r\n\r\n"),
2016     MockRead("Hello"),
2017   };
2018 
2019   // If there is a regression where we disconnect a Keep-Alive
2020   // connection during an auth roundtrip, we'll end up reading this.
2021   MockRead data_reads2[] = {
2022     MockRead(SYNCHRONOUS, ERR_FAILED),
2023   };
2024 
2025   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2026                                  data_writes1, arraysize(data_writes1));
2027   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2028                                  NULL, 0);
2029   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2030   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2031 
2032   TestCompletionCallback callback1;
2033 
2034   scoped_ptr<HttpTransaction> trans(
2035       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2036   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2037   EXPECT_EQ(ERR_IO_PENDING, rv);
2038 
2039   rv = callback1.WaitForResult();
2040   EXPECT_EQ(OK, rv);
2041 
2042   LoadTimingInfo load_timing_info1;
2043   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2044   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2045 
2046   const HttpResponseInfo* response = trans->GetResponseInfo();
2047   ASSERT_TRUE(response != NULL);
2048   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2049 
2050   TestCompletionCallback callback2;
2051 
2052   rv = trans->RestartWithAuth(
2053       AuthCredentials(kFoo, kBar), callback2.callback());
2054   EXPECT_EQ(ERR_IO_PENDING, rv);
2055 
2056   rv = callback2.WaitForResult();
2057   EXPECT_EQ(OK, rv);
2058 
2059   LoadTimingInfo load_timing_info2;
2060   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2061   TestLoadTimingReused(load_timing_info2);
2062   // The load timing after restart should have the same socket ID, and times
2063   // those of the first load timing.
2064   EXPECT_LE(load_timing_info1.receive_headers_end,
2065             load_timing_info2.send_start);
2066   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2067 
2068   response = trans->GetResponseInfo();
2069   ASSERT_TRUE(response != NULL);
2070   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2071   EXPECT_EQ(5, response->headers->GetContentLength());
2072 
2073   std::string response_data;
2074   rv = ReadTransaction(trans.get(), &response_data);
2075   EXPECT_EQ(OK, rv);
2076   int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2077   EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2078 }
2079 
2080 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2081 // connection and with no response body to drain.
TEST_P(HttpNetworkTransactionTest,BasicAuthKeepAliveNoBody)2082 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
2083   HttpRequestInfo request;
2084   request.method = "GET";
2085   request.url = GURL("http://www.google.com/");
2086   request.load_flags = 0;
2087 
2088   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2089 
2090   MockWrite data_writes1[] = {
2091     MockWrite("GET / HTTP/1.1\r\n"
2092               "Host: www.google.com\r\n"
2093               "Connection: keep-alive\r\n\r\n"),
2094 
2095     // After calling trans->RestartWithAuth(), this is the request we should
2096     // be issuing -- the final header line contains the credentials.
2097     MockWrite("GET / HTTP/1.1\r\n"
2098               "Host: www.google.com\r\n"
2099               "Connection: keep-alive\r\n"
2100               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2101   };
2102 
2103   MockRead data_reads1[] = {
2104     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2105     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2106     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
2107 
2108     // Lastly, the server responds with the actual content.
2109     MockRead("HTTP/1.1 200 OK\r\n"),
2110     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2111     MockRead("Content-Length: 5\r\n\r\n"),
2112     MockRead("hello"),
2113   };
2114 
2115   // An incorrect reconnect would cause this to be read.
2116   MockRead data_reads2[] = {
2117     MockRead(SYNCHRONOUS, ERR_FAILED),
2118   };
2119 
2120   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2121                                  data_writes1, arraysize(data_writes1));
2122   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2123                                  NULL, 0);
2124   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2125   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2126 
2127   TestCompletionCallback callback1;
2128 
2129   scoped_ptr<HttpTransaction> trans(
2130       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2131   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2132   EXPECT_EQ(ERR_IO_PENDING, rv);
2133 
2134   rv = callback1.WaitForResult();
2135   EXPECT_EQ(OK, rv);
2136 
2137   const HttpResponseInfo* response = trans->GetResponseInfo();
2138   ASSERT_TRUE(response != NULL);
2139   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2140 
2141   TestCompletionCallback callback2;
2142 
2143   rv = trans->RestartWithAuth(
2144       AuthCredentials(kFoo, kBar), callback2.callback());
2145   EXPECT_EQ(ERR_IO_PENDING, rv);
2146 
2147   rv = callback2.WaitForResult();
2148   EXPECT_EQ(OK, rv);
2149 
2150   response = trans->GetResponseInfo();
2151   ASSERT_TRUE(response != NULL);
2152   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2153   EXPECT_EQ(5, response->headers->GetContentLength());
2154 }
2155 
2156 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2157 // connection and with a large response body to drain.
TEST_P(HttpNetworkTransactionTest,BasicAuthKeepAliveLargeBody)2158 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
2159   HttpRequestInfo request;
2160   request.method = "GET";
2161   request.url = GURL("http://www.google.com/");
2162   request.load_flags = 0;
2163 
2164   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2165 
2166   MockWrite data_writes1[] = {
2167     MockWrite("GET / HTTP/1.1\r\n"
2168               "Host: www.google.com\r\n"
2169               "Connection: keep-alive\r\n\r\n"),
2170 
2171     // After calling trans->RestartWithAuth(), this is the request we should
2172     // be issuing -- the final header line contains the credentials.
2173     MockWrite("GET / HTTP/1.1\r\n"
2174               "Host: www.google.com\r\n"
2175               "Connection: keep-alive\r\n"
2176               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2177   };
2178 
2179   // Respond with 5 kb of response body.
2180   std::string large_body_string("Unauthorized");
2181   large_body_string.append(5 * 1024, ' ');
2182   large_body_string.append("\r\n");
2183 
2184   MockRead data_reads1[] = {
2185     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2186     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2187     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2188     // 5134 = 12 + 5 * 1024 + 2
2189     MockRead("Content-Length: 5134\r\n\r\n"),
2190     MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
2191 
2192     // Lastly, the server responds with the actual content.
2193     MockRead("HTTP/1.1 200 OK\r\n"),
2194     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2195     MockRead("Content-Length: 5\r\n\r\n"),
2196     MockRead("hello"),
2197   };
2198 
2199   // An incorrect reconnect would cause this to be read.
2200   MockRead data_reads2[] = {
2201     MockRead(SYNCHRONOUS, ERR_FAILED),
2202   };
2203 
2204   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2205                                  data_writes1, arraysize(data_writes1));
2206   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2207                                  NULL, 0);
2208   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2209   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2210 
2211   TestCompletionCallback callback1;
2212 
2213   scoped_ptr<HttpTransaction> trans(
2214       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2215   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2216   EXPECT_EQ(ERR_IO_PENDING, rv);
2217 
2218   rv = callback1.WaitForResult();
2219   EXPECT_EQ(OK, rv);
2220 
2221   const HttpResponseInfo* response = trans->GetResponseInfo();
2222   ASSERT_TRUE(response != NULL);
2223   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2224 
2225   TestCompletionCallback callback2;
2226 
2227   rv = trans->RestartWithAuth(
2228       AuthCredentials(kFoo, kBar), callback2.callback());
2229   EXPECT_EQ(ERR_IO_PENDING, rv);
2230 
2231   rv = callback2.WaitForResult();
2232   EXPECT_EQ(OK, rv);
2233 
2234   response = trans->GetResponseInfo();
2235   ASSERT_TRUE(response != NULL);
2236   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2237   EXPECT_EQ(5, response->headers->GetContentLength());
2238 }
2239 
2240 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2241 // connection, but the server gets impatient and closes the connection.
TEST_P(HttpNetworkTransactionTest,BasicAuthKeepAliveImpatientServer)2242 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
2243   HttpRequestInfo request;
2244   request.method = "GET";
2245   request.url = GURL("http://www.google.com/");
2246   request.load_flags = 0;
2247 
2248   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2249 
2250   MockWrite data_writes1[] = {
2251     MockWrite("GET / HTTP/1.1\r\n"
2252               "Host: www.google.com\r\n"
2253               "Connection: keep-alive\r\n\r\n"),
2254     // This simulates the seemingly successful write to a closed connection
2255     // if the bug is not fixed.
2256     MockWrite("GET / HTTP/1.1\r\n"
2257               "Host: www.google.com\r\n"
2258               "Connection: keep-alive\r\n"
2259               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2260   };
2261 
2262   MockRead data_reads1[] = {
2263     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2264     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2265     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2266     MockRead("Content-Length: 14\r\n\r\n"),
2267     // Tell MockTCPClientSocket to simulate the server closing the connection.
2268     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2269     MockRead("Unauthorized\r\n"),
2270     MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
2271   };
2272 
2273   // After calling trans->RestartWithAuth(), this is the request we should
2274   // be issuing -- the final header line contains the credentials.
2275   MockWrite data_writes2[] = {
2276     MockWrite("GET / HTTP/1.1\r\n"
2277               "Host: www.google.com\r\n"
2278               "Connection: keep-alive\r\n"
2279               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2280   };
2281 
2282   // Lastly, the server responds with the actual content.
2283   MockRead data_reads2[] = {
2284     MockRead("HTTP/1.1 200 OK\r\n"),
2285     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2286     MockRead("Content-Length: 5\r\n\r\n"),
2287     MockRead("hello"),
2288   };
2289 
2290   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2291                                  data_writes1, arraysize(data_writes1));
2292   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2293                                  data_writes2, arraysize(data_writes2));
2294   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2295   session_deps_.socket_factory->AddSocketDataProvider(&data2);
2296 
2297   TestCompletionCallback callback1;
2298 
2299   scoped_ptr<HttpTransaction> trans(
2300       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2301   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2302   EXPECT_EQ(ERR_IO_PENDING, rv);
2303 
2304   rv = callback1.WaitForResult();
2305   EXPECT_EQ(OK, rv);
2306 
2307   const HttpResponseInfo* response = trans->GetResponseInfo();
2308   ASSERT_TRUE(response != NULL);
2309   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2310 
2311   TestCompletionCallback callback2;
2312 
2313   rv = trans->RestartWithAuth(
2314       AuthCredentials(kFoo, kBar), callback2.callback());
2315   EXPECT_EQ(ERR_IO_PENDING, rv);
2316 
2317   rv = callback2.WaitForResult();
2318   EXPECT_EQ(OK, rv);
2319 
2320   response = trans->GetResponseInfo();
2321   ASSERT_TRUE(response != NULL);
2322   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2323   EXPECT_EQ(5, response->headers->GetContentLength());
2324 }
2325 
2326 // Test the request-challenge-retry sequence for basic auth, over a connection
2327 // that requires a restart when setting up an SSL tunnel.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyNoKeepAlive)2328 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
2329   HttpRequestInfo request;
2330   request.method = "GET";
2331   request.url = GURL("https://www.google.com/");
2332   // when the no authentication data flag is set.
2333   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2334 
2335   // Configure against proxy server "myproxy:70".
2336   session_deps_.proxy_service.reset(
2337       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2338   CapturingBoundNetLog log;
2339   session_deps_.net_log = log.bound().net_log();
2340   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2341 
2342   // Since we have proxy, should try to establish tunnel.
2343   MockWrite data_writes1[] = {
2344     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2345               "Host: www.google.com\r\n"
2346               "Proxy-Connection: keep-alive\r\n\r\n"),
2347 
2348     // After calling trans->RestartWithAuth(), this is the request we should
2349     // be issuing -- the final header line contains the credentials.
2350     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2351               "Host: www.google.com\r\n"
2352               "Proxy-Connection: keep-alive\r\n"
2353               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2354 
2355     MockWrite("GET / HTTP/1.1\r\n"
2356               "Host: www.google.com\r\n"
2357               "Connection: keep-alive\r\n\r\n"),
2358   };
2359 
2360   // The proxy responds to the connect with a 407, using a persistent
2361   // connection.
2362   MockRead data_reads1[] = {
2363     // No credentials.
2364     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2365     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2366     MockRead("Proxy-Connection: close\r\n\r\n"),
2367 
2368     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2369 
2370     MockRead("HTTP/1.1 200 OK\r\n"),
2371     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2372     MockRead("Content-Length: 5\r\n\r\n"),
2373     MockRead(SYNCHRONOUS, "hello"),
2374   };
2375 
2376   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2377                                  data_writes1, arraysize(data_writes1));
2378   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2379   SSLSocketDataProvider ssl(ASYNC, OK);
2380   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2381 
2382   TestCompletionCallback callback1;
2383 
2384   scoped_ptr<HttpTransaction> trans(
2385       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2386 
2387   int rv = trans->Start(&request, callback1.callback(), log.bound());
2388   EXPECT_EQ(ERR_IO_PENDING, rv);
2389 
2390   rv = callback1.WaitForResult();
2391   EXPECT_EQ(OK, rv);
2392   net::CapturingNetLog::CapturedEntryList entries;
2393   log.GetEntries(&entries);
2394   size_t pos = ExpectLogContainsSomewhere(
2395       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2396       NetLog::PHASE_NONE);
2397   ExpectLogContainsSomewhere(
2398       entries, pos,
2399       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2400       NetLog::PHASE_NONE);
2401 
2402   const HttpResponseInfo* response = trans->GetResponseInfo();
2403   ASSERT_TRUE(response != NULL);
2404   ASSERT_FALSE(response->headers.get() == NULL);
2405   EXPECT_EQ(407, response->headers->response_code());
2406   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2407   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2408 
2409   LoadTimingInfo load_timing_info;
2410   // CONNECT requests and responses are handled at the connect job level, so
2411   // the transaction does not yet have a connection.
2412   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2413 
2414   TestCompletionCallback callback2;
2415 
2416   rv = trans->RestartWithAuth(
2417       AuthCredentials(kFoo, kBar), callback2.callback());
2418   EXPECT_EQ(ERR_IO_PENDING, rv);
2419 
2420   rv = callback2.WaitForResult();
2421   EXPECT_EQ(OK, rv);
2422 
2423   response = trans->GetResponseInfo();
2424   ASSERT_TRUE(response != NULL);
2425 
2426   EXPECT_TRUE(response->headers->IsKeepAlive());
2427   EXPECT_EQ(200, response->headers->response_code());
2428   EXPECT_EQ(5, response->headers->GetContentLength());
2429   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2430 
2431   // The password prompt info should not be set.
2432   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2433 
2434   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2435   TestLoadTimingNotReusedWithPac(load_timing_info,
2436                                  CONNECT_TIMING_HAS_SSL_TIMES);
2437 
2438   trans.reset();
2439   session->CloseAllConnections();
2440 }
2441 
2442 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
2443 // proxy connection, when setting up an SSL tunnel.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyKeepAlive)2444 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
2445   HttpRequestInfo request;
2446   request.method = "GET";
2447   request.url = GURL("https://www.google.com/");
2448   // Ensure that proxy authentication is attempted even
2449   // when the no authentication data flag is set.
2450   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2451 
2452   // Configure against proxy server "myproxy:70".
2453   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2454   CapturingBoundNetLog log;
2455   session_deps_.net_log = log.bound().net_log();
2456   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2457 
2458   scoped_ptr<HttpTransaction> trans(
2459       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2460 
2461   // Since we have proxy, should try to establish tunnel.
2462   MockWrite data_writes1[] = {
2463     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2464               "Host: www.google.com\r\n"
2465               "Proxy-Connection: keep-alive\r\n\r\n"),
2466 
2467     // After calling trans->RestartWithAuth(), this is the request we should
2468     // be issuing -- the final header line contains the credentials.
2469     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2470               "Host: www.google.com\r\n"
2471               "Proxy-Connection: keep-alive\r\n"
2472               "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2473   };
2474 
2475   // The proxy responds to the connect with a 407, using a persistent
2476   // connection.
2477   MockRead data_reads1[] = {
2478     // No credentials.
2479     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2480     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2481     MockRead("Content-Length: 10\r\n\r\n"),
2482     MockRead("0123456789"),
2483 
2484     // Wrong credentials (wrong password).
2485     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2486     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2487     MockRead("Content-Length: 10\r\n\r\n"),
2488     // No response body because the test stops reading here.
2489     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
2490   };
2491 
2492   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2493                                  data_writes1, arraysize(data_writes1));
2494   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2495 
2496   TestCompletionCallback callback1;
2497 
2498   int rv = trans->Start(&request, callback1.callback(), log.bound());
2499   EXPECT_EQ(ERR_IO_PENDING, rv);
2500 
2501   rv = callback1.WaitForResult();
2502   EXPECT_EQ(OK, rv);
2503   net::CapturingNetLog::CapturedEntryList entries;
2504   log.GetEntries(&entries);
2505   size_t pos = ExpectLogContainsSomewhere(
2506       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2507       NetLog::PHASE_NONE);
2508   ExpectLogContainsSomewhere(
2509       entries, pos,
2510       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2511       NetLog::PHASE_NONE);
2512 
2513   const HttpResponseInfo* response = trans->GetResponseInfo();
2514   ASSERT_TRUE(response != NULL);
2515   ASSERT_FALSE(response->headers.get() == NULL);
2516   EXPECT_TRUE(response->headers->IsKeepAlive());
2517   EXPECT_EQ(407, response->headers->response_code());
2518   EXPECT_EQ(10, response->headers->GetContentLength());
2519   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2520   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2521 
2522   TestCompletionCallback callback2;
2523 
2524   // Wrong password (should be "bar").
2525   rv = trans->RestartWithAuth(
2526       AuthCredentials(kFoo, kBaz), callback2.callback());
2527   EXPECT_EQ(ERR_IO_PENDING, rv);
2528 
2529   rv = callback2.WaitForResult();
2530   EXPECT_EQ(OK, rv);
2531 
2532   response = trans->GetResponseInfo();
2533   ASSERT_TRUE(response != NULL);
2534   ASSERT_FALSE(response->headers.get() == NULL);
2535   EXPECT_TRUE(response->headers->IsKeepAlive());
2536   EXPECT_EQ(407, response->headers->response_code());
2537   EXPECT_EQ(10, response->headers->GetContentLength());
2538   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2539   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2540 
2541   // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2542   // out of scope.
2543   session->CloseAllConnections();
2544 }
2545 
2546 // Test that we don't read the response body when we fail to establish a tunnel,
2547 // even if the user cancels the proxy's auth attempt.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyCancelTunnel)2548 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
2549   HttpRequestInfo request;
2550   request.method = "GET";
2551   request.url = GURL("https://www.google.com/");
2552   request.load_flags = 0;
2553 
2554   // Configure against proxy server "myproxy:70".
2555   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2556 
2557   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2558 
2559   scoped_ptr<HttpTransaction> trans(
2560       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2561 
2562   // Since we have proxy, should try to establish tunnel.
2563   MockWrite data_writes[] = {
2564     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2565               "Host: www.google.com\r\n"
2566               "Proxy-Connection: keep-alive\r\n\r\n"),
2567   };
2568 
2569   // The proxy responds to the connect with a 407.
2570   MockRead data_reads[] = {
2571     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2572     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2573     MockRead("Content-Length: 10\r\n\r\n"),
2574     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
2575   };
2576 
2577   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2578                                 data_writes, arraysize(data_writes));
2579   session_deps_.socket_factory->AddSocketDataProvider(&data);
2580 
2581   TestCompletionCallback callback;
2582 
2583   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2584   EXPECT_EQ(ERR_IO_PENDING, rv);
2585 
2586   rv = callback.WaitForResult();
2587   EXPECT_EQ(OK, rv);
2588 
2589   const HttpResponseInfo* response = trans->GetResponseInfo();
2590   ASSERT_TRUE(response != NULL);
2591 
2592   EXPECT_TRUE(response->headers->IsKeepAlive());
2593   EXPECT_EQ(407, response->headers->response_code());
2594   EXPECT_EQ(10, response->headers->GetContentLength());
2595   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2596 
2597   std::string response_data;
2598   rv = ReadTransaction(trans.get(), &response_data);
2599   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
2600 
2601   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
2602   session->CloseAllConnections();
2603 }
2604 
2605 // Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2606 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
TEST_P(HttpNetworkTransactionTest,UnexpectedProxyAuth)2607 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
2608   HttpRequestInfo request;
2609   request.method = "GET";
2610   request.url = GURL("http://www.google.com/");
2611   request.load_flags = 0;
2612 
2613   // We are using a DIRECT connection (i.e. no proxy) for this session.
2614   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2615   scoped_ptr<HttpTransaction> trans(
2616       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
2617 
2618   MockWrite data_writes1[] = {
2619     MockWrite("GET / HTTP/1.1\r\n"
2620               "Host: www.google.com\r\n"
2621               "Connection: keep-alive\r\n\r\n"),
2622   };
2623 
2624   MockRead data_reads1[] = {
2625     MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2626     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2627     // Large content-length -- won't matter, as connection will be reset.
2628     MockRead("Content-Length: 10000\r\n\r\n"),
2629     MockRead(SYNCHRONOUS, ERR_FAILED),
2630   };
2631 
2632   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2633                                  data_writes1, arraysize(data_writes1));
2634   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2635 
2636   TestCompletionCallback callback;
2637 
2638   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2639   EXPECT_EQ(ERR_IO_PENDING, rv);
2640 
2641   rv = callback.WaitForResult();
2642   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2643 }
2644 
2645 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2646 // through a non-authenticating proxy. The request should fail with
2647 // ERR_UNEXPECTED_PROXY_AUTH.
2648 // Note that it is impossible to detect if an HTTP server returns a 407 through
2649 // a non-authenticating proxy - there is nothing to indicate whether the
2650 // response came from the proxy or the server, so it is treated as if the proxy
2651 // issued the challenge.
TEST_P(HttpNetworkTransactionTest,HttpsServerRequestsProxyAuthThroughProxy)2652 TEST_P(HttpNetworkTransactionTest,
2653        HttpsServerRequestsProxyAuthThroughProxy) {
2654   HttpRequestInfo request;
2655   request.method = "GET";
2656   request.url = GURL("https://www.google.com/");
2657 
2658   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2659   CapturingBoundNetLog log;
2660   session_deps_.net_log = log.bound().net_log();
2661   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2662 
2663   // Since we have proxy, should try to establish tunnel.
2664   MockWrite data_writes1[] = {
2665     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2666               "Host: www.google.com\r\n"
2667               "Proxy-Connection: keep-alive\r\n\r\n"),
2668 
2669     MockWrite("GET / HTTP/1.1\r\n"
2670               "Host: www.google.com\r\n"
2671               "Connection: keep-alive\r\n\r\n"),
2672   };
2673 
2674   MockRead data_reads1[] = {
2675     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2676 
2677     MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2678     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2679     MockRead("\r\n"),
2680     MockRead(SYNCHRONOUS, OK),
2681   };
2682 
2683   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2684                                  data_writes1, arraysize(data_writes1));
2685   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2686   SSLSocketDataProvider ssl(ASYNC, OK);
2687   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2688 
2689   TestCompletionCallback callback1;
2690 
2691   scoped_ptr<HttpTransaction> trans(
2692       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2693 
2694   int rv = trans->Start(&request, callback1.callback(), log.bound());
2695   EXPECT_EQ(ERR_IO_PENDING, rv);
2696 
2697   rv = callback1.WaitForResult();
2698   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2699   net::CapturingNetLog::CapturedEntryList entries;
2700   log.GetEntries(&entries);
2701   size_t pos = ExpectLogContainsSomewhere(
2702       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2703       NetLog::PHASE_NONE);
2704   ExpectLogContainsSomewhere(
2705       entries, pos,
2706       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2707       NetLog::PHASE_NONE);
2708 }
2709 
2710 // Test the load timing for HTTPS requests with an HTTP proxy.
TEST_P(HttpNetworkTransactionTest,HttpProxyLoadTimingNoPacTwoRequests)2711 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
2712   HttpRequestInfo request1;
2713   request1.method = "GET";
2714   request1.url = GURL("https://www.google.com/1");
2715 
2716   HttpRequestInfo request2;
2717   request2.method = "GET";
2718   request2.url = GURL("https://www.google.com/2");
2719 
2720   // Configure against proxy server "myproxy:70".
2721   session_deps_.proxy_service.reset(
2722       ProxyService::CreateFixed("PROXY myproxy:70"));
2723   CapturingBoundNetLog log;
2724   session_deps_.net_log = log.bound().net_log();
2725   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2726 
2727   // Since we have proxy, should try to establish tunnel.
2728   MockWrite data_writes1[] = {
2729     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2730               "Host: www.google.com\r\n"
2731               "Proxy-Connection: keep-alive\r\n\r\n"),
2732 
2733     MockWrite("GET /1 HTTP/1.1\r\n"
2734               "Host: www.google.com\r\n"
2735               "Connection: keep-alive\r\n\r\n"),
2736 
2737     MockWrite("GET /2 HTTP/1.1\r\n"
2738               "Host: www.google.com\r\n"
2739               "Connection: keep-alive\r\n\r\n"),
2740   };
2741 
2742   // The proxy responds to the connect with a 407, using a persistent
2743   // connection.
2744   MockRead data_reads1[] = {
2745     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2746 
2747     MockRead("HTTP/1.1 200 OK\r\n"),
2748     MockRead("Content-Length: 1\r\n\r\n"),
2749     MockRead(SYNCHRONOUS, "1"),
2750 
2751     MockRead("HTTP/1.1 200 OK\r\n"),
2752     MockRead("Content-Length: 2\r\n\r\n"),
2753     MockRead(SYNCHRONOUS, "22"),
2754   };
2755 
2756   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2757                                  data_writes1, arraysize(data_writes1));
2758   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2759   SSLSocketDataProvider ssl(ASYNC, OK);
2760   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2761 
2762   TestCompletionCallback callback1;
2763   scoped_ptr<HttpTransaction> trans1(
2764       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2765 
2766   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2767   EXPECT_EQ(ERR_IO_PENDING, rv);
2768 
2769   rv = callback1.WaitForResult();
2770   EXPECT_EQ(OK, rv);
2771 
2772   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2773   ASSERT_TRUE(response1 != NULL);
2774   ASSERT_TRUE(response1->headers.get() != NULL);
2775   EXPECT_EQ(1, response1->headers->GetContentLength());
2776 
2777   LoadTimingInfo load_timing_info1;
2778   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2779   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2780 
2781   trans1.reset();
2782 
2783   TestCompletionCallback callback2;
2784   scoped_ptr<HttpTransaction> trans2(
2785       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2786 
2787   rv = trans2->Start(&request2, callback2.callback(), log.bound());
2788   EXPECT_EQ(ERR_IO_PENDING, rv);
2789 
2790   rv = callback2.WaitForResult();
2791   EXPECT_EQ(OK, rv);
2792 
2793   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2794   ASSERT_TRUE(response2 != NULL);
2795   ASSERT_TRUE(response2->headers.get() != NULL);
2796   EXPECT_EQ(2, response2->headers->GetContentLength());
2797 
2798   LoadTimingInfo load_timing_info2;
2799   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2800   TestLoadTimingReused(load_timing_info2);
2801 
2802   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2803 
2804   trans2.reset();
2805   session->CloseAllConnections();
2806 }
2807 
2808 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
TEST_P(HttpNetworkTransactionTest,HttpProxyLoadTimingWithPacTwoRequests)2809 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
2810   HttpRequestInfo request1;
2811   request1.method = "GET";
2812   request1.url = GURL("https://www.google.com/1");
2813 
2814   HttpRequestInfo request2;
2815   request2.method = "GET";
2816   request2.url = GURL("https://www.google.com/2");
2817 
2818   // Configure against proxy server "myproxy:70".
2819   session_deps_.proxy_service.reset(
2820       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2821   CapturingBoundNetLog log;
2822   session_deps_.net_log = log.bound().net_log();
2823   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2824 
2825   // Since we have proxy, should try to establish tunnel.
2826   MockWrite data_writes1[] = {
2827     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2828               "Host: www.google.com\r\n"
2829               "Proxy-Connection: keep-alive\r\n\r\n"),
2830 
2831     MockWrite("GET /1 HTTP/1.1\r\n"
2832               "Host: www.google.com\r\n"
2833               "Connection: keep-alive\r\n\r\n"),
2834 
2835     MockWrite("GET /2 HTTP/1.1\r\n"
2836               "Host: www.google.com\r\n"
2837               "Connection: keep-alive\r\n\r\n"),
2838   };
2839 
2840   // The proxy responds to the connect with a 407, using a persistent
2841   // connection.
2842   MockRead data_reads1[] = {
2843     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2844 
2845     MockRead("HTTP/1.1 200 OK\r\n"),
2846     MockRead("Content-Length: 1\r\n\r\n"),
2847     MockRead(SYNCHRONOUS, "1"),
2848 
2849     MockRead("HTTP/1.1 200 OK\r\n"),
2850     MockRead("Content-Length: 2\r\n\r\n"),
2851     MockRead(SYNCHRONOUS, "22"),
2852   };
2853 
2854   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2855                                  data_writes1, arraysize(data_writes1));
2856   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2857   SSLSocketDataProvider ssl(ASYNC, OK);
2858   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2859 
2860   TestCompletionCallback callback1;
2861   scoped_ptr<HttpTransaction> trans1(
2862       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2863 
2864   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2865   EXPECT_EQ(ERR_IO_PENDING, rv);
2866 
2867   rv = callback1.WaitForResult();
2868   EXPECT_EQ(OK, rv);
2869 
2870   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2871   ASSERT_TRUE(response1 != NULL);
2872   ASSERT_TRUE(response1->headers.get() != NULL);
2873   EXPECT_EQ(1, response1->headers->GetContentLength());
2874 
2875   LoadTimingInfo load_timing_info1;
2876   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2877   TestLoadTimingNotReusedWithPac(load_timing_info1,
2878                                  CONNECT_TIMING_HAS_SSL_TIMES);
2879 
2880   trans1.reset();
2881 
2882   TestCompletionCallback callback2;
2883   scoped_ptr<HttpTransaction> trans2(
2884       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2885 
2886   rv = trans2->Start(&request2, callback2.callback(), log.bound());
2887   EXPECT_EQ(ERR_IO_PENDING, rv);
2888 
2889   rv = callback2.WaitForResult();
2890   EXPECT_EQ(OK, rv);
2891 
2892   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2893   ASSERT_TRUE(response2 != NULL);
2894   ASSERT_TRUE(response2->headers.get() != NULL);
2895   EXPECT_EQ(2, response2->headers->GetContentLength());
2896 
2897   LoadTimingInfo load_timing_info2;
2898   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2899   TestLoadTimingReusedWithPac(load_timing_info2);
2900 
2901   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2902 
2903   trans2.reset();
2904   session->CloseAllConnections();
2905 }
2906 
2907 // Test a simple get through an HTTPS Proxy.
TEST_P(HttpNetworkTransactionTest,HttpsProxyGet)2908 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
2909   HttpRequestInfo request;
2910   request.method = "GET";
2911   request.url = GURL("http://www.google.com/");
2912 
2913   // Configure against https proxy server "proxy:70".
2914   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
2915       "https://proxy:70"));
2916   CapturingBoundNetLog log;
2917   session_deps_.net_log = log.bound().net_log();
2918   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2919 
2920   // Since we have proxy, should use full url
2921   MockWrite data_writes1[] = {
2922     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2923               "Host: www.google.com\r\n"
2924               "Proxy-Connection: keep-alive\r\n\r\n"),
2925   };
2926 
2927   MockRead data_reads1[] = {
2928     MockRead("HTTP/1.1 200 OK\r\n"),
2929     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2930     MockRead("Content-Length: 100\r\n\r\n"),
2931     MockRead(SYNCHRONOUS, OK),
2932   };
2933 
2934   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2935                                  data_writes1, arraysize(data_writes1));
2936   session_deps_.socket_factory->AddSocketDataProvider(&data1);
2937   SSLSocketDataProvider ssl(ASYNC, OK);
2938   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2939 
2940   TestCompletionCallback callback1;
2941 
2942   scoped_ptr<HttpTransaction> trans(
2943       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2944 
2945   int rv = trans->Start(&request, callback1.callback(), log.bound());
2946   EXPECT_EQ(ERR_IO_PENDING, rv);
2947 
2948   rv = callback1.WaitForResult();
2949   EXPECT_EQ(OK, rv);
2950 
2951   LoadTimingInfo load_timing_info;
2952   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2953   TestLoadTimingNotReused(load_timing_info,
2954                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2955 
2956   const HttpResponseInfo* response = trans->GetResponseInfo();
2957   ASSERT_TRUE(response != NULL);
2958 
2959   EXPECT_TRUE(response->headers->IsKeepAlive());
2960   EXPECT_EQ(200, response->headers->response_code());
2961   EXPECT_EQ(100, response->headers->GetContentLength());
2962   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2963 
2964   // The password prompt info should not be set.
2965   EXPECT_TRUE(response->auth_challenge.get() == NULL);
2966 }
2967 
2968 // Test a SPDY get through an HTTPS Proxy.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyGet)2969 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
2970   HttpRequestInfo request;
2971   request.method = "GET";
2972   request.url = GURL("http://www.google.com/");
2973   request.load_flags = 0;
2974 
2975   // Configure against https proxy server "proxy:70".
2976   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
2977       "https://proxy:70"));
2978   CapturingBoundNetLog log;
2979   session_deps_.net_log = log.bound().net_log();
2980   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2981 
2982   // fetch http://www.google.com/ via SPDY
2983   scoped_ptr<SpdyFrame> req(
2984       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
2985   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2986 
2987   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2988   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
2989   MockRead spdy_reads[] = {
2990     CreateMockRead(*resp),
2991     CreateMockRead(*data),
2992     MockRead(ASYNC, 0, 0),
2993   };
2994 
2995   DelayedSocketData spdy_data(
2996       1,  // wait for one write to finish before reading.
2997       spdy_reads, arraysize(spdy_reads),
2998       spdy_writes, arraysize(spdy_writes));
2999   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3000 
3001   SSLSocketDataProvider ssl(ASYNC, OK);
3002   ssl.SetNextProto(GetParam());
3003   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3004 
3005   TestCompletionCallback callback1;
3006 
3007   scoped_ptr<HttpTransaction> trans(
3008       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3009 
3010   int rv = trans->Start(&request, callback1.callback(), log.bound());
3011   EXPECT_EQ(ERR_IO_PENDING, rv);
3012 
3013   rv = callback1.WaitForResult();
3014   EXPECT_EQ(OK, rv);
3015 
3016   LoadTimingInfo load_timing_info;
3017   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3018   TestLoadTimingNotReused(load_timing_info,
3019                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3020 
3021   const HttpResponseInfo* response = trans->GetResponseInfo();
3022   ASSERT_TRUE(response != NULL);
3023   ASSERT_TRUE(response->headers.get() != NULL);
3024   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3025 
3026   std::string response_data;
3027   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3028   EXPECT_EQ(kUploadData, response_data);
3029 }
3030 
3031 // Verifies that a session which races and wins against the owning transaction
3032 // (completing prior to host resolution), doesn't fail the transaction.
3033 // Regression test for crbug.com/334413.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyGetWithSessionRace)3034 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3035   HttpRequestInfo request;
3036   request.method = "GET";
3037   request.url = GURL("http://www.google.com/");
3038   request.load_flags = 0;
3039 
3040   // Configure SPDY proxy server "proxy:70".
3041   session_deps_.proxy_service.reset(
3042       ProxyService::CreateFixed("https://proxy:70"));
3043   CapturingBoundNetLog log;
3044   session_deps_.net_log = log.bound().net_log();
3045   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3046 
3047   // Fetch http://www.google.com/ through the SPDY proxy.
3048   scoped_ptr<SpdyFrame> req(
3049       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3050   MockWrite spdy_writes[] = {CreateMockWrite(*req)};
3051 
3052   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3053   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3054   MockRead spdy_reads[] = {
3055       CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
3056   };
3057 
3058   DelayedSocketData spdy_data(
3059       1,  // wait for one write to finish before reading.
3060       spdy_reads,
3061       arraysize(spdy_reads),
3062       spdy_writes,
3063       arraysize(spdy_writes));
3064   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3065 
3066   SSLSocketDataProvider ssl(ASYNC, OK);
3067   ssl.SetNextProto(GetParam());
3068   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3069 
3070   TestCompletionCallback callback1;
3071 
3072   scoped_ptr<HttpTransaction> trans(
3073       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3074 
3075   // Stall the hostname resolution begun by the transaction.
3076   session_deps_.host_resolver->set_synchronous_mode(false);
3077   session_deps_.host_resolver->set_ondemand_mode(true);
3078 
3079   int rv = trans->Start(&request, callback1.callback(), log.bound());
3080   EXPECT_EQ(ERR_IO_PENDING, rv);
3081 
3082   // Race a session to the proxy, which completes first.
3083   session_deps_.host_resolver->set_ondemand_mode(false);
3084   SpdySessionKey key(
3085       HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3086   base::WeakPtr<SpdySession> spdy_session =
3087       CreateSecureSpdySession(session, key, log.bound());
3088 
3089   // Unstall the resolution begun by the transaction.
3090   session_deps_.host_resolver->set_ondemand_mode(true);
3091   session_deps_.host_resolver->ResolveAllPending();
3092 
3093   EXPECT_FALSE(callback1.have_result());
3094   rv = callback1.WaitForResult();
3095   EXPECT_EQ(OK, rv);
3096 
3097   const HttpResponseInfo* response = trans->GetResponseInfo();
3098   ASSERT_TRUE(response != NULL);
3099   ASSERT_TRUE(response->headers.get() != NULL);
3100   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3101 
3102   std::string response_data;
3103   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3104   EXPECT_EQ(kUploadData, response_data);
3105 }
3106 
3107 // Test a SPDY get through an HTTPS Proxy.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyGetWithProxyAuth)3108 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
3109   HttpRequestInfo request;
3110   request.method = "GET";
3111   request.url = GURL("http://www.google.com/");
3112   request.load_flags = 0;
3113 
3114   // Configure against https proxy server "myproxy:70".
3115   session_deps_.proxy_service.reset(
3116       ProxyService::CreateFixed("https://myproxy:70"));
3117   CapturingBoundNetLog log;
3118   session_deps_.net_log = log.bound().net_log();
3119   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3120 
3121   // The first request will be a bare GET, the second request will be a
3122   // GET with a Proxy-Authorization header.
3123   scoped_ptr<SpdyFrame> req_get(
3124       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3125   const char* const kExtraAuthorizationHeaders[] = {
3126     "proxy-authorization", "Basic Zm9vOmJhcg=="
3127   };
3128   scoped_ptr<SpdyFrame> req_get_authorization(
3129       spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3130                                   arraysize(kExtraAuthorizationHeaders) / 2,
3131                                   false,
3132                                   3,
3133                                   LOWEST,
3134                                   false));
3135   MockWrite spdy_writes[] = {
3136     CreateMockWrite(*req_get, 1),
3137     CreateMockWrite(*req_get_authorization, 4),
3138   };
3139 
3140   // The first response is a 407 proxy authentication challenge, and the second
3141   // response will be a 200 response since the second request includes a valid
3142   // Authorization header.
3143   const char* const kExtraAuthenticationHeaders[] = {
3144     "proxy-authenticate", "Basic realm=\"MyRealm1\""
3145   };
3146   scoped_ptr<SpdyFrame> resp_authentication(
3147       spdy_util_.ConstructSpdySynReplyError(
3148           "407 Proxy Authentication Required",
3149           kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3150           1));
3151   scoped_ptr<SpdyFrame> body_authentication(
3152       spdy_util_.ConstructSpdyBodyFrame(1, true));
3153   scoped_ptr<SpdyFrame> resp_data(
3154       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3155   scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
3156   MockRead spdy_reads[] = {
3157     CreateMockRead(*resp_authentication, 2),
3158     CreateMockRead(*body_authentication, 3),
3159     CreateMockRead(*resp_data, 5),
3160     CreateMockRead(*body_data, 6),
3161     MockRead(ASYNC, 0, 7),
3162   };
3163 
3164   OrderedSocketData data(
3165       spdy_reads, arraysize(spdy_reads),
3166       spdy_writes, arraysize(spdy_writes));
3167   session_deps_.socket_factory->AddSocketDataProvider(&data);
3168 
3169   SSLSocketDataProvider ssl(ASYNC, OK);
3170   ssl.SetNextProto(GetParam());
3171   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3172 
3173   TestCompletionCallback callback1;
3174 
3175   scoped_ptr<HttpTransaction> trans(
3176       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3177 
3178   int rv = trans->Start(&request, callback1.callback(), log.bound());
3179   EXPECT_EQ(ERR_IO_PENDING, rv);
3180 
3181   rv = callback1.WaitForResult();
3182   EXPECT_EQ(OK, rv);
3183 
3184   const HttpResponseInfo* const response = trans->GetResponseInfo();
3185 
3186   ASSERT_TRUE(response != NULL);
3187   ASSERT_TRUE(response->headers.get() != NULL);
3188   EXPECT_EQ(407, response->headers->response_code());
3189   EXPECT_TRUE(response->was_fetched_via_spdy);
3190   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3191 
3192   TestCompletionCallback callback2;
3193 
3194   rv = trans->RestartWithAuth(
3195       AuthCredentials(kFoo, kBar), callback2.callback());
3196   EXPECT_EQ(ERR_IO_PENDING, rv);
3197 
3198   rv = callback2.WaitForResult();
3199   EXPECT_EQ(OK, rv);
3200 
3201   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3202 
3203   ASSERT_TRUE(response_restart != NULL);
3204   ASSERT_TRUE(response_restart->headers.get() != NULL);
3205   EXPECT_EQ(200, response_restart->headers->response_code());
3206   // The password prompt info should not be set.
3207   EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3208 }
3209 
3210 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyConnectHttps)3211 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
3212   HttpRequestInfo request;
3213   request.method = "GET";
3214   request.url = GURL("https://www.google.com/");
3215   request.load_flags = 0;
3216 
3217   // Configure against https proxy server "proxy:70".
3218   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3219       "https://proxy:70"));
3220   CapturingBoundNetLog log;
3221   session_deps_.net_log = log.bound().net_log();
3222   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3223 
3224   scoped_ptr<HttpTransaction> trans(
3225       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3226 
3227   // CONNECT to www.google.com:443 via SPDY
3228   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3229                                                                 LOWEST));
3230   // fetch https://www.google.com/ via HTTP
3231 
3232   const char get[] = "GET / HTTP/1.1\r\n"
3233     "Host: www.google.com\r\n"
3234     "Connection: keep-alive\r\n\r\n";
3235   scoped_ptr<SpdyFrame> wrapped_get(
3236       spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3237   scoped_ptr<SpdyFrame> conn_resp(
3238       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3239   const char resp[] = "HTTP/1.1 200 OK\r\n"
3240       "Content-Length: 10\r\n\r\n";
3241   scoped_ptr<SpdyFrame> wrapped_get_resp(
3242       spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
3243   scoped_ptr<SpdyFrame> wrapped_body(
3244       spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
3245   scoped_ptr<SpdyFrame> window_update(
3246       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
3247 
3248   MockWrite spdy_writes[] = {
3249       CreateMockWrite(*connect, 1),
3250       CreateMockWrite(*wrapped_get, 3),
3251       CreateMockWrite(*window_update, 5),
3252   };
3253 
3254   MockRead spdy_reads[] = {
3255     CreateMockRead(*conn_resp, 2, ASYNC),
3256     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3257     CreateMockRead(*wrapped_body, 6, ASYNC),
3258     CreateMockRead(*wrapped_body, 7, ASYNC),
3259     MockRead(ASYNC, 0, 8),
3260   };
3261 
3262   OrderedSocketData spdy_data(
3263       spdy_reads, arraysize(spdy_reads),
3264       spdy_writes, arraysize(spdy_writes));
3265   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3266 
3267   SSLSocketDataProvider ssl(ASYNC, OK);
3268   ssl.SetNextProto(GetParam());
3269   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3270   SSLSocketDataProvider ssl2(ASYNC, OK);
3271   ssl2.was_npn_negotiated = false;
3272   ssl2.protocol_negotiated = kProtoUnknown;
3273   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
3274 
3275   TestCompletionCallback callback1;
3276 
3277   int rv = trans->Start(&request, callback1.callback(), log.bound());
3278   EXPECT_EQ(ERR_IO_PENDING, rv);
3279 
3280   rv = callback1.WaitForResult();
3281   EXPECT_EQ(OK, rv);
3282 
3283   LoadTimingInfo load_timing_info;
3284   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3285   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3286 
3287   const HttpResponseInfo* response = trans->GetResponseInfo();
3288   ASSERT_TRUE(response != NULL);
3289   ASSERT_TRUE(response->headers.get() != NULL);
3290   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3291 
3292   std::string response_data;
3293   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3294   EXPECT_EQ("1234567890", response_data);
3295 }
3296 
3297 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyConnectSpdy)3298 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
3299   HttpRequestInfo request;
3300   request.method = "GET";
3301   request.url = GURL("https://www.google.com/");
3302   request.load_flags = 0;
3303 
3304   // Configure against https proxy server "proxy:70".
3305   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3306       "https://proxy:70"));
3307   CapturingBoundNetLog log;
3308   session_deps_.net_log = log.bound().net_log();
3309   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3310 
3311   scoped_ptr<HttpTransaction> trans(
3312       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3313 
3314   // CONNECT to www.google.com:443 via SPDY
3315   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3316                                                                 LOWEST));
3317   // fetch https://www.google.com/ via SPDY
3318   const char* const kMyUrl = "https://www.google.com/";
3319   scoped_ptr<SpdyFrame> get(
3320       spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
3321   scoped_ptr<SpdyFrame> wrapped_get(
3322       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3323   scoped_ptr<SpdyFrame> conn_resp(
3324       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3325   scoped_ptr<SpdyFrame> get_resp(
3326       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3327   scoped_ptr<SpdyFrame> wrapped_get_resp(
3328       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3329   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3330   scoped_ptr<SpdyFrame> wrapped_body(
3331       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
3332   scoped_ptr<SpdyFrame> window_update_get_resp(
3333       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
3334   scoped_ptr<SpdyFrame> window_update_body(
3335       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
3336 
3337   MockWrite spdy_writes[] = {
3338       CreateMockWrite(*connect, 1),
3339       CreateMockWrite(*wrapped_get, 3),
3340       CreateMockWrite(*window_update_get_resp, 5),
3341       CreateMockWrite(*window_update_body, 7),
3342   };
3343 
3344   MockRead spdy_reads[] = {
3345     CreateMockRead(*conn_resp, 2, ASYNC),
3346     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3347     CreateMockRead(*wrapped_body, 6, ASYNC),
3348     MockRead(ASYNC, 0, 8),
3349   };
3350 
3351   OrderedSocketData spdy_data(
3352       spdy_reads, arraysize(spdy_reads),
3353       spdy_writes, arraysize(spdy_writes));
3354   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3355 
3356   SSLSocketDataProvider ssl(ASYNC, OK);
3357   ssl.SetNextProto(GetParam());
3358   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3359   SSLSocketDataProvider ssl2(ASYNC, OK);
3360   ssl2.SetNextProto(GetParam());
3361   ssl2.protocol_negotiated = GetParam();
3362   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
3363 
3364   TestCompletionCallback callback1;
3365 
3366   int rv = trans->Start(&request, callback1.callback(), log.bound());
3367   EXPECT_EQ(ERR_IO_PENDING, rv);
3368 
3369   rv = callback1.WaitForResult();
3370   EXPECT_EQ(OK, rv);
3371 
3372   LoadTimingInfo load_timing_info;
3373   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3374   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3375 
3376   const HttpResponseInfo* response = trans->GetResponseInfo();
3377   ASSERT_TRUE(response != NULL);
3378   ASSERT_TRUE(response->headers.get() != NULL);
3379   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3380 
3381   std::string response_data;
3382   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3383   EXPECT_EQ(kUploadData, response_data);
3384 }
3385 
3386 // Test a SPDY CONNECT failure through an HTTPS Proxy.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyConnectFailure)3387 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
3388   HttpRequestInfo request;
3389   request.method = "GET";
3390   request.url = GURL("https://www.google.com/");
3391   request.load_flags = 0;
3392 
3393   // Configure against https proxy server "proxy:70".
3394   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3395       "https://proxy:70"));
3396   CapturingBoundNetLog log;
3397   session_deps_.net_log = log.bound().net_log();
3398   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3399 
3400   scoped_ptr<HttpTransaction> trans(
3401       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3402 
3403   // CONNECT to www.google.com:443 via SPDY
3404   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3405                                                                 LOWEST));
3406   scoped_ptr<SpdyFrame> get(
3407       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
3408 
3409   MockWrite spdy_writes[] = {
3410       CreateMockWrite(*connect, 1),
3411       CreateMockWrite(*get, 3),
3412   };
3413 
3414   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3415   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3416   MockRead spdy_reads[] = {
3417     CreateMockRead(*resp, 2, ASYNC),
3418     MockRead(ASYNC, 0, 4),
3419   };
3420 
3421   OrderedSocketData spdy_data(
3422       spdy_reads, arraysize(spdy_reads),
3423       spdy_writes, arraysize(spdy_writes));
3424   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3425 
3426   SSLSocketDataProvider ssl(ASYNC, OK);
3427   ssl.SetNextProto(GetParam());
3428   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3429   SSLSocketDataProvider ssl2(ASYNC, OK);
3430   ssl2.SetNextProto(GetParam());
3431   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
3432 
3433   TestCompletionCallback callback1;
3434 
3435   int rv = trans->Start(&request, callback1.callback(), log.bound());
3436   EXPECT_EQ(ERR_IO_PENDING, rv);
3437 
3438   rv = callback1.WaitForResult();
3439   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3440 
3441   // TODO(ttuttle): Anything else to check here?
3442 }
3443 
3444 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3445 // HTTPS Proxy to different servers.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers)3446 TEST_P(HttpNetworkTransactionTest,
3447        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3448   // Configure against https proxy server "proxy:70".
3449   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3450       "https://proxy:70"));
3451   CapturingBoundNetLog log;
3452   session_deps_.net_log = log.bound().net_log();
3453   scoped_refptr<HttpNetworkSession> session(
3454       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
3455 
3456   HttpRequestInfo request1;
3457   request1.method = "GET";
3458   request1.url = GURL("https://www.google.com/");
3459   request1.load_flags = 0;
3460 
3461   HttpRequestInfo request2;
3462   request2.method = "GET";
3463   request2.url = GURL("https://news.google.com/");
3464   request2.load_flags = 0;
3465 
3466   // CONNECT to www.google.com:443 via SPDY.
3467   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3468                                                                  LOWEST));
3469   scoped_ptr<SpdyFrame> conn_resp1(
3470       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3471 
3472   // Fetch https://www.google.com/ via HTTP.
3473   const char get1[] = "GET / HTTP/1.1\r\n"
3474       "Host: www.google.com\r\n"
3475       "Connection: keep-alive\r\n\r\n";
3476   scoped_ptr<SpdyFrame> wrapped_get1(
3477       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
3478   const char resp1[] = "HTTP/1.1 200 OK\r\n"
3479       "Content-Length: 1\r\n\r\n";
3480   scoped_ptr<SpdyFrame> wrapped_get_resp1(
3481       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3482   scoped_ptr<SpdyFrame> wrapped_body1(
3483       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
3484   scoped_ptr<SpdyFrame> window_update(
3485       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
3486 
3487   // CONNECT to news.google.com:443 via SPDY.
3488   SpdySynStreamIR connect2_ir(3);
3489   spdy_util_.SetPriority(LOWEST, &connect2_ir);
3490   connect2_ir.SetHeader(spdy_util_.GetMethodKey(), "CONNECT");
3491   connect2_ir.SetHeader(spdy_util_.GetPathKey(), "news.google.com:443");
3492   connect2_ir.SetHeader(spdy_util_.GetHostKey(), "news.google.com");
3493   spdy_util_.MaybeAddVersionHeader(&connect2_ir);
3494   scoped_ptr<SpdyFrame> connect2(
3495       spdy_util_.CreateFramer(false)->SerializeFrame(connect2_ir));
3496 
3497   scoped_ptr<SpdyFrame> conn_resp2(
3498       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3499 
3500   // Fetch https://news.google.com/ via HTTP.
3501   const char get2[] = "GET / HTTP/1.1\r\n"
3502       "Host: news.google.com\r\n"
3503       "Connection: keep-alive\r\n\r\n";
3504   scoped_ptr<SpdyFrame> wrapped_get2(
3505       spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
3506   const char resp2[] = "HTTP/1.1 200 OK\r\n"
3507       "Content-Length: 2\r\n\r\n";
3508   scoped_ptr<SpdyFrame> wrapped_get_resp2(
3509       spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
3510   scoped_ptr<SpdyFrame> wrapped_body2(
3511       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
3512 
3513   MockWrite spdy_writes[] = {
3514       CreateMockWrite(*connect1, 0),
3515       CreateMockWrite(*wrapped_get1, 2),
3516       CreateMockWrite(*connect2, 5),
3517       CreateMockWrite(*wrapped_get2, 7),
3518   };
3519 
3520   MockRead spdy_reads[] = {
3521     CreateMockRead(*conn_resp1, 1, ASYNC),
3522     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3523     CreateMockRead(*wrapped_body1, 4, ASYNC),
3524     CreateMockRead(*conn_resp2, 6, ASYNC),
3525     CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3526     CreateMockRead(*wrapped_body2, 9, ASYNC),
3527     MockRead(ASYNC, 0, 10),
3528   };
3529 
3530   DeterministicSocketData spdy_data(
3531       spdy_reads, arraysize(spdy_reads),
3532       spdy_writes, arraysize(spdy_writes));
3533   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
3534 
3535   SSLSocketDataProvider ssl(ASYNC, OK);
3536   ssl.SetNextProto(GetParam());
3537   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3538   SSLSocketDataProvider ssl2(ASYNC, OK);
3539   ssl2.was_npn_negotiated = false;
3540   ssl2.protocol_negotiated = kProtoUnknown;
3541   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
3542   SSLSocketDataProvider ssl3(ASYNC, OK);
3543   ssl3.was_npn_negotiated = false;
3544   ssl3.protocol_negotiated = kProtoUnknown;
3545   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
3546 
3547   TestCompletionCallback callback;
3548 
3549   scoped_ptr<HttpTransaction> trans(
3550       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3551   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3552   EXPECT_EQ(ERR_IO_PENDING, rv);
3553   // The first connect and request, each of their responses, and the body.
3554   spdy_data.RunFor(5);
3555 
3556   rv = callback.WaitForResult();
3557   EXPECT_EQ(OK, rv);
3558 
3559   LoadTimingInfo load_timing_info;
3560   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3561   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3562 
3563   const HttpResponseInfo* response = trans->GetResponseInfo();
3564   ASSERT_TRUE(response != NULL);
3565   ASSERT_TRUE(response->headers.get() != NULL);
3566   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3567 
3568   std::string response_data;
3569   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3570   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
3571 
3572   scoped_ptr<HttpTransaction> trans2(
3573       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3574   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3575   EXPECT_EQ(ERR_IO_PENDING, rv);
3576 
3577   // The second connect and request, each of their responses, and the body.
3578   spdy_data.RunFor(5);
3579   rv = callback.WaitForResult();
3580   EXPECT_EQ(OK, rv);
3581 
3582   LoadTimingInfo load_timing_info2;
3583   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3584   // Even though the SPDY connection is reused, a new tunnelled connection has
3585   // to be created, so the socket's load timing looks like a fresh connection.
3586   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3587 
3588   // The requests should have different IDs, since they each are using their own
3589   // separate stream.
3590   EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3591 
3592   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
3593 }
3594 
3595 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3596 // HTTPS Proxy to the same server.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer)3597 TEST_P(HttpNetworkTransactionTest,
3598        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3599   // Configure against https proxy server "proxy:70".
3600   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3601       "https://proxy:70"));
3602   CapturingBoundNetLog log;
3603   session_deps_.net_log = log.bound().net_log();
3604   scoped_refptr<HttpNetworkSession> session(
3605       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
3606 
3607   HttpRequestInfo request1;
3608   request1.method = "GET";
3609   request1.url = GURL("https://www.google.com/");
3610   request1.load_flags = 0;
3611 
3612   HttpRequestInfo request2;
3613   request2.method = "GET";
3614   request2.url = GURL("https://www.google.com/2");
3615   request2.load_flags = 0;
3616 
3617   // CONNECT to www.google.com:443 via SPDY.
3618   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3619                                                                  LOWEST));
3620   scoped_ptr<SpdyFrame> conn_resp1(
3621       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3622 
3623   // Fetch https://www.google.com/ via HTTP.
3624   const char get1[] = "GET / HTTP/1.1\r\n"
3625       "Host: www.google.com\r\n"
3626       "Connection: keep-alive\r\n\r\n";
3627   scoped_ptr<SpdyFrame> wrapped_get1(
3628       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
3629   const char resp1[] = "HTTP/1.1 200 OK\r\n"
3630       "Content-Length: 1\r\n\r\n";
3631   scoped_ptr<SpdyFrame> wrapped_get_resp1(
3632       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3633   scoped_ptr<SpdyFrame> wrapped_body1(
3634       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
3635   scoped_ptr<SpdyFrame> window_update(
3636       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
3637 
3638   // Fetch https://www.google.com/2 via HTTP.
3639   const char get2[] = "GET /2 HTTP/1.1\r\n"
3640       "Host: www.google.com\r\n"
3641       "Connection: keep-alive\r\n\r\n";
3642   scoped_ptr<SpdyFrame> wrapped_get2(
3643       spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
3644   const char resp2[] = "HTTP/1.1 200 OK\r\n"
3645       "Content-Length: 2\r\n\r\n";
3646   scoped_ptr<SpdyFrame> wrapped_get_resp2(
3647       spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
3648   scoped_ptr<SpdyFrame> wrapped_body2(
3649       spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
3650 
3651   MockWrite spdy_writes[] = {
3652       CreateMockWrite(*connect1, 0),
3653       CreateMockWrite(*wrapped_get1, 2),
3654       CreateMockWrite(*wrapped_get2, 5),
3655   };
3656 
3657   MockRead spdy_reads[] = {
3658     CreateMockRead(*conn_resp1, 1, ASYNC),
3659     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3660     CreateMockRead(*wrapped_body1, 4, ASYNC),
3661     CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3662     CreateMockRead(*wrapped_body2, 7, ASYNC),
3663     MockRead(ASYNC, 0, 8),
3664   };
3665 
3666   DeterministicSocketData spdy_data(
3667       spdy_reads, arraysize(spdy_reads),
3668       spdy_writes, arraysize(spdy_writes));
3669   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
3670 
3671   SSLSocketDataProvider ssl(ASYNC, OK);
3672   ssl.SetNextProto(GetParam());
3673   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3674   SSLSocketDataProvider ssl2(ASYNC, OK);
3675   ssl2.was_npn_negotiated = false;
3676   ssl2.protocol_negotiated = kProtoUnknown;
3677   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
3678 
3679   TestCompletionCallback callback;
3680 
3681   scoped_ptr<HttpTransaction> trans(
3682       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3683   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3684   EXPECT_EQ(ERR_IO_PENDING, rv);
3685   // The first connect and request, each of their responses, and the body.
3686   spdy_data.RunFor(5);
3687 
3688   rv = callback.WaitForResult();
3689   EXPECT_EQ(OK, rv);
3690 
3691   LoadTimingInfo load_timing_info;
3692   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3693   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3694 
3695   const HttpResponseInfo* response = trans->GetResponseInfo();
3696   ASSERT_TRUE(response != NULL);
3697   ASSERT_TRUE(response->headers.get() != NULL);
3698   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3699 
3700   std::string response_data;
3701   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3702   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
3703   trans.reset();
3704 
3705   scoped_ptr<HttpTransaction> trans2(
3706       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3707   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3708   EXPECT_EQ(ERR_IO_PENDING, rv);
3709 
3710   // The second request, response, and body.  There should not be a second
3711   // connect.
3712   spdy_data.RunFor(3);
3713   rv = callback.WaitForResult();
3714   EXPECT_EQ(OK, rv);
3715 
3716   LoadTimingInfo load_timing_info2;
3717   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3718   TestLoadTimingReused(load_timing_info2);
3719 
3720   // The requests should have the same ID.
3721   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3722 
3723   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
3724 }
3725 
3726 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3727 // Proxy to different servers.
TEST_P(HttpNetworkTransactionTest,HttpsProxySpdyLoadTimingTwoHttpRequests)3728 TEST_P(HttpNetworkTransactionTest,
3729        HttpsProxySpdyLoadTimingTwoHttpRequests) {
3730   // Configure against https proxy server "proxy:70".
3731   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
3732       "https://proxy:70"));
3733   CapturingBoundNetLog log;
3734   session_deps_.net_log = log.bound().net_log();
3735   scoped_refptr<HttpNetworkSession> session(
3736       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
3737 
3738   HttpRequestInfo request1;
3739   request1.method = "GET";
3740   request1.url = GURL("http://www.google.com/");
3741   request1.load_flags = 0;
3742 
3743   HttpRequestInfo request2;
3744   request2.method = "GET";
3745   request2.url = GURL("http://news.google.com/");
3746   request2.load_flags = 0;
3747 
3748   // http://www.google.com/
3749   scoped_ptr<SpdyHeaderBlock> headers(
3750       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
3751   scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
3752       headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3753   scoped_ptr<SpdyFrame> get_resp1(
3754       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3755   scoped_ptr<SpdyFrame> body1(
3756       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
3757 
3758   // http://news.google.com/
3759   scoped_ptr<SpdyHeaderBlock> headers2(
3760       spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
3761   scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
3762       headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3763   scoped_ptr<SpdyFrame> get_resp2(
3764       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3765   scoped_ptr<SpdyFrame> body2(
3766       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
3767 
3768   MockWrite spdy_writes[] = {
3769       CreateMockWrite(*get1, 0),
3770       CreateMockWrite(*get2, 3),
3771   };
3772 
3773   MockRead spdy_reads[] = {
3774     CreateMockRead(*get_resp1, 1, ASYNC),
3775     CreateMockRead(*body1, 2, ASYNC),
3776     CreateMockRead(*get_resp2, 4, ASYNC),
3777     CreateMockRead(*body2, 5, ASYNC),
3778     MockRead(ASYNC, 0, 6),
3779   };
3780 
3781   DeterministicSocketData spdy_data(
3782       spdy_reads, arraysize(spdy_reads),
3783       spdy_writes, arraysize(spdy_writes));
3784   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
3785 
3786   SSLSocketDataProvider ssl(ASYNC, OK);
3787   ssl.SetNextProto(GetParam());
3788   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3789 
3790   TestCompletionCallback callback;
3791 
3792   scoped_ptr<HttpTransaction> trans(
3793       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3794   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3795   EXPECT_EQ(ERR_IO_PENDING, rv);
3796   spdy_data.RunFor(2);
3797 
3798   rv = callback.WaitForResult();
3799   EXPECT_EQ(OK, rv);
3800 
3801   LoadTimingInfo load_timing_info;
3802   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3803   TestLoadTimingNotReused(load_timing_info,
3804                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3805 
3806   const HttpResponseInfo* response = trans->GetResponseInfo();
3807   ASSERT_TRUE(response != NULL);
3808   ASSERT_TRUE(response->headers.get() != NULL);
3809   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3810 
3811   std::string response_data;
3812   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3813   EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
3814   spdy_data.RunFor(1);
3815   EXPECT_EQ(1, callback.WaitForResult());
3816   // Delete the first request, so the second one can reuse the socket.
3817   trans.reset();
3818 
3819   scoped_ptr<HttpTransaction> trans2(
3820       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3821   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3822   EXPECT_EQ(ERR_IO_PENDING, rv);
3823 
3824   spdy_data.RunFor(2);
3825   rv = callback.WaitForResult();
3826   EXPECT_EQ(OK, rv);
3827 
3828   LoadTimingInfo load_timing_info2;
3829   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3830   TestLoadTimingReused(load_timing_info2);
3831 
3832   // The requests should have the same ID.
3833   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3834 
3835   EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
3836   spdy_data.RunFor(1);
3837   EXPECT_EQ(2, callback.WaitForResult());
3838 }
3839 
3840 // Test the challenge-response-retry sequence through an HTTPS Proxy
TEST_P(HttpNetworkTransactionTest,HttpsProxyAuthRetry)3841 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
3842   HttpRequestInfo request;
3843   request.method = "GET";
3844   request.url = GURL("http://www.google.com/");
3845   // when the no authentication data flag is set.
3846   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3847 
3848   // Configure against https proxy server "myproxy:70".
3849   session_deps_.proxy_service.reset(
3850       ProxyService::CreateFixed("https://myproxy:70"));
3851   CapturingBoundNetLog log;
3852   session_deps_.net_log = log.bound().net_log();
3853   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3854 
3855   // Since we have proxy, should use full url
3856   MockWrite data_writes1[] = {
3857     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3858               "Host: www.google.com\r\n"
3859               "Proxy-Connection: keep-alive\r\n\r\n"),
3860 
3861     // After calling trans->RestartWithAuth(), this is the request we should
3862     // be issuing -- the final header line contains the credentials.
3863     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3864               "Host: www.google.com\r\n"
3865               "Proxy-Connection: keep-alive\r\n"
3866               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3867   };
3868 
3869   // The proxy responds to the GET with a 407, using a persistent
3870   // connection.
3871   MockRead data_reads1[] = {
3872     // No credentials.
3873     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3874     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3875     MockRead("Proxy-Connection: keep-alive\r\n"),
3876     MockRead("Content-Length: 0\r\n\r\n"),
3877 
3878     MockRead("HTTP/1.1 200 OK\r\n"),
3879     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3880     MockRead("Content-Length: 100\r\n\r\n"),
3881     MockRead(SYNCHRONOUS, OK),
3882   };
3883 
3884   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3885                                  data_writes1, arraysize(data_writes1));
3886   session_deps_.socket_factory->AddSocketDataProvider(&data1);
3887   SSLSocketDataProvider ssl(ASYNC, OK);
3888   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3889 
3890   TestCompletionCallback callback1;
3891 
3892   scoped_ptr<HttpTransaction> trans(
3893       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3894 
3895   int rv = trans->Start(&request, callback1.callback(), log.bound());
3896   EXPECT_EQ(ERR_IO_PENDING, rv);
3897 
3898   rv = callback1.WaitForResult();
3899   EXPECT_EQ(OK, rv);
3900 
3901   LoadTimingInfo load_timing_info;
3902   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3903   TestLoadTimingNotReused(load_timing_info,
3904                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3905 
3906   const HttpResponseInfo* response = trans->GetResponseInfo();
3907   ASSERT_TRUE(response != NULL);
3908   ASSERT_FALSE(response->headers.get() == NULL);
3909   EXPECT_EQ(407, response->headers->response_code());
3910   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3911   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3912 
3913   TestCompletionCallback callback2;
3914 
3915   rv = trans->RestartWithAuth(
3916       AuthCredentials(kFoo, kBar), callback2.callback());
3917   EXPECT_EQ(ERR_IO_PENDING, rv);
3918 
3919   rv = callback2.WaitForResult();
3920   EXPECT_EQ(OK, rv);
3921 
3922   load_timing_info = LoadTimingInfo();
3923   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3924   // Retrying with HTTP AUTH is considered to be reusing a socket.
3925   TestLoadTimingReused(load_timing_info);
3926 
3927   response = trans->GetResponseInfo();
3928   ASSERT_TRUE(response != NULL);
3929 
3930   EXPECT_TRUE(response->headers->IsKeepAlive());
3931   EXPECT_EQ(200, response->headers->response_code());
3932   EXPECT_EQ(100, response->headers->GetContentLength());
3933   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3934 
3935   // The password prompt info should not be set.
3936   EXPECT_TRUE(response->auth_challenge.get() == NULL);
3937 }
3938 
ConnectStatusHelperWithExpectedStatus(const MockRead & status,int expected_status)3939 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
3940     const MockRead& status, int expected_status) {
3941   HttpRequestInfo request;
3942   request.method = "GET";
3943   request.url = GURL("https://www.google.com/");
3944   request.load_flags = 0;
3945 
3946   // Configure against proxy server "myproxy:70".
3947   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3948   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3949 
3950   // Since we have proxy, should try to establish tunnel.
3951   MockWrite data_writes[] = {
3952     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
3953               "Host: www.google.com\r\n"
3954               "Proxy-Connection: keep-alive\r\n\r\n"),
3955   };
3956 
3957   MockRead data_reads[] = {
3958     status,
3959     MockRead("Content-Length: 10\r\n\r\n"),
3960     // No response body because the test stops reading here.
3961     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
3962   };
3963 
3964   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3965                                 data_writes, arraysize(data_writes));
3966   session_deps_.socket_factory->AddSocketDataProvider(&data);
3967 
3968   TestCompletionCallback callback;
3969 
3970   scoped_ptr<HttpTransaction> trans(
3971       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3972 
3973   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3974   EXPECT_EQ(ERR_IO_PENDING, rv);
3975 
3976   rv = callback.WaitForResult();
3977   EXPECT_EQ(expected_status, rv);
3978 }
3979 
ConnectStatusHelper(const MockRead & status)3980 void HttpNetworkTransactionTest::ConnectStatusHelper(
3981     const MockRead& status) {
3982   ConnectStatusHelperWithExpectedStatus(
3983       status, ERR_TUNNEL_CONNECTION_FAILED);
3984 }
3985 
TEST_P(HttpNetworkTransactionTest,ConnectStatus100)3986 TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
3987   ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
3988 }
3989 
TEST_P(HttpNetworkTransactionTest,ConnectStatus101)3990 TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
3991   ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
3992 }
3993 
TEST_P(HttpNetworkTransactionTest,ConnectStatus201)3994 TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
3995   ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
3996 }
3997 
TEST_P(HttpNetworkTransactionTest,ConnectStatus202)3998 TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
3999   ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4000 }
4001 
TEST_P(HttpNetworkTransactionTest,ConnectStatus203)4002 TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
4003   ConnectStatusHelper(
4004       MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4005 }
4006 
TEST_P(HttpNetworkTransactionTest,ConnectStatus204)4007 TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
4008   ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4009 }
4010 
TEST_P(HttpNetworkTransactionTest,ConnectStatus205)4011 TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
4012   ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4013 }
4014 
TEST_P(HttpNetworkTransactionTest,ConnectStatus206)4015 TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
4016   ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4017 }
4018 
TEST_P(HttpNetworkTransactionTest,ConnectStatus300)4019 TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
4020   ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4021 }
4022 
TEST_P(HttpNetworkTransactionTest,ConnectStatus301)4023 TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
4024   ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4025 }
4026 
TEST_P(HttpNetworkTransactionTest,ConnectStatus302)4027 TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
4028   ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4029 }
4030 
TEST_P(HttpNetworkTransactionTest,ConnectStatus303)4031 TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
4032   ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4033 }
4034 
TEST_P(HttpNetworkTransactionTest,ConnectStatus304)4035 TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
4036   ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4037 }
4038 
TEST_P(HttpNetworkTransactionTest,ConnectStatus305)4039 TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
4040   ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4041 }
4042 
TEST_P(HttpNetworkTransactionTest,ConnectStatus306)4043 TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
4044   ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4045 }
4046 
TEST_P(HttpNetworkTransactionTest,ConnectStatus307)4047 TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
4048   ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4049 }
4050 
TEST_P(HttpNetworkTransactionTest,ConnectStatus308)4051 TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4052   ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4053 }
4054 
TEST_P(HttpNetworkTransactionTest,ConnectStatus400)4055 TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
4056   ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4057 }
4058 
TEST_P(HttpNetworkTransactionTest,ConnectStatus401)4059 TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
4060   ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4061 }
4062 
TEST_P(HttpNetworkTransactionTest,ConnectStatus402)4063 TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
4064   ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4065 }
4066 
TEST_P(HttpNetworkTransactionTest,ConnectStatus403)4067 TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
4068   ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4069 }
4070 
TEST_P(HttpNetworkTransactionTest,ConnectStatus404)4071 TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
4072   ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4073 }
4074 
TEST_P(HttpNetworkTransactionTest,ConnectStatus405)4075 TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
4076   ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4077 }
4078 
TEST_P(HttpNetworkTransactionTest,ConnectStatus406)4079 TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
4080   ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4081 }
4082 
TEST_P(HttpNetworkTransactionTest,ConnectStatus407)4083 TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
4084   ConnectStatusHelperWithExpectedStatus(
4085       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4086       ERR_PROXY_AUTH_UNSUPPORTED);
4087 }
4088 
TEST_P(HttpNetworkTransactionTest,ConnectStatus408)4089 TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
4090   ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4091 }
4092 
TEST_P(HttpNetworkTransactionTest,ConnectStatus409)4093 TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
4094   ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4095 }
4096 
TEST_P(HttpNetworkTransactionTest,ConnectStatus410)4097 TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
4098   ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4099 }
4100 
TEST_P(HttpNetworkTransactionTest,ConnectStatus411)4101 TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
4102   ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4103 }
4104 
TEST_P(HttpNetworkTransactionTest,ConnectStatus412)4105 TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
4106   ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4107 }
4108 
TEST_P(HttpNetworkTransactionTest,ConnectStatus413)4109 TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
4110   ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4111 }
4112 
TEST_P(HttpNetworkTransactionTest,ConnectStatus414)4113 TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
4114   ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4115 }
4116 
TEST_P(HttpNetworkTransactionTest,ConnectStatus415)4117 TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
4118   ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4119 }
4120 
TEST_P(HttpNetworkTransactionTest,ConnectStatus416)4121 TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
4122   ConnectStatusHelper(
4123       MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4124 }
4125 
TEST_P(HttpNetworkTransactionTest,ConnectStatus417)4126 TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
4127   ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4128 }
4129 
TEST_P(HttpNetworkTransactionTest,ConnectStatus500)4130 TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
4131   ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4132 }
4133 
TEST_P(HttpNetworkTransactionTest,ConnectStatus501)4134 TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
4135   ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4136 }
4137 
TEST_P(HttpNetworkTransactionTest,ConnectStatus502)4138 TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
4139   ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4140 }
4141 
TEST_P(HttpNetworkTransactionTest,ConnectStatus503)4142 TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
4143   ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4144 }
4145 
TEST_P(HttpNetworkTransactionTest,ConnectStatus504)4146 TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
4147   ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4148 }
4149 
TEST_P(HttpNetworkTransactionTest,ConnectStatus505)4150 TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
4151   ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4152 }
4153 
4154 // Test the flow when both the proxy server AND origin server require
4155 // authentication. Again, this uses basic auth for both since that is
4156 // the simplest to mock.
TEST_P(HttpNetworkTransactionTest,BasicAuthProxyThenServer)4157 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
4158   HttpRequestInfo request;
4159   request.method = "GET";
4160   request.url = GURL("http://www.google.com/");
4161   request.load_flags = 0;
4162 
4163   // Configure against proxy server "myproxy:70".
4164   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4165   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4166 
4167   scoped_ptr<HttpTransaction> trans(
4168       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
4169 
4170   MockWrite data_writes1[] = {
4171     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4172               "Host: www.google.com\r\n"
4173               "Proxy-Connection: keep-alive\r\n\r\n"),
4174   };
4175 
4176   MockRead data_reads1[] = {
4177     MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4178     // Give a couple authenticate options (only the middle one is actually
4179     // supported).
4180     MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
4181     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4182     MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4183     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4184     // Large content-length -- won't matter, as connection will be reset.
4185     MockRead("Content-Length: 10000\r\n\r\n"),
4186     MockRead(SYNCHRONOUS, ERR_FAILED),
4187   };
4188 
4189   // After calling trans->RestartWithAuth() the first time, this is the
4190   // request we should be issuing -- the final header line contains the
4191   // proxy's credentials.
4192   MockWrite data_writes2[] = {
4193     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4194               "Host: www.google.com\r\n"
4195               "Proxy-Connection: keep-alive\r\n"
4196               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4197   };
4198 
4199   // Now the proxy server lets the request pass through to origin server.
4200   // The origin server responds with a 401.
4201   MockRead data_reads2[] = {
4202     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4203     // Note: We are using the same realm-name as the proxy server. This is
4204     // completely valid, as realms are unique across hosts.
4205     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4206     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4207     MockRead("Content-Length: 2000\r\n\r\n"),
4208     MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
4209   };
4210 
4211   // After calling trans->RestartWithAuth() the second time, we should send
4212   // the credentials for both the proxy and origin server.
4213   MockWrite data_writes3[] = {
4214     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4215               "Host: www.google.com\r\n"
4216               "Proxy-Connection: keep-alive\r\n"
4217               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4218               "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4219   };
4220 
4221   // Lastly we get the desired content.
4222   MockRead data_reads3[] = {
4223     MockRead("HTTP/1.0 200 OK\r\n"),
4224     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4225     MockRead("Content-Length: 100\r\n\r\n"),
4226     MockRead(SYNCHRONOUS, OK),
4227   };
4228 
4229   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4230                                  data_writes1, arraysize(data_writes1));
4231   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4232                                  data_writes2, arraysize(data_writes2));
4233   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4234                                  data_writes3, arraysize(data_writes3));
4235   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4236   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4237   session_deps_.socket_factory->AddSocketDataProvider(&data3);
4238 
4239   TestCompletionCallback callback1;
4240 
4241   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4242   EXPECT_EQ(ERR_IO_PENDING, rv);
4243 
4244   rv = callback1.WaitForResult();
4245   EXPECT_EQ(OK, rv);
4246 
4247   const HttpResponseInfo* response = trans->GetResponseInfo();
4248   ASSERT_TRUE(response != NULL);
4249   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
4250 
4251   TestCompletionCallback callback2;
4252 
4253   rv = trans->RestartWithAuth(
4254       AuthCredentials(kFoo, kBar), callback2.callback());
4255   EXPECT_EQ(ERR_IO_PENDING, rv);
4256 
4257   rv = callback2.WaitForResult();
4258   EXPECT_EQ(OK, rv);
4259 
4260   response = trans->GetResponseInfo();
4261   ASSERT_TRUE(response != NULL);
4262   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4263 
4264   TestCompletionCallback callback3;
4265 
4266   rv = trans->RestartWithAuth(
4267       AuthCredentials(kFoo2, kBar2), callback3.callback());
4268   EXPECT_EQ(ERR_IO_PENDING, rv);
4269 
4270   rv = callback3.WaitForResult();
4271   EXPECT_EQ(OK, rv);
4272 
4273   response = trans->GetResponseInfo();
4274   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4275   EXPECT_EQ(100, response->headers->GetContentLength());
4276 }
4277 
4278 // For the NTLM implementation using SSPI, we skip the NTLM tests since we
4279 // can't hook into its internals to cause it to generate predictable NTLM
4280 // authorization headers.
4281 #if defined(NTLM_PORTABLE)
4282 // The NTLM authentication unit tests were generated by capturing the HTTP
4283 // requests and responses using Fiddler 2 and inspecting the generated random
4284 // bytes in the debugger.
4285 
4286 // Enter the correct password and authenticate successfully.
TEST_P(HttpNetworkTransactionTest,NTLMAuth1)4287 TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
4288   HttpRequestInfo request;
4289   request.method = "GET";
4290   request.url = GURL("http://172.22.68.17/kids/login.aspx");
4291 
4292   // Ensure load is not disrupted by flags which suppress behaviour specific
4293   // to other auth schemes.
4294   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
4295 
4296   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4297                                                     MockGetHostName);
4298   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4299 
4300   MockWrite data_writes1[] = {
4301     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4302               "Host: 172.22.68.17\r\n"
4303               "Connection: keep-alive\r\n\r\n"),
4304   };
4305 
4306   MockRead data_reads1[] = {
4307     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4308     // Negotiate and NTLM are often requested together.  However, we only want
4309     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4310     // the header that requests Negotiate for this test.
4311     MockRead("WWW-Authenticate: NTLM\r\n"),
4312     MockRead("Connection: close\r\n"),
4313     MockRead("Content-Length: 42\r\n"),
4314     MockRead("Content-Type: text/html\r\n\r\n"),
4315     // Missing content -- won't matter, as connection will be reset.
4316     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4317   };
4318 
4319   MockWrite data_writes2[] = {
4320     // After restarting with a null identity, this is the
4321     // request we should be issuing -- the final header line contains a Type
4322     // 1 message.
4323     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4324               "Host: 172.22.68.17\r\n"
4325               "Connection: keep-alive\r\n"
4326               "Authorization: NTLM "
4327               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4328 
4329     // After calling trans->RestartWithAuth(), we should send a Type 3 message
4330     // (the credentials for the origin server).  The second request continues
4331     // on the same connection.
4332     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4333               "Host: 172.22.68.17\r\n"
4334               "Connection: keep-alive\r\n"
4335               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4336               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4337               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4338               "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4339               "ahlhx5I=\r\n\r\n"),
4340   };
4341 
4342   MockRead data_reads2[] = {
4343     // The origin server responds with a Type 2 message.
4344     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4345     MockRead("WWW-Authenticate: NTLM "
4346              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
4347              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4348              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4349              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4350              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4351              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4352              "BtAAAAAAA=\r\n"),
4353     MockRead("Content-Length: 42\r\n"),
4354     MockRead("Content-Type: text/html\r\n\r\n"),
4355     MockRead("You are not authorized to view this page\r\n"),
4356 
4357     // Lastly we get the desired content.
4358     MockRead("HTTP/1.1 200 OK\r\n"),
4359     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4360     MockRead("Content-Length: 13\r\n\r\n"),
4361     MockRead("Please Login\r\n"),
4362     MockRead(SYNCHRONOUS, OK),
4363   };
4364 
4365   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4366                                  data_writes1, arraysize(data_writes1));
4367   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4368                                  data_writes2, arraysize(data_writes2));
4369   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4370   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4371 
4372   TestCompletionCallback callback1;
4373 
4374   scoped_ptr<HttpTransaction> trans(
4375       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4376 
4377   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4378   EXPECT_EQ(ERR_IO_PENDING, rv);
4379 
4380   rv = callback1.WaitForResult();
4381   EXPECT_EQ(OK, rv);
4382 
4383   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4384 
4385   const HttpResponseInfo* response = trans->GetResponseInfo();
4386   ASSERT_FALSE(response == NULL);
4387   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
4388 
4389   TestCompletionCallback callback2;
4390 
4391   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
4392                               callback2.callback());
4393   EXPECT_EQ(ERR_IO_PENDING, rv);
4394 
4395   rv = callback2.WaitForResult();
4396   EXPECT_EQ(OK, rv);
4397 
4398   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4399 
4400   response = trans->GetResponseInfo();
4401   ASSERT_TRUE(response != NULL);
4402   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4403 
4404   TestCompletionCallback callback3;
4405 
4406   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
4407   EXPECT_EQ(ERR_IO_PENDING, rv);
4408 
4409   rv = callback3.WaitForResult();
4410   EXPECT_EQ(OK, rv);
4411 
4412   response = trans->GetResponseInfo();
4413   ASSERT_TRUE(response != NULL);
4414   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4415   EXPECT_EQ(13, response->headers->GetContentLength());
4416 }
4417 
4418 // Enter a wrong password, and then the correct one.
TEST_P(HttpNetworkTransactionTest,NTLMAuth2)4419 TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
4420   HttpRequestInfo request;
4421   request.method = "GET";
4422   request.url = GURL("http://172.22.68.17/kids/login.aspx");
4423   request.load_flags = 0;
4424 
4425   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4426                                                     MockGetHostName);
4427   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4428 
4429   MockWrite data_writes1[] = {
4430     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4431               "Host: 172.22.68.17\r\n"
4432               "Connection: keep-alive\r\n\r\n"),
4433   };
4434 
4435   MockRead data_reads1[] = {
4436     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4437     // Negotiate and NTLM are often requested together.  However, we only want
4438     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4439     // the header that requests Negotiate for this test.
4440     MockRead("WWW-Authenticate: NTLM\r\n"),
4441     MockRead("Connection: close\r\n"),
4442     MockRead("Content-Length: 42\r\n"),
4443     MockRead("Content-Type: text/html\r\n\r\n"),
4444     // Missing content -- won't matter, as connection will be reset.
4445     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4446   };
4447 
4448   MockWrite data_writes2[] = {
4449     // After restarting with a null identity, this is the
4450     // request we should be issuing -- the final header line contains a Type
4451     // 1 message.
4452     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4453               "Host: 172.22.68.17\r\n"
4454               "Connection: keep-alive\r\n"
4455               "Authorization: NTLM "
4456               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4457 
4458     // After calling trans->RestartWithAuth(), we should send a Type 3 message
4459     // (the credentials for the origin server).  The second request continues
4460     // on the same connection.
4461     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4462               "Host: 172.22.68.17\r\n"
4463               "Connection: keep-alive\r\n"
4464               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4465               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4466               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4467               "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4468               "4Ww7b7E=\r\n\r\n"),
4469   };
4470 
4471   MockRead data_reads2[] = {
4472     // The origin server responds with a Type 2 message.
4473     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4474     MockRead("WWW-Authenticate: NTLM "
4475              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4476              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4477              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4478              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4479              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4480              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4481              "BtAAAAAAA=\r\n"),
4482     MockRead("Content-Length: 42\r\n"),
4483     MockRead("Content-Type: text/html\r\n\r\n"),
4484     MockRead("You are not authorized to view this page\r\n"),
4485 
4486     // Wrong password.
4487     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4488     MockRead("WWW-Authenticate: NTLM\r\n"),
4489     MockRead("Connection: close\r\n"),
4490     MockRead("Content-Length: 42\r\n"),
4491     MockRead("Content-Type: text/html\r\n\r\n"),
4492     // Missing content -- won't matter, as connection will be reset.
4493     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
4494   };
4495 
4496   MockWrite data_writes3[] = {
4497     // After restarting with a null identity, this is the
4498     // request we should be issuing -- the final header line contains a Type
4499     // 1 message.
4500     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4501               "Host: 172.22.68.17\r\n"
4502               "Connection: keep-alive\r\n"
4503               "Authorization: NTLM "
4504               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4505 
4506     // After calling trans->RestartWithAuth(), we should send a Type 3 message
4507     // (the credentials for the origin server).  The second request continues
4508     // on the same connection.
4509     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4510               "Host: 172.22.68.17\r\n"
4511               "Connection: keep-alive\r\n"
4512               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4513               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4514               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4515               "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4516               "+4MUm7c=\r\n\r\n"),
4517   };
4518 
4519   MockRead data_reads3[] = {
4520     // The origin server responds with a Type 2 message.
4521     MockRead("HTTP/1.1 401 Access Denied\r\n"),
4522     MockRead("WWW-Authenticate: NTLM "
4523              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4524              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4525              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4526              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4527              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4528              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4529              "BtAAAAAAA=\r\n"),
4530     MockRead("Content-Length: 42\r\n"),
4531     MockRead("Content-Type: text/html\r\n\r\n"),
4532     MockRead("You are not authorized to view this page\r\n"),
4533 
4534     // Lastly we get the desired content.
4535     MockRead("HTTP/1.1 200 OK\r\n"),
4536     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4537     MockRead("Content-Length: 13\r\n\r\n"),
4538     MockRead("Please Login\r\n"),
4539     MockRead(SYNCHRONOUS, OK),
4540   };
4541 
4542   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4543                                  data_writes1, arraysize(data_writes1));
4544   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4545                                  data_writes2, arraysize(data_writes2));
4546   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4547                                  data_writes3, arraysize(data_writes3));
4548   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4549   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4550   session_deps_.socket_factory->AddSocketDataProvider(&data3);
4551 
4552   TestCompletionCallback callback1;
4553 
4554   scoped_ptr<HttpTransaction> trans(
4555       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4556 
4557   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4558   EXPECT_EQ(ERR_IO_PENDING, rv);
4559 
4560   rv = callback1.WaitForResult();
4561   EXPECT_EQ(OK, rv);
4562 
4563   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4564 
4565   const HttpResponseInfo* response = trans->GetResponseInfo();
4566   ASSERT_TRUE(response != NULL);
4567   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
4568 
4569   TestCompletionCallback callback2;
4570 
4571   // Enter the wrong password.
4572   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
4573                               callback2.callback());
4574   EXPECT_EQ(ERR_IO_PENDING, rv);
4575 
4576   rv = callback2.WaitForResult();
4577   EXPECT_EQ(OK, rv);
4578 
4579   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4580   TestCompletionCallback callback3;
4581   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
4582   EXPECT_EQ(ERR_IO_PENDING, rv);
4583   rv = callback3.WaitForResult();
4584   EXPECT_EQ(OK, rv);
4585   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4586 
4587   response = trans->GetResponseInfo();
4588   ASSERT_FALSE(response == NULL);
4589   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
4590 
4591   TestCompletionCallback callback4;
4592 
4593   // Now enter the right password.
4594   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
4595                               callback4.callback());
4596   EXPECT_EQ(ERR_IO_PENDING, rv);
4597 
4598   rv = callback4.WaitForResult();
4599   EXPECT_EQ(OK, rv);
4600 
4601   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4602 
4603   TestCompletionCallback callback5;
4604 
4605   // One more roundtrip
4606   rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
4607   EXPECT_EQ(ERR_IO_PENDING, rv);
4608 
4609   rv = callback5.WaitForResult();
4610   EXPECT_EQ(OK, rv);
4611 
4612   response = trans->GetResponseInfo();
4613   EXPECT_TRUE(response->auth_challenge.get() == NULL);
4614   EXPECT_EQ(13, response->headers->GetContentLength());
4615 }
4616 #endif  // NTLM_PORTABLE
4617 
4618 // Test reading a server response which has only headers, and no body.
4619 // After some maximum number of bytes is consumed, the transaction should
4620 // fail with ERR_RESPONSE_HEADERS_TOO_BIG.
TEST_P(HttpNetworkTransactionTest,LargeHeadersNoBody)4621 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
4622   HttpRequestInfo request;
4623   request.method = "GET";
4624   request.url = GURL("http://www.google.com/");
4625   request.load_flags = 0;
4626 
4627   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4628   scoped_ptr<HttpTransaction> trans(
4629       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
4630 
4631   // Respond with 300 kb of headers (we should fail after 256 kb).
4632   std::string large_headers_string;
4633   FillLargeHeadersString(&large_headers_string, 300 * 1024);
4634 
4635   MockRead data_reads[] = {
4636     MockRead("HTTP/1.0 200 OK\r\n"),
4637     MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
4638     MockRead("\r\nBODY"),
4639     MockRead(SYNCHRONOUS, OK),
4640   };
4641   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4642   session_deps_.socket_factory->AddSocketDataProvider(&data);
4643 
4644   TestCompletionCallback callback;
4645 
4646   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4647   EXPECT_EQ(ERR_IO_PENDING, rv);
4648 
4649   rv = callback.WaitForResult();
4650   EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
4651 
4652   const HttpResponseInfo* response = trans->GetResponseInfo();
4653   EXPECT_TRUE(response == NULL);
4654 }
4655 
4656 // Make sure that we don't try to reuse a TCPClientSocket when failing to
4657 // establish tunnel.
4658 // http://code.google.com/p/chromium/issues/detail?id=3772
TEST_P(HttpNetworkTransactionTest,DontRecycleTransportSocketForSSLTunnel)4659 TEST_P(HttpNetworkTransactionTest,
4660        DontRecycleTransportSocketForSSLTunnel) {
4661   HttpRequestInfo request;
4662   request.method = "GET";
4663   request.url = GURL("https://www.google.com/");
4664   request.load_flags = 0;
4665 
4666   // Configure against proxy server "myproxy:70".
4667   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4668 
4669   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4670 
4671   scoped_ptr<HttpTransaction> trans(
4672       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4673 
4674   // Since we have proxy, should try to establish tunnel.
4675   MockWrite data_writes1[] = {
4676     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
4677               "Host: www.google.com\r\n"
4678               "Proxy-Connection: keep-alive\r\n\r\n"),
4679   };
4680 
4681   // The proxy responds to the connect with a 404, using a persistent
4682   // connection. Usually a proxy would return 501 (not implemented),
4683   // or 200 (tunnel established).
4684   MockRead data_reads1[] = {
4685     MockRead("HTTP/1.1 404 Not Found\r\n"),
4686     MockRead("Content-Length: 10\r\n\r\n"),
4687     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
4688   };
4689 
4690   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4691                                  data_writes1, arraysize(data_writes1));
4692   session_deps_.socket_factory->AddSocketDataProvider(&data1);
4693 
4694   TestCompletionCallback callback1;
4695 
4696   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4697   EXPECT_EQ(ERR_IO_PENDING, rv);
4698 
4699   rv = callback1.WaitForResult();
4700   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
4701 
4702   const HttpResponseInfo* response = trans->GetResponseInfo();
4703   EXPECT_TRUE(response == NULL);
4704 
4705   // Empty the current queue.  This is necessary because idle sockets are
4706   // added to the connection pool asynchronously with a PostTask.
4707   base::MessageLoop::current()->RunUntilIdle();
4708 
4709   // We now check to make sure the TCPClientSocket was not added back to
4710   // the pool.
4711   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4712   trans.reset();
4713   base::MessageLoop::current()->RunUntilIdle();
4714   // Make sure that the socket didn't get recycled after calling the destructor.
4715   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4716 }
4717 
4718 // Make sure that we recycle a socket after reading all of the response body.
TEST_P(HttpNetworkTransactionTest,RecycleSocket)4719 TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
4720   HttpRequestInfo request;
4721   request.method = "GET";
4722   request.url = GURL("http://www.google.com/");
4723   request.load_flags = 0;
4724 
4725   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4726 
4727   scoped_ptr<HttpTransaction> trans(
4728       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4729 
4730   MockRead data_reads[] = {
4731     // A part of the response body is received with the response headers.
4732     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4733     // The rest of the response body is received in two parts.
4734     MockRead("lo"),
4735     MockRead(" world"),
4736     MockRead("junk"),  // Should not be read!!
4737     MockRead(SYNCHRONOUS, OK),
4738   };
4739 
4740   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4741   session_deps_.socket_factory->AddSocketDataProvider(&data);
4742 
4743   TestCompletionCallback callback;
4744 
4745   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4746   EXPECT_EQ(ERR_IO_PENDING, rv);
4747 
4748   rv = callback.WaitForResult();
4749   EXPECT_EQ(OK, rv);
4750 
4751   const HttpResponseInfo* response = trans->GetResponseInfo();
4752   ASSERT_TRUE(response != NULL);
4753 
4754   EXPECT_TRUE(response->headers.get() != NULL);
4755   std::string status_line = response->headers->GetStatusLine();
4756   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4757 
4758   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4759 
4760   std::string response_data;
4761   rv = ReadTransaction(trans.get(), &response_data);
4762   EXPECT_EQ(OK, rv);
4763   EXPECT_EQ("hello world", response_data);
4764 
4765   // Empty the current queue.  This is necessary because idle sockets are
4766   // added to the connection pool asynchronously with a PostTask.
4767   base::MessageLoop::current()->RunUntilIdle();
4768 
4769   // We now check to make sure the socket was added back to the pool.
4770   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
4771 }
4772 
4773 // Make sure that we recycle a SSL socket after reading all of the response
4774 // body.
TEST_P(HttpNetworkTransactionTest,RecycleSSLSocket)4775 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
4776   HttpRequestInfo request;
4777   request.method = "GET";
4778   request.url = GURL("https://www.google.com/");
4779   request.load_flags = 0;
4780 
4781   MockWrite data_writes[] = {
4782     MockWrite("GET / HTTP/1.1\r\n"
4783               "Host: www.google.com\r\n"
4784               "Connection: keep-alive\r\n\r\n"),
4785   };
4786 
4787   MockRead data_reads[] = {
4788     MockRead("HTTP/1.1 200 OK\r\n"),
4789     MockRead("Content-Length: 11\r\n\r\n"),
4790     MockRead("hello world"),
4791     MockRead(SYNCHRONOUS, OK),
4792   };
4793 
4794   SSLSocketDataProvider ssl(ASYNC, OK);
4795   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4796 
4797   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4798                                 data_writes, arraysize(data_writes));
4799   session_deps_.socket_factory->AddSocketDataProvider(&data);
4800 
4801   TestCompletionCallback callback;
4802 
4803   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4804   scoped_ptr<HttpTransaction> trans(
4805       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4806 
4807   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4808 
4809   EXPECT_EQ(ERR_IO_PENDING, rv);
4810   EXPECT_EQ(OK, callback.WaitForResult());
4811 
4812   const HttpResponseInfo* response = trans->GetResponseInfo();
4813   ASSERT_TRUE(response != NULL);
4814   ASSERT_TRUE(response->headers.get() != NULL);
4815   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4816 
4817   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4818 
4819   std::string response_data;
4820   rv = ReadTransaction(trans.get(), &response_data);
4821   EXPECT_EQ(OK, rv);
4822   EXPECT_EQ("hello world", response_data);
4823 
4824   // Empty the current queue.  This is necessary because idle sockets are
4825   // added to the connection pool asynchronously with a PostTask.
4826   base::MessageLoop::current()->RunUntilIdle();
4827 
4828   // We now check to make sure the socket was added back to the pool.
4829   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
4830 }
4831 
4832 // Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
4833 // from the pool and make sure that we recover okay.
TEST_P(HttpNetworkTransactionTest,RecycleDeadSSLSocket)4834 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
4835   HttpRequestInfo request;
4836   request.method = "GET";
4837   request.url = GURL("https://www.google.com/");
4838   request.load_flags = 0;
4839 
4840   MockWrite data_writes[] = {
4841     MockWrite("GET / HTTP/1.1\r\n"
4842               "Host: www.google.com\r\n"
4843               "Connection: keep-alive\r\n\r\n"),
4844     MockWrite("GET / HTTP/1.1\r\n"
4845               "Host: www.google.com\r\n"
4846               "Connection: keep-alive\r\n\r\n"),
4847   };
4848 
4849   MockRead data_reads[] = {
4850     MockRead("HTTP/1.1 200 OK\r\n"),
4851     MockRead("Content-Length: 11\r\n\r\n"),
4852     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4853     MockRead("hello world"),
4854     MockRead(ASYNC, 0, 0)   // EOF
4855   };
4856 
4857   SSLSocketDataProvider ssl(ASYNC, OK);
4858   SSLSocketDataProvider ssl2(ASYNC, OK);
4859   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4860   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
4861 
4862   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4863                                 data_writes, arraysize(data_writes));
4864   StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4865                                 data_writes, arraysize(data_writes));
4866   session_deps_.socket_factory->AddSocketDataProvider(&data);
4867   session_deps_.socket_factory->AddSocketDataProvider(&data2);
4868 
4869   TestCompletionCallback callback;
4870 
4871   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4872   scoped_ptr<HttpTransaction> trans(
4873       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4874 
4875   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4876 
4877   EXPECT_EQ(ERR_IO_PENDING, rv);
4878   EXPECT_EQ(OK, callback.WaitForResult());
4879 
4880   const HttpResponseInfo* response = trans->GetResponseInfo();
4881   ASSERT_TRUE(response != NULL);
4882   ASSERT_TRUE(response->headers.get() != NULL);
4883   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4884 
4885   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4886 
4887   std::string response_data;
4888   rv = ReadTransaction(trans.get(), &response_data);
4889   EXPECT_EQ(OK, rv);
4890   EXPECT_EQ("hello world", response_data);
4891 
4892   // Empty the current queue.  This is necessary because idle sockets are
4893   // added to the connection pool asynchronously with a PostTask.
4894   base::MessageLoop::current()->RunUntilIdle();
4895 
4896   // We now check to make sure the socket was added back to the pool.
4897   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
4898 
4899   // Now start the second transaction, which should reuse the previous socket.
4900 
4901   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4902 
4903   rv = trans->Start(&request, callback.callback(), BoundNetLog());
4904 
4905   EXPECT_EQ(ERR_IO_PENDING, rv);
4906   EXPECT_EQ(OK, callback.WaitForResult());
4907 
4908   response = trans->GetResponseInfo();
4909   ASSERT_TRUE(response != NULL);
4910   ASSERT_TRUE(response->headers.get() != NULL);
4911   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4912 
4913   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4914 
4915   rv = ReadTransaction(trans.get(), &response_data);
4916   EXPECT_EQ(OK, rv);
4917   EXPECT_EQ("hello world", response_data);
4918 
4919   // Empty the current queue.  This is necessary because idle sockets are
4920   // added to the connection pool asynchronously with a PostTask.
4921   base::MessageLoop::current()->RunUntilIdle();
4922 
4923   // We now check to make sure the socket was added back to the pool.
4924   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
4925 }
4926 
4927 // Make sure that we recycle a socket after a zero-length response.
4928 // http://crbug.com/9880
TEST_P(HttpNetworkTransactionTest,RecycleSocketAfterZeroContentLength)4929 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
4930   HttpRequestInfo request;
4931   request.method = "GET";
4932   request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4933                      "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4934                      "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4935                      "rt=prt.2642,ol.2649,xjs.2951");
4936   request.load_flags = 0;
4937 
4938   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4939 
4940   scoped_ptr<HttpTransaction> trans(
4941       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4942 
4943   MockRead data_reads[] = {
4944     MockRead("HTTP/1.1 204 No Content\r\n"
4945              "Content-Length: 0\r\n"
4946              "Content-Type: text/html\r\n\r\n"),
4947     MockRead("junk"),  // Should not be read!!
4948     MockRead(SYNCHRONOUS, OK),
4949   };
4950 
4951   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4952   session_deps_.socket_factory->AddSocketDataProvider(&data);
4953 
4954   TestCompletionCallback callback;
4955 
4956   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4957   EXPECT_EQ(ERR_IO_PENDING, rv);
4958 
4959   rv = callback.WaitForResult();
4960   EXPECT_EQ(OK, rv);
4961 
4962   const HttpResponseInfo* response = trans->GetResponseInfo();
4963   ASSERT_TRUE(response != NULL);
4964 
4965   EXPECT_TRUE(response->headers.get() != NULL);
4966   std::string status_line = response->headers->GetStatusLine();
4967   EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4968 
4969   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
4970 
4971   std::string response_data;
4972   rv = ReadTransaction(trans.get(), &response_data);
4973   EXPECT_EQ(OK, rv);
4974   EXPECT_EQ("", response_data);
4975 
4976   // Empty the current queue.  This is necessary because idle sockets are
4977   // added to the connection pool asynchronously with a PostTask.
4978   base::MessageLoop::current()->RunUntilIdle();
4979 
4980   // We now check to make sure the socket was added back to the pool.
4981   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
4982 }
4983 
TEST_P(HttpNetworkTransactionTest,ResendRequestOnWriteBodyError)4984 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
4985   ScopedVector<UploadElementReader> element_readers;
4986   element_readers.push_back(new UploadBytesElementReader("foo", 3));
4987   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
4988 
4989   HttpRequestInfo request[2];
4990   // Transaction 1: a GET request that succeeds.  The socket is recycled
4991   // after use.
4992   request[0].method = "GET";
4993   request[0].url = GURL("http://www.google.com/");
4994   request[0].load_flags = 0;
4995   // Transaction 2: a POST request.  Reuses the socket kept alive from
4996   // transaction 1.  The first attempts fails when writing the POST data.
4997   // This causes the transaction to retry with a new socket.  The second
4998   // attempt succeeds.
4999   request[1].method = "POST";
5000   request[1].url = GURL("http://www.google.com/login.cgi");
5001   request[1].upload_data_stream = &upload_data_stream;
5002   request[1].load_flags = 0;
5003 
5004   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5005 
5006   // The first socket is used for transaction 1 and the first attempt of
5007   // transaction 2.
5008 
5009   // The response of transaction 1.
5010   MockRead data_reads1[] = {
5011     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5012     MockRead("hello world"),
5013     MockRead(SYNCHRONOUS, OK),
5014   };
5015   // The mock write results of transaction 1 and the first attempt of
5016   // transaction 2.
5017   MockWrite data_writes1[] = {
5018     MockWrite(SYNCHRONOUS, 64),  // GET
5019     MockWrite(SYNCHRONOUS, 93),  // POST
5020     MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
5021   };
5022   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5023                                  data_writes1, arraysize(data_writes1));
5024 
5025   // The second socket is used for the second attempt of transaction 2.
5026 
5027   // The response of transaction 2.
5028   MockRead data_reads2[] = {
5029     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5030     MockRead("welcome"),
5031     MockRead(SYNCHRONOUS, OK),
5032   };
5033   // The mock write results of the second attempt of transaction 2.
5034   MockWrite data_writes2[] = {
5035     MockWrite(SYNCHRONOUS, 93),  // POST
5036     MockWrite(SYNCHRONOUS, 3),  // POST data
5037   };
5038   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5039                                  data_writes2, arraysize(data_writes2));
5040 
5041   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5042   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5043 
5044   const char* kExpectedResponseData[] = {
5045     "hello world", "welcome"
5046   };
5047 
5048   for (int i = 0; i < 2; ++i) {
5049     scoped_ptr<HttpTransaction> trans(
5050         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5051 
5052     TestCompletionCallback callback;
5053 
5054     int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
5055     EXPECT_EQ(ERR_IO_PENDING, rv);
5056 
5057     rv = callback.WaitForResult();
5058     EXPECT_EQ(OK, rv);
5059 
5060     const HttpResponseInfo* response = trans->GetResponseInfo();
5061     ASSERT_TRUE(response != NULL);
5062 
5063     EXPECT_TRUE(response->headers.get() != NULL);
5064     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5065 
5066     std::string response_data;
5067     rv = ReadTransaction(trans.get(), &response_data);
5068     EXPECT_EQ(OK, rv);
5069     EXPECT_EQ(kExpectedResponseData[i], response_data);
5070   }
5071 }
5072 
5073 // Test the request-challenge-retry sequence for basic auth when there is
5074 // an identity in the URL. The request should be sent as normal, but when
5075 // it fails the identity from the URL is used to answer the challenge.
TEST_P(HttpNetworkTransactionTest,AuthIdentityInURL)5076 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
5077   HttpRequestInfo request;
5078   request.method = "GET";
5079   request.url = GURL("http://foo:b@r@www.google.com/");
5080   request.load_flags = LOAD_NORMAL;
5081 
5082   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5083   scoped_ptr<HttpTransaction> trans(
5084       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5085 
5086   // The password contains an escaped character -- for this test to pass it
5087   // will need to be unescaped by HttpNetworkTransaction.
5088   EXPECT_EQ("b%40r", request.url.password());
5089 
5090   MockWrite data_writes1[] = {
5091     MockWrite("GET / HTTP/1.1\r\n"
5092               "Host: www.google.com\r\n"
5093               "Connection: keep-alive\r\n\r\n"),
5094   };
5095 
5096   MockRead data_reads1[] = {
5097     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5098     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5099     MockRead("Content-Length: 10\r\n\r\n"),
5100     MockRead(SYNCHRONOUS, ERR_FAILED),
5101   };
5102 
5103   // After the challenge above, the transaction will be restarted using the
5104   // identity from the url (foo, b@r) to answer the challenge.
5105   MockWrite data_writes2[] = {
5106     MockWrite("GET / HTTP/1.1\r\n"
5107               "Host: www.google.com\r\n"
5108               "Connection: keep-alive\r\n"
5109               "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
5110   };
5111 
5112   MockRead data_reads2[] = {
5113     MockRead("HTTP/1.0 200 OK\r\n"),
5114     MockRead("Content-Length: 100\r\n\r\n"),
5115     MockRead(SYNCHRONOUS, OK),
5116   };
5117 
5118   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5119                                  data_writes1, arraysize(data_writes1));
5120   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5121                                  data_writes2, arraysize(data_writes2));
5122   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5123   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5124 
5125   TestCompletionCallback callback1;
5126   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5127   EXPECT_EQ(ERR_IO_PENDING, rv);
5128   rv = callback1.WaitForResult();
5129   EXPECT_EQ(OK, rv);
5130   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5131 
5132   TestCompletionCallback callback2;
5133   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5134   EXPECT_EQ(ERR_IO_PENDING, rv);
5135   rv = callback2.WaitForResult();
5136   EXPECT_EQ(OK, rv);
5137   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5138 
5139   const HttpResponseInfo* response = trans->GetResponseInfo();
5140   ASSERT_TRUE(response != NULL);
5141 
5142   // There is no challenge info, since the identity in URL worked.
5143   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5144 
5145   EXPECT_EQ(100, response->headers->GetContentLength());
5146 
5147   // Empty the current queue.
5148   base::MessageLoop::current()->RunUntilIdle();
5149 }
5150 
5151 // Test the request-challenge-retry sequence for basic auth when there is an
5152 // incorrect identity in the URL. The identity from the URL should be used only
5153 // once.
TEST_P(HttpNetworkTransactionTest,WrongAuthIdentityInURL)5154 TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
5155   HttpRequestInfo request;
5156   request.method = "GET";
5157   // Note: the URL has a username:password in it.  The password "baz" is
5158   // wrong (should be "bar").
5159   request.url = GURL("http://foo:baz@www.google.com/");
5160 
5161   request.load_flags = LOAD_NORMAL;
5162 
5163   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5164   scoped_ptr<HttpTransaction> trans(
5165       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5166 
5167   MockWrite data_writes1[] = {
5168     MockWrite("GET / HTTP/1.1\r\n"
5169               "Host: www.google.com\r\n"
5170               "Connection: keep-alive\r\n\r\n"),
5171   };
5172 
5173   MockRead data_reads1[] = {
5174     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5175     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5176     MockRead("Content-Length: 10\r\n\r\n"),
5177     MockRead(SYNCHRONOUS, ERR_FAILED),
5178   };
5179 
5180   // After the challenge above, the transaction will be restarted using the
5181   // identity from the url (foo, baz) to answer the challenge.
5182   MockWrite data_writes2[] = {
5183     MockWrite("GET / HTTP/1.1\r\n"
5184               "Host: www.google.com\r\n"
5185               "Connection: keep-alive\r\n"
5186               "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
5187   };
5188 
5189   MockRead data_reads2[] = {
5190     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5191     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5192     MockRead("Content-Length: 10\r\n\r\n"),
5193     MockRead(SYNCHRONOUS, ERR_FAILED),
5194   };
5195 
5196   // After the challenge above, the transaction will be restarted using the
5197   // identity supplied by the user (foo, bar) to answer the challenge.
5198   MockWrite data_writes3[] = {
5199     MockWrite("GET / HTTP/1.1\r\n"
5200               "Host: www.google.com\r\n"
5201               "Connection: keep-alive\r\n"
5202               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5203   };
5204 
5205   MockRead data_reads3[] = {
5206     MockRead("HTTP/1.0 200 OK\r\n"),
5207     MockRead("Content-Length: 100\r\n\r\n"),
5208     MockRead(SYNCHRONOUS, OK),
5209   };
5210 
5211   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5212                                  data_writes1, arraysize(data_writes1));
5213   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5214                                  data_writes2, arraysize(data_writes2));
5215   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5216                                  data_writes3, arraysize(data_writes3));
5217   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5218   session_deps_.socket_factory->AddSocketDataProvider(&data2);
5219   session_deps_.socket_factory->AddSocketDataProvider(&data3);
5220 
5221   TestCompletionCallback callback1;
5222 
5223   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5224   EXPECT_EQ(ERR_IO_PENDING, rv);
5225 
5226   rv = callback1.WaitForResult();
5227   EXPECT_EQ(OK, rv);
5228 
5229   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5230   TestCompletionCallback callback2;
5231   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5232   EXPECT_EQ(ERR_IO_PENDING, rv);
5233   rv = callback2.WaitForResult();
5234   EXPECT_EQ(OK, rv);
5235   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5236 
5237   const HttpResponseInfo* response = trans->GetResponseInfo();
5238   ASSERT_TRUE(response != NULL);
5239   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5240 
5241   TestCompletionCallback callback3;
5242   rv = trans->RestartWithAuth(
5243       AuthCredentials(kFoo, kBar), callback3.callback());
5244   EXPECT_EQ(ERR_IO_PENDING, rv);
5245   rv = callback3.WaitForResult();
5246   EXPECT_EQ(OK, rv);
5247   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5248 
5249   response = trans->GetResponseInfo();
5250   ASSERT_TRUE(response != NULL);
5251 
5252   // There is no challenge info, since the identity worked.
5253   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5254 
5255   EXPECT_EQ(100, response->headers->GetContentLength());
5256 
5257   // Empty the current queue.
5258   base::MessageLoop::current()->RunUntilIdle();
5259 }
5260 
5261 
5262 // Test the request-challenge-retry sequence for basic auth when there is a
5263 // correct identity in the URL, but its use is being suppressed. The identity
5264 // from the URL should never be used.
TEST_P(HttpNetworkTransactionTest,AuthIdentityInURLSuppressed)5265 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5266   HttpRequestInfo request;
5267   request.method = "GET";
5268   request.url = GURL("http://foo:bar@www.google.com/");
5269   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5270 
5271   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5272   scoped_ptr<HttpTransaction> trans(
5273       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5274 
5275   MockWrite data_writes1[] = {
5276     MockWrite("GET / HTTP/1.1\r\n"
5277               "Host: www.google.com\r\n"
5278               "Connection: keep-alive\r\n\r\n"),
5279   };
5280 
5281   MockRead data_reads1[] = {
5282     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5283     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5284     MockRead("Content-Length: 10\r\n\r\n"),
5285     MockRead(SYNCHRONOUS, ERR_FAILED),
5286   };
5287 
5288   // After the challenge above, the transaction will be restarted using the
5289   // identity supplied by the user, not the one in the URL, to answer the
5290   // challenge.
5291   MockWrite data_writes3[] = {
5292     MockWrite("GET / HTTP/1.1\r\n"
5293               "Host: www.google.com\r\n"
5294               "Connection: keep-alive\r\n"
5295               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5296   };
5297 
5298   MockRead data_reads3[] = {
5299     MockRead("HTTP/1.0 200 OK\r\n"),
5300     MockRead("Content-Length: 100\r\n\r\n"),
5301     MockRead(SYNCHRONOUS, OK),
5302   };
5303 
5304   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5305                                  data_writes1, arraysize(data_writes1));
5306   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5307                                  data_writes3, arraysize(data_writes3));
5308   session_deps_.socket_factory->AddSocketDataProvider(&data1);
5309   session_deps_.socket_factory->AddSocketDataProvider(&data3);
5310 
5311   TestCompletionCallback callback1;
5312   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5313   EXPECT_EQ(ERR_IO_PENDING, rv);
5314   rv = callback1.WaitForResult();
5315   EXPECT_EQ(OK, rv);
5316   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5317 
5318   const HttpResponseInfo* response = trans->GetResponseInfo();
5319   ASSERT_TRUE(response != NULL);
5320   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5321 
5322   TestCompletionCallback callback3;
5323   rv = trans->RestartWithAuth(
5324       AuthCredentials(kFoo, kBar), callback3.callback());
5325   EXPECT_EQ(ERR_IO_PENDING, rv);
5326   rv = callback3.WaitForResult();
5327   EXPECT_EQ(OK, rv);
5328   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5329 
5330   response = trans->GetResponseInfo();
5331   ASSERT_TRUE(response != NULL);
5332 
5333   // There is no challenge info, since the identity worked.
5334   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5335   EXPECT_EQ(100, response->headers->GetContentLength());
5336 
5337   // Empty the current queue.
5338   base::MessageLoop::current()->RunUntilIdle();
5339 }
5340 
5341 // Test that previously tried username/passwords for a realm get re-used.
TEST_P(HttpNetworkTransactionTest,BasicAuthCacheAndPreauth)5342 TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
5343   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5344 
5345   // Transaction 1: authenticate (foo, bar) on MyRealm1
5346   {
5347     HttpRequestInfo request;
5348     request.method = "GET";
5349     request.url = GURL("http://www.google.com/x/y/z");
5350     request.load_flags = 0;
5351 
5352     scoped_ptr<HttpTransaction> trans(
5353         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5354 
5355     MockWrite data_writes1[] = {
5356       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5357                 "Host: www.google.com\r\n"
5358                 "Connection: keep-alive\r\n\r\n"),
5359     };
5360 
5361     MockRead data_reads1[] = {
5362       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5363       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5364       MockRead("Content-Length: 10000\r\n\r\n"),
5365       MockRead(SYNCHRONOUS, ERR_FAILED),
5366     };
5367 
5368     // Resend with authorization (username=foo, password=bar)
5369     MockWrite data_writes2[] = {
5370       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5371                 "Host: www.google.com\r\n"
5372                 "Connection: keep-alive\r\n"
5373                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5374     };
5375 
5376     // Sever accepts the authorization.
5377     MockRead data_reads2[] = {
5378       MockRead("HTTP/1.0 200 OK\r\n"),
5379       MockRead("Content-Length: 100\r\n\r\n"),
5380       MockRead(SYNCHRONOUS, OK),
5381     };
5382 
5383     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5384                                    data_writes1, arraysize(data_writes1));
5385     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5386                                    data_writes2, arraysize(data_writes2));
5387     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5388     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5389 
5390     TestCompletionCallback callback1;
5391 
5392     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5393     EXPECT_EQ(ERR_IO_PENDING, rv);
5394 
5395     rv = callback1.WaitForResult();
5396     EXPECT_EQ(OK, rv);
5397 
5398     const HttpResponseInfo* response = trans->GetResponseInfo();
5399     ASSERT_TRUE(response != NULL);
5400     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5401 
5402     TestCompletionCallback callback2;
5403 
5404     rv = trans->RestartWithAuth(
5405         AuthCredentials(kFoo, kBar), callback2.callback());
5406     EXPECT_EQ(ERR_IO_PENDING, rv);
5407 
5408     rv = callback2.WaitForResult();
5409     EXPECT_EQ(OK, rv);
5410 
5411     response = trans->GetResponseInfo();
5412     ASSERT_TRUE(response != NULL);
5413     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5414     EXPECT_EQ(100, response->headers->GetContentLength());
5415   }
5416 
5417   // ------------------------------------------------------------------------
5418 
5419   // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5420   {
5421     HttpRequestInfo request;
5422     request.method = "GET";
5423     // Note that Transaction 1 was at /x/y/z, so this is in the same
5424     // protection space as MyRealm1.
5425     request.url = GURL("http://www.google.com/x/y/a/b");
5426     request.load_flags = 0;
5427 
5428     scoped_ptr<HttpTransaction> trans(
5429         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5430 
5431     MockWrite data_writes1[] = {
5432       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5433                 "Host: www.google.com\r\n"
5434                 "Connection: keep-alive\r\n"
5435                 // Send preemptive authorization for MyRealm1
5436                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5437     };
5438 
5439     // The server didn't like the preemptive authorization, and
5440     // challenges us for a different realm (MyRealm2).
5441     MockRead data_reads1[] = {
5442       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5443       MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5444       MockRead("Content-Length: 10000\r\n\r\n"),
5445       MockRead(SYNCHRONOUS, ERR_FAILED),
5446     };
5447 
5448     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5449     MockWrite data_writes2[] = {
5450       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5451                 "Host: www.google.com\r\n"
5452                 "Connection: keep-alive\r\n"
5453                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5454     };
5455 
5456     // Sever accepts the authorization.
5457     MockRead data_reads2[] = {
5458       MockRead("HTTP/1.0 200 OK\r\n"),
5459       MockRead("Content-Length: 100\r\n\r\n"),
5460       MockRead(SYNCHRONOUS, OK),
5461     };
5462 
5463     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5464                                    data_writes1, arraysize(data_writes1));
5465     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5466                                    data_writes2, arraysize(data_writes2));
5467     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5468     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5469 
5470     TestCompletionCallback callback1;
5471 
5472     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5473     EXPECT_EQ(ERR_IO_PENDING, rv);
5474 
5475     rv = callback1.WaitForResult();
5476     EXPECT_EQ(OK, rv);
5477 
5478     const HttpResponseInfo* response = trans->GetResponseInfo();
5479     ASSERT_TRUE(response != NULL);
5480     ASSERT_TRUE(response->auth_challenge.get());
5481     EXPECT_FALSE(response->auth_challenge->is_proxy);
5482     EXPECT_EQ("www.google.com:80",
5483               response->auth_challenge->challenger.ToString());
5484     EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5485     EXPECT_EQ("basic", response->auth_challenge->scheme);
5486 
5487     TestCompletionCallback callback2;
5488 
5489     rv = trans->RestartWithAuth(
5490         AuthCredentials(kFoo2, kBar2), callback2.callback());
5491     EXPECT_EQ(ERR_IO_PENDING, rv);
5492 
5493     rv = callback2.WaitForResult();
5494     EXPECT_EQ(OK, rv);
5495 
5496     response = trans->GetResponseInfo();
5497     ASSERT_TRUE(response != NULL);
5498     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5499     EXPECT_EQ(100, response->headers->GetContentLength());
5500   }
5501 
5502   // ------------------------------------------------------------------------
5503 
5504   // Transaction 3: Resend a request in MyRealm's protection space --
5505   // succeed with preemptive authorization.
5506   {
5507     HttpRequestInfo request;
5508     request.method = "GET";
5509     request.url = GURL("http://www.google.com/x/y/z2");
5510     request.load_flags = 0;
5511 
5512     scoped_ptr<HttpTransaction> trans(
5513         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5514 
5515     MockWrite data_writes1[] = {
5516       MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5517                 "Host: www.google.com\r\n"
5518                 "Connection: keep-alive\r\n"
5519                 // The authorization for MyRealm1 gets sent preemptively
5520                 // (since the url is in the same protection space)
5521                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5522     };
5523 
5524     // Sever accepts the preemptive authorization
5525     MockRead data_reads1[] = {
5526       MockRead("HTTP/1.0 200 OK\r\n"),
5527       MockRead("Content-Length: 100\r\n\r\n"),
5528       MockRead(SYNCHRONOUS, OK),
5529     };
5530 
5531     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5532                                    data_writes1, arraysize(data_writes1));
5533     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5534 
5535     TestCompletionCallback callback1;
5536 
5537     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5538     EXPECT_EQ(ERR_IO_PENDING, rv);
5539 
5540     rv = callback1.WaitForResult();
5541     EXPECT_EQ(OK, rv);
5542 
5543     const HttpResponseInfo* response = trans->GetResponseInfo();
5544     ASSERT_TRUE(response != NULL);
5545 
5546     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5547     EXPECT_EQ(100, response->headers->GetContentLength());
5548   }
5549 
5550   // ------------------------------------------------------------------------
5551 
5552   // Transaction 4: request another URL in MyRealm (however the
5553   // url is not known to belong to the protection space, so no pre-auth).
5554   {
5555     HttpRequestInfo request;
5556     request.method = "GET";
5557     request.url = GURL("http://www.google.com/x/1");
5558     request.load_flags = 0;
5559 
5560     scoped_ptr<HttpTransaction> trans(
5561         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5562 
5563     MockWrite data_writes1[] = {
5564       MockWrite("GET /x/1 HTTP/1.1\r\n"
5565                 "Host: www.google.com\r\n"
5566                 "Connection: keep-alive\r\n\r\n"),
5567     };
5568 
5569     MockRead data_reads1[] = {
5570       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5571       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5572       MockRead("Content-Length: 10000\r\n\r\n"),
5573       MockRead(SYNCHRONOUS, ERR_FAILED),
5574     };
5575 
5576     // Resend with authorization from MyRealm's cache.
5577     MockWrite data_writes2[] = {
5578       MockWrite("GET /x/1 HTTP/1.1\r\n"
5579                 "Host: www.google.com\r\n"
5580                 "Connection: keep-alive\r\n"
5581                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5582     };
5583 
5584     // Sever accepts the authorization.
5585     MockRead data_reads2[] = {
5586       MockRead("HTTP/1.0 200 OK\r\n"),
5587       MockRead("Content-Length: 100\r\n\r\n"),
5588       MockRead(SYNCHRONOUS, OK),
5589     };
5590 
5591     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5592                                    data_writes1, arraysize(data_writes1));
5593     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5594                                    data_writes2, arraysize(data_writes2));
5595     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5596     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5597 
5598     TestCompletionCallback callback1;
5599 
5600     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5601     EXPECT_EQ(ERR_IO_PENDING, rv);
5602 
5603     rv = callback1.WaitForResult();
5604     EXPECT_EQ(OK, rv);
5605 
5606     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5607     TestCompletionCallback callback2;
5608     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5609     EXPECT_EQ(ERR_IO_PENDING, rv);
5610     rv = callback2.WaitForResult();
5611     EXPECT_EQ(OK, rv);
5612     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5613 
5614     const HttpResponseInfo* response = trans->GetResponseInfo();
5615     ASSERT_TRUE(response != NULL);
5616     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5617     EXPECT_EQ(100, response->headers->GetContentLength());
5618   }
5619 
5620   // ------------------------------------------------------------------------
5621 
5622   // Transaction 5: request a URL in MyRealm, but the server rejects the
5623   // cached identity. Should invalidate and re-prompt.
5624   {
5625     HttpRequestInfo request;
5626     request.method = "GET";
5627     request.url = GURL("http://www.google.com/p/q/t");
5628     request.load_flags = 0;
5629 
5630     scoped_ptr<HttpTransaction> trans(
5631         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5632 
5633     MockWrite data_writes1[] = {
5634       MockWrite("GET /p/q/t 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_reads1[] = {
5640       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5641       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5642       MockRead("Content-Length: 10000\r\n\r\n"),
5643       MockRead(SYNCHRONOUS, ERR_FAILED),
5644     };
5645 
5646     // Resend with authorization from cache for MyRealm.
5647     MockWrite data_writes2[] = {
5648       MockWrite("GET /p/q/t HTTP/1.1\r\n"
5649                 "Host: www.google.com\r\n"
5650                 "Connection: keep-alive\r\n"
5651                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5652     };
5653 
5654     // Sever rejects the authorization.
5655     MockRead data_reads2[] = {
5656       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5657       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5658       MockRead("Content-Length: 10000\r\n\r\n"),
5659       MockRead(SYNCHRONOUS, ERR_FAILED),
5660     };
5661 
5662     // At this point we should prompt for new credentials for MyRealm.
5663     // Restart with username=foo3, password=foo4.
5664     MockWrite data_writes3[] = {
5665       MockWrite("GET /p/q/t HTTP/1.1\r\n"
5666                 "Host: www.google.com\r\n"
5667                 "Connection: keep-alive\r\n"
5668                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5669     };
5670 
5671     // Sever accepts the authorization.
5672     MockRead data_reads3[] = {
5673       MockRead("HTTP/1.0 200 OK\r\n"),
5674       MockRead("Content-Length: 100\r\n\r\n"),
5675       MockRead(SYNCHRONOUS, OK),
5676     };
5677 
5678     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5679                                    data_writes1, arraysize(data_writes1));
5680     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5681                                    data_writes2, arraysize(data_writes2));
5682     StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5683                                    data_writes3, arraysize(data_writes3));
5684     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5685     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5686     session_deps_.socket_factory->AddSocketDataProvider(&data3);
5687 
5688     TestCompletionCallback callback1;
5689 
5690     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5691     EXPECT_EQ(ERR_IO_PENDING, rv);
5692 
5693     rv = callback1.WaitForResult();
5694     EXPECT_EQ(OK, rv);
5695 
5696     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5697     TestCompletionCallback callback2;
5698     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5699     EXPECT_EQ(ERR_IO_PENDING, rv);
5700     rv = callback2.WaitForResult();
5701     EXPECT_EQ(OK, rv);
5702     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5703 
5704     const HttpResponseInfo* response = trans->GetResponseInfo();
5705     ASSERT_TRUE(response != NULL);
5706     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5707 
5708     TestCompletionCallback callback3;
5709 
5710     rv = trans->RestartWithAuth(
5711         AuthCredentials(kFoo3, kBar3), callback3.callback());
5712     EXPECT_EQ(ERR_IO_PENDING, rv);
5713 
5714     rv = callback3.WaitForResult();
5715     EXPECT_EQ(OK, rv);
5716 
5717     response = trans->GetResponseInfo();
5718     ASSERT_TRUE(response != NULL);
5719     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5720     EXPECT_EQ(100, response->headers->GetContentLength());
5721   }
5722 }
5723 
5724 // Tests that nonce count increments when multiple auth attempts
5725 // are started with the same nonce.
TEST_P(HttpNetworkTransactionTest,DigestPreAuthNonceCount)5726 TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
5727   HttpAuthHandlerDigest::Factory* digest_factory =
5728       new HttpAuthHandlerDigest::Factory();
5729   HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5730       new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5731   digest_factory->set_nonce_generator(nonce_generator);
5732   session_deps_.http_auth_handler_factory.reset(digest_factory);
5733   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5734 
5735   // Transaction 1: authenticate (foo, bar) on MyRealm1
5736   {
5737     HttpRequestInfo request;
5738     request.method = "GET";
5739     request.url = GURL("http://www.google.com/x/y/z");
5740     request.load_flags = 0;
5741 
5742     scoped_ptr<HttpTransaction> trans(
5743         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5744 
5745     MockWrite data_writes1[] = {
5746       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5747                 "Host: www.google.com\r\n"
5748                 "Connection: keep-alive\r\n\r\n"),
5749     };
5750 
5751     MockRead data_reads1[] = {
5752       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5753       MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5754                "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
5755       MockRead(SYNCHRONOUS, OK),
5756     };
5757 
5758     // Resend with authorization (username=foo, password=bar)
5759     MockWrite data_writes2[] = {
5760       MockWrite("GET /x/y/z HTTP/1.1\r\n"
5761                 "Host: www.google.com\r\n"
5762                 "Connection: keep-alive\r\n"
5763                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5764                 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5765                 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5766                 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5767     };
5768 
5769     // Sever accepts the authorization.
5770     MockRead data_reads2[] = {
5771       MockRead("HTTP/1.0 200 OK\r\n"),
5772       MockRead(SYNCHRONOUS, OK),
5773     };
5774 
5775     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5776                                    data_writes1, arraysize(data_writes1));
5777     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5778                                    data_writes2, arraysize(data_writes2));
5779     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5780     session_deps_.socket_factory->AddSocketDataProvider(&data2);
5781 
5782     TestCompletionCallback callback1;
5783 
5784     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5785     EXPECT_EQ(ERR_IO_PENDING, rv);
5786 
5787     rv = callback1.WaitForResult();
5788     EXPECT_EQ(OK, rv);
5789 
5790     const HttpResponseInfo* response = trans->GetResponseInfo();
5791     ASSERT_TRUE(response != NULL);
5792     EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
5793 
5794     TestCompletionCallback callback2;
5795 
5796     rv = trans->RestartWithAuth(
5797         AuthCredentials(kFoo, kBar), callback2.callback());
5798     EXPECT_EQ(ERR_IO_PENDING, rv);
5799 
5800     rv = callback2.WaitForResult();
5801     EXPECT_EQ(OK, rv);
5802 
5803     response = trans->GetResponseInfo();
5804     ASSERT_TRUE(response != NULL);
5805     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5806   }
5807 
5808   // ------------------------------------------------------------------------
5809 
5810   // Transaction 2: Request another resource in digestive's protection space.
5811   // This will preemptively add an Authorization header which should have an
5812   // "nc" value of 2 (as compared to 1 in the first use.
5813   {
5814     HttpRequestInfo request;
5815     request.method = "GET";
5816     // Note that Transaction 1 was at /x/y/z, so this is in the same
5817     // protection space as digest.
5818     request.url = GURL("http://www.google.com/x/y/a/b");
5819     request.load_flags = 0;
5820 
5821     scoped_ptr<HttpTransaction> trans(
5822         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
5823 
5824     MockWrite data_writes1[] = {
5825       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5826                 "Host: www.google.com\r\n"
5827                 "Connection: keep-alive\r\n"
5828                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5829                 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5830                 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5831                 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5832     };
5833 
5834     // Sever accepts the authorization.
5835     MockRead data_reads1[] = {
5836       MockRead("HTTP/1.0 200 OK\r\n"),
5837       MockRead("Content-Length: 100\r\n\r\n"),
5838       MockRead(SYNCHRONOUS, OK),
5839     };
5840 
5841     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5842                                    data_writes1, arraysize(data_writes1));
5843     session_deps_.socket_factory->AddSocketDataProvider(&data1);
5844 
5845     TestCompletionCallback callback1;
5846 
5847     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5848     EXPECT_EQ(ERR_IO_PENDING, rv);
5849 
5850     rv = callback1.WaitForResult();
5851     EXPECT_EQ(OK, rv);
5852 
5853     const HttpResponseInfo* response = trans->GetResponseInfo();
5854     ASSERT_TRUE(response != NULL);
5855     EXPECT_TRUE(response->auth_challenge.get() == NULL);
5856   }
5857 }
5858 
5859 // Test the ResetStateForRestart() private method.
TEST_P(HttpNetworkTransactionTest,ResetStateForRestart)5860 TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
5861   // Create a transaction (the dependencies aren't important).
5862   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5863   scoped_ptr<HttpNetworkTransaction> trans(
5864       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5865 
5866   // Setup some state (which we expect ResetStateForRestart() will clear).
5867   trans->read_buf_ = new IOBuffer(15);
5868   trans->read_buf_len_ = 15;
5869   trans->request_headers_.SetHeader("Authorization", "NTLM");
5870 
5871   // Setup state in response_
5872   HttpResponseInfo* response = &trans->response_;
5873   response->auth_challenge = new AuthChallengeInfo();
5874   response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
5875   response->response_time = base::Time::Now();
5876   response->was_cached = true;  // (Wouldn't ever actually be true...)
5877 
5878   { // Setup state for response_.vary_data
5879     HttpRequestInfo request;
5880     std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5881     std::replace(temp.begin(), temp.end(), '\n', '\0');
5882     scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
5883     request.extra_headers.SetHeader("Foo", "1");
5884     request.extra_headers.SetHeader("bar", "23");
5885     EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
5886   }
5887 
5888   // Cause the above state to be reset.
5889   trans->ResetStateForRestart();
5890 
5891   // Verify that the state that needed to be reset, has been reset.
5892   EXPECT_TRUE(trans->read_buf_.get() == NULL);
5893   EXPECT_EQ(0, trans->read_buf_len_);
5894   EXPECT_TRUE(trans->request_headers_.IsEmpty());
5895   EXPECT_TRUE(response->auth_challenge.get() == NULL);
5896   EXPECT_TRUE(response->headers.get() == NULL);
5897   EXPECT_FALSE(response->was_cached);
5898   EXPECT_EQ(0U, response->ssl_info.cert_status);
5899   EXPECT_FALSE(response->vary_data.is_valid());
5900 }
5901 
5902 // Test HTTPS connections to a site with a bad certificate
TEST_P(HttpNetworkTransactionTest,HTTPSBadCertificate)5903 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
5904   HttpRequestInfo request;
5905   request.method = "GET";
5906   request.url = GURL("https://www.google.com/");
5907   request.load_flags = 0;
5908 
5909   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5910   scoped_ptr<HttpTransaction> trans(
5911       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
5912 
5913   MockWrite data_writes[] = {
5914     MockWrite("GET / HTTP/1.1\r\n"
5915               "Host: www.google.com\r\n"
5916               "Connection: keep-alive\r\n\r\n"),
5917   };
5918 
5919   MockRead data_reads[] = {
5920     MockRead("HTTP/1.0 200 OK\r\n"),
5921     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5922     MockRead("Content-Length: 100\r\n\r\n"),
5923     MockRead(SYNCHRONOUS, OK),
5924   };
5925 
5926   StaticSocketDataProvider ssl_bad_certificate;
5927   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5928                                 data_writes, arraysize(data_writes));
5929   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5930   SSLSocketDataProvider ssl(ASYNC, OK);
5931 
5932   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5933   session_deps_.socket_factory->AddSocketDataProvider(&data);
5934   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5935   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5936 
5937   TestCompletionCallback callback;
5938 
5939   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5940   EXPECT_EQ(ERR_IO_PENDING, rv);
5941 
5942   rv = callback.WaitForResult();
5943   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5944 
5945   rv = trans->RestartIgnoringLastError(callback.callback());
5946   EXPECT_EQ(ERR_IO_PENDING, rv);
5947 
5948   rv = callback.WaitForResult();
5949   EXPECT_EQ(OK, rv);
5950 
5951   const HttpResponseInfo* response = trans->GetResponseInfo();
5952 
5953   ASSERT_TRUE(response != NULL);
5954   EXPECT_EQ(100, response->headers->GetContentLength());
5955 }
5956 
5957 // Test HTTPS connections to a site with a bad certificate, going through a
5958 // proxy
TEST_P(HttpNetworkTransactionTest,HTTPSBadCertificateViaProxy)5959 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
5960   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
5961 
5962   HttpRequestInfo request;
5963   request.method = "GET";
5964   request.url = GURL("https://www.google.com/");
5965   request.load_flags = 0;
5966 
5967   MockWrite proxy_writes[] = {
5968     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5969               "Host: www.google.com\r\n"
5970               "Proxy-Connection: keep-alive\r\n\r\n"),
5971   };
5972 
5973   MockRead proxy_reads[] = {
5974     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5975     MockRead(SYNCHRONOUS, OK)
5976   };
5977 
5978   MockWrite data_writes[] = {
5979     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5980               "Host: www.google.com\r\n"
5981               "Proxy-Connection: keep-alive\r\n\r\n"),
5982     MockWrite("GET / HTTP/1.1\r\n"
5983               "Host: www.google.com\r\n"
5984               "Connection: keep-alive\r\n\r\n"),
5985   };
5986 
5987   MockRead data_reads[] = {
5988     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5989     MockRead("HTTP/1.0 200 OK\r\n"),
5990     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5991     MockRead("Content-Length: 100\r\n\r\n"),
5992     MockRead(SYNCHRONOUS, OK),
5993   };
5994 
5995   StaticSocketDataProvider ssl_bad_certificate(
5996       proxy_reads, arraysize(proxy_reads),
5997       proxy_writes, arraysize(proxy_writes));
5998   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5999                                 data_writes, arraysize(data_writes));
6000   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6001   SSLSocketDataProvider ssl(ASYNC, OK);
6002 
6003   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6004   session_deps_.socket_factory->AddSocketDataProvider(&data);
6005   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6006   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6007 
6008   TestCompletionCallback callback;
6009 
6010   for (int i = 0; i < 2; i++) {
6011     session_deps_.socket_factory->ResetNextMockIndexes();
6012 
6013     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6014     scoped_ptr<HttpTransaction> trans(
6015         new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6016 
6017     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6018     EXPECT_EQ(ERR_IO_PENDING, rv);
6019 
6020     rv = callback.WaitForResult();
6021     EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6022 
6023     rv = trans->RestartIgnoringLastError(callback.callback());
6024     EXPECT_EQ(ERR_IO_PENDING, rv);
6025 
6026     rv = callback.WaitForResult();
6027     EXPECT_EQ(OK, rv);
6028 
6029     const HttpResponseInfo* response = trans->GetResponseInfo();
6030 
6031     ASSERT_TRUE(response != NULL);
6032     EXPECT_EQ(100, response->headers->GetContentLength());
6033   }
6034 }
6035 
6036 
6037 // Test HTTPS connections to a site, going through an HTTPS proxy
TEST_P(HttpNetworkTransactionTest,HTTPSViaHttpsProxy)6038 TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
6039   session_deps_.proxy_service.reset(
6040       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6041   CapturingNetLog net_log;
6042   session_deps_.net_log = &net_log;
6043 
6044   HttpRequestInfo request;
6045   request.method = "GET";
6046   request.url = GURL("https://www.google.com/");
6047   request.load_flags = 0;
6048 
6049   MockWrite data_writes[] = {
6050     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6051               "Host: www.google.com\r\n"
6052               "Proxy-Connection: keep-alive\r\n\r\n"),
6053     MockWrite("GET / HTTP/1.1\r\n"
6054               "Host: www.google.com\r\n"
6055               "Connection: keep-alive\r\n\r\n"),
6056   };
6057 
6058   MockRead data_reads[] = {
6059     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6060     MockRead("HTTP/1.1 200 OK\r\n"),
6061     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6062     MockRead("Content-Length: 100\r\n\r\n"),
6063     MockRead(SYNCHRONOUS, OK),
6064   };
6065 
6066   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6067                                 data_writes, arraysize(data_writes));
6068   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6069   SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
6070 
6071   session_deps_.socket_factory->AddSocketDataProvider(&data);
6072   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6073   session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
6074 
6075   TestCompletionCallback callback;
6076 
6077   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6078   scoped_ptr<HttpTransaction> trans(
6079       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6080 
6081   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6082   EXPECT_EQ(ERR_IO_PENDING, rv);
6083 
6084   rv = callback.WaitForResult();
6085   EXPECT_EQ(OK, rv);
6086   const HttpResponseInfo* response = trans->GetResponseInfo();
6087 
6088   ASSERT_TRUE(response != NULL);
6089 
6090   EXPECT_TRUE(response->headers->IsKeepAlive());
6091   EXPECT_EQ(200, response->headers->response_code());
6092   EXPECT_EQ(100, response->headers->GetContentLength());
6093   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6094 
6095   LoadTimingInfo load_timing_info;
6096   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6097   TestLoadTimingNotReusedWithPac(load_timing_info,
6098                                  CONNECT_TIMING_HAS_SSL_TIMES);
6099 }
6100 
6101 // Test an HTTPS Proxy's ability to redirect a CONNECT request
TEST_P(HttpNetworkTransactionTest,RedirectOfHttpsConnectViaHttpsProxy)6102 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
6103   session_deps_.proxy_service.reset(
6104       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6105   CapturingNetLog net_log;
6106   session_deps_.net_log = &net_log;
6107 
6108   HttpRequestInfo request;
6109   request.method = "GET";
6110   request.url = GURL("https://www.google.com/");
6111   request.load_flags = 0;
6112 
6113   MockWrite data_writes[] = {
6114     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6115               "Host: www.google.com\r\n"
6116               "Proxy-Connection: keep-alive\r\n\r\n"),
6117   };
6118 
6119   MockRead data_reads[] = {
6120     MockRead("HTTP/1.1 302 Redirect\r\n"),
6121     MockRead("Location: http://login.example.com/\r\n"),
6122     MockRead("Content-Length: 0\r\n\r\n"),
6123     MockRead(SYNCHRONOUS, OK),
6124   };
6125 
6126   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6127                                 data_writes, arraysize(data_writes));
6128   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6129 
6130   session_deps_.socket_factory->AddSocketDataProvider(&data);
6131   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6132 
6133   TestCompletionCallback callback;
6134 
6135   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6136   scoped_ptr<HttpTransaction> trans(
6137       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6138 
6139   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6140   EXPECT_EQ(ERR_IO_PENDING, rv);
6141 
6142   rv = callback.WaitForResult();
6143   EXPECT_EQ(OK, rv);
6144   const HttpResponseInfo* response = trans->GetResponseInfo();
6145 
6146   ASSERT_TRUE(response != NULL);
6147 
6148   EXPECT_EQ(302, response->headers->response_code());
6149   std::string url;
6150   EXPECT_TRUE(response->headers->IsRedirect(&url));
6151   EXPECT_EQ("http://login.example.com/", url);
6152 
6153   // In the case of redirects from proxies, HttpNetworkTransaction returns
6154   // timing for the proxy connection instead of the connection to the host,
6155   // and no send / receive times.
6156   // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6157   LoadTimingInfo load_timing_info;
6158   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6159 
6160   EXPECT_FALSE(load_timing_info.socket_reused);
6161   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
6162 
6163   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6164   EXPECT_LE(load_timing_info.proxy_resolve_start,
6165             load_timing_info.proxy_resolve_end);
6166   EXPECT_LE(load_timing_info.proxy_resolve_end,
6167             load_timing_info.connect_timing.connect_start);
6168   ExpectConnectTimingHasTimes(
6169       load_timing_info.connect_timing,
6170       CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6171 
6172   EXPECT_TRUE(load_timing_info.send_start.is_null());
6173   EXPECT_TRUE(load_timing_info.send_end.is_null());
6174   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
6175 }
6176 
6177 // Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
TEST_P(HttpNetworkTransactionTest,RedirectOfHttpsConnectViaSpdyProxy)6178 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
6179   session_deps_.proxy_service.reset(
6180       ProxyService::CreateFixed("https://proxy:70"));
6181 
6182   HttpRequestInfo request;
6183   request.method = "GET";
6184   request.url = GURL("https://www.google.com/");
6185   request.load_flags = 0;
6186 
6187   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6188                                                              LOWEST));
6189   scoped_ptr<SpdyFrame> goaway(
6190       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
6191   MockWrite data_writes[] = {
6192     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6193     CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
6194   };
6195 
6196   static const char* const kExtraHeaders[] = {
6197     "location",
6198     "http://login.example.com/",
6199   };
6200   scoped_ptr<SpdyFrame> resp(
6201       spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
6202                                  arraysize(kExtraHeaders)/2, 1));
6203   MockRead data_reads[] = {
6204     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6205     MockRead(ASYNC, 0, 2),  // EOF
6206   };
6207 
6208   DelayedSocketData data(
6209       1,  // wait for one write to finish before reading.
6210       data_reads, arraysize(data_reads),
6211       data_writes, arraysize(data_writes));
6212   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6213   proxy_ssl.SetNextProto(GetParam());
6214 
6215   session_deps_.socket_factory->AddSocketDataProvider(&data);
6216   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6217 
6218   TestCompletionCallback callback;
6219 
6220   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6221   scoped_ptr<HttpTransaction> trans(
6222       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6223 
6224   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6225   EXPECT_EQ(ERR_IO_PENDING, rv);
6226 
6227   rv = callback.WaitForResult();
6228   EXPECT_EQ(OK, rv);
6229   const HttpResponseInfo* response = trans->GetResponseInfo();
6230 
6231   ASSERT_TRUE(response != NULL);
6232 
6233   EXPECT_EQ(302, response->headers->response_code());
6234   std::string url;
6235   EXPECT_TRUE(response->headers->IsRedirect(&url));
6236   EXPECT_EQ("http://login.example.com/", url);
6237 }
6238 
6239 // Test that an HTTPS proxy's response to a CONNECT request is filtered.
TEST_P(HttpNetworkTransactionTest,ErrorResponseToHttpsConnectViaHttpsProxy)6240 TEST_P(HttpNetworkTransactionTest,
6241        ErrorResponseToHttpsConnectViaHttpsProxy) {
6242   session_deps_.proxy_service.reset(
6243       ProxyService::CreateFixed("https://proxy:70"));
6244 
6245   HttpRequestInfo request;
6246   request.method = "GET";
6247   request.url = GURL("https://www.google.com/");
6248   request.load_flags = 0;
6249 
6250   MockWrite data_writes[] = {
6251     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6252               "Host: www.google.com\r\n"
6253               "Proxy-Connection: keep-alive\r\n\r\n"),
6254   };
6255 
6256   MockRead data_reads[] = {
6257     MockRead("HTTP/1.1 404 Not Found\r\n"),
6258     MockRead("Content-Length: 23\r\n\r\n"),
6259     MockRead("The host does not exist"),
6260     MockRead(SYNCHRONOUS, OK),
6261   };
6262 
6263   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6264                                 data_writes, arraysize(data_writes));
6265   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6266 
6267   session_deps_.socket_factory->AddSocketDataProvider(&data);
6268   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6269 
6270   TestCompletionCallback callback;
6271 
6272   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6273   scoped_ptr<HttpTransaction> trans(
6274       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6275 
6276   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6277   EXPECT_EQ(ERR_IO_PENDING, rv);
6278 
6279   rv = callback.WaitForResult();
6280   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
6281 
6282   // TODO(ttuttle): Anything else to check here?
6283 }
6284 
6285 // Test that a SPDY proxy's response to a CONNECT request is filtered.
TEST_P(HttpNetworkTransactionTest,ErrorResponseToHttpsConnectViaSpdyProxy)6286 TEST_P(HttpNetworkTransactionTest,
6287        ErrorResponseToHttpsConnectViaSpdyProxy) {
6288   session_deps_.proxy_service.reset(
6289      ProxyService::CreateFixed("https://proxy:70"));
6290 
6291   HttpRequestInfo request;
6292   request.method = "GET";
6293   request.url = GURL("https://www.google.com/");
6294   request.load_flags = 0;
6295 
6296   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6297                                                              LOWEST));
6298   scoped_ptr<SpdyFrame> rst(
6299       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
6300   MockWrite data_writes[] = {
6301     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6302     CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
6303   };
6304 
6305   static const char* const kExtraHeaders[] = {
6306     "location",
6307     "http://login.example.com/",
6308   };
6309   scoped_ptr<SpdyFrame> resp(
6310       spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
6311                                  arraysize(kExtraHeaders)/2, 1));
6312   scoped_ptr<SpdyFrame> body(
6313       spdy_util_.ConstructSpdyBodyFrame(
6314           1, "The host does not exist", 23, true));
6315   MockRead data_reads[] = {
6316     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6317     CreateMockRead(*body.get(), 2, SYNCHRONOUS),
6318     MockRead(ASYNC, 0, 4),  // EOF
6319   };
6320 
6321   DelayedSocketData data(
6322       1,  // wait for one write to finish before reading.
6323       data_reads, arraysize(data_reads),
6324       data_writes, arraysize(data_writes));
6325   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
6326   proxy_ssl.SetNextProto(GetParam());
6327 
6328   session_deps_.socket_factory->AddSocketDataProvider(&data);
6329   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6330 
6331   TestCompletionCallback callback;
6332 
6333   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6334   scoped_ptr<HttpTransaction> trans(
6335       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6336 
6337   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6338   EXPECT_EQ(ERR_IO_PENDING, rv);
6339 
6340   rv = callback.WaitForResult();
6341   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
6342 
6343   // TODO(ttuttle): Anything else to check here?
6344 }
6345 
6346 // Test the request-challenge-retry sequence for basic auth, through
6347 // a SPDY proxy over a single SPDY session.
TEST_P(HttpNetworkTransactionTest,BasicAuthSpdyProxy)6348 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
6349   HttpRequestInfo request;
6350   request.method = "GET";
6351   request.url = GURL("https://www.google.com/");
6352   // when the no authentication data flag is set.
6353   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6354 
6355   // Configure against https proxy server "myproxy:70".
6356   session_deps_.proxy_service.reset(
6357       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
6358   CapturingBoundNetLog log;
6359   session_deps_.net_log = log.bound().net_log();
6360   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6361 
6362   // Since we have proxy, should try to establish tunnel.
6363   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6364                                                             LOWEST));
6365   scoped_ptr<SpdyFrame> rst(
6366       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
6367 
6368   // After calling trans->RestartWithAuth(), this is the request we should
6369   // be issuing -- the final header line contains the credentials.
6370   const char* const kAuthCredentials[] = {
6371       "proxy-authorization", "Basic Zm9vOmJhcg==",
6372   };
6373   scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
6374       kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
6375   // fetch https://www.google.com/ via HTTP
6376   const char get[] = "GET / HTTP/1.1\r\n"
6377     "Host: www.google.com\r\n"
6378     "Connection: keep-alive\r\n\r\n";
6379   scoped_ptr<SpdyFrame> wrapped_get(
6380       spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
6381 
6382   MockWrite spdy_writes[] = {
6383     CreateMockWrite(*req, 1, ASYNC),
6384     CreateMockWrite(*rst, 4, ASYNC),
6385     CreateMockWrite(*connect2, 5),
6386     CreateMockWrite(*wrapped_get, 8),
6387   };
6388 
6389   // The proxy responds to the connect with a 407, using a persistent
6390   // connection.
6391   const char* const kAuthChallenge[] = {
6392     spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
6393     spdy_util_.GetVersionKey(), "HTTP/1.1",
6394     "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6395   };
6396 
6397   scoped_ptr<SpdyFrame> conn_auth_resp(
6398       spdy_util_.ConstructSpdyControlFrame(NULL,
6399                                            0,
6400                                            false,
6401                                            1,
6402                                            LOWEST,
6403                                            SYN_REPLY,
6404                                            CONTROL_FLAG_NONE,
6405                                            kAuthChallenge,
6406                                            arraysize(kAuthChallenge),
6407                                            0));
6408 
6409   scoped_ptr<SpdyFrame> conn_resp(
6410       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
6411   const char resp[] = "HTTP/1.1 200 OK\r\n"
6412       "Content-Length: 5\r\n\r\n";
6413 
6414   scoped_ptr<SpdyFrame> wrapped_get_resp(
6415       spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
6416   scoped_ptr<SpdyFrame> wrapped_body(
6417       spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
6418   MockRead spdy_reads[] = {
6419     CreateMockRead(*conn_auth_resp, 2, ASYNC),
6420     CreateMockRead(*conn_resp, 6, ASYNC),
6421     CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6422     CreateMockRead(*wrapped_body, 10, ASYNC),
6423     MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
6424   };
6425 
6426   OrderedSocketData spdy_data(
6427       spdy_reads, arraysize(spdy_reads),
6428       spdy_writes, arraysize(spdy_writes));
6429   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6430   // Negotiate SPDY to the proxy
6431   SSLSocketDataProvider proxy(ASYNC, OK);
6432   proxy.SetNextProto(GetParam());
6433   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
6434   // Vanilla SSL to the server
6435   SSLSocketDataProvider server(ASYNC, OK);
6436   session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
6437 
6438   TestCompletionCallback callback1;
6439 
6440   scoped_ptr<HttpTransaction> trans(
6441       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6442 
6443   int rv = trans->Start(&request, callback1.callback(), log.bound());
6444   EXPECT_EQ(ERR_IO_PENDING, rv);
6445 
6446   rv = callback1.WaitForResult();
6447   EXPECT_EQ(OK, rv);
6448   net::CapturingNetLog::CapturedEntryList entries;
6449   log.GetEntries(&entries);
6450   size_t pos = ExpectLogContainsSomewhere(
6451       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6452       NetLog::PHASE_NONE);
6453   ExpectLogContainsSomewhere(
6454       entries, pos,
6455       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6456       NetLog::PHASE_NONE);
6457 
6458   const HttpResponseInfo* response = trans->GetResponseInfo();
6459   ASSERT_TRUE(response != NULL);
6460   ASSERT_FALSE(response->headers.get() == NULL);
6461   EXPECT_EQ(407, response->headers->response_code());
6462   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6463   EXPECT_TRUE(response->auth_challenge.get() != NULL);
6464   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6465 
6466   TestCompletionCallback callback2;
6467 
6468   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6469                               callback2.callback());
6470   EXPECT_EQ(ERR_IO_PENDING, rv);
6471 
6472   rv = callback2.WaitForResult();
6473   EXPECT_EQ(OK, rv);
6474 
6475   response = trans->GetResponseInfo();
6476   ASSERT_TRUE(response != NULL);
6477 
6478   EXPECT_TRUE(response->headers->IsKeepAlive());
6479   EXPECT_EQ(200, response->headers->response_code());
6480   EXPECT_EQ(5, response->headers->GetContentLength());
6481   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6482 
6483   // The password prompt info should not be set.
6484   EXPECT_TRUE(response->auth_challenge.get() == NULL);
6485 
6486   LoadTimingInfo load_timing_info;
6487   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6488   TestLoadTimingNotReusedWithPac(load_timing_info,
6489                                  CONNECT_TIMING_HAS_SSL_TIMES);
6490 
6491   trans.reset();
6492   session->CloseAllConnections();
6493 }
6494 
6495 // Test that an explicitly trusted SPDY proxy can push a resource from an
6496 // origin that is different from that of its associated resource.
TEST_P(HttpNetworkTransactionTest,CrossOriginProxyPush)6497 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
6498   HttpRequestInfo request;
6499   HttpRequestInfo push_request;
6500 
6501   request.method = "GET";
6502   request.url = GURL("http://www.google.com/");
6503   push_request.method = "GET";
6504   push_request.url = GURL("http://www.another-origin.com/foo.dat");
6505 
6506   // Configure against https proxy server "myproxy:70".
6507   session_deps_.proxy_service.reset(
6508       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
6509   CapturingBoundNetLog log;
6510   session_deps_.net_log = log.bound().net_log();
6511 
6512   // Enable cross-origin push.
6513   session_deps_.trusted_spdy_proxy = "myproxy:70";
6514 
6515   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6516 
6517   scoped_ptr<SpdyFrame> stream1_syn(
6518       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
6519 
6520   MockWrite spdy_writes[] = {
6521     CreateMockWrite(*stream1_syn, 1, ASYNC),
6522   };
6523 
6524   scoped_ptr<SpdyFrame>
6525       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
6526 
6527   scoped_ptr<SpdyFrame>
6528       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
6529 
6530   scoped_ptr<SpdyFrame>
6531       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
6532                                     0,
6533                                     2,
6534                                     1,
6535                                     "http://www.another-origin.com/foo.dat"));
6536   const char kPushedData[] = "pushed";
6537   scoped_ptr<SpdyFrame> stream2_body(
6538       spdy_util_.ConstructSpdyBodyFrame(
6539           2, kPushedData, strlen(kPushedData), true));
6540 
6541   MockRead spdy_reads[] = {
6542     CreateMockRead(*stream1_reply, 2, ASYNC),
6543     CreateMockRead(*stream2_syn, 3, ASYNC),
6544     CreateMockRead(*stream1_body, 4, ASYNC),
6545     CreateMockRead(*stream2_body, 5, ASYNC),
6546     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
6547   };
6548 
6549   OrderedSocketData spdy_data(
6550       spdy_reads, arraysize(spdy_reads),
6551       spdy_writes, arraysize(spdy_writes));
6552   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6553   // Negotiate SPDY to the proxy
6554   SSLSocketDataProvider proxy(ASYNC, OK);
6555   proxy.SetNextProto(GetParam());
6556   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
6557 
6558   scoped_ptr<HttpTransaction> trans(
6559       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6560   TestCompletionCallback callback;
6561   int rv = trans->Start(&request, callback.callback(), log.bound());
6562   EXPECT_EQ(ERR_IO_PENDING, rv);
6563 
6564   rv = callback.WaitForResult();
6565   EXPECT_EQ(OK, rv);
6566   const HttpResponseInfo* response = trans->GetResponseInfo();
6567 
6568   scoped_ptr<HttpTransaction> push_trans(
6569       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6570   rv = push_trans->Start(&push_request, callback.callback(), log.bound());
6571   EXPECT_EQ(ERR_IO_PENDING, rv);
6572 
6573   rv = callback.WaitForResult();
6574   EXPECT_EQ(OK, rv);
6575   const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6576 
6577   ASSERT_TRUE(response != NULL);
6578   EXPECT_TRUE(response->headers->IsKeepAlive());
6579 
6580   EXPECT_EQ(200, response->headers->response_code());
6581   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6582 
6583   std::string response_data;
6584   rv = ReadTransaction(trans.get(), &response_data);
6585   EXPECT_EQ(OK, rv);
6586   EXPECT_EQ("hello!", response_data);
6587 
6588   LoadTimingInfo load_timing_info;
6589   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6590   TestLoadTimingNotReusedWithPac(load_timing_info,
6591                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6592 
6593   // Verify the pushed stream.
6594   EXPECT_TRUE(push_response->headers.get() != NULL);
6595   EXPECT_EQ(200, push_response->headers->response_code());
6596 
6597   rv = ReadTransaction(push_trans.get(), &response_data);
6598   EXPECT_EQ(OK, rv);
6599   EXPECT_EQ("pushed", response_data);
6600 
6601   LoadTimingInfo push_load_timing_info;
6602   EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6603   TestLoadTimingReusedWithPac(push_load_timing_info);
6604   // The transactions should share a socket ID, despite being for different
6605   // origins.
6606   EXPECT_EQ(load_timing_info.socket_log_id,
6607             push_load_timing_info.socket_log_id);
6608 
6609   trans.reset();
6610   push_trans.reset();
6611   session->CloseAllConnections();
6612 }
6613 
6614 // Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
TEST_P(HttpNetworkTransactionTest,CrossOriginProxyPushCorrectness)6615 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
6616   HttpRequestInfo request;
6617 
6618   request.method = "GET";
6619   request.url = GURL("http://www.google.com/");
6620 
6621   // Configure against https proxy server "myproxy:70".
6622   session_deps_.proxy_service.reset(
6623       ProxyService::CreateFixed("https://myproxy:70"));
6624   CapturingBoundNetLog log;
6625   session_deps_.net_log = log.bound().net_log();
6626 
6627   // Enable cross-origin push.
6628   session_deps_.trusted_spdy_proxy = "myproxy:70";
6629 
6630   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6631 
6632   scoped_ptr<SpdyFrame> stream1_syn(
6633       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
6634 
6635   scoped_ptr<SpdyFrame> push_rst(
6636       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
6637 
6638   MockWrite spdy_writes[] = {
6639     CreateMockWrite(*stream1_syn, 1, ASYNC),
6640     CreateMockWrite(*push_rst, 4),
6641   };
6642 
6643   scoped_ptr<SpdyFrame>
6644       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
6645 
6646   scoped_ptr<SpdyFrame>
6647       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
6648 
6649   scoped_ptr<SpdyFrame>
6650       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
6651                                     0,
6652                                     2,
6653                                     1,
6654                                     "https://www.another-origin.com/foo.dat"));
6655 
6656   MockRead spdy_reads[] = {
6657     CreateMockRead(*stream1_reply, 2, ASYNC),
6658     CreateMockRead(*stream2_syn, 3, ASYNC),
6659     CreateMockRead(*stream1_body, 5, ASYNC),
6660     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
6661   };
6662 
6663   OrderedSocketData spdy_data(
6664       spdy_reads, arraysize(spdy_reads),
6665       spdy_writes, arraysize(spdy_writes));
6666   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
6667   // Negotiate SPDY to the proxy
6668   SSLSocketDataProvider proxy(ASYNC, OK);
6669   proxy.SetNextProto(GetParam());
6670   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
6671 
6672   scoped_ptr<HttpTransaction> trans(
6673       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6674   TestCompletionCallback callback;
6675   int rv = trans->Start(&request, callback.callback(), log.bound());
6676   EXPECT_EQ(ERR_IO_PENDING, rv);
6677 
6678   rv = callback.WaitForResult();
6679   EXPECT_EQ(OK, rv);
6680   const HttpResponseInfo* response = trans->GetResponseInfo();
6681 
6682   ASSERT_TRUE(response != NULL);
6683   EXPECT_TRUE(response->headers->IsKeepAlive());
6684 
6685   EXPECT_EQ(200, response->headers->response_code());
6686   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6687 
6688   std::string response_data;
6689   rv = ReadTransaction(trans.get(), &response_data);
6690   EXPECT_EQ(OK, rv);
6691   EXPECT_EQ("hello!", response_data);
6692 
6693   trans.reset();
6694   session->CloseAllConnections();
6695 }
6696 
6697 // Test HTTPS connections to a site with a bad certificate, going through an
6698 // HTTPS proxy
TEST_P(HttpNetworkTransactionTest,HTTPSBadCertificateViaHttpsProxy)6699 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
6700   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
6701       "https://proxy:70"));
6702 
6703   HttpRequestInfo request;
6704   request.method = "GET";
6705   request.url = GURL("https://www.google.com/");
6706   request.load_flags = 0;
6707 
6708   // Attempt to fetch the URL from a server with a bad cert
6709   MockWrite bad_cert_writes[] = {
6710     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6711               "Host: www.google.com\r\n"
6712               "Proxy-Connection: keep-alive\r\n\r\n"),
6713   };
6714 
6715   MockRead bad_cert_reads[] = {
6716     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6717     MockRead(SYNCHRONOUS, OK)
6718   };
6719 
6720   // Attempt to fetch the URL with a good cert
6721   MockWrite good_data_writes[] = {
6722     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6723               "Host: www.google.com\r\n"
6724               "Proxy-Connection: keep-alive\r\n\r\n"),
6725     MockWrite("GET / HTTP/1.1\r\n"
6726               "Host: www.google.com\r\n"
6727               "Connection: keep-alive\r\n\r\n"),
6728   };
6729 
6730   MockRead good_cert_reads[] = {
6731     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6732     MockRead("HTTP/1.0 200 OK\r\n"),
6733     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6734     MockRead("Content-Length: 100\r\n\r\n"),
6735     MockRead(SYNCHRONOUS, OK),
6736   };
6737 
6738   StaticSocketDataProvider ssl_bad_certificate(
6739       bad_cert_reads, arraysize(bad_cert_reads),
6740       bad_cert_writes, arraysize(bad_cert_writes));
6741   StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6742                                 good_data_writes, arraysize(good_data_writes));
6743   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6744   SSLSocketDataProvider ssl(ASYNC, OK);
6745 
6746   // SSL to the proxy, then CONNECT request, then SSL with bad certificate
6747   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6748   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6749   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6750 
6751   // SSL to the proxy, then CONNECT request, then valid SSL certificate
6752   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6753   session_deps_.socket_factory->AddSocketDataProvider(&data);
6754   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6755 
6756   TestCompletionCallback callback;
6757 
6758   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6759   scoped_ptr<HttpTransaction> trans(
6760       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6761 
6762   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6763   EXPECT_EQ(ERR_IO_PENDING, rv);
6764 
6765   rv = callback.WaitForResult();
6766   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6767 
6768   rv = trans->RestartIgnoringLastError(callback.callback());
6769   EXPECT_EQ(ERR_IO_PENDING, rv);
6770 
6771   rv = callback.WaitForResult();
6772   EXPECT_EQ(OK, rv);
6773 
6774   const HttpResponseInfo* response = trans->GetResponseInfo();
6775 
6776   ASSERT_TRUE(response != NULL);
6777   EXPECT_EQ(100, response->headers->GetContentLength());
6778 }
6779 
TEST_P(HttpNetworkTransactionTest,BuildRequest_UserAgent)6780 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
6781   HttpRequestInfo request;
6782   request.method = "GET";
6783   request.url = GURL("http://www.google.com/");
6784   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6785                                   "Chromium Ultra Awesome X Edition");
6786 
6787   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6788   scoped_ptr<HttpTransaction> trans(
6789       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6790 
6791   MockWrite data_writes[] = {
6792     MockWrite("GET / HTTP/1.1\r\n"
6793               "Host: www.google.com\r\n"
6794               "Connection: keep-alive\r\n"
6795               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6796   };
6797 
6798   // Lastly, the server responds with the actual content.
6799   MockRead data_reads[] = {
6800     MockRead("HTTP/1.0 200 OK\r\n"),
6801     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6802     MockRead("Content-Length: 100\r\n\r\n"),
6803     MockRead(SYNCHRONOUS, OK),
6804   };
6805 
6806   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6807                                 data_writes, arraysize(data_writes));
6808   session_deps_.socket_factory->AddSocketDataProvider(&data);
6809 
6810   TestCompletionCallback callback;
6811 
6812   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6813   EXPECT_EQ(ERR_IO_PENDING, rv);
6814 
6815   rv = callback.WaitForResult();
6816   EXPECT_EQ(OK, rv);
6817 }
6818 
TEST_P(HttpNetworkTransactionTest,BuildRequest_UserAgentOverTunnel)6819 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
6820   HttpRequestInfo request;
6821   request.method = "GET";
6822   request.url = GURL("https://www.google.com/");
6823   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6824                                   "Chromium Ultra Awesome X Edition");
6825 
6826   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
6827   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6828   scoped_ptr<HttpTransaction> trans(
6829       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6830 
6831   MockWrite data_writes[] = {
6832     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6833               "Host: www.google.com\r\n"
6834               "Proxy-Connection: keep-alive\r\n"
6835               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6836   };
6837   MockRead data_reads[] = {
6838     // Return an error, so the transaction stops here (this test isn't
6839     // interested in the rest).
6840     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6841     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6842     MockRead("Proxy-Connection: close\r\n\r\n"),
6843   };
6844 
6845   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6846                                 data_writes, arraysize(data_writes));
6847   session_deps_.socket_factory->AddSocketDataProvider(&data);
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 
TEST_P(HttpNetworkTransactionTest,BuildRequest_Referer)6858 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
6859   HttpRequestInfo request;
6860   request.method = "GET";
6861   request.url = GURL("http://www.google.com/");
6862   request.load_flags = 0;
6863   request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6864                                   "http://the.previous.site.com/");
6865 
6866   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6867   scoped_ptr<HttpTransaction> trans(
6868       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6869 
6870   MockWrite data_writes[] = {
6871     MockWrite("GET / HTTP/1.1\r\n"
6872               "Host: www.google.com\r\n"
6873               "Connection: keep-alive\r\n"
6874               "Referer: http://the.previous.site.com/\r\n\r\n"),
6875   };
6876 
6877   // Lastly, the server responds with the actual content.
6878   MockRead data_reads[] = {
6879     MockRead("HTTP/1.0 200 OK\r\n"),
6880     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6881     MockRead("Content-Length: 100\r\n\r\n"),
6882     MockRead(SYNCHRONOUS, OK),
6883   };
6884 
6885   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6886                                 data_writes, arraysize(data_writes));
6887   session_deps_.socket_factory->AddSocketDataProvider(&data);
6888 
6889   TestCompletionCallback callback;
6890 
6891   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6892   EXPECT_EQ(ERR_IO_PENDING, rv);
6893 
6894   rv = callback.WaitForResult();
6895   EXPECT_EQ(OK, rv);
6896 }
6897 
TEST_P(HttpNetworkTransactionTest,BuildRequest_PostContentLengthZero)6898 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
6899   HttpRequestInfo request;
6900   request.method = "POST";
6901   request.url = GURL("http://www.google.com/");
6902 
6903   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6904   scoped_ptr<HttpTransaction> trans(
6905       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6906 
6907   MockWrite data_writes[] = {
6908     MockWrite("POST / HTTP/1.1\r\n"
6909               "Host: www.google.com\r\n"
6910               "Connection: keep-alive\r\n"
6911               "Content-Length: 0\r\n\r\n"),
6912   };
6913 
6914   // Lastly, the server responds with the actual content.
6915   MockRead data_reads[] = {
6916     MockRead("HTTP/1.0 200 OK\r\n"),
6917     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6918     MockRead("Content-Length: 100\r\n\r\n"),
6919     MockRead(SYNCHRONOUS, OK),
6920   };
6921 
6922   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6923                                 data_writes, arraysize(data_writes));
6924   session_deps_.socket_factory->AddSocketDataProvider(&data);
6925 
6926   TestCompletionCallback callback;
6927 
6928   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6929   EXPECT_EQ(ERR_IO_PENDING, rv);
6930 
6931   rv = callback.WaitForResult();
6932   EXPECT_EQ(OK, rv);
6933 }
6934 
TEST_P(HttpNetworkTransactionTest,BuildRequest_PutContentLengthZero)6935 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
6936   HttpRequestInfo request;
6937   request.method = "PUT";
6938   request.url = GURL("http://www.google.com/");
6939 
6940   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6941   scoped_ptr<HttpTransaction> trans(
6942       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6943 
6944   MockWrite data_writes[] = {
6945     MockWrite("PUT / HTTP/1.1\r\n"
6946               "Host: www.google.com\r\n"
6947               "Connection: keep-alive\r\n"
6948               "Content-Length: 0\r\n\r\n"),
6949   };
6950 
6951   // Lastly, the server responds with the actual content.
6952   MockRead data_reads[] = {
6953     MockRead("HTTP/1.0 200 OK\r\n"),
6954     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6955     MockRead("Content-Length: 100\r\n\r\n"),
6956     MockRead(SYNCHRONOUS, OK),
6957   };
6958 
6959   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6960                                 data_writes, arraysize(data_writes));
6961   session_deps_.socket_factory->AddSocketDataProvider(&data);
6962 
6963   TestCompletionCallback callback;
6964 
6965   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6966   EXPECT_EQ(ERR_IO_PENDING, rv);
6967 
6968   rv = callback.WaitForResult();
6969   EXPECT_EQ(OK, rv);
6970 }
6971 
TEST_P(HttpNetworkTransactionTest,BuildRequest_HeadContentLengthZero)6972 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
6973   HttpRequestInfo request;
6974   request.method = "HEAD";
6975   request.url = GURL("http://www.google.com/");
6976 
6977   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6978   scoped_ptr<HttpTransaction> trans(
6979       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6980 
6981   MockWrite data_writes[] = {
6982     MockWrite("HEAD / HTTP/1.1\r\n"
6983               "Host: www.google.com\r\n"
6984               "Connection: keep-alive\r\n"
6985               "Content-Length: 0\r\n\r\n"),
6986   };
6987 
6988   // Lastly, the server responds with the actual content.
6989   MockRead data_reads[] = {
6990     MockRead("HTTP/1.0 200 OK\r\n"),
6991     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6992     MockRead("Content-Length: 100\r\n\r\n"),
6993     MockRead(SYNCHRONOUS, OK),
6994   };
6995 
6996   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6997                                 data_writes, arraysize(data_writes));
6998   session_deps_.socket_factory->AddSocketDataProvider(&data);
6999 
7000   TestCompletionCallback callback;
7001 
7002   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7003   EXPECT_EQ(ERR_IO_PENDING, rv);
7004 
7005   rv = callback.WaitForResult();
7006   EXPECT_EQ(OK, rv);
7007 }
7008 
TEST_P(HttpNetworkTransactionTest,BuildRequest_CacheControlNoCache)7009 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
7010   HttpRequestInfo request;
7011   request.method = "GET";
7012   request.url = GURL("http://www.google.com/");
7013   request.load_flags = LOAD_BYPASS_CACHE;
7014 
7015   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7016   scoped_ptr<HttpTransaction> trans(
7017       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7018 
7019   MockWrite data_writes[] = {
7020     MockWrite("GET / HTTP/1.1\r\n"
7021               "Host: www.google.com\r\n"
7022               "Connection: keep-alive\r\n"
7023               "Pragma: no-cache\r\n"
7024               "Cache-Control: no-cache\r\n\r\n"),
7025   };
7026 
7027   // Lastly, the server responds with the actual content.
7028   MockRead data_reads[] = {
7029     MockRead("HTTP/1.0 200 OK\r\n"),
7030     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7031     MockRead("Content-Length: 100\r\n\r\n"),
7032     MockRead(SYNCHRONOUS, OK),
7033   };
7034 
7035   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7036                                 data_writes, arraysize(data_writes));
7037   session_deps_.socket_factory->AddSocketDataProvider(&data);
7038 
7039   TestCompletionCallback callback;
7040 
7041   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7042   EXPECT_EQ(ERR_IO_PENDING, rv);
7043 
7044   rv = callback.WaitForResult();
7045   EXPECT_EQ(OK, rv);
7046 }
7047 
TEST_P(HttpNetworkTransactionTest,BuildRequest_CacheControlValidateCache)7048 TEST_P(HttpNetworkTransactionTest,
7049        BuildRequest_CacheControlValidateCache) {
7050   HttpRequestInfo request;
7051   request.method = "GET";
7052   request.url = GURL("http://www.google.com/");
7053   request.load_flags = LOAD_VALIDATE_CACHE;
7054 
7055   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7056   scoped_ptr<HttpTransaction> trans(
7057       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7058 
7059   MockWrite data_writes[] = {
7060     MockWrite("GET / HTTP/1.1\r\n"
7061               "Host: www.google.com\r\n"
7062               "Connection: keep-alive\r\n"
7063               "Cache-Control: max-age=0\r\n\r\n"),
7064   };
7065 
7066   // Lastly, the server responds with the actual content.
7067   MockRead data_reads[] = {
7068     MockRead("HTTP/1.0 200 OK\r\n"),
7069     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7070     MockRead("Content-Length: 100\r\n\r\n"),
7071     MockRead(SYNCHRONOUS, OK),
7072   };
7073 
7074   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7075                                 data_writes, arraysize(data_writes));
7076   session_deps_.socket_factory->AddSocketDataProvider(&data);
7077 
7078   TestCompletionCallback callback;
7079 
7080   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7081   EXPECT_EQ(ERR_IO_PENDING, rv);
7082 
7083   rv = callback.WaitForResult();
7084   EXPECT_EQ(OK, rv);
7085 }
7086 
TEST_P(HttpNetworkTransactionTest,BuildRequest_ExtraHeaders)7087 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
7088   HttpRequestInfo request;
7089   request.method = "GET";
7090   request.url = GURL("http://www.google.com/");
7091   request.extra_headers.SetHeader("FooHeader", "Bar");
7092 
7093   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7094   scoped_ptr<HttpTransaction> trans(
7095       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7096 
7097   MockWrite data_writes[] = {
7098     MockWrite("GET / HTTP/1.1\r\n"
7099               "Host: www.google.com\r\n"
7100               "Connection: keep-alive\r\n"
7101               "FooHeader: Bar\r\n\r\n"),
7102   };
7103 
7104   // Lastly, the server responds with the actual content.
7105   MockRead data_reads[] = {
7106     MockRead("HTTP/1.0 200 OK\r\n"),
7107     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7108     MockRead("Content-Length: 100\r\n\r\n"),
7109     MockRead(SYNCHRONOUS, OK),
7110   };
7111 
7112   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7113                                 data_writes, arraysize(data_writes));
7114   session_deps_.socket_factory->AddSocketDataProvider(&data);
7115 
7116   TestCompletionCallback callback;
7117 
7118   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7119   EXPECT_EQ(ERR_IO_PENDING, rv);
7120 
7121   rv = callback.WaitForResult();
7122   EXPECT_EQ(OK, rv);
7123 }
7124 
TEST_P(HttpNetworkTransactionTest,BuildRequest_ExtraHeadersStripped)7125 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
7126   HttpRequestInfo request;
7127   request.method = "GET";
7128   request.url = GURL("http://www.google.com/");
7129   request.extra_headers.SetHeader("referer", "www.foo.com");
7130   request.extra_headers.SetHeader("hEllo", "Kitty");
7131   request.extra_headers.SetHeader("FoO", "bar");
7132 
7133   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7134   scoped_ptr<HttpTransaction> trans(
7135       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7136 
7137   MockWrite data_writes[] = {
7138     MockWrite("GET / HTTP/1.1\r\n"
7139               "Host: www.google.com\r\n"
7140               "Connection: keep-alive\r\n"
7141               "referer: www.foo.com\r\n"
7142               "hEllo: Kitty\r\n"
7143               "FoO: bar\r\n\r\n"),
7144   };
7145 
7146   // Lastly, the server responds with the actual content.
7147   MockRead data_reads[] = {
7148     MockRead("HTTP/1.0 200 OK\r\n"),
7149     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7150     MockRead("Content-Length: 100\r\n\r\n"),
7151     MockRead(SYNCHRONOUS, OK),
7152   };
7153 
7154   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7155                                 data_writes, arraysize(data_writes));
7156   session_deps_.socket_factory->AddSocketDataProvider(&data);
7157 
7158   TestCompletionCallback callback;
7159 
7160   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7161   EXPECT_EQ(ERR_IO_PENDING, rv);
7162 
7163   rv = callback.WaitForResult();
7164   EXPECT_EQ(OK, rv);
7165 }
7166 
TEST_P(HttpNetworkTransactionTest,SOCKS4_HTTP_GET)7167 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
7168   HttpRequestInfo request;
7169   request.method = "GET";
7170   request.url = GURL("http://www.google.com/");
7171   request.load_flags = 0;
7172 
7173   session_deps_.proxy_service.reset(
7174       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7175   CapturingNetLog net_log;
7176   session_deps_.net_log = &net_log;
7177 
7178   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7179   scoped_ptr<HttpTransaction> trans(
7180       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7181 
7182   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7183   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7184 
7185   MockWrite data_writes[] = {
7186     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7187     MockWrite("GET / HTTP/1.1\r\n"
7188               "Host: www.google.com\r\n"
7189               "Connection: keep-alive\r\n\r\n")
7190   };
7191 
7192   MockRead data_reads[] = {
7193     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7194     MockRead("HTTP/1.0 200 OK\r\n"),
7195     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7196     MockRead("Payload"),
7197     MockRead(SYNCHRONOUS, OK)
7198   };
7199 
7200   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7201                                 data_writes, arraysize(data_writes));
7202   session_deps_.socket_factory->AddSocketDataProvider(&data);
7203 
7204   TestCompletionCallback callback;
7205 
7206   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7207   EXPECT_EQ(ERR_IO_PENDING, rv);
7208 
7209   rv = callback.WaitForResult();
7210   EXPECT_EQ(OK, rv);
7211 
7212   const HttpResponseInfo* response = trans->GetResponseInfo();
7213   ASSERT_TRUE(response != NULL);
7214 
7215   LoadTimingInfo load_timing_info;
7216   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7217   TestLoadTimingNotReusedWithPac(load_timing_info,
7218                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7219 
7220   std::string response_text;
7221   rv = ReadTransaction(trans.get(), &response_text);
7222   EXPECT_EQ(OK, rv);
7223   EXPECT_EQ("Payload", response_text);
7224 }
7225 
TEST_P(HttpNetworkTransactionTest,SOCKS4_SSL_GET)7226 TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
7227   HttpRequestInfo request;
7228   request.method = "GET";
7229   request.url = GURL("https://www.google.com/");
7230   request.load_flags = 0;
7231 
7232   session_deps_.proxy_service.reset(
7233       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7234   CapturingNetLog net_log;
7235   session_deps_.net_log = &net_log;
7236 
7237   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7238   scoped_ptr<HttpTransaction> trans(
7239       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7240 
7241   unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7242   unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7243 
7244   MockWrite data_writes[] = {
7245     MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7246               arraysize(write_buffer)),
7247     MockWrite("GET / HTTP/1.1\r\n"
7248               "Host: www.google.com\r\n"
7249               "Connection: keep-alive\r\n\r\n")
7250   };
7251 
7252   MockRead data_reads[] = {
7253     MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7254              arraysize(read_buffer)),
7255     MockRead("HTTP/1.0 200 OK\r\n"),
7256     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7257     MockRead("Payload"),
7258     MockRead(SYNCHRONOUS, OK)
7259   };
7260 
7261   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7262                                 data_writes, arraysize(data_writes));
7263   session_deps_.socket_factory->AddSocketDataProvider(&data);
7264 
7265   SSLSocketDataProvider ssl(ASYNC, OK);
7266   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7267 
7268   TestCompletionCallback callback;
7269 
7270   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7271   EXPECT_EQ(ERR_IO_PENDING, rv);
7272 
7273   rv = callback.WaitForResult();
7274   EXPECT_EQ(OK, rv);
7275 
7276   LoadTimingInfo load_timing_info;
7277   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7278   TestLoadTimingNotReusedWithPac(load_timing_info,
7279                                  CONNECT_TIMING_HAS_SSL_TIMES);
7280 
7281   const HttpResponseInfo* response = trans->GetResponseInfo();
7282   ASSERT_TRUE(response != NULL);
7283 
7284   std::string response_text;
7285   rv = ReadTransaction(trans.get(), &response_text);
7286   EXPECT_EQ(OK, rv);
7287   EXPECT_EQ("Payload", response_text);
7288 }
7289 
TEST_P(HttpNetworkTransactionTest,SOCKS4_HTTP_GET_no_PAC)7290 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
7291   HttpRequestInfo request;
7292   request.method = "GET";
7293   request.url = GURL("http://www.google.com/");
7294   request.load_flags = 0;
7295 
7296   session_deps_.proxy_service.reset(
7297       ProxyService::CreateFixed("socks4://myproxy:1080"));
7298   CapturingNetLog net_log;
7299   session_deps_.net_log = &net_log;
7300 
7301   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7302   scoped_ptr<HttpTransaction> trans(
7303       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7304 
7305   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7306   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7307 
7308   MockWrite data_writes[] = {
7309     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7310     MockWrite("GET / HTTP/1.1\r\n"
7311               "Host: www.google.com\r\n"
7312               "Connection: keep-alive\r\n\r\n")
7313   };
7314 
7315   MockRead data_reads[] = {
7316     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7317     MockRead("HTTP/1.0 200 OK\r\n"),
7318     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7319     MockRead("Payload"),
7320     MockRead(SYNCHRONOUS, OK)
7321   };
7322 
7323   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7324                                 data_writes, arraysize(data_writes));
7325   session_deps_.socket_factory->AddSocketDataProvider(&data);
7326 
7327   TestCompletionCallback callback;
7328 
7329   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7330   EXPECT_EQ(ERR_IO_PENDING, rv);
7331 
7332   rv = callback.WaitForResult();
7333   EXPECT_EQ(OK, rv);
7334 
7335   const HttpResponseInfo* response = trans->GetResponseInfo();
7336   ASSERT_TRUE(response != NULL);
7337 
7338   LoadTimingInfo load_timing_info;
7339   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7340   TestLoadTimingNotReused(load_timing_info,
7341                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7342 
7343   std::string response_text;
7344   rv = ReadTransaction(trans.get(), &response_text);
7345   EXPECT_EQ(OK, rv);
7346   EXPECT_EQ("Payload", response_text);
7347 }
7348 
TEST_P(HttpNetworkTransactionTest,SOCKS5_HTTP_GET)7349 TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
7350   HttpRequestInfo request;
7351   request.method = "GET";
7352   request.url = GURL("http://www.google.com/");
7353   request.load_flags = 0;
7354 
7355   session_deps_.proxy_service.reset(
7356       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7357   CapturingNetLog net_log;
7358   session_deps_.net_log = &net_log;
7359 
7360   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7361   scoped_ptr<HttpTransaction> trans(
7362       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7363 
7364   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7365   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
7366   const char kSOCKS5OkRequest[] = {
7367     0x05,  // Version
7368     0x01,  // Command (CONNECT)
7369     0x00,  // Reserved.
7370     0x03,  // Address type (DOMAINNAME).
7371     0x0E,  // Length of domain (14)
7372     // Domain string:
7373     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7374     0x00, 0x50,  // 16-bit port (80)
7375   };
7376   const char kSOCKS5OkResponse[] =
7377       { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7378 
7379   MockWrite data_writes[] = {
7380     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7381     MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7382     MockWrite("GET / HTTP/1.1\r\n"
7383               "Host: www.google.com\r\n"
7384               "Connection: keep-alive\r\n\r\n")
7385   };
7386 
7387   MockRead data_reads[] = {
7388     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7389     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
7390     MockRead("HTTP/1.0 200 OK\r\n"),
7391     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7392     MockRead("Payload"),
7393     MockRead(SYNCHRONOUS, OK)
7394   };
7395 
7396   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7397                                 data_writes, arraysize(data_writes));
7398   session_deps_.socket_factory->AddSocketDataProvider(&data);
7399 
7400   TestCompletionCallback callback;
7401 
7402   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7403   EXPECT_EQ(ERR_IO_PENDING, rv);
7404 
7405   rv = callback.WaitForResult();
7406   EXPECT_EQ(OK, rv);
7407 
7408   const HttpResponseInfo* response = trans->GetResponseInfo();
7409   ASSERT_TRUE(response != NULL);
7410 
7411   LoadTimingInfo load_timing_info;
7412   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7413   TestLoadTimingNotReusedWithPac(load_timing_info,
7414                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7415 
7416   std::string response_text;
7417   rv = ReadTransaction(trans.get(), &response_text);
7418   EXPECT_EQ(OK, rv);
7419   EXPECT_EQ("Payload", response_text);
7420 }
7421 
TEST_P(HttpNetworkTransactionTest,SOCKS5_SSL_GET)7422 TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
7423   HttpRequestInfo request;
7424   request.method = "GET";
7425   request.url = GURL("https://www.google.com/");
7426   request.load_flags = 0;
7427 
7428   session_deps_.proxy_service.reset(
7429       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7430   CapturingNetLog net_log;
7431   session_deps_.net_log = &net_log;
7432 
7433   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7434   scoped_ptr<HttpTransaction> trans(
7435       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7436 
7437   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7438   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
7439   const unsigned char kSOCKS5OkRequest[] = {
7440     0x05,  // Version
7441     0x01,  // Command (CONNECT)
7442     0x00,  // Reserved.
7443     0x03,  // Address type (DOMAINNAME).
7444     0x0E,  // Length of domain (14)
7445     // Domain string:
7446     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7447     0x01, 0xBB,  // 16-bit port (443)
7448   };
7449 
7450   const char kSOCKS5OkResponse[] =
7451       { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7452 
7453   MockWrite data_writes[] = {
7454     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7455     MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7456               arraysize(kSOCKS5OkRequest)),
7457     MockWrite("GET / HTTP/1.1\r\n"
7458               "Host: www.google.com\r\n"
7459               "Connection: keep-alive\r\n\r\n")
7460   };
7461 
7462   MockRead data_reads[] = {
7463     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7464     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
7465     MockRead("HTTP/1.0 200 OK\r\n"),
7466     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7467     MockRead("Payload"),
7468     MockRead(SYNCHRONOUS, OK)
7469   };
7470 
7471   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7472                                 data_writes, arraysize(data_writes));
7473   session_deps_.socket_factory->AddSocketDataProvider(&data);
7474 
7475   SSLSocketDataProvider ssl(ASYNC, OK);
7476   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7477 
7478   TestCompletionCallback callback;
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   LoadTimingInfo load_timing_info;
7490   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7491   TestLoadTimingNotReusedWithPac(load_timing_info,
7492                                  CONNECT_TIMING_HAS_SSL_TIMES);
7493 
7494   std::string response_text;
7495   rv = ReadTransaction(trans.get(), &response_text);
7496   EXPECT_EQ(OK, rv);
7497   EXPECT_EQ("Payload", response_text);
7498 }
7499 
7500 namespace {
7501 
7502 // Tests that for connection endpoints the group names are correctly set.
7503 
7504 struct GroupNameTest {
7505   std::string proxy_server;
7506   std::string url;
7507   std::string expected_group_name;
7508   bool ssl;
7509 };
7510 
SetupSessionForGroupNameTests(NextProto next_proto,SpdySessionDependencies * session_deps_)7511 scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
7512     NextProto next_proto,
7513     SpdySessionDependencies* session_deps_) {
7514   scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
7515 
7516   base::WeakPtr<HttpServerProperties> http_server_properties =
7517       session->http_server_properties();
7518   http_server_properties->SetAlternateProtocol(
7519       HostPortPair("host.with.alternate", 80), 443,
7520       AlternateProtocolFromNextProto(next_proto));
7521 
7522   return session;
7523 }
7524 
GroupNameTransactionHelper(const std::string & url,const scoped_refptr<HttpNetworkSession> & session)7525 int GroupNameTransactionHelper(
7526     const std::string& url,
7527     const scoped_refptr<HttpNetworkSession>& session) {
7528   HttpRequestInfo request;
7529   request.method = "GET";
7530   request.url = GURL(url);
7531   request.load_flags = 0;
7532 
7533   scoped_ptr<HttpTransaction> trans(
7534       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7535 
7536   TestCompletionCallback callback;
7537 
7538   // We do not complete this request, the dtor will clean the transaction up.
7539   return trans->Start(&request, callback.callback(), BoundNetLog());
7540 }
7541 
7542 }  // namespace
7543 
TEST_P(HttpNetworkTransactionTest,GroupNameForDirectConnections)7544 TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
7545   const GroupNameTest tests[] = {
7546     {
7547       "",  // unused
7548       "http://www.google.com/direct",
7549       "www.google.com:80",
7550       false,
7551     },
7552     {
7553       "",  // unused
7554       "http://[2001:1418:13:1::25]/direct",
7555       "[2001:1418:13:1::25]:80",
7556       false,
7557     },
7558 
7559     // SSL Tests
7560     {
7561       "",  // unused
7562       "https://www.google.com/direct_ssl",
7563       "ssl/www.google.com:443",
7564       true,
7565     },
7566     {
7567       "",  // unused
7568       "https://[2001:1418:13:1::25]/direct",
7569       "ssl/[2001:1418:13:1::25]:443",
7570       true,
7571     },
7572     {
7573       "",  // unused
7574       "http://host.with.alternate/direct",
7575       "ssl/host.with.alternate:443",
7576       true,
7577     },
7578   };
7579 
7580   session_deps_.use_alternate_protocols = true;
7581 
7582   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7583     session_deps_.proxy_service.reset(
7584         ProxyService::CreateFixed(tests[i].proxy_server));
7585     scoped_refptr<HttpNetworkSession> session(
7586         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
7587 
7588     HttpNetworkSessionPeer peer(session);
7589     CaptureGroupNameTransportSocketPool* transport_conn_pool =
7590         new CaptureGroupNameTransportSocketPool(NULL, NULL);
7591     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
7592         new CaptureGroupNameSSLSocketPool(NULL, NULL);
7593     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7594         new MockClientSocketPoolManager);
7595     mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7596     mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
7597     peer.SetClientSocketPoolManager(
7598         mock_pool_manager.PassAs<ClientSocketPoolManager>());
7599 
7600     EXPECT_EQ(ERR_IO_PENDING,
7601               GroupNameTransactionHelper(tests[i].url, session));
7602     if (tests[i].ssl)
7603       EXPECT_EQ(tests[i].expected_group_name,
7604                 ssl_conn_pool->last_group_name_received());
7605     else
7606       EXPECT_EQ(tests[i].expected_group_name,
7607                 transport_conn_pool->last_group_name_received());
7608   }
7609 
7610 }
7611 
TEST_P(HttpNetworkTransactionTest,GroupNameForHTTPProxyConnections)7612 TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
7613   const GroupNameTest tests[] = {
7614     {
7615       "http_proxy",
7616       "http://www.google.com/http_proxy_normal",
7617       "www.google.com:80",
7618       false,
7619     },
7620 
7621     // SSL Tests
7622     {
7623       "http_proxy",
7624       "https://www.google.com/http_connect_ssl",
7625       "ssl/www.google.com:443",
7626       true,
7627     },
7628 
7629     {
7630       "http_proxy",
7631       "http://host.with.alternate/direct",
7632       "ssl/host.with.alternate:443",
7633       true,
7634     },
7635 
7636     {
7637       "http_proxy",
7638       "ftp://ftp.google.com/http_proxy_normal",
7639       "ftp/ftp.google.com:21",
7640       false,
7641     },
7642   };
7643 
7644   session_deps_.use_alternate_protocols = true;
7645 
7646   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7647     session_deps_.proxy_service.reset(
7648         ProxyService::CreateFixed(tests[i].proxy_server));
7649     scoped_refptr<HttpNetworkSession> session(
7650         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
7651 
7652     HttpNetworkSessionPeer peer(session);
7653 
7654     HostPortPair proxy_host("http_proxy", 80);
7655     CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
7656         new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
7657     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
7658         new CaptureGroupNameSSLSocketPool(NULL, NULL);
7659 
7660     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7661         new MockClientSocketPoolManager);
7662     mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7663     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7664     peer.SetClientSocketPoolManager(
7665         mock_pool_manager.PassAs<ClientSocketPoolManager>());
7666 
7667     EXPECT_EQ(ERR_IO_PENDING,
7668               GroupNameTransactionHelper(tests[i].url, session));
7669     if (tests[i].ssl)
7670       EXPECT_EQ(tests[i].expected_group_name,
7671                 ssl_conn_pool->last_group_name_received());
7672     else
7673       EXPECT_EQ(tests[i].expected_group_name,
7674                 http_proxy_pool->last_group_name_received());
7675   }
7676 }
7677 
TEST_P(HttpNetworkTransactionTest,GroupNameForSOCKSConnections)7678 TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
7679   const GroupNameTest tests[] = {
7680     {
7681       "socks4://socks_proxy:1080",
7682       "http://www.google.com/socks4_direct",
7683       "socks4/www.google.com:80",
7684       false,
7685     },
7686     {
7687       "socks5://socks_proxy:1080",
7688       "http://www.google.com/socks5_direct",
7689       "socks5/www.google.com:80",
7690       false,
7691     },
7692 
7693     // SSL Tests
7694     {
7695       "socks4://socks_proxy:1080",
7696       "https://www.google.com/socks4_ssl",
7697       "socks4/ssl/www.google.com:443",
7698       true,
7699     },
7700     {
7701       "socks5://socks_proxy:1080",
7702       "https://www.google.com/socks5_ssl",
7703       "socks5/ssl/www.google.com:443",
7704       true,
7705     },
7706 
7707     {
7708       "socks4://socks_proxy:1080",
7709       "http://host.with.alternate/direct",
7710       "socks4/ssl/host.with.alternate:443",
7711       true,
7712     },
7713   };
7714 
7715   session_deps_.use_alternate_protocols = true;
7716 
7717   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7718     session_deps_.proxy_service.reset(
7719         ProxyService::CreateFixed(tests[i].proxy_server));
7720     scoped_refptr<HttpNetworkSession> session(
7721         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
7722 
7723     HttpNetworkSessionPeer peer(session);
7724 
7725     HostPortPair proxy_host("socks_proxy", 1080);
7726     CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
7727         new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
7728     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
7729         new CaptureGroupNameSSLSocketPool(NULL, NULL);
7730 
7731     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7732         new MockClientSocketPoolManager);
7733     mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7734     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7735     peer.SetClientSocketPoolManager(
7736         mock_pool_manager.PassAs<ClientSocketPoolManager>());
7737 
7738     scoped_ptr<HttpTransaction> trans(
7739         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7740 
7741     EXPECT_EQ(ERR_IO_PENDING,
7742               GroupNameTransactionHelper(tests[i].url, session));
7743     if (tests[i].ssl)
7744       EXPECT_EQ(tests[i].expected_group_name,
7745                 ssl_conn_pool->last_group_name_received());
7746     else
7747       EXPECT_EQ(tests[i].expected_group_name,
7748                 socks_conn_pool->last_group_name_received());
7749   }
7750 }
7751 
TEST_P(HttpNetworkTransactionTest,ReconsiderProxyAfterFailedConnection)7752 TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
7753   HttpRequestInfo request;
7754   request.method = "GET";
7755   request.url = GURL("http://www.google.com/");
7756 
7757   session_deps_.proxy_service.reset(
7758       ProxyService::CreateFixed("myproxy:70;foobar:80"));
7759 
7760   // This simulates failure resolving all hostnames; that means we will fail
7761   // connecting to both proxies (myproxy:70 and foobar:80).
7762   session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
7763 
7764   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7765   scoped_ptr<HttpTransaction> trans(
7766       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7767 
7768   TestCompletionCallback callback;
7769 
7770   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7771   EXPECT_EQ(ERR_IO_PENDING, rv);
7772 
7773   rv = callback.WaitForResult();
7774   EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
7775 }
7776 
7777 // Base test to make sure that when the load flags for a request specify to
7778 // bypass the cache, the DNS cache is not used.
BypassHostCacheOnRefreshHelper(int load_flags)7779 void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
7780     int load_flags) {
7781   // Issue a request, asking to bypass the cache(s).
7782   HttpRequestInfo request;
7783   request.method = "GET";
7784   request.load_flags = load_flags;
7785   request.url = GURL("http://www.google.com/");
7786 
7787   // Select a host resolver that does caching.
7788   session_deps_.host_resolver.reset(new MockCachingHostResolver);
7789 
7790   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7791   scoped_ptr<HttpTransaction> trans(
7792       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7793 
7794   // Warm up the host cache so it has an entry for "www.google.com".
7795   AddressList addrlist;
7796   TestCompletionCallback callback;
7797   int rv = session_deps_.host_resolver->Resolve(
7798       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7799       DEFAULT_PRIORITY,
7800       &addrlist,
7801       callback.callback(),
7802       NULL,
7803       BoundNetLog());
7804   EXPECT_EQ(ERR_IO_PENDING, rv);
7805   rv = callback.WaitForResult();
7806   EXPECT_EQ(OK, rv);
7807 
7808   // Verify that it was added to host cache, by doing a subsequent async lookup
7809   // and confirming it completes synchronously.
7810   rv = session_deps_.host_resolver->Resolve(
7811       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7812       DEFAULT_PRIORITY,
7813       &addrlist,
7814       callback.callback(),
7815       NULL,
7816       BoundNetLog());
7817   ASSERT_EQ(OK, rv);
7818 
7819   // Inject a failure the next time that "www.google.com" is resolved. This way
7820   // we can tell if the next lookup hit the cache, or the "network".
7821   // (cache --> success, "network" --> failure).
7822   session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
7823 
7824   // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7825   // first read -- this won't be reached as the host resolution will fail first.
7826   MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
7827   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7828   session_deps_.socket_factory->AddSocketDataProvider(&data);
7829 
7830   // Run the request.
7831   rv = trans->Start(&request, callback.callback(), BoundNetLog());
7832   ASSERT_EQ(ERR_IO_PENDING, rv);
7833   rv = callback.WaitForResult();
7834 
7835   // If we bypassed the cache, we would have gotten a failure while resolving
7836   // "www.google.com".
7837   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7838 }
7839 
7840 // There are multiple load flags that should trigger the host cache bypass.
7841 // Test each in isolation:
TEST_P(HttpNetworkTransactionTest,BypassHostCacheOnRefresh1)7842 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
7843   BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7844 }
7845 
TEST_P(HttpNetworkTransactionTest,BypassHostCacheOnRefresh2)7846 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
7847   BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7848 }
7849 
TEST_P(HttpNetworkTransactionTest,BypassHostCacheOnRefresh3)7850 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
7851   BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7852 }
7853 
7854 // Make sure we can handle an error when writing the request.
TEST_P(HttpNetworkTransactionTest,RequestWriteError)7855 TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
7856   HttpRequestInfo request;
7857   request.method = "GET";
7858   request.url = GURL("http://www.foo.com/");
7859   request.load_flags = 0;
7860 
7861   MockWrite write_failure[] = {
7862     MockWrite(ASYNC, ERR_CONNECTION_RESET),
7863   };
7864   StaticSocketDataProvider data(NULL, 0,
7865                                 write_failure, arraysize(write_failure));
7866   session_deps_.socket_factory->AddSocketDataProvider(&data);
7867   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7868 
7869   TestCompletionCallback callback;
7870 
7871   scoped_ptr<HttpTransaction> trans(
7872       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7873 
7874   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7875   EXPECT_EQ(ERR_IO_PENDING, rv);
7876 
7877   rv = callback.WaitForResult();
7878   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7879 }
7880 
7881 // Check that a connection closed after the start of the headers finishes ok.
TEST_P(HttpNetworkTransactionTest,ConnectionClosedAfterStartOfHeaders)7882 TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
7883   HttpRequestInfo request;
7884   request.method = "GET";
7885   request.url = GURL("http://www.foo.com/");
7886   request.load_flags = 0;
7887 
7888   MockRead data_reads[] = {
7889     MockRead("HTTP/1."),
7890     MockRead(SYNCHRONOUS, OK),
7891   };
7892 
7893   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7894   session_deps_.socket_factory->AddSocketDataProvider(&data);
7895   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7896 
7897   TestCompletionCallback callback;
7898 
7899   scoped_ptr<HttpTransaction> trans(
7900       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
7901 
7902   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7903   EXPECT_EQ(ERR_IO_PENDING, rv);
7904 
7905   rv = callback.WaitForResult();
7906   EXPECT_EQ(OK, rv);
7907 
7908   const HttpResponseInfo* response = trans->GetResponseInfo();
7909   ASSERT_TRUE(response != NULL);
7910 
7911   EXPECT_TRUE(response->headers.get() != NULL);
7912   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7913 
7914   std::string response_data;
7915   rv = ReadTransaction(trans.get(), &response_data);
7916   EXPECT_EQ(OK, rv);
7917   EXPECT_EQ("", response_data);
7918 }
7919 
7920 // Make sure that a dropped connection while draining the body for auth
7921 // restart does the right thing.
TEST_P(HttpNetworkTransactionTest,DrainResetOK)7922 TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
7923   HttpRequestInfo request;
7924   request.method = "GET";
7925   request.url = GURL("http://www.google.com/");
7926   request.load_flags = 0;
7927 
7928   MockWrite data_writes1[] = {
7929     MockWrite("GET / HTTP/1.1\r\n"
7930               "Host: www.google.com\r\n"
7931               "Connection: keep-alive\r\n\r\n"),
7932   };
7933 
7934   MockRead data_reads1[] = {
7935     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7936     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7937     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7938     MockRead("Content-Length: 14\r\n\r\n"),
7939     MockRead("Unauth"),
7940     MockRead(ASYNC, ERR_CONNECTION_RESET),
7941   };
7942 
7943   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7944                                  data_writes1, arraysize(data_writes1));
7945   session_deps_.socket_factory->AddSocketDataProvider(&data1);
7946 
7947   // After calling trans->RestartWithAuth(), this is the request we should
7948   // be issuing -- the final header line contains the credentials.
7949   MockWrite data_writes2[] = {
7950     MockWrite("GET / HTTP/1.1\r\n"
7951               "Host: www.google.com\r\n"
7952               "Connection: keep-alive\r\n"
7953               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7954   };
7955 
7956   // Lastly, the server responds with the actual content.
7957   MockRead data_reads2[] = {
7958     MockRead("HTTP/1.1 200 OK\r\n"),
7959     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7960     MockRead("Content-Length: 100\r\n\r\n"),
7961     MockRead(SYNCHRONOUS, OK),
7962   };
7963 
7964   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7965                                  data_writes2, arraysize(data_writes2));
7966   session_deps_.socket_factory->AddSocketDataProvider(&data2);
7967   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7968 
7969   TestCompletionCallback callback1;
7970 
7971   scoped_ptr<HttpTransaction> trans(
7972       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7973 
7974   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
7975   EXPECT_EQ(ERR_IO_PENDING, rv);
7976 
7977   rv = callback1.WaitForResult();
7978   EXPECT_EQ(OK, rv);
7979 
7980   const HttpResponseInfo* response = trans->GetResponseInfo();
7981   ASSERT_TRUE(response != NULL);
7982   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7983 
7984   TestCompletionCallback callback2;
7985 
7986   rv = trans->RestartWithAuth(
7987       AuthCredentials(kFoo, kBar), callback2.callback());
7988   EXPECT_EQ(ERR_IO_PENDING, rv);
7989 
7990   rv = callback2.WaitForResult();
7991   EXPECT_EQ(OK, rv);
7992 
7993   response = trans->GetResponseInfo();
7994   ASSERT_TRUE(response != NULL);
7995   EXPECT_TRUE(response->auth_challenge.get() == NULL);
7996   EXPECT_EQ(100, response->headers->GetContentLength());
7997 }
7998 
7999 // Test HTTPS connections going through a proxy that sends extra data.
TEST_P(HttpNetworkTransactionTest,HTTPSViaProxyWithExtraData)8000 TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
8001   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
8002 
8003   HttpRequestInfo request;
8004   request.method = "GET";
8005   request.url = GURL("https://www.google.com/");
8006   request.load_flags = 0;
8007 
8008   MockRead proxy_reads[] = {
8009     MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
8010     MockRead(SYNCHRONOUS, OK)
8011   };
8012 
8013   StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
8014   SSLSocketDataProvider ssl(ASYNC, OK);
8015 
8016   session_deps_.socket_factory->AddSocketDataProvider(&data);
8017   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8018 
8019   TestCompletionCallback callback;
8020 
8021   session_deps_.socket_factory->ResetNextMockIndexes();
8022 
8023   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8024   scoped_ptr<HttpTransaction> trans(
8025       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
8026 
8027   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8028   EXPECT_EQ(ERR_IO_PENDING, rv);
8029 
8030   rv = callback.WaitForResult();
8031   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8032 }
8033 
TEST_P(HttpNetworkTransactionTest,LargeContentLengthThenClose)8034 TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
8035   HttpRequestInfo request;
8036   request.method = "GET";
8037   request.url = GURL("http://www.google.com/");
8038   request.load_flags = 0;
8039 
8040   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8041   scoped_ptr<HttpTransaction> trans(
8042       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
8043 
8044   MockRead data_reads[] = {
8045     MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
8046     MockRead(SYNCHRONOUS, OK),
8047   };
8048 
8049   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8050   session_deps_.socket_factory->AddSocketDataProvider(&data);
8051 
8052   TestCompletionCallback callback;
8053 
8054   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8055   EXPECT_EQ(ERR_IO_PENDING, rv);
8056 
8057   EXPECT_EQ(OK, callback.WaitForResult());
8058 
8059   const HttpResponseInfo* response = trans->GetResponseInfo();
8060   ASSERT_TRUE(response != NULL);
8061 
8062   EXPECT_TRUE(response->headers.get() != NULL);
8063   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8064 
8065   std::string response_data;
8066   rv = ReadTransaction(trans.get(), &response_data);
8067   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
8068 }
8069 
TEST_P(HttpNetworkTransactionTest,UploadFileSmallerThanLength)8070 TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
8071   base::FilePath temp_file_path;
8072   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
8073   const uint64 kFakeSize = 100000;  // file is actually blank
8074   UploadFileElementReader::ScopedOverridingContentLengthForTests
8075       overriding_content_length(kFakeSize);
8076 
8077   ScopedVector<UploadElementReader> element_readers;
8078   element_readers.push_back(
8079       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8080                                   temp_file_path,
8081                                   0,
8082                                   kuint64max,
8083                                   base::Time()));
8084   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
8085 
8086   HttpRequestInfo request;
8087   request.method = "POST";
8088   request.url = GURL("http://www.google.com/upload");
8089   request.upload_data_stream = &upload_data_stream;
8090   request.load_flags = 0;
8091 
8092   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8093   scoped_ptr<HttpTransaction> trans(
8094       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
8095 
8096   MockRead data_reads[] = {
8097     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8098     MockRead("hello world"),
8099     MockRead(SYNCHRONOUS, OK),
8100   };
8101   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8102   session_deps_.socket_factory->AddSocketDataProvider(&data);
8103 
8104   TestCompletionCallback callback;
8105 
8106   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8107   EXPECT_EQ(ERR_IO_PENDING, rv);
8108 
8109   rv = callback.WaitForResult();
8110   EXPECT_EQ(OK, rv);
8111 
8112   const HttpResponseInfo* response = trans->GetResponseInfo();
8113   ASSERT_TRUE(response != NULL);
8114 
8115   EXPECT_TRUE(response->headers.get() != NULL);
8116   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8117 
8118   std::string response_data;
8119   rv = ReadTransaction(trans.get(), &response_data);
8120   EXPECT_EQ(OK, rv);
8121   EXPECT_EQ("hello world", response_data);
8122 
8123   base::DeleteFile(temp_file_path, false);
8124 }
8125 
TEST_P(HttpNetworkTransactionTest,UploadUnreadableFile)8126 TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
8127   base::FilePath temp_file;
8128   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
8129   std::string temp_file_content("Unreadable file.");
8130   ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
8131                                    temp_file_content.length()));
8132   ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
8133 
8134   ScopedVector<UploadElementReader> element_readers;
8135   element_readers.push_back(
8136       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8137                                   temp_file,
8138                                   0,
8139                                   kuint64max,
8140                                   base::Time()));
8141   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
8142 
8143   HttpRequestInfo request;
8144   request.method = "POST";
8145   request.url = GURL("http://www.google.com/upload");
8146   request.upload_data_stream = &upload_data_stream;
8147   request.load_flags = 0;
8148 
8149   // If we try to upload an unreadable file, the transaction should fail.
8150   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8151   scoped_ptr<HttpTransaction> trans(
8152       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
8153 
8154   StaticSocketDataProvider data(NULL, 0, NULL, 0);
8155   session_deps_.socket_factory->AddSocketDataProvider(&data);
8156 
8157   TestCompletionCallback callback;
8158 
8159   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8160   EXPECT_EQ(ERR_IO_PENDING, rv);
8161 
8162   rv = callback.WaitForResult();
8163   EXPECT_EQ(ERR_ACCESS_DENIED, rv);
8164 
8165   const HttpResponseInfo* response = trans->GetResponseInfo();
8166   EXPECT_FALSE(response);
8167 
8168   base::DeleteFile(temp_file, false);
8169 }
8170 
TEST_P(HttpNetworkTransactionTest,CancelDuringInitRequestBody)8171 TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8172   class FakeUploadElementReader : public UploadElementReader {
8173    public:
8174     FakeUploadElementReader() {}
8175     virtual ~FakeUploadElementReader() {}
8176 
8177     const CompletionCallback& callback() const { return callback_; }
8178 
8179     // UploadElementReader overrides:
8180     virtual int Init(const CompletionCallback& callback) OVERRIDE {
8181       callback_ = callback;
8182       return ERR_IO_PENDING;
8183     }
8184     virtual uint64 GetContentLength() const OVERRIDE { return 0; }
8185     virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
8186     virtual int Read(IOBuffer* buf,
8187                      int buf_length,
8188                      const CompletionCallback& callback) OVERRIDE {
8189       return ERR_FAILED;
8190     }
8191 
8192    private:
8193     CompletionCallback callback_;
8194   };
8195 
8196   FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8197   ScopedVector<UploadElementReader> element_readers;
8198   element_readers.push_back(fake_reader);
8199   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
8200 
8201   HttpRequestInfo request;
8202   request.method = "POST";
8203   request.url = GURL("http://www.google.com/upload");
8204   request.upload_data_stream = &upload_data_stream;
8205   request.load_flags = 0;
8206 
8207   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8208   scoped_ptr<HttpTransaction> trans(
8209       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
8210 
8211   StaticSocketDataProvider data;
8212   session_deps_.socket_factory->AddSocketDataProvider(&data);
8213 
8214   TestCompletionCallback callback;
8215   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8216   EXPECT_EQ(ERR_IO_PENDING, rv);
8217   base::MessageLoop::current()->RunUntilIdle();
8218 
8219   // Transaction is pending on request body initialization.
8220   ASSERT_FALSE(fake_reader->callback().is_null());
8221 
8222   // Return Init()'s result after the transaction gets destroyed.
8223   trans.reset();
8224   fake_reader->callback().Run(OK);  // Should not crash.
8225 }
8226 
8227 // Tests that changes to Auth realms are treated like auth rejections.
TEST_P(HttpNetworkTransactionTest,ChangeAuthRealms)8228 TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
8229 
8230   HttpRequestInfo request;
8231   request.method = "GET";
8232   request.url = GURL("http://www.google.com/");
8233   request.load_flags = 0;
8234 
8235   // First transaction will request a resource and receive a Basic challenge
8236   // with realm="first_realm".
8237   MockWrite data_writes1[] = {
8238     MockWrite("GET / HTTP/1.1\r\n"
8239               "Host: www.google.com\r\n"
8240               "Connection: keep-alive\r\n"
8241               "\r\n"),
8242   };
8243   MockRead data_reads1[] = {
8244     MockRead("HTTP/1.1 401 Unauthorized\r\n"
8245              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8246              "\r\n"),
8247   };
8248 
8249   // After calling trans->RestartWithAuth(), provide an Authentication header
8250   // for first_realm. The server will reject and provide a challenge with
8251   // second_realm.
8252   MockWrite data_writes2[] = {
8253     MockWrite("GET / HTTP/1.1\r\n"
8254               "Host: www.google.com\r\n"
8255               "Connection: keep-alive\r\n"
8256               "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8257               "\r\n"),
8258   };
8259   MockRead data_reads2[] = {
8260     MockRead("HTTP/1.1 401 Unauthorized\r\n"
8261              "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8262              "\r\n"),
8263   };
8264 
8265   // This again fails, and goes back to first_realm. Make sure that the
8266   // entry is removed from cache.
8267   MockWrite data_writes3[] = {
8268     MockWrite("GET / HTTP/1.1\r\n"
8269               "Host: www.google.com\r\n"
8270               "Connection: keep-alive\r\n"
8271               "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8272               "\r\n"),
8273   };
8274   MockRead data_reads3[] = {
8275     MockRead("HTTP/1.1 401 Unauthorized\r\n"
8276              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8277              "\r\n"),
8278   };
8279 
8280   // Try one last time (with the correct password) and get the resource.
8281   MockWrite data_writes4[] = {
8282     MockWrite("GET / HTTP/1.1\r\n"
8283               "Host: www.google.com\r\n"
8284               "Connection: keep-alive\r\n"
8285               "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8286               "\r\n"),
8287   };
8288   MockRead data_reads4[] = {
8289     MockRead("HTTP/1.1 200 OK\r\n"
8290              "Content-Type: text/html; charset=iso-8859-1\r\n"
8291              "Content-Length: 5\r\n"
8292              "\r\n"
8293              "hello"),
8294   };
8295 
8296   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8297                                  data_writes1, arraysize(data_writes1));
8298   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8299                                  data_writes2, arraysize(data_writes2));
8300   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8301                                  data_writes3, arraysize(data_writes3));
8302   StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8303                                  data_writes4, arraysize(data_writes4));
8304   session_deps_.socket_factory->AddSocketDataProvider(&data1);
8305   session_deps_.socket_factory->AddSocketDataProvider(&data2);
8306   session_deps_.socket_factory->AddSocketDataProvider(&data3);
8307   session_deps_.socket_factory->AddSocketDataProvider(&data4);
8308 
8309   TestCompletionCallback callback1;
8310 
8311   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8312   scoped_ptr<HttpTransaction> trans(
8313       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
8314 
8315   // Issue the first request with Authorize headers. There should be a
8316   // password prompt for first_realm waiting to be filled in after the
8317   // transaction completes.
8318   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
8319   EXPECT_EQ(ERR_IO_PENDING, rv);
8320   rv = callback1.WaitForResult();
8321   EXPECT_EQ(OK, rv);
8322   const HttpResponseInfo* response = trans->GetResponseInfo();
8323   ASSERT_TRUE(response != NULL);
8324   const AuthChallengeInfo* challenge = response->auth_challenge.get();
8325   ASSERT_FALSE(challenge == NULL);
8326   EXPECT_FALSE(challenge->is_proxy);
8327   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8328   EXPECT_EQ("first_realm", challenge->realm);
8329   EXPECT_EQ("basic", challenge->scheme);
8330 
8331   // Issue the second request with an incorrect password. There should be a
8332   // password prompt for second_realm waiting to be filled in after the
8333   // transaction completes.
8334   TestCompletionCallback callback2;
8335   rv = trans->RestartWithAuth(
8336       AuthCredentials(kFirst, kBaz), callback2.callback());
8337   EXPECT_EQ(ERR_IO_PENDING, rv);
8338   rv = callback2.WaitForResult();
8339   EXPECT_EQ(OK, rv);
8340   response = trans->GetResponseInfo();
8341   ASSERT_TRUE(response != NULL);
8342   challenge = response->auth_challenge.get();
8343   ASSERT_FALSE(challenge == NULL);
8344   EXPECT_FALSE(challenge->is_proxy);
8345   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8346   EXPECT_EQ("second_realm", challenge->realm);
8347   EXPECT_EQ("basic", challenge->scheme);
8348 
8349   // Issue the third request with another incorrect password. There should be
8350   // a password prompt for first_realm waiting to be filled in. If the password
8351   // prompt is not present, it indicates that the HttpAuthCacheEntry for
8352   // first_realm was not correctly removed.
8353   TestCompletionCallback callback3;
8354   rv = trans->RestartWithAuth(
8355       AuthCredentials(kSecond, kFou), callback3.callback());
8356   EXPECT_EQ(ERR_IO_PENDING, rv);
8357   rv = callback3.WaitForResult();
8358   EXPECT_EQ(OK, rv);
8359   response = trans->GetResponseInfo();
8360   ASSERT_TRUE(response != NULL);
8361   challenge = response->auth_challenge.get();
8362   ASSERT_FALSE(challenge == NULL);
8363   EXPECT_FALSE(challenge->is_proxy);
8364   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8365   EXPECT_EQ("first_realm", challenge->realm);
8366   EXPECT_EQ("basic", challenge->scheme);
8367 
8368   // Issue the fourth request with the correct password and username.
8369   TestCompletionCallback callback4;
8370   rv = trans->RestartWithAuth(
8371       AuthCredentials(kFirst, kBar), callback4.callback());
8372   EXPECT_EQ(ERR_IO_PENDING, rv);
8373   rv = callback4.WaitForResult();
8374   EXPECT_EQ(OK, rv);
8375   response = trans->GetResponseInfo();
8376   ASSERT_TRUE(response != NULL);
8377   EXPECT_TRUE(response->auth_challenge.get() == NULL);
8378 }
8379 
TEST_P(HttpNetworkTransactionTest,HonorAlternateProtocolHeader)8380 TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
8381   session_deps_.next_protos = SpdyNextProtos();
8382   session_deps_.use_alternate_protocols = true;
8383 
8384   std::string alternate_protocol_http_header =
8385       GetAlternateProtocolHttpHeader();
8386 
8387   MockRead data_reads[] = {
8388     MockRead("HTTP/1.1 200 OK\r\n"),
8389     MockRead(alternate_protocol_http_header.c_str()),
8390     MockRead("hello world"),
8391     MockRead(SYNCHRONOUS, OK),
8392   };
8393 
8394   HttpRequestInfo request;
8395   request.method = "GET";
8396   request.url = GURL("http://www.google.com/");
8397   request.load_flags = 0;
8398 
8399   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8400 
8401   session_deps_.socket_factory->AddSocketDataProvider(&data);
8402 
8403   TestCompletionCallback callback;
8404 
8405   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8406   scoped_ptr<HttpTransaction> trans(
8407       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8408 
8409   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8410   EXPECT_EQ(ERR_IO_PENDING, rv);
8411 
8412   HostPortPair http_host_port_pair("www.google.com", 80);
8413   HttpServerProperties& http_server_properties =
8414       *session->http_server_properties();
8415   EXPECT_FALSE(
8416       http_server_properties.HasAlternateProtocol(http_host_port_pair));
8417 
8418   EXPECT_EQ(OK, callback.WaitForResult());
8419 
8420   const HttpResponseInfo* response = trans->GetResponseInfo();
8421   ASSERT_TRUE(response != NULL);
8422   ASSERT_TRUE(response->headers.get() != NULL);
8423   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8424   EXPECT_FALSE(response->was_fetched_via_spdy);
8425   EXPECT_FALSE(response->was_npn_negotiated);
8426 
8427   std::string response_data;
8428   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8429   EXPECT_EQ("hello world", response_data);
8430 
8431   ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8432   const PortAlternateProtocolPair alternate =
8433       http_server_properties.GetAlternateProtocol(http_host_port_pair);
8434   PortAlternateProtocolPair expected_alternate;
8435   expected_alternate.port = 443;
8436   expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
8437   EXPECT_TRUE(expected_alternate.Equals(alternate));
8438 }
8439 
TEST_P(HttpNetworkTransactionTest,MarkBrokenAlternateProtocolAndFallback)8440 TEST_P(HttpNetworkTransactionTest,
8441        MarkBrokenAlternateProtocolAndFallback) {
8442   session_deps_.use_alternate_protocols = true;
8443 
8444   HttpRequestInfo request;
8445   request.method = "GET";
8446   request.url = GURL("http://www.google.com/");
8447   request.load_flags = 0;
8448 
8449   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8450   StaticSocketDataProvider first_data;
8451   first_data.set_connect_data(mock_connect);
8452   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8453 
8454   MockRead data_reads[] = {
8455     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8456     MockRead("hello world"),
8457     MockRead(ASYNC, OK),
8458   };
8459   StaticSocketDataProvider second_data(
8460       data_reads, arraysize(data_reads), NULL, 0);
8461   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8462 
8463   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8464 
8465   base::WeakPtr<HttpServerProperties> http_server_properties =
8466       session->http_server_properties();
8467   // Port must be < 1024, or the header will be ignored (since initial port was
8468   // port 80 (another restricted port).
8469   http_server_properties->SetAlternateProtocol(
8470       HostPortPair::FromURL(request.url),
8471       666 /* port is ignored by MockConnect anyway */,
8472       AlternateProtocolFromNextProto(GetParam()));
8473 
8474   scoped_ptr<HttpTransaction> trans(
8475       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8476   TestCompletionCallback callback;
8477 
8478   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8479   EXPECT_EQ(ERR_IO_PENDING, rv);
8480   EXPECT_EQ(OK, callback.WaitForResult());
8481 
8482   const HttpResponseInfo* response = trans->GetResponseInfo();
8483   ASSERT_TRUE(response != NULL);
8484   ASSERT_TRUE(response->headers.get() != NULL);
8485   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8486 
8487   std::string response_data;
8488   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8489   EXPECT_EQ("hello world", response_data);
8490 
8491   ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
8492       HostPortPair::FromURL(request.url)));
8493   const PortAlternateProtocolPair alternate =
8494       http_server_properties->GetAlternateProtocol(
8495           HostPortPair::FromURL(request.url));
8496   EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
8497 }
8498 
TEST_P(HttpNetworkTransactionTest,AlternateProtocolPortRestrictedBlocked)8499 TEST_P(HttpNetworkTransactionTest,
8500        AlternateProtocolPortRestrictedBlocked) {
8501   // Ensure that we're not allowed to redirect traffic via an alternate
8502   // protocol to an unrestricted (port >= 1024) when the original traffic was
8503   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8504   // other cases.
8505   session_deps_.use_alternate_protocols = true;
8506 
8507   HttpRequestInfo restricted_port_request;
8508   restricted_port_request.method = "GET";
8509   restricted_port_request.url = GURL("http://www.google.com:1023/");
8510   restricted_port_request.load_flags = 0;
8511 
8512   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8513   StaticSocketDataProvider first_data;
8514   first_data.set_connect_data(mock_connect);
8515   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8516 
8517   MockRead data_reads[] = {
8518     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8519     MockRead("hello world"),
8520     MockRead(ASYNC, OK),
8521   };
8522   StaticSocketDataProvider second_data(
8523       data_reads, arraysize(data_reads), NULL, 0);
8524   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8525 
8526   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8527 
8528   base::WeakPtr<HttpServerProperties> http_server_properties =
8529       session->http_server_properties();
8530   const int kUnrestrictedAlternatePort = 1024;
8531   http_server_properties->SetAlternateProtocol(
8532       HostPortPair::FromURL(restricted_port_request.url),
8533       kUnrestrictedAlternatePort,
8534       AlternateProtocolFromNextProto(GetParam()));
8535 
8536   scoped_ptr<HttpTransaction> trans(
8537       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8538   TestCompletionCallback callback;
8539 
8540   int rv = trans->Start(
8541       &restricted_port_request,
8542       callback.callback(), BoundNetLog());
8543   EXPECT_EQ(ERR_IO_PENDING, rv);
8544   // Invalid change to unrestricted port should fail.
8545   EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
8546 }
8547 
TEST_P(HttpNetworkTransactionTest,AlternateProtocolPortRestrictedPermitted)8548 TEST_P(HttpNetworkTransactionTest,
8549        AlternateProtocolPortRestrictedPermitted) {
8550   // Ensure that we're allowed to redirect traffic via an alternate
8551   // protocol to an unrestricted (port >= 1024) when the original traffic was
8552   // on a restricted port (port < 1024) if we set
8553   // enable_user_alternate_protocol_ports.
8554 
8555   session_deps_.use_alternate_protocols = true;
8556   session_deps_.enable_user_alternate_protocol_ports = true;
8557 
8558   HttpRequestInfo restricted_port_request;
8559   restricted_port_request.method = "GET";
8560   restricted_port_request.url = GURL("http://www.google.com:1023/");
8561   restricted_port_request.load_flags = 0;
8562 
8563   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8564   StaticSocketDataProvider first_data;
8565   first_data.set_connect_data(mock_connect);
8566   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8567 
8568   MockRead data_reads[] = {
8569     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8570     MockRead("hello world"),
8571     MockRead(ASYNC, OK),
8572   };
8573   StaticSocketDataProvider second_data(
8574       data_reads, arraysize(data_reads), NULL, 0);
8575   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8576 
8577   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8578 
8579   base::WeakPtr<HttpServerProperties> http_server_properties =
8580       session->http_server_properties();
8581   const int kUnrestrictedAlternatePort = 1024;
8582   http_server_properties->SetAlternateProtocol(
8583       HostPortPair::FromURL(restricted_port_request.url),
8584       kUnrestrictedAlternatePort,
8585       AlternateProtocolFromNextProto(GetParam()));
8586 
8587   scoped_ptr<HttpTransaction> trans(
8588       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8589   TestCompletionCallback callback;
8590 
8591   EXPECT_EQ(ERR_IO_PENDING, trans->Start(
8592       &restricted_port_request,
8593       callback.callback(), BoundNetLog()));
8594   // Change to unrestricted port should succeed.
8595   EXPECT_EQ(OK, callback.WaitForResult());
8596 }
8597 
TEST_P(HttpNetworkTransactionTest,AlternateProtocolPortRestrictedAllowed)8598 TEST_P(HttpNetworkTransactionTest,
8599        AlternateProtocolPortRestrictedAllowed) {
8600   // Ensure that we're not allowed to redirect traffic via an alternate
8601   // protocol to an unrestricted (port >= 1024) when the original traffic was
8602   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8603   // other cases.
8604   session_deps_.use_alternate_protocols = true;
8605 
8606   HttpRequestInfo restricted_port_request;
8607   restricted_port_request.method = "GET";
8608   restricted_port_request.url = GURL("http://www.google.com:1023/");
8609   restricted_port_request.load_flags = 0;
8610 
8611   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8612   StaticSocketDataProvider first_data;
8613   first_data.set_connect_data(mock_connect);
8614   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8615 
8616   MockRead data_reads[] = {
8617     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8618     MockRead("hello world"),
8619     MockRead(ASYNC, OK),
8620   };
8621   StaticSocketDataProvider second_data(
8622       data_reads, arraysize(data_reads), NULL, 0);
8623   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8624 
8625   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8626 
8627   base::WeakPtr<HttpServerProperties> http_server_properties =
8628       session->http_server_properties();
8629   const int kRestrictedAlternatePort = 80;
8630   http_server_properties->SetAlternateProtocol(
8631       HostPortPair::FromURL(restricted_port_request.url),
8632       kRestrictedAlternatePort,
8633       AlternateProtocolFromNextProto(GetParam()));
8634 
8635   scoped_ptr<HttpTransaction> trans(
8636       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8637   TestCompletionCallback callback;
8638 
8639   int rv = trans->Start(
8640       &restricted_port_request,
8641       callback.callback(), BoundNetLog());
8642   EXPECT_EQ(ERR_IO_PENDING, rv);
8643   // Valid change to restricted port should pass.
8644   EXPECT_EQ(OK, callback.WaitForResult());
8645 }
8646 
TEST_P(HttpNetworkTransactionTest,AlternateProtocolPortUnrestrictedAllowed1)8647 TEST_P(HttpNetworkTransactionTest,
8648        AlternateProtocolPortUnrestrictedAllowed1) {
8649   // Ensure that we're not allowed to redirect traffic via an alternate
8650   // protocol to an unrestricted (port >= 1024) when the original traffic was
8651   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8652   // other cases.
8653   session_deps_.use_alternate_protocols = true;
8654 
8655   HttpRequestInfo unrestricted_port_request;
8656   unrestricted_port_request.method = "GET";
8657   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8658   unrestricted_port_request.load_flags = 0;
8659 
8660   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8661   StaticSocketDataProvider first_data;
8662   first_data.set_connect_data(mock_connect);
8663   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8664 
8665   MockRead data_reads[] = {
8666     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8667     MockRead("hello world"),
8668     MockRead(ASYNC, OK),
8669   };
8670   StaticSocketDataProvider second_data(
8671       data_reads, arraysize(data_reads), NULL, 0);
8672   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8673 
8674   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8675 
8676   base::WeakPtr<HttpServerProperties> http_server_properties =
8677       session->http_server_properties();
8678   const int kRestrictedAlternatePort = 80;
8679   http_server_properties->SetAlternateProtocol(
8680       HostPortPair::FromURL(unrestricted_port_request.url),
8681       kRestrictedAlternatePort,
8682       AlternateProtocolFromNextProto(GetParam()));
8683 
8684   scoped_ptr<HttpTransaction> trans(
8685       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8686   TestCompletionCallback callback;
8687 
8688   int rv = trans->Start(
8689       &unrestricted_port_request, callback.callback(), BoundNetLog());
8690   EXPECT_EQ(ERR_IO_PENDING, rv);
8691   // Valid change to restricted port should pass.
8692   EXPECT_EQ(OK, callback.WaitForResult());
8693 }
8694 
TEST_P(HttpNetworkTransactionTest,AlternateProtocolPortUnrestrictedAllowed2)8695 TEST_P(HttpNetworkTransactionTest,
8696        AlternateProtocolPortUnrestrictedAllowed2) {
8697   // Ensure that we're not allowed to redirect traffic via an alternate
8698   // protocol to an unrestricted (port >= 1024) when the original traffic was
8699   // on a restricted port (port < 1024).  Ensure that we can redirect in all
8700   // other cases.
8701   session_deps_.use_alternate_protocols = true;
8702 
8703   HttpRequestInfo unrestricted_port_request;
8704   unrestricted_port_request.method = "GET";
8705   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8706   unrestricted_port_request.load_flags = 0;
8707 
8708   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8709   StaticSocketDataProvider first_data;
8710   first_data.set_connect_data(mock_connect);
8711   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
8712 
8713   MockRead data_reads[] = {
8714     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8715     MockRead("hello world"),
8716     MockRead(ASYNC, OK),
8717   };
8718   StaticSocketDataProvider second_data(
8719       data_reads, arraysize(data_reads), NULL, 0);
8720   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
8721 
8722   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8723 
8724   base::WeakPtr<HttpServerProperties> http_server_properties =
8725       session->http_server_properties();
8726   const int kUnrestrictedAlternatePort = 1024;
8727   http_server_properties->SetAlternateProtocol(
8728       HostPortPair::FromURL(unrestricted_port_request.url),
8729       kUnrestrictedAlternatePort,
8730       AlternateProtocolFromNextProto(GetParam()));
8731 
8732   scoped_ptr<HttpTransaction> trans(
8733       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8734   TestCompletionCallback callback;
8735 
8736   int rv = trans->Start(
8737       &unrestricted_port_request, callback.callback(), BoundNetLog());
8738   EXPECT_EQ(ERR_IO_PENDING, rv);
8739   // Valid change to an unrestricted port should pass.
8740   EXPECT_EQ(OK, callback.WaitForResult());
8741 }
8742 
TEST_P(HttpNetworkTransactionTest,AlternateProtocolUnsafeBlocked)8743 TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
8744   // Ensure that we're not allowed to redirect traffic via an alternate
8745   // protocol to an unsafe port, and that we resume the second
8746   // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8747   session_deps_.use_alternate_protocols = true;
8748 
8749   HttpRequestInfo request;
8750   request.method = "GET";
8751   request.url = GURL("http://www.google.com/");
8752   request.load_flags = 0;
8753 
8754   // The alternate protocol request will error out before we attempt to connect,
8755   // so only the standard HTTP request will try to connect.
8756   MockRead data_reads[] = {
8757     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8758     MockRead("hello world"),
8759     MockRead(ASYNC, OK),
8760   };
8761   StaticSocketDataProvider data(
8762       data_reads, arraysize(data_reads), NULL, 0);
8763   session_deps_.socket_factory->AddSocketDataProvider(&data);
8764 
8765   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8766 
8767   base::WeakPtr<HttpServerProperties> http_server_properties =
8768       session->http_server_properties();
8769   const int kUnsafePort = 7;
8770   http_server_properties->SetAlternateProtocol(
8771       HostPortPair::FromURL(request.url),
8772       kUnsafePort,
8773       AlternateProtocolFromNextProto(GetParam()));
8774 
8775   scoped_ptr<HttpTransaction> trans(
8776       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8777   TestCompletionCallback callback;
8778 
8779   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8780   EXPECT_EQ(ERR_IO_PENDING, rv);
8781   // The HTTP request should succeed.
8782   EXPECT_EQ(OK, callback.WaitForResult());
8783 
8784   // Disable alternate protocol before the asserts.
8785  // HttpStreamFactory::set_use_alternate_protocols(false);
8786 
8787   const HttpResponseInfo* response = trans->GetResponseInfo();
8788   ASSERT_TRUE(response != NULL);
8789   ASSERT_TRUE(response->headers.get() != NULL);
8790   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8791 
8792   std::string response_data;
8793   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8794   EXPECT_EQ("hello world", response_data);
8795 }
8796 
TEST_P(HttpNetworkTransactionTest,UseAlternateProtocolForNpnSpdy)8797 TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
8798   session_deps_.use_alternate_protocols = true;
8799   session_deps_.next_protos = SpdyNextProtos();
8800 
8801   HttpRequestInfo request;
8802   request.method = "GET";
8803   request.url = GURL("http://www.google.com/");
8804   request.load_flags = 0;
8805 
8806   std::string alternate_protocol_http_header =
8807       GetAlternateProtocolHttpHeader();
8808 
8809   MockRead data_reads[] = {
8810     MockRead("HTTP/1.1 200 OK\r\n"),
8811     MockRead(alternate_protocol_http_header.c_str()),
8812     MockRead("hello world"),
8813     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8814     MockRead(ASYNC, OK)
8815   };
8816 
8817   StaticSocketDataProvider first_transaction(
8818       data_reads, arraysize(data_reads), NULL, 0);
8819   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
8820 
8821   SSLSocketDataProvider ssl(ASYNC, OK);
8822   ssl.SetNextProto(GetParam());
8823   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8824 
8825   scoped_ptr<SpdyFrame> req(
8826       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8827   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
8828 
8829   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8830   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
8831   MockRead spdy_reads[] = {
8832     CreateMockRead(*resp),
8833     CreateMockRead(*data),
8834     MockRead(ASYNC, 0, 0),
8835   };
8836 
8837   DelayedSocketData spdy_data(
8838       1,  // wait for one write to finish before reading.
8839       spdy_reads, arraysize(spdy_reads),
8840       spdy_writes, arraysize(spdy_writes));
8841   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8842 
8843   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
8844   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8845       NULL, 0, NULL, 0);
8846   hanging_non_alternate_protocol_socket.set_connect_data(
8847       never_finishing_connect);
8848   session_deps_.socket_factory->AddSocketDataProvider(
8849       &hanging_non_alternate_protocol_socket);
8850 
8851   TestCompletionCallback callback;
8852 
8853   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8854   scoped_ptr<HttpTransaction> trans(
8855       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8856 
8857   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8858   EXPECT_EQ(ERR_IO_PENDING, rv);
8859   EXPECT_EQ(OK, callback.WaitForResult());
8860 
8861   const HttpResponseInfo* response = trans->GetResponseInfo();
8862   ASSERT_TRUE(response != NULL);
8863   ASSERT_TRUE(response->headers.get() != NULL);
8864   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8865 
8866   std::string response_data;
8867   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8868   EXPECT_EQ("hello world", response_data);
8869 
8870   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8871 
8872   rv = trans->Start(&request, callback.callback(), BoundNetLog());
8873   EXPECT_EQ(ERR_IO_PENDING, rv);
8874   EXPECT_EQ(OK, callback.WaitForResult());
8875 
8876   response = trans->GetResponseInfo();
8877   ASSERT_TRUE(response != NULL);
8878   ASSERT_TRUE(response->headers.get() != NULL);
8879   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8880   EXPECT_TRUE(response->was_fetched_via_spdy);
8881   EXPECT_TRUE(response->was_npn_negotiated);
8882 
8883   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8884   EXPECT_EQ("hello!", response_data);
8885 }
8886 
TEST_P(HttpNetworkTransactionTest,AlternateProtocolWithSpdyLateBinding)8887 TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
8888   session_deps_.use_alternate_protocols = true;
8889   session_deps_.next_protos = SpdyNextProtos();
8890 
8891   HttpRequestInfo request;
8892   request.method = "GET";
8893   request.url = GURL("http://www.google.com/");
8894   request.load_flags = 0;
8895 
8896   std::string alternate_protocol_http_header =
8897       GetAlternateProtocolHttpHeader();
8898 
8899   MockRead data_reads[] = {
8900     MockRead("HTTP/1.1 200 OK\r\n"),
8901     MockRead(alternate_protocol_http_header.c_str()),
8902     MockRead("hello world"),
8903     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8904     MockRead(ASYNC, OK),
8905   };
8906 
8907   StaticSocketDataProvider first_transaction(
8908       data_reads, arraysize(data_reads), NULL, 0);
8909   // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
8910   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
8911 
8912   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
8913   StaticSocketDataProvider hanging_socket(
8914       NULL, 0, NULL, 0);
8915   hanging_socket.set_connect_data(never_finishing_connect);
8916   // Socket 2 and 3 are the hanging Alternate-Protocol and
8917   // non-Alternate-Protocol jobs from the 2nd transaction.
8918   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8919   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8920 
8921   SSLSocketDataProvider ssl(ASYNC, OK);
8922   ssl.SetNextProto(GetParam());
8923   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8924 
8925   scoped_ptr<SpdyFrame> req1(
8926       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8927   scoped_ptr<SpdyFrame> req2(
8928       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
8929   MockWrite spdy_writes[] = {
8930     CreateMockWrite(*req1),
8931     CreateMockWrite(*req2),
8932   };
8933   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8934   scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8935   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8936   scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
8937   MockRead spdy_reads[] = {
8938     CreateMockRead(*resp1),
8939     CreateMockRead(*data1),
8940     CreateMockRead(*resp2),
8941     CreateMockRead(*data2),
8942     MockRead(ASYNC, 0, 0),
8943   };
8944 
8945   DelayedSocketData spdy_data(
8946       2,  // wait for writes to finish before reading.
8947       spdy_reads, arraysize(spdy_reads),
8948       spdy_writes, arraysize(spdy_writes));
8949   // Socket 4 is the successful Alternate-Protocol for transaction 3.
8950   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8951 
8952   // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
8953   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8954 
8955   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8956   TestCompletionCallback callback1;
8957   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
8958 
8959   int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
8960   EXPECT_EQ(ERR_IO_PENDING, rv);
8961   EXPECT_EQ(OK, callback1.WaitForResult());
8962 
8963   const HttpResponseInfo* response = trans1.GetResponseInfo();
8964   ASSERT_TRUE(response != NULL);
8965   ASSERT_TRUE(response->headers.get() != NULL);
8966   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8967 
8968   std::string response_data;
8969   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8970   EXPECT_EQ("hello world", response_data);
8971 
8972   TestCompletionCallback callback2;
8973   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
8974   rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
8975   EXPECT_EQ(ERR_IO_PENDING, rv);
8976 
8977   TestCompletionCallback callback3;
8978   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
8979   rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
8980   EXPECT_EQ(ERR_IO_PENDING, rv);
8981 
8982   EXPECT_EQ(OK, callback2.WaitForResult());
8983   EXPECT_EQ(OK, callback3.WaitForResult());
8984 
8985   response = trans2.GetResponseInfo();
8986   ASSERT_TRUE(response != NULL);
8987   ASSERT_TRUE(response->headers.get() != NULL);
8988   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8989   EXPECT_TRUE(response->was_fetched_via_spdy);
8990   EXPECT_TRUE(response->was_npn_negotiated);
8991   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
8992   EXPECT_EQ("hello!", response_data);
8993 
8994   response = trans3.GetResponseInfo();
8995   ASSERT_TRUE(response != NULL);
8996   ASSERT_TRUE(response->headers.get() != NULL);
8997   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8998   EXPECT_TRUE(response->was_fetched_via_spdy);
8999   EXPECT_TRUE(response->was_npn_negotiated);
9000   ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9001   EXPECT_EQ("hello!", response_data);
9002 }
9003 
TEST_P(HttpNetworkTransactionTest,StallAlternateProtocolForNpnSpdy)9004 TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
9005   session_deps_.use_alternate_protocols = true;
9006   session_deps_.next_protos = SpdyNextProtos();
9007 
9008   HttpRequestInfo request;
9009   request.method = "GET";
9010   request.url = GURL("http://www.google.com/");
9011   request.load_flags = 0;
9012 
9013   std::string alternate_protocol_http_header =
9014       GetAlternateProtocolHttpHeader();
9015 
9016   MockRead data_reads[] = {
9017     MockRead("HTTP/1.1 200 OK\r\n"),
9018     MockRead(alternate_protocol_http_header.c_str()),
9019     MockRead("hello world"),
9020     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9021     MockRead(ASYNC, OK),
9022   };
9023 
9024   StaticSocketDataProvider first_transaction(
9025       data_reads, arraysize(data_reads), NULL, 0);
9026   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
9027 
9028   SSLSocketDataProvider ssl(ASYNC, OK);
9029   ssl.SetNextProto(GetParam());
9030   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9031 
9032   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
9033   StaticSocketDataProvider hanging_alternate_protocol_socket(
9034       NULL, 0, NULL, 0);
9035   hanging_alternate_protocol_socket.set_connect_data(
9036       never_finishing_connect);
9037   session_deps_.socket_factory->AddSocketDataProvider(
9038       &hanging_alternate_protocol_socket);
9039 
9040   // 2nd request is just a copy of the first one, over HTTP again.
9041   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
9042 
9043   TestCompletionCallback callback;
9044 
9045   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9046   scoped_ptr<HttpTransaction> trans(
9047       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9048 
9049   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9050   EXPECT_EQ(ERR_IO_PENDING, rv);
9051   EXPECT_EQ(OK, callback.WaitForResult());
9052 
9053   const HttpResponseInfo* response = trans->GetResponseInfo();
9054   ASSERT_TRUE(response != NULL);
9055   ASSERT_TRUE(response->headers.get() != NULL);
9056   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9057 
9058   std::string response_data;
9059   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9060   EXPECT_EQ("hello world", response_data);
9061 
9062   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9063 
9064   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9065   EXPECT_EQ(ERR_IO_PENDING, rv);
9066   EXPECT_EQ(OK, callback.WaitForResult());
9067 
9068   response = trans->GetResponseInfo();
9069   ASSERT_TRUE(response != NULL);
9070   ASSERT_TRUE(response->headers.get() != NULL);
9071   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9072   EXPECT_FALSE(response->was_fetched_via_spdy);
9073   EXPECT_FALSE(response->was_npn_negotiated);
9074 
9075   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9076   EXPECT_EQ("hello world", response_data);
9077 }
9078 
9079 class CapturingProxyResolver : public ProxyResolver {
9080  public:
CapturingProxyResolver()9081   CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
~CapturingProxyResolver()9082   virtual ~CapturingProxyResolver() {}
9083 
GetProxyForURL(const GURL & url,ProxyInfo * results,const CompletionCallback & callback,RequestHandle * request,const BoundNetLog & net_log)9084   virtual int GetProxyForURL(const GURL& url,
9085                              ProxyInfo* results,
9086                              const CompletionCallback& callback,
9087                              RequestHandle* request,
9088                              const BoundNetLog& net_log) OVERRIDE {
9089     ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9090                              HostPortPair("myproxy", 80));
9091     results->UseProxyServer(proxy_server);
9092     resolved_.push_back(url);
9093     return OK;
9094   }
9095 
CancelRequest(RequestHandle request)9096   virtual void CancelRequest(RequestHandle request) OVERRIDE {
9097     NOTREACHED();
9098   }
9099 
GetLoadState(RequestHandle request) const9100   virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
9101     NOTREACHED();
9102     return LOAD_STATE_IDLE;
9103   }
9104 
CancelSetPacScript()9105   virtual void CancelSetPacScript() OVERRIDE {
9106     NOTREACHED();
9107   }
9108 
SetPacScript(const scoped_refptr<ProxyResolverScriptData> &,const CompletionCallback &)9109   virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
9110                            const CompletionCallback& /*callback*/) OVERRIDE {
9111     return OK;
9112   }
9113 
resolved() const9114   const std::vector<GURL>& resolved() const { return resolved_; }
9115 
9116  private:
9117   std::vector<GURL> resolved_;
9118 
9119   DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9120 };
9121 
TEST_P(HttpNetworkTransactionTest,UseAlternateProtocolForTunneledNpnSpdy)9122 TEST_P(HttpNetworkTransactionTest,
9123        UseAlternateProtocolForTunneledNpnSpdy) {
9124   session_deps_.use_alternate_protocols = true;
9125   session_deps_.next_protos = SpdyNextProtos();
9126 
9127   ProxyConfig proxy_config;
9128   proxy_config.set_auto_detect(true);
9129   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
9130 
9131   CapturingProxyResolver* capturing_proxy_resolver =
9132       new CapturingProxyResolver();
9133   session_deps_.proxy_service.reset(new ProxyService(
9134       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
9135       NULL));
9136   CapturingNetLog net_log;
9137   session_deps_.net_log = &net_log;
9138 
9139   HttpRequestInfo request;
9140   request.method = "GET";
9141   request.url = GURL("http://www.google.com/");
9142   request.load_flags = 0;
9143 
9144   std::string alternate_protocol_http_header =
9145       GetAlternateProtocolHttpHeader();
9146 
9147   MockRead data_reads[] = {
9148     MockRead("HTTP/1.1 200 OK\r\n"),
9149     MockRead(alternate_protocol_http_header.c_str()),
9150     MockRead("hello world"),
9151     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9152     MockRead(ASYNC, OK),
9153   };
9154 
9155   StaticSocketDataProvider first_transaction(
9156       data_reads, arraysize(data_reads), NULL, 0);
9157   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
9158 
9159   SSLSocketDataProvider ssl(ASYNC, OK);
9160   ssl.SetNextProto(GetParam());
9161   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9162 
9163   scoped_ptr<SpdyFrame> req(
9164       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9165   MockWrite spdy_writes[] = {
9166     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9167               "Host: www.google.com\r\n"
9168               "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
9169     CreateMockWrite(*req),                              // 3
9170   };
9171 
9172   const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9173 
9174   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9175   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
9176   MockRead spdy_reads[] = {
9177     MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
9178     CreateMockRead(*resp.get(), 4),  // 2, 4
9179     CreateMockRead(*data.get(), 4),  // 5
9180     MockRead(ASYNC, 0, 0, 4),  // 6
9181   };
9182 
9183   OrderedSocketData spdy_data(
9184       spdy_reads, arraysize(spdy_reads),
9185       spdy_writes, arraysize(spdy_writes));
9186   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9187 
9188   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
9189   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9190       NULL, 0, NULL, 0);
9191   hanging_non_alternate_protocol_socket.set_connect_data(
9192       never_finishing_connect);
9193   session_deps_.socket_factory->AddSocketDataProvider(
9194       &hanging_non_alternate_protocol_socket);
9195 
9196   TestCompletionCallback callback;
9197 
9198   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9199   scoped_ptr<HttpTransaction> trans(
9200       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9201 
9202   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9203   EXPECT_EQ(ERR_IO_PENDING, rv);
9204   EXPECT_EQ(OK, callback.WaitForResult());
9205 
9206   const HttpResponseInfo* response = trans->GetResponseInfo();
9207   ASSERT_TRUE(response != NULL);
9208   ASSERT_TRUE(response->headers.get() != NULL);
9209   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9210   EXPECT_FALSE(response->was_fetched_via_spdy);
9211   EXPECT_FALSE(response->was_npn_negotiated);
9212 
9213   std::string response_data;
9214   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9215   EXPECT_EQ("hello world", response_data);
9216 
9217   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9218 
9219   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9220   EXPECT_EQ(ERR_IO_PENDING, rv);
9221   EXPECT_EQ(OK, callback.WaitForResult());
9222 
9223   response = trans->GetResponseInfo();
9224   ASSERT_TRUE(response != NULL);
9225   ASSERT_TRUE(response->headers.get() != NULL);
9226   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9227   EXPECT_TRUE(response->was_fetched_via_spdy);
9228   EXPECT_TRUE(response->was_npn_negotiated);
9229 
9230   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9231   EXPECT_EQ("hello!", response_data);
9232   ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
9233   EXPECT_EQ("http://www.google.com/",
9234             capturing_proxy_resolver->resolved()[0].spec());
9235   EXPECT_EQ("https://www.google.com/",
9236             capturing_proxy_resolver->resolved()[1].spec());
9237 
9238   LoadTimingInfo load_timing_info;
9239   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9240   TestLoadTimingNotReusedWithPac(load_timing_info,
9241                                  CONNECT_TIMING_HAS_SSL_TIMES);
9242 }
9243 
TEST_P(HttpNetworkTransactionTest,UseAlternateProtocolForNpnSpdyWithExistingSpdySession)9244 TEST_P(HttpNetworkTransactionTest,
9245        UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
9246   session_deps_.use_alternate_protocols = true;
9247   session_deps_.next_protos = SpdyNextProtos();
9248 
9249   HttpRequestInfo request;
9250   request.method = "GET";
9251   request.url = GURL("http://www.google.com/");
9252   request.load_flags = 0;
9253 
9254   std::string alternate_protocol_http_header =
9255       GetAlternateProtocolHttpHeader();
9256 
9257   MockRead data_reads[] = {
9258     MockRead("HTTP/1.1 200 OK\r\n"),
9259     MockRead(alternate_protocol_http_header.c_str()),
9260     MockRead("hello world"),
9261     MockRead(ASYNC, OK),
9262   };
9263 
9264   StaticSocketDataProvider first_transaction(
9265       data_reads, arraysize(data_reads), NULL, 0);
9266   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
9267 
9268   SSLSocketDataProvider ssl(ASYNC, OK);
9269   ssl.SetNextProto(GetParam());
9270   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9271 
9272   scoped_ptr<SpdyFrame> req(
9273       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9274   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
9275 
9276   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9277   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
9278   MockRead spdy_reads[] = {
9279     CreateMockRead(*resp),
9280     CreateMockRead(*data),
9281     MockRead(ASYNC, 0, 0),
9282   };
9283 
9284   DelayedSocketData spdy_data(
9285       1,  // wait for one write to finish before reading.
9286       spdy_reads, arraysize(spdy_reads),
9287       spdy_writes, arraysize(spdy_writes));
9288   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9289 
9290   TestCompletionCallback callback;
9291 
9292   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9293 
9294   scoped_ptr<HttpTransaction> trans(
9295       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9296 
9297   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9298   EXPECT_EQ(ERR_IO_PENDING, rv);
9299   EXPECT_EQ(OK, callback.WaitForResult());
9300 
9301   const HttpResponseInfo* response = trans->GetResponseInfo();
9302   ASSERT_TRUE(response != NULL);
9303   ASSERT_TRUE(response->headers.get() != NULL);
9304   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9305 
9306   std::string response_data;
9307   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9308   EXPECT_EQ("hello world", response_data);
9309 
9310   // Set up an initial SpdySession in the pool to reuse.
9311   HostPortPair host_port_pair("www.google.com", 443);
9312   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
9313                      PRIVACY_MODE_DISABLED);
9314   base::WeakPtr<SpdySession> spdy_session =
9315       CreateSecureSpdySession(session, key, BoundNetLog());
9316 
9317   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9318 
9319   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9320   EXPECT_EQ(ERR_IO_PENDING, rv);
9321   EXPECT_EQ(OK, callback.WaitForResult());
9322 
9323   response = trans->GetResponseInfo();
9324   ASSERT_TRUE(response != NULL);
9325   ASSERT_TRUE(response->headers.get() != NULL);
9326   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9327   EXPECT_TRUE(response->was_fetched_via_spdy);
9328   EXPECT_TRUE(response->was_npn_negotiated);
9329 
9330   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9331   EXPECT_EQ("hello!", response_data);
9332 }
9333 
9334 // GenerateAuthToken is a mighty big test.
9335 // It tests all permutation of GenerateAuthToken behavior:
9336 //   - Synchronous and Asynchronous completion.
9337 //   - OK or error on completion.
9338 //   - Direct connection, non-authenticating proxy, and authenticating proxy.
9339 //   - HTTP or HTTPS backend (to include proxy tunneling).
9340 //   - Non-authenticating and authenticating backend.
9341 //
9342 // In all, there are 44 reasonable permuations (for example, if there are
9343 // problems generating an auth token for an authenticating proxy, we don't
9344 // need to test all permutations of the backend server).
9345 //
9346 // The test proceeds by going over each of the configuration cases, and
9347 // potentially running up to three rounds in each of the tests. The TestConfig
9348 // specifies both the configuration for the test as well as the expectations
9349 // for the results.
TEST_P(HttpNetworkTransactionTest,GenerateAuthToken)9350 TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
9351   static const char kServer[] = "http://www.example.com";
9352   static const char kSecureServer[] = "https://www.example.com";
9353   static const char kProxy[] = "myproxy:70";
9354   const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9355 
9356   enum AuthTiming {
9357     AUTH_NONE,
9358     AUTH_SYNC,
9359     AUTH_ASYNC,
9360   };
9361 
9362   const MockWrite kGet(
9363       "GET / HTTP/1.1\r\n"
9364       "Host: www.example.com\r\n"
9365       "Connection: keep-alive\r\n\r\n");
9366   const MockWrite kGetProxy(
9367       "GET http://www.example.com/ HTTP/1.1\r\n"
9368       "Host: www.example.com\r\n"
9369       "Proxy-Connection: keep-alive\r\n\r\n");
9370   const MockWrite kGetAuth(
9371       "GET / HTTP/1.1\r\n"
9372       "Host: www.example.com\r\n"
9373       "Connection: keep-alive\r\n"
9374       "Authorization: auth_token\r\n\r\n");
9375   const MockWrite kGetProxyAuth(
9376       "GET http://www.example.com/ HTTP/1.1\r\n"
9377       "Host: www.example.com\r\n"
9378       "Proxy-Connection: keep-alive\r\n"
9379       "Proxy-Authorization: auth_token\r\n\r\n");
9380   const MockWrite kGetAuthThroughProxy(
9381       "GET http://www.example.com/ HTTP/1.1\r\n"
9382       "Host: www.example.com\r\n"
9383       "Proxy-Connection: keep-alive\r\n"
9384       "Authorization: auth_token\r\n\r\n");
9385   const MockWrite kGetAuthWithProxyAuth(
9386       "GET http://www.example.com/ HTTP/1.1\r\n"
9387       "Host: www.example.com\r\n"
9388       "Proxy-Connection: keep-alive\r\n"
9389       "Proxy-Authorization: auth_token\r\n"
9390       "Authorization: auth_token\r\n\r\n");
9391   const MockWrite kConnect(
9392       "CONNECT www.example.com:443 HTTP/1.1\r\n"
9393       "Host: www.example.com\r\n"
9394       "Proxy-Connection: keep-alive\r\n\r\n");
9395   const MockWrite kConnectProxyAuth(
9396       "CONNECT www.example.com:443 HTTP/1.1\r\n"
9397       "Host: www.example.com\r\n"
9398       "Proxy-Connection: keep-alive\r\n"
9399       "Proxy-Authorization: auth_token\r\n\r\n");
9400 
9401   const MockRead kSuccess(
9402       "HTTP/1.1 200 OK\r\n"
9403       "Content-Type: text/html; charset=iso-8859-1\r\n"
9404       "Content-Length: 3\r\n\r\n"
9405       "Yes");
9406   const MockRead kFailure(
9407       "Should not be called.");
9408   const MockRead kServerChallenge(
9409       "HTTP/1.1 401 Unauthorized\r\n"
9410       "WWW-Authenticate: Mock realm=server\r\n"
9411       "Content-Type: text/html; charset=iso-8859-1\r\n"
9412       "Content-Length: 14\r\n\r\n"
9413       "Unauthorized\r\n");
9414   const MockRead kProxyChallenge(
9415       "HTTP/1.1 407 Unauthorized\r\n"
9416       "Proxy-Authenticate: Mock realm=proxy\r\n"
9417       "Proxy-Connection: close\r\n"
9418       "Content-Type: text/html; charset=iso-8859-1\r\n"
9419       "Content-Length: 14\r\n\r\n"
9420       "Unauthorized\r\n");
9421   const MockRead kProxyConnected(
9422       "HTTP/1.1 200 Connection Established\r\n\r\n");
9423 
9424   // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9425   // no constructors, but the C++ compiler on Windows warns about
9426   // unspecified data in compound literals. So, moved to using constructors,
9427   // and TestRound's created with the default constructor should not be used.
9428   struct TestRound {
9429     TestRound()
9430         : expected_rv(ERR_UNEXPECTED),
9431           extra_write(NULL),
9432           extra_read(NULL) {
9433     }
9434     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9435               int expected_rv_arg)
9436         : write(write_arg),
9437           read(read_arg),
9438           expected_rv(expected_rv_arg),
9439           extra_write(NULL),
9440           extra_read(NULL) {
9441     }
9442     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9443               int expected_rv_arg, const MockWrite* extra_write_arg,
9444               const MockRead* extra_read_arg)
9445         : write(write_arg),
9446           read(read_arg),
9447           expected_rv(expected_rv_arg),
9448           extra_write(extra_write_arg),
9449           extra_read(extra_read_arg) {
9450     }
9451     MockWrite write;
9452     MockRead read;
9453     int expected_rv;
9454     const MockWrite* extra_write;
9455     const MockRead* extra_read;
9456   };
9457 
9458   static const int kNoSSL = 500;
9459 
9460   struct TestConfig {
9461     const char* proxy_url;
9462     AuthTiming proxy_auth_timing;
9463     int proxy_auth_rv;
9464     const char* server_url;
9465     AuthTiming server_auth_timing;
9466     int server_auth_rv;
9467     int num_auth_rounds;
9468     int first_ssl_round;
9469     TestRound rounds[3];
9470   } test_configs[] = {
9471     // Non-authenticating HTTP server with a direct connection.
9472     { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9473       { TestRound(kGet, kSuccess, OK)}},
9474     // Authenticating HTTP server with a direct connection.
9475     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9476       { TestRound(kGet, kServerChallenge, OK),
9477         TestRound(kGetAuth, kSuccess, OK)}},
9478     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9479       { TestRound(kGet, kServerChallenge, OK),
9480         TestRound(kGetAuth, kFailure, kAuthErr)}},
9481     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9482       { TestRound(kGet, kServerChallenge, OK),
9483         TestRound(kGetAuth, kSuccess, OK)}},
9484     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9485       { TestRound(kGet, kServerChallenge, OK),
9486         TestRound(kGetAuth, kFailure, kAuthErr)}},
9487     // Non-authenticating HTTP server through a non-authenticating proxy.
9488     { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9489       { TestRound(kGetProxy, kSuccess, OK)}},
9490     // Authenticating HTTP server through a non-authenticating proxy.
9491     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9492       { TestRound(kGetProxy, kServerChallenge, OK),
9493         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9494     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9495       { TestRound(kGetProxy, kServerChallenge, OK),
9496         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9497     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9498       { TestRound(kGetProxy, kServerChallenge, OK),
9499         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9500     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9501       { TestRound(kGetProxy, kServerChallenge, OK),
9502         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9503     // Non-authenticating HTTP server through an authenticating proxy.
9504     { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9505       { TestRound(kGetProxy, kProxyChallenge, OK),
9506         TestRound(kGetProxyAuth, kSuccess, OK)}},
9507     { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9508       { TestRound(kGetProxy, kProxyChallenge, OK),
9509         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9510     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9511       { TestRound(kGetProxy, kProxyChallenge, OK),
9512         TestRound(kGetProxyAuth, kSuccess, OK)}},
9513     { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9514       { TestRound(kGetProxy, kProxyChallenge, OK),
9515         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9516     // Authenticating HTTP server through an authenticating proxy.
9517     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9518       { TestRound(kGetProxy, kProxyChallenge, OK),
9519         TestRound(kGetProxyAuth, kServerChallenge, OK),
9520         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9521     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9522       { TestRound(kGetProxy, kProxyChallenge, OK),
9523         TestRound(kGetProxyAuth, kServerChallenge, OK),
9524         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9525     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9526       { TestRound(kGetProxy, kProxyChallenge, OK),
9527         TestRound(kGetProxyAuth, kServerChallenge, OK),
9528         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9529     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9530       { TestRound(kGetProxy, kProxyChallenge, OK),
9531         TestRound(kGetProxyAuth, kServerChallenge, OK),
9532         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9533     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9534       { TestRound(kGetProxy, kProxyChallenge, OK),
9535         TestRound(kGetProxyAuth, kServerChallenge, OK),
9536         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9537     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9538       { TestRound(kGetProxy, kProxyChallenge, OK),
9539         TestRound(kGetProxyAuth, kServerChallenge, OK),
9540         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9541     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9542       { TestRound(kGetProxy, kProxyChallenge, OK),
9543         TestRound(kGetProxyAuth, kServerChallenge, OK),
9544         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9545     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9546       { TestRound(kGetProxy, kProxyChallenge, OK),
9547         TestRound(kGetProxyAuth, kServerChallenge, OK),
9548         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9549     // Non-authenticating HTTPS server with a direct connection.
9550     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9551       { TestRound(kGet, kSuccess, OK)}},
9552     // Authenticating HTTPS server with a direct connection.
9553     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9554       { TestRound(kGet, kServerChallenge, OK),
9555         TestRound(kGetAuth, kSuccess, OK)}},
9556     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9557       { TestRound(kGet, kServerChallenge, OK),
9558         TestRound(kGetAuth, kFailure, kAuthErr)}},
9559     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9560       { TestRound(kGet, kServerChallenge, OK),
9561         TestRound(kGetAuth, kSuccess, OK)}},
9562     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9563       { TestRound(kGet, kServerChallenge, OK),
9564         TestRound(kGetAuth, kFailure, kAuthErr)}},
9565     // Non-authenticating HTTPS server with a non-authenticating proxy.
9566     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9567       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9568     // Authenticating HTTPS server through a non-authenticating proxy.
9569     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9570       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9571         TestRound(kGetAuth, kSuccess, OK)}},
9572     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9573       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9574         TestRound(kGetAuth, kFailure, kAuthErr)}},
9575     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9576       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9577         TestRound(kGetAuth, kSuccess, OK)}},
9578     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9579       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9580         TestRound(kGetAuth, kFailure, kAuthErr)}},
9581     // Non-Authenticating HTTPS server through an authenticating proxy.
9582     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9583       { TestRound(kConnect, kProxyChallenge, OK),
9584         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9585     { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9586       { TestRound(kConnect, kProxyChallenge, OK),
9587         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9588     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9589       { TestRound(kConnect, kProxyChallenge, OK),
9590         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9591     { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9592       { TestRound(kConnect, kProxyChallenge, OK),
9593         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9594     // Authenticating HTTPS server through an authenticating proxy.
9595     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9596       { TestRound(kConnect, kProxyChallenge, OK),
9597         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9598                   &kGet, &kServerChallenge),
9599         TestRound(kGetAuth, kSuccess, OK)}},
9600     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9601       { TestRound(kConnect, kProxyChallenge, OK),
9602         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9603                   &kGet, &kServerChallenge),
9604         TestRound(kGetAuth, kFailure, kAuthErr)}},
9605     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9606       { TestRound(kConnect, kProxyChallenge, OK),
9607         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9608                   &kGet, &kServerChallenge),
9609         TestRound(kGetAuth, kSuccess, OK)}},
9610     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9611       { TestRound(kConnect, kProxyChallenge, OK),
9612         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9613                   &kGet, &kServerChallenge),
9614         TestRound(kGetAuth, kFailure, kAuthErr)}},
9615     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9616       { TestRound(kConnect, kProxyChallenge, OK),
9617         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9618                   &kGet, &kServerChallenge),
9619         TestRound(kGetAuth, kSuccess, OK)}},
9620     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9621       { TestRound(kConnect, kProxyChallenge, OK),
9622         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9623                   &kGet, &kServerChallenge),
9624         TestRound(kGetAuth, kFailure, kAuthErr)}},
9625     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9626       { TestRound(kConnect, kProxyChallenge, OK),
9627         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9628                   &kGet, &kServerChallenge),
9629         TestRound(kGetAuth, kSuccess, OK)}},
9630     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9631       { TestRound(kConnect, kProxyChallenge, OK),
9632         TestRound(kConnectProxyAuth, kProxyConnected, OK,
9633                   &kGet, &kServerChallenge),
9634         TestRound(kGetAuth, kFailure, kAuthErr)}},
9635   };
9636 
9637   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
9638     HttpAuthHandlerMock::Factory* auth_factory(
9639         new HttpAuthHandlerMock::Factory());
9640     session_deps_.http_auth_handler_factory.reset(auth_factory);
9641     const TestConfig& test_config = test_configs[i];
9642 
9643     // Set up authentication handlers as necessary.
9644     if (test_config.proxy_auth_timing != AUTH_NONE) {
9645       for (int n = 0; n < 2; n++) {
9646         HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9647         std::string auth_challenge = "Mock realm=proxy";
9648         GURL origin(test_config.proxy_url);
9649         HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9650                                              auth_challenge.end());
9651         auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9652                                         origin, BoundNetLog());
9653         auth_handler->SetGenerateExpectation(
9654             test_config.proxy_auth_timing == AUTH_ASYNC,
9655             test_config.proxy_auth_rv);
9656         auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9657       }
9658     }
9659     if (test_config.server_auth_timing != AUTH_NONE) {
9660       HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9661       std::string auth_challenge = "Mock realm=server";
9662       GURL origin(test_config.server_url);
9663       HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9664                                            auth_challenge.end());
9665       auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9666                                       origin, BoundNetLog());
9667       auth_handler->SetGenerateExpectation(
9668           test_config.server_auth_timing == AUTH_ASYNC,
9669           test_config.server_auth_rv);
9670       auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
9671     }
9672     if (test_config.proxy_url) {
9673       session_deps_.proxy_service.reset(
9674           ProxyService::CreateFixed(test_config.proxy_url));
9675     } else {
9676       session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9677     }
9678 
9679     HttpRequestInfo request;
9680     request.method = "GET";
9681     request.url = GURL(test_config.server_url);
9682     request.load_flags = 0;
9683 
9684     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9685     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
9686 
9687     for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9688       const TestRound& read_write_round = test_config.rounds[round];
9689 
9690       // Set up expected reads and writes.
9691       MockRead reads[2];
9692       reads[0] = read_write_round.read;
9693       size_t length_reads = 1;
9694       if (read_write_round.extra_read) {
9695         reads[1] = *read_write_round.extra_read;
9696         length_reads = 2;
9697       }
9698 
9699       MockWrite writes[2];
9700       writes[0] = read_write_round.write;
9701       size_t length_writes = 1;
9702       if (read_write_round.extra_write) {
9703         writes[1] = *read_write_round.extra_write;
9704         length_writes = 2;
9705       }
9706       StaticSocketDataProvider data_provider(
9707           reads, length_reads, writes, length_writes);
9708       session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
9709 
9710       // Add an SSL sequence if necessary.
9711       SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
9712       if (round >= test_config.first_ssl_round)
9713         session_deps_.socket_factory->AddSSLSocketDataProvider(
9714             &ssl_socket_data_provider);
9715 
9716       // Start or restart the transaction.
9717       TestCompletionCallback callback;
9718       int rv;
9719       if (round == 0) {
9720         rv = trans.Start(&request, callback.callback(), BoundNetLog());
9721       } else {
9722         rv = trans.RestartWithAuth(
9723             AuthCredentials(kFoo, kBar), callback.callback());
9724       }
9725       if (rv == ERR_IO_PENDING)
9726         rv = callback.WaitForResult();
9727 
9728       // Compare results with expected data.
9729       EXPECT_EQ(read_write_round.expected_rv, rv);
9730       const HttpResponseInfo* response = trans.GetResponseInfo();
9731       if (read_write_round.expected_rv == OK) {
9732         ASSERT_TRUE(response != NULL);
9733       } else {
9734         EXPECT_TRUE(response == NULL);
9735         EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9736         continue;
9737       }
9738       if (round + 1 < test_config.num_auth_rounds) {
9739         EXPECT_FALSE(response->auth_challenge.get() == NULL);
9740       } else {
9741         EXPECT_TRUE(response->auth_challenge.get() == NULL);
9742       }
9743     }
9744   }
9745 }
9746 
TEST_P(HttpNetworkTransactionTest,MultiRoundAuth)9747 TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
9748   // Do multi-round authentication and make sure it works correctly.
9749   HttpAuthHandlerMock::Factory* auth_factory(
9750       new HttpAuthHandlerMock::Factory());
9751   session_deps_.http_auth_handler_factory.reset(auth_factory);
9752   session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9753   session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9754   session_deps_.host_resolver->set_synchronous_mode(true);
9755 
9756   HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9757   auth_handler->set_connection_based(true);
9758   std::string auth_challenge = "Mock realm=server";
9759   GURL origin("http://www.example.com");
9760   HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9761                                        auth_challenge.end());
9762   auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9763                                   origin, BoundNetLog());
9764   auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
9765 
9766   int rv = OK;
9767   const HttpResponseInfo* response = NULL;
9768   HttpRequestInfo request;
9769   request.method = "GET";
9770   request.url = origin;
9771   request.load_flags = 0;
9772 
9773   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9774 
9775   // Use a TCP Socket Pool with only one connection per group. This is used
9776   // to validate that the TCP socket is not released to the pool between
9777   // each round of multi-round authentication.
9778   HttpNetworkSessionPeer session_peer(session);
9779   ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9780   TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
9781       50,  // Max sockets for pool
9782       1,   // Max sockets per group
9783       &transport_pool_histograms,
9784       session_deps_.host_resolver.get(),
9785       session_deps_.socket_factory.get(),
9786       session_deps_.net_log);
9787   scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9788       new MockClientSocketPoolManager);
9789   mock_pool_manager->SetTransportSocketPool(transport_pool);
9790   session_peer.SetClientSocketPoolManager(
9791       mock_pool_manager.PassAs<ClientSocketPoolManager>());
9792 
9793   scoped_ptr<HttpTransaction> trans(
9794       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9795   TestCompletionCallback callback;
9796 
9797   const MockWrite kGet(
9798       "GET / HTTP/1.1\r\n"
9799       "Host: www.example.com\r\n"
9800       "Connection: keep-alive\r\n\r\n");
9801   const MockWrite kGetAuth(
9802       "GET / HTTP/1.1\r\n"
9803       "Host: www.example.com\r\n"
9804       "Connection: keep-alive\r\n"
9805       "Authorization: auth_token\r\n\r\n");
9806 
9807   const MockRead kServerChallenge(
9808       "HTTP/1.1 401 Unauthorized\r\n"
9809       "WWW-Authenticate: Mock realm=server\r\n"
9810       "Content-Type: text/html; charset=iso-8859-1\r\n"
9811       "Content-Length: 14\r\n\r\n"
9812       "Unauthorized\r\n");
9813   const MockRead kSuccess(
9814       "HTTP/1.1 200 OK\r\n"
9815       "Content-Type: text/html; charset=iso-8859-1\r\n"
9816       "Content-Length: 3\r\n\r\n"
9817       "Yes");
9818 
9819   MockWrite writes[] = {
9820     // First round
9821     kGet,
9822     // Second round
9823     kGetAuth,
9824     // Third round
9825     kGetAuth,
9826     // Fourth round
9827     kGetAuth,
9828     // Competing request
9829     kGet,
9830   };
9831   MockRead reads[] = {
9832     // First round
9833     kServerChallenge,
9834     // Second round
9835     kServerChallenge,
9836     // Third round
9837     kServerChallenge,
9838     // Fourth round
9839     kSuccess,
9840     // Competing response
9841     kSuccess,
9842   };
9843   StaticSocketDataProvider data_provider(reads, arraysize(reads),
9844                                          writes, arraysize(writes));
9845   session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
9846 
9847   const char* const kSocketGroup = "www.example.com:80";
9848 
9849   // First round of authentication.
9850   auth_handler->SetGenerateExpectation(false, OK);
9851   rv = trans->Start(&request, callback.callback(), BoundNetLog());
9852   if (rv == ERR_IO_PENDING)
9853     rv = callback.WaitForResult();
9854   EXPECT_EQ(OK, rv);
9855   response = trans->GetResponseInfo();
9856   ASSERT_TRUE(response != NULL);
9857   EXPECT_FALSE(response->auth_challenge.get() == NULL);
9858   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9859 
9860   // In between rounds, another request comes in for the same domain.
9861   // It should not be able to grab the TCP socket that trans has already
9862   // claimed.
9863   scoped_ptr<HttpTransaction> trans_compete(
9864       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9865   TestCompletionCallback callback_compete;
9866   rv = trans_compete->Start(
9867       &request, callback_compete.callback(), BoundNetLog());
9868   EXPECT_EQ(ERR_IO_PENDING, rv);
9869   // callback_compete.WaitForResult at this point would stall forever,
9870   // since the HttpNetworkTransaction does not release the request back to
9871   // the pool until after authentication completes.
9872 
9873   // Second round of authentication.
9874   auth_handler->SetGenerateExpectation(false, OK);
9875   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
9876   if (rv == ERR_IO_PENDING)
9877     rv = callback.WaitForResult();
9878   EXPECT_EQ(OK, rv);
9879   response = trans->GetResponseInfo();
9880   ASSERT_TRUE(response != NULL);
9881   EXPECT_TRUE(response->auth_challenge.get() == NULL);
9882   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9883 
9884   // Third round of authentication.
9885   auth_handler->SetGenerateExpectation(false, OK);
9886   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
9887   if (rv == ERR_IO_PENDING)
9888     rv = callback.WaitForResult();
9889   EXPECT_EQ(OK, rv);
9890   response = trans->GetResponseInfo();
9891   ASSERT_TRUE(response != NULL);
9892   EXPECT_TRUE(response->auth_challenge.get() == NULL);
9893   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9894 
9895   // Fourth round of authentication, which completes successfully.
9896   auth_handler->SetGenerateExpectation(false, OK);
9897   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
9898   if (rv == ERR_IO_PENDING)
9899     rv = callback.WaitForResult();
9900   EXPECT_EQ(OK, rv);
9901   response = trans->GetResponseInfo();
9902   ASSERT_TRUE(response != NULL);
9903   EXPECT_TRUE(response->auth_challenge.get() == NULL);
9904   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9905 
9906   // Read the body since the fourth round was successful. This will also
9907   // release the socket back to the pool.
9908   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
9909   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
9910   if (rv == ERR_IO_PENDING)
9911     rv = callback.WaitForResult();
9912   EXPECT_EQ(3, rv);
9913   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
9914   EXPECT_EQ(0, rv);
9915   // There are still 0 idle sockets, since the trans_compete transaction
9916   // will be handed it immediately after trans releases it to the group.
9917   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9918 
9919   // The competing request can now finish. Wait for the headers and then
9920   // read the body.
9921   rv = callback_compete.WaitForResult();
9922   EXPECT_EQ(OK, rv);
9923   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
9924   if (rv == ERR_IO_PENDING)
9925     rv = callback.WaitForResult();
9926   EXPECT_EQ(3, rv);
9927   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
9928   EXPECT_EQ(0, rv);
9929 
9930   // Finally, the socket is released to the group.
9931   EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
9932 }
9933 
9934 // This tests the case that a request is issued via http instead of spdy after
9935 // npn is negotiated.
TEST_P(HttpNetworkTransactionTest,NpnWithHttpOverSSL)9936 TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
9937   session_deps_.use_alternate_protocols = true;
9938   NextProtoVector next_protos;
9939   next_protos.push_back(kProtoHTTP11);
9940   session_deps_.next_protos = next_protos;
9941 
9942   HttpRequestInfo request;
9943   request.method = "GET";
9944   request.url = GURL("https://www.google.com/");
9945   request.load_flags = 0;
9946 
9947   MockWrite data_writes[] = {
9948     MockWrite("GET / HTTP/1.1\r\n"
9949               "Host: www.google.com\r\n"
9950               "Connection: keep-alive\r\n\r\n"),
9951   };
9952 
9953   std::string alternate_protocol_http_header =
9954       GetAlternateProtocolHttpHeader();
9955 
9956   MockRead data_reads[] = {
9957     MockRead("HTTP/1.1 200 OK\r\n"),
9958     MockRead(alternate_protocol_http_header.c_str()),
9959     MockRead("hello world"),
9960     MockRead(SYNCHRONOUS, OK),
9961   };
9962 
9963   SSLSocketDataProvider ssl(ASYNC, OK);
9964   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9965   ssl.next_proto = "http/1.1";
9966   ssl.protocol_negotiated = kProtoHTTP11;
9967 
9968   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9969 
9970   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9971                                 data_writes, arraysize(data_writes));
9972   session_deps_.socket_factory->AddSocketDataProvider(&data);
9973 
9974   TestCompletionCallback callback;
9975 
9976   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9977   scoped_ptr<HttpTransaction> trans(
9978       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9979 
9980   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9981 
9982   EXPECT_EQ(ERR_IO_PENDING, rv);
9983   EXPECT_EQ(OK, callback.WaitForResult());
9984 
9985   const HttpResponseInfo* response = trans->GetResponseInfo();
9986   ASSERT_TRUE(response != NULL);
9987   ASSERT_TRUE(response->headers.get() != NULL);
9988   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9989 
9990   std::string response_data;
9991   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9992   EXPECT_EQ("hello world", response_data);
9993 
9994   EXPECT_FALSE(response->was_fetched_via_spdy);
9995   EXPECT_TRUE(response->was_npn_negotiated);
9996 }
9997 
TEST_P(HttpNetworkTransactionTest,SpdyPostNPNServerHangup)9998 TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
9999   // Simulate the SSL handshake completing with an NPN negotiation
10000   // followed by an immediate server closing of the socket.
10001   // Fix crash:  http://crbug.com/46369
10002   session_deps_.use_alternate_protocols = true;
10003   session_deps_.next_protos = SpdyNextProtos();
10004 
10005   HttpRequestInfo request;
10006   request.method = "GET";
10007   request.url = GURL("https://www.google.com/");
10008   request.load_flags = 0;
10009 
10010   SSLSocketDataProvider ssl(ASYNC, OK);
10011   ssl.SetNextProto(GetParam());
10012   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10013 
10014   scoped_ptr<SpdyFrame> req(
10015       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
10016   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10017 
10018   MockRead spdy_reads[] = {
10019     MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
10020   };
10021 
10022   DelayedSocketData spdy_data(
10023       0,  // don't wait in this case, immediate hangup.
10024       spdy_reads, arraysize(spdy_reads),
10025       spdy_writes, arraysize(spdy_writes));
10026   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10027 
10028   TestCompletionCallback callback;
10029 
10030   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10031   scoped_ptr<HttpTransaction> trans(
10032       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10033 
10034   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10035   EXPECT_EQ(ERR_IO_PENDING, rv);
10036   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
10037 }
10038 
10039 // A subclass of HttpAuthHandlerMock that records the request URL when
10040 // it gets it. This is needed since the auth handler may get destroyed
10041 // before we get a chance to query it.
10042 class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10043  public:
UrlRecordingHttpAuthHandlerMock(GURL * url)10044   explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10045 
~UrlRecordingHttpAuthHandlerMock()10046   virtual ~UrlRecordingHttpAuthHandlerMock() {}
10047 
10048  protected:
GenerateAuthTokenImpl(const AuthCredentials * credentials,const HttpRequestInfo * request,const CompletionCallback & callback,std::string * auth_token)10049   virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10050                                     const HttpRequestInfo* request,
10051                                     const CompletionCallback& callback,
10052                                     std::string* auth_token) OVERRIDE {
10053     *url_ = request->url;
10054     return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10055         credentials, request, callback, auth_token);
10056   }
10057 
10058  private:
10059   GURL* url_;
10060 };
10061 
TEST_P(HttpNetworkTransactionTest,SpdyAlternateProtocolThroughProxy)10062 TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
10063   // This test ensures that the URL passed into the proxy is upgraded
10064   // to https when doing an Alternate Protocol upgrade.
10065   session_deps_.use_alternate_protocols = true;
10066   session_deps_.next_protos = SpdyNextProtos();
10067 
10068   session_deps_.proxy_service.reset(
10069       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10070   CapturingNetLog net_log;
10071   session_deps_.net_log = &net_log;
10072   GURL request_url;
10073   {
10074     HttpAuthHandlerMock::Factory* auth_factory =
10075         new HttpAuthHandlerMock::Factory();
10076     UrlRecordingHttpAuthHandlerMock* auth_handler =
10077         new UrlRecordingHttpAuthHandlerMock(&request_url);
10078     auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10079     auth_factory->set_do_init_from_challenge(true);
10080     session_deps_.http_auth_handler_factory.reset(auth_factory);
10081   }
10082 
10083   HttpRequestInfo request;
10084   request.method = "GET";
10085   request.url = GURL("http://www.google.com");
10086   request.load_flags = 0;
10087 
10088   // First round goes unauthenticated through the proxy.
10089   MockWrite data_writes_1[] = {
10090     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10091               "Host: www.google.com\r\n"
10092               "Proxy-Connection: keep-alive\r\n"
10093               "\r\n"),
10094   };
10095   MockRead data_reads_1[] = {
10096     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10097     MockRead("HTTP/1.1 200 OK\r\n"
10098              "Alternate-Protocol: 443:npn-spdy/2\r\n"
10099              "Proxy-Connection: close\r\n"
10100              "\r\n"),
10101   };
10102   StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10103                                   data_writes_1, arraysize(data_writes_1));
10104 
10105   // Second round tries to tunnel to www.google.com due to the
10106   // Alternate-Protocol announcement in the first round. It fails due
10107   // to a proxy authentication challenge.
10108   // After the failure, a tunnel is established to www.google.com using
10109   // Proxy-Authorization headers. There is then a SPDY request round.
10110   //
10111   // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10112   // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10113   // does a Disconnect and Connect on the same socket, rather than trying
10114   // to obtain a new one.
10115   //
10116   // NOTE: Originally, the proxy response to the second CONNECT request
10117   // simply returned another 407 so the unit test could skip the SSL connection
10118   // establishment and SPDY framing issues. Alas, the
10119   // retry-http-when-alternate-protocol fails logic kicks in, which was more
10120   // complicated to set up expectations for than the SPDY session.
10121 
10122   scoped_ptr<SpdyFrame> req(
10123       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
10124   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10125   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
10126 
10127   MockWrite data_writes_2[] = {
10128     // First connection attempt without Proxy-Authorization.
10129     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10130               "Host: www.google.com\r\n"
10131               "Proxy-Connection: keep-alive\r\n"
10132               "\r\n"),
10133 
10134     // Second connection attempt with Proxy-Authorization.
10135     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10136               "Host: www.google.com\r\n"
10137               "Proxy-Connection: keep-alive\r\n"
10138               "Proxy-Authorization: auth_token\r\n"
10139               "\r\n"),
10140 
10141     // SPDY request
10142     CreateMockWrite(*req),
10143   };
10144   const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10145                                          "Proxy-Authenticate: Mock\r\n"
10146                                          "Proxy-Connection: close\r\n"
10147                                          "\r\n");
10148   const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10149   MockRead data_reads_2[] = {
10150     // First connection attempt fails
10151     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
10152     MockRead(ASYNC, kRejectConnectResponse,
10153              arraysize(kRejectConnectResponse) - 1, 1),
10154 
10155     // Second connection attempt passes
10156     MockRead(ASYNC, kAcceptConnectResponse,
10157              arraysize(kAcceptConnectResponse) -1, 4),
10158 
10159     // SPDY response
10160     CreateMockRead(*resp.get(), 6),
10161     CreateMockRead(*data.get(), 6),
10162     MockRead(ASYNC, 0, 0, 6),
10163   };
10164   OrderedSocketData data_2(
10165       data_reads_2, arraysize(data_reads_2),
10166       data_writes_2, arraysize(data_writes_2));
10167 
10168   SSLSocketDataProvider ssl(ASYNC, OK);
10169   ssl.SetNextProto(GetParam());
10170 
10171   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
10172   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10173       NULL, 0, NULL, 0);
10174   hanging_non_alternate_protocol_socket.set_connect_data(
10175       never_finishing_connect);
10176 
10177   session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10178   session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10179   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10180   session_deps_.socket_factory->AddSocketDataProvider(
10181       &hanging_non_alternate_protocol_socket);
10182   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10183 
10184   // First round should work and provide the Alternate-Protocol state.
10185   TestCompletionCallback callback_1;
10186   scoped_ptr<HttpTransaction> trans_1(
10187       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10188   int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
10189   EXPECT_EQ(ERR_IO_PENDING, rv);
10190   EXPECT_EQ(OK, callback_1.WaitForResult());
10191 
10192   // Second round should attempt a tunnel connect and get an auth challenge.
10193   TestCompletionCallback callback_2;
10194   scoped_ptr<HttpTransaction> trans_2(
10195       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10196   rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
10197   EXPECT_EQ(ERR_IO_PENDING, rv);
10198   EXPECT_EQ(OK, callback_2.WaitForResult());
10199   const HttpResponseInfo* response = trans_2->GetResponseInfo();
10200   ASSERT_TRUE(response != NULL);
10201   ASSERT_FALSE(response->auth_challenge.get() == NULL);
10202 
10203   // Restart with auth. Tunnel should work and response received.
10204   TestCompletionCallback callback_3;
10205   rv = trans_2->RestartWithAuth(
10206       AuthCredentials(kFoo, kBar), callback_3.callback());
10207   EXPECT_EQ(ERR_IO_PENDING, rv);
10208   EXPECT_EQ(OK, callback_3.WaitForResult());
10209 
10210   // After all that work, these two lines (or actually, just the scheme) are
10211   // what this test is all about. Make sure it happens correctly.
10212   EXPECT_EQ("https", request_url.scheme());
10213   EXPECT_EQ("www.google.com", request_url.host());
10214 
10215   LoadTimingInfo load_timing_info;
10216   EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10217   TestLoadTimingNotReusedWithPac(load_timing_info,
10218                                  CONNECT_TIMING_HAS_SSL_TIMES);
10219 }
10220 
10221 // Test that if we cancel the transaction as the connection is completing, that
10222 // everything tears down correctly.
TEST_P(HttpNetworkTransactionTest,SimpleCancel)10223 TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
10224   // Setup everything about the connection to complete synchronously, so that
10225   // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10226   // for is the callback from the HttpStreamRequest.
10227   // Then cancel the transaction.
10228   // Verify that we don't crash.
10229   MockConnect mock_connect(SYNCHRONOUS, OK);
10230   MockRead data_reads[] = {
10231     MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10232     MockRead(SYNCHRONOUS, "hello world"),
10233     MockRead(SYNCHRONOUS, OK),
10234   };
10235 
10236   HttpRequestInfo request;
10237   request.method = "GET";
10238   request.url = GURL("http://www.google.com/");
10239   request.load_flags = 0;
10240 
10241   session_deps_.host_resolver->set_synchronous_mode(true);
10242   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10243   scoped_ptr<HttpTransaction> trans(
10244       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
10245 
10246   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10247   data.set_connect_data(mock_connect);
10248   session_deps_.socket_factory->AddSocketDataProvider(&data);
10249 
10250   TestCompletionCallback callback;
10251 
10252   CapturingBoundNetLog log;
10253   int rv = trans->Start(&request, callback.callback(), log.bound());
10254   EXPECT_EQ(ERR_IO_PENDING, rv);
10255   trans.reset();  // Cancel the transaction here.
10256 
10257   base::MessageLoop::current()->RunUntilIdle();
10258 }
10259 
10260 // Test that if a transaction is cancelled after receiving the headers, the
10261 // stream is drained properly and added back to the socket pool.  The main
10262 // purpose of this test is to make sure that an HttpStreamParser can be read
10263 // from after the HttpNetworkTransaction and the objects it owns have been
10264 // deleted.
10265 // See http://crbug.com/368418
TEST_P(HttpNetworkTransactionTest,CancelAfterHeaders)10266 TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10267   MockRead data_reads[] = {
10268     MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10269     MockRead(ASYNC, "Content-Length: 2\r\n"),
10270     MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10271     MockRead(ASYNC, "1"),
10272     // 2 async reads are necessary to trigger a ReadResponseBody call after the
10273     // HttpNetworkTransaction has been deleted.
10274     MockRead(ASYNC, "2"),
10275     MockRead(SYNCHRONOUS, ERR_IO_PENDING),  // Should never read this.
10276   };
10277   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10278   session_deps_.socket_factory->AddSocketDataProvider(&data);
10279 
10280   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10281 
10282   {
10283     HttpRequestInfo request;
10284     request.method = "GET";
10285     request.url = GURL("http://www.google.com/");
10286     request.load_flags = 0;
10287 
10288     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
10289     TestCompletionCallback callback;
10290 
10291     int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10292     EXPECT_EQ(ERR_IO_PENDING, rv);
10293     callback.WaitForResult();
10294 
10295     const HttpResponseInfo* response = trans.GetResponseInfo();
10296     ASSERT_TRUE(response != NULL);
10297     EXPECT_TRUE(response->headers.get() != NULL);
10298     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10299 
10300     // The transaction and HttpRequestInfo are deleted.
10301   }
10302 
10303   // Let the HttpResponseBodyDrainer drain the socket.
10304   base::MessageLoop::current()->RunUntilIdle();
10305 
10306   // Socket should now be idle, waiting to be reused.
10307   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
10308 }
10309 
10310 // Test a basic GET request through a proxy.
TEST_P(HttpNetworkTransactionTest,ProxyGet)10311 TEST_P(HttpNetworkTransactionTest, ProxyGet) {
10312   session_deps_.proxy_service.reset(
10313       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10314   CapturingBoundNetLog log;
10315   session_deps_.net_log = log.bound().net_log();
10316   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10317 
10318   HttpRequestInfo request;
10319   request.method = "GET";
10320   request.url = GURL("http://www.google.com/");
10321 
10322   MockWrite data_writes1[] = {
10323     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10324               "Host: www.google.com\r\n"
10325               "Proxy-Connection: keep-alive\r\n\r\n"),
10326   };
10327 
10328   MockRead data_reads1[] = {
10329     MockRead("HTTP/1.1 200 OK\r\n"),
10330     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10331     MockRead("Content-Length: 100\r\n\r\n"),
10332     MockRead(SYNCHRONOUS, OK),
10333   };
10334 
10335   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10336                                  data_writes1, arraysize(data_writes1));
10337   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10338 
10339   TestCompletionCallback callback1;
10340 
10341   scoped_ptr<HttpTransaction> trans(
10342       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10343 
10344   int rv = trans->Start(&request, callback1.callback(), log.bound());
10345   EXPECT_EQ(ERR_IO_PENDING, rv);
10346 
10347   rv = callback1.WaitForResult();
10348   EXPECT_EQ(OK, rv);
10349 
10350   const HttpResponseInfo* response = trans->GetResponseInfo();
10351   ASSERT_TRUE(response != NULL);
10352 
10353   EXPECT_TRUE(response->headers->IsKeepAlive());
10354   EXPECT_EQ(200, response->headers->response_code());
10355   EXPECT_EQ(100, response->headers->GetContentLength());
10356   EXPECT_TRUE(response->was_fetched_via_proxy);
10357   EXPECT_TRUE(
10358       response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
10359   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10360 
10361   LoadTimingInfo load_timing_info;
10362   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10363   TestLoadTimingNotReusedWithPac(load_timing_info,
10364                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10365 }
10366 
10367 // Test a basic HTTPS GET request through a proxy.
TEST_P(HttpNetworkTransactionTest,ProxyTunnelGet)10368 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
10369   session_deps_.proxy_service.reset(
10370       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10371   CapturingBoundNetLog log;
10372   session_deps_.net_log = log.bound().net_log();
10373   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10374 
10375   HttpRequestInfo request;
10376   request.method = "GET";
10377   request.url = GURL("https://www.google.com/");
10378 
10379   // Since we have proxy, should try to establish tunnel.
10380   MockWrite data_writes1[] = {
10381     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10382               "Host: www.google.com\r\n"
10383               "Proxy-Connection: keep-alive\r\n\r\n"),
10384 
10385     MockWrite("GET / HTTP/1.1\r\n"
10386               "Host: www.google.com\r\n"
10387               "Connection: keep-alive\r\n\r\n"),
10388   };
10389 
10390   MockRead data_reads1[] = {
10391     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10392 
10393     MockRead("HTTP/1.1 200 OK\r\n"),
10394     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10395     MockRead("Content-Length: 100\r\n\r\n"),
10396     MockRead(SYNCHRONOUS, OK),
10397   };
10398 
10399   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10400                                  data_writes1, arraysize(data_writes1));
10401   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10402   SSLSocketDataProvider ssl(ASYNC, OK);
10403   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10404 
10405   TestCompletionCallback callback1;
10406 
10407   scoped_ptr<HttpTransaction> trans(
10408       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10409 
10410   int rv = trans->Start(&request, callback1.callback(), log.bound());
10411   EXPECT_EQ(ERR_IO_PENDING, rv);
10412 
10413   rv = callback1.WaitForResult();
10414   EXPECT_EQ(OK, rv);
10415   net::CapturingNetLog::CapturedEntryList entries;
10416   log.GetEntries(&entries);
10417   size_t pos = ExpectLogContainsSomewhere(
10418       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10419       NetLog::PHASE_NONE);
10420   ExpectLogContainsSomewhere(
10421       entries, pos,
10422       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10423       NetLog::PHASE_NONE);
10424 
10425   const HttpResponseInfo* response = trans->GetResponseInfo();
10426   ASSERT_TRUE(response != NULL);
10427 
10428   EXPECT_TRUE(response->headers->IsKeepAlive());
10429   EXPECT_EQ(200, response->headers->response_code());
10430   EXPECT_EQ(100, response->headers->GetContentLength());
10431   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10432   EXPECT_TRUE(response->was_fetched_via_proxy);
10433   EXPECT_TRUE(
10434       response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
10435 
10436   LoadTimingInfo load_timing_info;
10437   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10438   TestLoadTimingNotReusedWithPac(load_timing_info,
10439                                  CONNECT_TIMING_HAS_SSL_TIMES);
10440 }
10441 
10442 // Test a basic HTTPS GET request through a proxy, but the server hangs up
10443 // while establishing the tunnel.
TEST_P(HttpNetworkTransactionTest,ProxyTunnelGetHangup)10444 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
10445   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
10446   CapturingBoundNetLog log;
10447   session_deps_.net_log = log.bound().net_log();
10448   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10449 
10450   HttpRequestInfo request;
10451   request.method = "GET";
10452   request.url = GURL("https://www.google.com/");
10453 
10454   // Since we have proxy, should try to establish tunnel.
10455   MockWrite data_writes1[] = {
10456     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10457               "Host: www.google.com\r\n"
10458               "Proxy-Connection: keep-alive\r\n\r\n"),
10459 
10460     MockWrite("GET / HTTP/1.1\r\n"
10461               "Host: www.google.com\r\n"
10462               "Connection: keep-alive\r\n\r\n"),
10463   };
10464 
10465   MockRead data_reads1[] = {
10466     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10467     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10468     MockRead(ASYNC, 0, 0),  // EOF
10469   };
10470 
10471   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10472                                  data_writes1, arraysize(data_writes1));
10473   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10474   SSLSocketDataProvider ssl(ASYNC, OK);
10475   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10476 
10477   TestCompletionCallback callback1;
10478 
10479   scoped_ptr<HttpTransaction> trans(
10480       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10481 
10482   int rv = trans->Start(&request, callback1.callback(), log.bound());
10483   EXPECT_EQ(ERR_IO_PENDING, rv);
10484 
10485   rv = callback1.WaitForResult();
10486   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
10487   net::CapturingNetLog::CapturedEntryList entries;
10488   log.GetEntries(&entries);
10489   size_t pos = ExpectLogContainsSomewhere(
10490       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10491       NetLog::PHASE_NONE);
10492   ExpectLogContainsSomewhere(
10493       entries, pos,
10494       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10495       NetLog::PHASE_NONE);
10496 }
10497 
10498 // Test for crbug.com/55424.
TEST_P(HttpNetworkTransactionTest,PreconnectWithExistingSpdySession)10499 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
10500   scoped_ptr<SpdyFrame> req(
10501       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10502   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10503 
10504   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10505   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
10506   MockRead spdy_reads[] = {
10507     CreateMockRead(*resp),
10508     CreateMockRead(*data),
10509     MockRead(ASYNC, 0, 0),
10510   };
10511 
10512   DelayedSocketData spdy_data(
10513       1,  // wait for one write to finish before reading.
10514       spdy_reads, arraysize(spdy_reads),
10515       spdy_writes, arraysize(spdy_writes));
10516   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10517 
10518   SSLSocketDataProvider ssl(ASYNC, OK);
10519   ssl.SetNextProto(GetParam());
10520   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10521 
10522   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10523 
10524   // Set up an initial SpdySession in the pool to reuse.
10525   HostPortPair host_port_pair("www.google.com", 443);
10526   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10527                      PRIVACY_MODE_DISABLED);
10528   base::WeakPtr<SpdySession> spdy_session =
10529       CreateInsecureSpdySession(session, key, BoundNetLog());
10530 
10531   HttpRequestInfo request;
10532   request.method = "GET";
10533   request.url = GURL("https://www.google.com/");
10534   request.load_flags = 0;
10535 
10536   // This is the important line that marks this as a preconnect.
10537   request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10538 
10539   scoped_ptr<HttpTransaction> trans(
10540       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10541 
10542   TestCompletionCallback callback;
10543   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10544   EXPECT_EQ(ERR_IO_PENDING, rv);
10545   EXPECT_EQ(OK, callback.WaitForResult());
10546 }
10547 
10548 // Given a net error, cause that error to be returned from the first Write()
10549 // call and verify that the HttpTransaction fails with that error.
CheckErrorIsPassedBack(int error,IoMode mode)10550 void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
10551     int error, IoMode mode) {
10552   net::HttpRequestInfo request_info;
10553   request_info.url = GURL("https://www.example.com/");
10554   request_info.method = "GET";
10555   request_info.load_flags = net::LOAD_NORMAL;
10556 
10557   SSLSocketDataProvider ssl_data(mode, OK);
10558   net::MockWrite data_writes[] = {
10559     net::MockWrite(mode, error),
10560   };
10561   net::StaticSocketDataProvider data(NULL, 0,
10562                                      data_writes, arraysize(data_writes));
10563   session_deps_.socket_factory->AddSocketDataProvider(&data);
10564   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
10565 
10566   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10567   scoped_ptr<HttpTransaction> trans(
10568       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10569 
10570   TestCompletionCallback callback;
10571   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
10572   if (rv == net::ERR_IO_PENDING)
10573     rv = callback.WaitForResult();
10574   ASSERT_EQ(error, rv);
10575 }
10576 
TEST_P(HttpNetworkTransactionTest,SSLWriteCertError)10577 TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
10578   // Just check a grab bag of cert errors.
10579   static const int kErrors[] = {
10580     ERR_CERT_COMMON_NAME_INVALID,
10581     ERR_CERT_AUTHORITY_INVALID,
10582     ERR_CERT_DATE_INVALID,
10583   };
10584   for (size_t i = 0; i < arraysize(kErrors); i++) {
10585     CheckErrorIsPassedBack(kErrors[i], ASYNC);
10586     CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
10587   }
10588 }
10589 
10590 // Ensure that a client certificate is removed from the SSL client auth
10591 // cache when:
10592 //  1) No proxy is involved.
10593 //  2) TLS False Start is disabled.
10594 //  3) The initial TLS handshake requests a client certificate.
10595 //  4) The client supplies an invalid/unacceptable certificate.
TEST_P(HttpNetworkTransactionTest,ClientAuthCertCache_Direct_NoFalseStart)10596 TEST_P(HttpNetworkTransactionTest,
10597        ClientAuthCertCache_Direct_NoFalseStart) {
10598   net::HttpRequestInfo request_info;
10599   request_info.url = GURL("https://www.example.com/");
10600   request_info.method = "GET";
10601   request_info.load_flags = net::LOAD_NORMAL;
10602 
10603   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10604   cert_request->host_and_port = HostPortPair("www.example.com", 443);
10605 
10606   // [ssl_]data1 contains the data for the first SSL handshake. When a
10607   // CertificateRequest is received for the first time, the handshake will
10608   // be aborted to allow the caller to provide a certificate.
10609   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
10610   ssl_data1.cert_request_info = cert_request.get();
10611   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
10612   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10613   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10614 
10615   // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10616   // False Start is not being used, the result of the SSL handshake will be
10617   // returned as part of the SSLClientSocket::Connect() call. This test
10618   // matches the result of a server sending a handshake_failure alert,
10619   // rather than a Finished message, because it requires a client
10620   // certificate and none was supplied.
10621   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10622   ssl_data2.cert_request_info = cert_request.get();
10623   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
10624   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10625   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10626 
10627   // [ssl_]data3 contains the data for the third SSL handshake. When a
10628   // connection to a server fails during an SSL handshake,
10629   // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10630   // connection was attempted with TLSv1.1. This is transparent to the caller
10631   // of the HttpNetworkTransaction. Because this test failure is due to
10632   // requiring a client certificate, this fallback handshake should also
10633   // fail.
10634   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10635   ssl_data3.cert_request_info = cert_request.get();
10636   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
10637   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10638   session_deps_.socket_factory->AddSocketDataProvider(&data3);
10639 
10640   // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10641   // connection to a server fails during an SSL handshake,
10642   // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10643   // connection was attempted with TLSv1. This is transparent to the caller
10644   // of the HttpNetworkTransaction. Because this test failure is due to
10645   // requiring a client certificate, this fallback handshake should also
10646   // fail.
10647   SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10648   ssl_data4.cert_request_info = cert_request.get();
10649   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
10650   net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
10651   session_deps_.socket_factory->AddSocketDataProvider(&data4);
10652 
10653   // Need one more if TLSv1.2 is enabled.
10654   SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10655   ssl_data5.cert_request_info = cert_request.get();
10656   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10657   net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10658   session_deps_.socket_factory->AddSocketDataProvider(&data5);
10659 
10660   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10661   scoped_ptr<HttpTransaction> trans(
10662       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10663 
10664   // Begin the SSL handshake with the peer. This consumes ssl_data1.
10665   TestCompletionCallback callback;
10666   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
10667   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10668 
10669   // Complete the SSL handshake, which should abort due to requiring a
10670   // client certificate.
10671   rv = callback.WaitForResult();
10672   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10673 
10674   // Indicate that no certificate should be supplied. From the perspective
10675   // of SSLClientCertCache, NULL is just as meaningful as a real
10676   // certificate, so this is the same as supply a
10677   // legitimate-but-unacceptable certificate.
10678   rv = trans->RestartWithCertificate(NULL, callback.callback());
10679   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10680 
10681   // Ensure the certificate was added to the client auth cache before
10682   // allowing the connection to continue restarting.
10683   scoped_refptr<X509Certificate> client_cert;
10684   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10685       HostPortPair("www.example.com", 443), &client_cert));
10686   ASSERT_EQ(NULL, client_cert.get());
10687 
10688   // Restart the handshake. This will consume ssl_data2, which fails, and
10689   // then consume ssl_data3 and ssl_data4, both of which should also fail.
10690   // The result code is checked against what ssl_data4 should return.
10691   rv = callback.WaitForResult();
10692   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10693 
10694   // Ensure that the client certificate is removed from the cache on a
10695   // handshake failure.
10696   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10697       HostPortPair("www.example.com", 443), &client_cert));
10698 }
10699 
10700 // Ensure that a client certificate is removed from the SSL client auth
10701 // cache when:
10702 //  1) No proxy is involved.
10703 //  2) TLS False Start is enabled.
10704 //  3) The initial TLS handshake requests a client certificate.
10705 //  4) The client supplies an invalid/unacceptable certificate.
TEST_P(HttpNetworkTransactionTest,ClientAuthCertCache_Direct_FalseStart)10706 TEST_P(HttpNetworkTransactionTest,
10707        ClientAuthCertCache_Direct_FalseStart) {
10708   net::HttpRequestInfo request_info;
10709   request_info.url = GURL("https://www.example.com/");
10710   request_info.method = "GET";
10711   request_info.load_flags = net::LOAD_NORMAL;
10712 
10713   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10714   cert_request->host_and_port = HostPortPair("www.example.com", 443);
10715 
10716   // When TLS False Start is used, SSLClientSocket::Connect() calls will
10717   // return successfully after reading up to the peer's Certificate message.
10718   // This is to allow the caller to call SSLClientSocket::Write(), which can
10719   // enqueue application data to be sent in the same packet as the
10720   // ChangeCipherSpec and Finished messages.
10721   // The actual handshake will be finished when SSLClientSocket::Read() is
10722   // called, which expects to process the peer's ChangeCipherSpec and
10723   // Finished messages. If there was an error negotiating with the peer,
10724   // such as due to the peer requiring a client certificate when none was
10725   // supplied, the alert sent by the peer won't be processed until Read() is
10726   // called.
10727 
10728   // Like the non-False Start case, when a client certificate is requested by
10729   // the peer, the handshake is aborted during the Connect() call.
10730   // [ssl_]data1 represents the initial SSL handshake with the peer.
10731   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
10732   ssl_data1.cert_request_info = cert_request.get();
10733   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
10734   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10735   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10736 
10737   // When a client certificate is supplied, Connect() will not be aborted
10738   // when the peer requests the certificate. Instead, the handshake will
10739   // artificially succeed, allowing the caller to write the HTTP request to
10740   // the socket. The handshake messages are not processed until Read() is
10741   // called, which then detects that the handshake was aborted, due to the
10742   // peer sending a handshake_failure because it requires a client
10743   // certificate.
10744   SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
10745   ssl_data2.cert_request_info = cert_request.get();
10746   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
10747   net::MockRead data2_reads[] = {
10748     net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
10749   };
10750   net::StaticSocketDataProvider data2(
10751       data2_reads, arraysize(data2_reads), NULL, 0);
10752   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10753 
10754   // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
10755   // the data for the SSL handshake once the TLSv1.1 connection falls back to
10756   // TLSv1. It has the same behaviour as [ssl_]data2.
10757   SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
10758   ssl_data3.cert_request_info = cert_request.get();
10759   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
10760   net::StaticSocketDataProvider data3(
10761       data2_reads, arraysize(data2_reads), NULL, 0);
10762   session_deps_.socket_factory->AddSocketDataProvider(&data3);
10763 
10764   // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10765   // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10766   SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10767   ssl_data4.cert_request_info = cert_request.get();
10768   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
10769   net::StaticSocketDataProvider data4(
10770       data2_reads, arraysize(data2_reads), NULL, 0);
10771   session_deps_.socket_factory->AddSocketDataProvider(&data4);
10772 
10773   // Need one more if TLSv1.2 is enabled.
10774   SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10775   ssl_data5.cert_request_info = cert_request.get();
10776   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10777   net::StaticSocketDataProvider data5(
10778       data2_reads, arraysize(data2_reads), NULL, 0);
10779   session_deps_.socket_factory->AddSocketDataProvider(&data5);
10780 
10781   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10782   scoped_ptr<HttpTransaction> trans(
10783       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10784 
10785   // Begin the initial SSL handshake.
10786   TestCompletionCallback callback;
10787   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
10788   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10789 
10790   // Complete the SSL handshake, which should abort due to requiring a
10791   // client certificate.
10792   rv = callback.WaitForResult();
10793   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10794 
10795   // Indicate that no certificate should be supplied. From the perspective
10796   // of SSLClientCertCache, NULL is just as meaningful as a real
10797   // certificate, so this is the same as supply a
10798   // legitimate-but-unacceptable certificate.
10799   rv = trans->RestartWithCertificate(NULL, callback.callback());
10800   ASSERT_EQ(net::ERR_IO_PENDING, rv);
10801 
10802   // Ensure the certificate was added to the client auth cache before
10803   // allowing the connection to continue restarting.
10804   scoped_refptr<X509Certificate> client_cert;
10805   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10806       HostPortPair("www.example.com", 443), &client_cert));
10807   ASSERT_EQ(NULL, client_cert.get());
10808 
10809   // Restart the handshake. This will consume ssl_data2, which fails, and
10810   // then consume ssl_data3 and ssl_data4, both of which should also fail.
10811   // The result code is checked against what ssl_data4 should return.
10812   rv = callback.WaitForResult();
10813   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10814 
10815   // Ensure that the client certificate is removed from the cache on a
10816   // handshake failure.
10817   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10818       HostPortPair("www.example.com", 443), &client_cert));
10819 }
10820 
10821 // Ensure that a client certificate is removed from the SSL client auth
10822 // cache when:
10823 //  1) An HTTPS proxy is involved.
10824 //  3) The HTTPS proxy requests a client certificate.
10825 //  4) The client supplies an invalid/unacceptable certificate for the
10826 //     proxy.
10827 // The test is repeated twice, first for connecting to an HTTPS endpoint,
10828 // then for connecting to an HTTP endpoint.
TEST_P(HttpNetworkTransactionTest,ClientAuthCertCache_Proxy_Fail)10829 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
10830   session_deps_.proxy_service.reset(
10831       ProxyService::CreateFixed("https://proxy:70"));
10832   CapturingBoundNetLog log;
10833   session_deps_.net_log = log.bound().net_log();
10834 
10835   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10836   cert_request->host_and_port = HostPortPair("proxy", 70);
10837 
10838   // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10839   // [ssl_]data[1-3]. Rather than represending the endpoint
10840   // (www.example.com:443), they represent failures with the HTTPS proxy
10841   // (proxy:70).
10842   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
10843   ssl_data1.cert_request_info = cert_request.get();
10844   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
10845   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10846   session_deps_.socket_factory->AddSocketDataProvider(&data1);
10847 
10848   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10849   ssl_data2.cert_request_info = cert_request.get();
10850   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
10851   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10852   session_deps_.socket_factory->AddSocketDataProvider(&data2);
10853 
10854   // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10855 #if 0
10856   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10857   ssl_data3.cert_request_info = cert_request.get();
10858   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
10859   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10860   session_deps_.socket_factory->AddSocketDataProvider(&data3);
10861 #endif
10862 
10863   net::HttpRequestInfo requests[2];
10864   requests[0].url = GURL("https://www.example.com/");
10865   requests[0].method = "GET";
10866   requests[0].load_flags = net::LOAD_NORMAL;
10867 
10868   requests[1].url = GURL("http://www.example.com/");
10869   requests[1].method = "GET";
10870   requests[1].load_flags = net::LOAD_NORMAL;
10871 
10872   for (size_t i = 0; i < arraysize(requests); ++i) {
10873     session_deps_.socket_factory->ResetNextMockIndexes();
10874     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10875     scoped_ptr<HttpNetworkTransaction> trans(
10876         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10877 
10878     // Begin the SSL handshake with the proxy.
10879     TestCompletionCallback callback;
10880     int rv = trans->Start(
10881         &requests[i], callback.callback(), net::BoundNetLog());
10882     ASSERT_EQ(net::ERR_IO_PENDING, rv);
10883 
10884     // Complete the SSL handshake, which should abort due to requiring a
10885     // client certificate.
10886     rv = callback.WaitForResult();
10887     ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10888 
10889     // Indicate that no certificate should be supplied. From the perspective
10890     // of SSLClientCertCache, NULL is just as meaningful as a real
10891     // certificate, so this is the same as supply a
10892     // legitimate-but-unacceptable certificate.
10893     rv = trans->RestartWithCertificate(NULL, callback.callback());
10894     ASSERT_EQ(net::ERR_IO_PENDING, rv);
10895 
10896     // Ensure the certificate was added to the client auth cache before
10897     // allowing the connection to continue restarting.
10898     scoped_refptr<X509Certificate> client_cert;
10899     ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10900         HostPortPair("proxy", 70), &client_cert));
10901     ASSERT_EQ(NULL, client_cert.get());
10902     // Ensure the certificate was NOT cached for the endpoint. This only
10903     // applies to HTTPS requests, but is fine to check for HTTP requests.
10904     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10905         HostPortPair("www.example.com", 443), &client_cert));
10906 
10907     // Restart the handshake. This will consume ssl_data2, which fails, and
10908     // then consume ssl_data3, which should also fail. The result code is
10909     // checked against what ssl_data3 should return.
10910     rv = callback.WaitForResult();
10911     ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10912 
10913     // Now that the new handshake has failed, ensure that the client
10914     // certificate was removed from the client auth cache.
10915     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10916         HostPortPair("proxy", 70), &client_cert));
10917     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10918         HostPortPair("www.example.com", 443), &client_cert));
10919   }
10920 }
10921 
10922 // Unlike TEST/TEST_F, which are macros that expand to further macros,
10923 // TEST_P is a macro that expands directly to code that stringizes the
10924 // arguments. As a result, macros passed as parameters (such as prefix
10925 // or test_case_name) will not be expanded by the preprocessor. To
10926 // work around this, indirect the macro for TEST_P, so that the
10927 // pre-processor will expand macros such as MAYBE_test_name before
10928 // instantiating the test.
10929 #define WRAPPED_TEST_P(test_case_name, test_name) \
10930   TEST_P(test_case_name, test_name)
10931 
10932 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
10933 #if defined(OS_WIN)
10934 #define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10935 #else
10936 #define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10937 #endif
WRAPPED_TEST_P(HttpNetworkTransactionTest,MAYBE_UseIPConnectionPooling)10938 WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
10939   session_deps_.use_alternate_protocols = true;
10940   session_deps_.next_protos = SpdyNextProtos();
10941 
10942   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
10943   session_deps_.host_resolver.reset(new MockCachingHostResolver());
10944   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10945   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10946   pool_peer.DisableDomainAuthenticationVerification();
10947 
10948   SSLSocketDataProvider ssl(ASYNC, OK);
10949   ssl.SetNextProto(GetParam());
10950   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10951 
10952   scoped_ptr<SpdyFrame> host1_req(
10953       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10954   scoped_ptr<SpdyFrame> host2_req(
10955       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
10956   MockWrite spdy_writes[] = {
10957     CreateMockWrite(*host1_req, 1),
10958     CreateMockWrite(*host2_req, 4),
10959   };
10960   scoped_ptr<SpdyFrame> host1_resp(
10961       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10962   scoped_ptr<SpdyFrame> host1_resp_body(
10963       spdy_util_.ConstructSpdyBodyFrame(1, true));
10964   scoped_ptr<SpdyFrame> host2_resp(
10965       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10966   scoped_ptr<SpdyFrame> host2_resp_body(
10967       spdy_util_.ConstructSpdyBodyFrame(3, true));
10968   MockRead spdy_reads[] = {
10969     CreateMockRead(*host1_resp, 2),
10970     CreateMockRead(*host1_resp_body, 3),
10971     CreateMockRead(*host2_resp, 5),
10972     CreateMockRead(*host2_resp_body, 6),
10973     MockRead(ASYNC, 0, 7),
10974   };
10975 
10976   IPAddressNumber ip;
10977   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10978   IPEndPoint peer_addr = IPEndPoint(ip, 443);
10979   MockConnect connect(ASYNC, OK, peer_addr);
10980   OrderedSocketData spdy_data(
10981       connect,
10982       spdy_reads, arraysize(spdy_reads),
10983       spdy_writes, arraysize(spdy_writes));
10984   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10985 
10986   TestCompletionCallback callback;
10987   HttpRequestInfo request1;
10988   request1.method = "GET";
10989   request1.url = GURL("https://www.google.com/");
10990   request1.load_flags = 0;
10991   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
10992 
10993   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10994   EXPECT_EQ(ERR_IO_PENDING, rv);
10995   EXPECT_EQ(OK, callback.WaitForResult());
10996 
10997   const HttpResponseInfo* response = trans1.GetResponseInfo();
10998   ASSERT_TRUE(response != NULL);
10999   ASSERT_TRUE(response->headers.get() != NULL);
11000   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11001 
11002   std::string response_data;
11003   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11004   EXPECT_EQ("hello!", response_data);
11005 
11006   // Preload www.gmail.com into HostCache.
11007   HostPortPair host_port("www.gmail.com", 443);
11008   HostResolver::RequestInfo resolve_info(host_port);
11009   AddressList ignored;
11010   rv = session_deps_.host_resolver->Resolve(resolve_info,
11011                                             DEFAULT_PRIORITY,
11012                                             &ignored,
11013                                             callback.callback(),
11014                                             NULL,
11015                                             BoundNetLog());
11016   EXPECT_EQ(ERR_IO_PENDING, rv);
11017   rv = callback.WaitForResult();
11018   EXPECT_EQ(OK, rv);
11019 
11020   HttpRequestInfo request2;
11021   request2.method = "GET";
11022   request2.url = GURL("https://www.gmail.com/");
11023   request2.load_flags = 0;
11024   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
11025 
11026   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11027   EXPECT_EQ(ERR_IO_PENDING, rv);
11028   EXPECT_EQ(OK, callback.WaitForResult());
11029 
11030   response = trans2.GetResponseInfo();
11031   ASSERT_TRUE(response != NULL);
11032   ASSERT_TRUE(response->headers.get() != NULL);
11033   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11034   EXPECT_TRUE(response->was_fetched_via_spdy);
11035   EXPECT_TRUE(response->was_npn_negotiated);
11036   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11037   EXPECT_EQ("hello!", response_data);
11038 }
11039 #undef MAYBE_UseIPConnectionPooling
11040 
TEST_P(HttpNetworkTransactionTest,UseIPConnectionPoolingAfterResolution)11041 TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
11042   session_deps_.use_alternate_protocols = true;
11043   session_deps_.next_protos = SpdyNextProtos();
11044 
11045   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
11046   session_deps_.host_resolver.reset(new MockCachingHostResolver());
11047   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11048   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11049   pool_peer.DisableDomainAuthenticationVerification();
11050 
11051   SSLSocketDataProvider ssl(ASYNC, OK);
11052   ssl.SetNextProto(GetParam());
11053   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11054 
11055   scoped_ptr<SpdyFrame> host1_req(
11056       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11057   scoped_ptr<SpdyFrame> host2_req(
11058       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
11059   MockWrite spdy_writes[] = {
11060     CreateMockWrite(*host1_req, 1),
11061     CreateMockWrite(*host2_req, 4),
11062   };
11063   scoped_ptr<SpdyFrame> host1_resp(
11064       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11065   scoped_ptr<SpdyFrame> host1_resp_body(
11066       spdy_util_.ConstructSpdyBodyFrame(1, true));
11067   scoped_ptr<SpdyFrame> host2_resp(
11068       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11069   scoped_ptr<SpdyFrame> host2_resp_body(
11070       spdy_util_.ConstructSpdyBodyFrame(3, true));
11071   MockRead spdy_reads[] = {
11072     CreateMockRead(*host1_resp, 2),
11073     CreateMockRead(*host1_resp_body, 3),
11074     CreateMockRead(*host2_resp, 5),
11075     CreateMockRead(*host2_resp_body, 6),
11076     MockRead(ASYNC, 0, 7),
11077   };
11078 
11079   IPAddressNumber ip;
11080   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11081   IPEndPoint peer_addr = IPEndPoint(ip, 443);
11082   MockConnect connect(ASYNC, OK, peer_addr);
11083   OrderedSocketData spdy_data(
11084       connect,
11085       spdy_reads, arraysize(spdy_reads),
11086       spdy_writes, arraysize(spdy_writes));
11087   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11088 
11089   TestCompletionCallback callback;
11090   HttpRequestInfo request1;
11091   request1.method = "GET";
11092   request1.url = GURL("https://www.google.com/");
11093   request1.load_flags = 0;
11094   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
11095 
11096   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11097   EXPECT_EQ(ERR_IO_PENDING, rv);
11098   EXPECT_EQ(OK, callback.WaitForResult());
11099 
11100   const HttpResponseInfo* response = trans1.GetResponseInfo();
11101   ASSERT_TRUE(response != NULL);
11102   ASSERT_TRUE(response->headers.get() != NULL);
11103   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11104 
11105   std::string response_data;
11106   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11107   EXPECT_EQ("hello!", response_data);
11108 
11109   HttpRequestInfo request2;
11110   request2.method = "GET";
11111   request2.url = GURL("https://www.gmail.com/");
11112   request2.load_flags = 0;
11113   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
11114 
11115   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11116   EXPECT_EQ(ERR_IO_PENDING, rv);
11117   EXPECT_EQ(OK, callback.WaitForResult());
11118 
11119   response = trans2.GetResponseInfo();
11120   ASSERT_TRUE(response != NULL);
11121   ASSERT_TRUE(response->headers.get() != NULL);
11122   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11123   EXPECT_TRUE(response->was_fetched_via_spdy);
11124   EXPECT_TRUE(response->was_npn_negotiated);
11125   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11126   EXPECT_EQ("hello!", response_data);
11127 }
11128 
11129 class OneTimeCachingHostResolver : public net::HostResolver {
11130  public:
OneTimeCachingHostResolver(const HostPortPair & host_port)11131   explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11132       : host_port_(host_port) {}
~OneTimeCachingHostResolver()11133   virtual ~OneTimeCachingHostResolver() {}
11134 
rules()11135   RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11136 
11137   // HostResolver methods:
Resolve(const RequestInfo & info,RequestPriority priority,AddressList * addresses,const CompletionCallback & callback,RequestHandle * out_req,const BoundNetLog & net_log)11138   virtual int Resolve(const RequestInfo& info,
11139                       RequestPriority priority,
11140                       AddressList* addresses,
11141                       const CompletionCallback& callback,
11142                       RequestHandle* out_req,
11143                       const BoundNetLog& net_log) OVERRIDE {
11144     return host_resolver_.Resolve(
11145         info, priority, addresses, callback, out_req, net_log);
11146   }
11147 
ResolveFromCache(const RequestInfo & info,AddressList * addresses,const BoundNetLog & net_log)11148   virtual int ResolveFromCache(const RequestInfo& info,
11149                                AddressList* addresses,
11150                                const BoundNetLog& net_log) OVERRIDE {
11151     int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11152     if (rv == OK && info.host_port_pair().Equals(host_port_))
11153       host_resolver_.GetHostCache()->clear();
11154     return rv;
11155   }
11156 
CancelRequest(RequestHandle req)11157   virtual void CancelRequest(RequestHandle req) OVERRIDE {
11158     host_resolver_.CancelRequest(req);
11159   }
11160 
GetMockHostResolver()11161   MockCachingHostResolver* GetMockHostResolver() {
11162     return &host_resolver_;
11163   }
11164 
11165  private:
11166   MockCachingHostResolver host_resolver_;
11167   const HostPortPair host_port_;
11168 };
11169 
11170 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
11171 #if defined(OS_WIN)
11172 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11173     DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
11174 #else
11175 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11176     UseIPConnectionPoolingWithHostCacheExpiration
11177 #endif
WRAPPED_TEST_P(HttpNetworkTransactionTest,MAYBE_UseIPConnectionPoolingWithHostCacheExpiration)11178 WRAPPED_TEST_P(HttpNetworkTransactionTest,
11179                MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
11180 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11181 // prefix doesn't work with parametrized tests).
11182 #if defined(OS_WIN)
11183   return;
11184 #else
11185   session_deps_.use_alternate_protocols = true;
11186   session_deps_.next_protos = SpdyNextProtos();
11187 
11188   // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
11189   OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
11190   HttpNetworkSession::Params params =
11191       SpdySessionDependencies::CreateSessionParams(&session_deps_);
11192   params.host_resolver = &host_resolver;
11193   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11194   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11195   pool_peer.DisableDomainAuthenticationVerification();
11196 
11197   SSLSocketDataProvider ssl(ASYNC, OK);
11198   ssl.SetNextProto(GetParam());
11199   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11200 
11201   scoped_ptr<SpdyFrame> host1_req(
11202       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11203   scoped_ptr<SpdyFrame> host2_req(
11204       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
11205   MockWrite spdy_writes[] = {
11206     CreateMockWrite(*host1_req, 1),
11207     CreateMockWrite(*host2_req, 4),
11208   };
11209   scoped_ptr<SpdyFrame> host1_resp(
11210       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11211   scoped_ptr<SpdyFrame> host1_resp_body(
11212       spdy_util_.ConstructSpdyBodyFrame(1, true));
11213   scoped_ptr<SpdyFrame> host2_resp(
11214       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11215   scoped_ptr<SpdyFrame> host2_resp_body(
11216       spdy_util_.ConstructSpdyBodyFrame(3, true));
11217   MockRead spdy_reads[] = {
11218     CreateMockRead(*host1_resp, 2),
11219     CreateMockRead(*host1_resp_body, 3),
11220     CreateMockRead(*host2_resp, 5),
11221     CreateMockRead(*host2_resp_body, 6),
11222     MockRead(ASYNC, 0, 7),
11223   };
11224 
11225   IPAddressNumber ip;
11226   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11227   IPEndPoint peer_addr = IPEndPoint(ip, 443);
11228   MockConnect connect(ASYNC, OK, peer_addr);
11229   OrderedSocketData spdy_data(
11230       connect,
11231       spdy_reads, arraysize(spdy_reads),
11232       spdy_writes, arraysize(spdy_writes));
11233   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11234 
11235   TestCompletionCallback callback;
11236   HttpRequestInfo request1;
11237   request1.method = "GET";
11238   request1.url = GURL("https://www.google.com/");
11239   request1.load_flags = 0;
11240   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
11241 
11242   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11243   EXPECT_EQ(ERR_IO_PENDING, rv);
11244   EXPECT_EQ(OK, callback.WaitForResult());
11245 
11246   const HttpResponseInfo* response = trans1.GetResponseInfo();
11247   ASSERT_TRUE(response != NULL);
11248   ASSERT_TRUE(response->headers.get() != NULL);
11249   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11250 
11251   std::string response_data;
11252   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11253   EXPECT_EQ("hello!", response_data);
11254 
11255   // Preload cache entries into HostCache.
11256   HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
11257   AddressList ignored;
11258   rv = host_resolver.Resolve(resolve_info,
11259                              DEFAULT_PRIORITY,
11260                              &ignored,
11261                              callback.callback(),
11262                              NULL,
11263                              BoundNetLog());
11264   EXPECT_EQ(ERR_IO_PENDING, rv);
11265   rv = callback.WaitForResult();
11266   EXPECT_EQ(OK, rv);
11267 
11268   HttpRequestInfo request2;
11269   request2.method = "GET";
11270   request2.url = GURL("https://www.gmail.com/");
11271   request2.load_flags = 0;
11272   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
11273 
11274   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11275   EXPECT_EQ(ERR_IO_PENDING, rv);
11276   EXPECT_EQ(OK, callback.WaitForResult());
11277 
11278   response = trans2.GetResponseInfo();
11279   ASSERT_TRUE(response != NULL);
11280   ASSERT_TRUE(response->headers.get() != NULL);
11281   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11282   EXPECT_TRUE(response->was_fetched_via_spdy);
11283   EXPECT_TRUE(response->was_npn_negotiated);
11284   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11285   EXPECT_EQ("hello!", response_data);
11286 #endif
11287 }
11288 #undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
11289 
TEST_P(HttpNetworkTransactionTest,DoNotUseSpdySessionForHttp)11290 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
11291   const std::string https_url = "https://www.google.com/";
11292   const std::string http_url = "http://www.google.com:443/";
11293 
11294   // SPDY GET for HTTPS URL
11295   scoped_ptr<SpdyFrame> req1(
11296       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
11297 
11298   MockWrite writes1[] = {
11299     CreateMockWrite(*req1, 0),
11300   };
11301 
11302   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11303   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11304   MockRead reads1[] = {
11305     CreateMockRead(*resp1, 1),
11306     CreateMockRead(*body1, 2),
11307     MockRead(ASYNC, ERR_IO_PENDING, 3)
11308   };
11309 
11310   DelayedSocketData data1(
11311       1, reads1, arraysize(reads1),
11312       writes1, arraysize(writes1));
11313   MockConnect connect_data1(ASYNC, OK);
11314   data1.set_connect_data(connect_data1);
11315 
11316   // HTTP GET for the HTTP URL
11317   MockWrite writes2[] = {
11318     MockWrite(ASYNC, 4,
11319               "GET / HTTP/1.1\r\n"
11320               "Host: www.google.com:443\r\n"
11321               "Connection: keep-alive\r\n\r\n"),
11322   };
11323 
11324   MockRead reads2[] = {
11325     MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11326     MockRead(ASYNC, 6, "hello"),
11327     MockRead(ASYNC, 7, OK),
11328   };
11329 
11330   DelayedSocketData data2(
11331       1, reads2, arraysize(reads2),
11332       writes2, arraysize(writes2));
11333 
11334   SSLSocketDataProvider ssl(ASYNC, OK);
11335   ssl.SetNextProto(GetParam());
11336   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11337   session_deps_.socket_factory->AddSocketDataProvider(&data1);
11338   session_deps_.socket_factory->AddSocketDataProvider(&data2);
11339 
11340   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11341 
11342   // Start the first transaction to set up the SpdySession
11343   HttpRequestInfo request1;
11344   request1.method = "GET";
11345   request1.url = GURL(https_url);
11346   request1.load_flags = 0;
11347   HttpNetworkTransaction trans1(LOWEST, session.get());
11348   TestCompletionCallback callback1;
11349   EXPECT_EQ(ERR_IO_PENDING,
11350             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11351   base::MessageLoop::current()->RunUntilIdle();
11352 
11353   EXPECT_EQ(OK, callback1.WaitForResult());
11354   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11355 
11356   // Now, start the HTTP request
11357   HttpRequestInfo request2;
11358   request2.method = "GET";
11359   request2.url = GURL(http_url);
11360   request2.load_flags = 0;
11361   HttpNetworkTransaction trans2(MEDIUM, session.get());
11362   TestCompletionCallback callback2;
11363   EXPECT_EQ(ERR_IO_PENDING,
11364             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11365   base::MessageLoop::current()->RunUntilIdle();
11366 
11367   EXPECT_EQ(OK, callback2.WaitForResult());
11368   EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11369 }
11370 
TEST_P(HttpNetworkTransactionTest,DoNotUseSpdySessionForHttpOverTunnel)11371 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
11372   const std::string https_url = "https://www.google.com/";
11373   const std::string http_url = "http://www.google.com:443/";
11374 
11375   // SPDY GET for HTTPS URL (through CONNECT tunnel)
11376   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
11377                                                                 LOWEST));
11378   scoped_ptr<SpdyFrame> req1(
11379       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
11380   scoped_ptr<SpdyFrame> wrapped_req1(
11381       spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
11382 
11383   // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
11384   SpdySynStreamIR req2_ir(3);
11385   spdy_util_.SetPriority(MEDIUM, &req2_ir);
11386   req2_ir.set_fin(true);
11387   req2_ir.SetHeader(spdy_util_.GetMethodKey(), "GET");
11388   req2_ir.SetHeader(spdy_util_.GetPathKey(),
11389                     spdy_util_.is_spdy2() ? http_url.c_str() : "/");
11390   req2_ir.SetHeader(spdy_util_.GetHostKey(), "www.google.com:443");
11391   req2_ir.SetHeader(spdy_util_.GetSchemeKey(), "http");
11392   spdy_util_.MaybeAddVersionHeader(&req2_ir);
11393   scoped_ptr<SpdyFrame> req2(
11394       spdy_util_.CreateFramer(false)->SerializeFrame(req2_ir));
11395 
11396   MockWrite writes1[] = {
11397     CreateMockWrite(*connect, 0),
11398     CreateMockWrite(*wrapped_req1, 2),
11399     CreateMockWrite(*req2, 5),
11400   };
11401 
11402   scoped_ptr<SpdyFrame> conn_resp(
11403       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11404   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11405   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11406   scoped_ptr<SpdyFrame> wrapped_resp1(
11407       spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11408   scoped_ptr<SpdyFrame> wrapped_body1(
11409       spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11410   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11411   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
11412   MockRead reads1[] = {
11413     CreateMockRead(*conn_resp, 1),
11414     CreateMockRead(*wrapped_resp1, 3),
11415     CreateMockRead(*wrapped_body1, 4),
11416     CreateMockRead(*resp2, 6),
11417     CreateMockRead(*body2, 7),
11418     MockRead(ASYNC, ERR_IO_PENDING, 8)
11419   };
11420 
11421   DeterministicSocketData data1(reads1, arraysize(reads1),
11422                                 writes1, arraysize(writes1));
11423   MockConnect connect_data1(ASYNC, OK);
11424   data1.set_connect_data(connect_data1);
11425 
11426   session_deps_.proxy_service.reset(
11427       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11428   CapturingNetLog log;
11429   session_deps_.net_log = &log;
11430   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
11431   ssl1.SetNextProto(GetParam());
11432   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11433   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
11434   ssl2.SetNextProto(GetParam());
11435   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11436   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
11437 
11438   scoped_refptr<HttpNetworkSession> session(
11439       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11440 
11441   // Start the first transaction to set up the SpdySession
11442   HttpRequestInfo request1;
11443   request1.method = "GET";
11444   request1.url = GURL(https_url);
11445   request1.load_flags = 0;
11446   HttpNetworkTransaction trans1(LOWEST, session.get());
11447   TestCompletionCallback callback1;
11448   EXPECT_EQ(ERR_IO_PENDING,
11449             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11450   base::MessageLoop::current()->RunUntilIdle();
11451   data1.RunFor(4);
11452 
11453   EXPECT_EQ(OK, callback1.WaitForResult());
11454   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11455 
11456   LoadTimingInfo load_timing_info1;
11457   EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11458   TestLoadTimingNotReusedWithPac(load_timing_info1,
11459                                  CONNECT_TIMING_HAS_SSL_TIMES);
11460 
11461   // Now, start the HTTP request
11462   HttpRequestInfo request2;
11463   request2.method = "GET";
11464   request2.url = GURL(http_url);
11465   request2.load_flags = 0;
11466   HttpNetworkTransaction trans2(MEDIUM, session.get());
11467   TestCompletionCallback callback2;
11468   EXPECT_EQ(ERR_IO_PENDING,
11469             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11470   base::MessageLoop::current()->RunUntilIdle();
11471   data1.RunFor(3);
11472 
11473   EXPECT_EQ(OK, callback2.WaitForResult());
11474   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11475 
11476   LoadTimingInfo load_timing_info2;
11477   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11478   // The established SPDY sessions is considered reused by the HTTP request.
11479   TestLoadTimingReusedWithPac(load_timing_info2);
11480   // HTTP requests over a SPDY session should have a different connection
11481   // socket_log_id than requests over a tunnel.
11482   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
11483 }
11484 
TEST_P(HttpNetworkTransactionTest,UseSpdySessionForHttpWhenForced)11485 TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
11486   session_deps_.force_spdy_always = true;
11487   const std::string https_url = "https://www.google.com/";
11488   const std::string http_url = "http://www.google.com:443/";
11489 
11490   // SPDY GET for HTTPS URL
11491   scoped_ptr<SpdyFrame> req1(
11492       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
11493   // SPDY GET for the HTTP URL
11494   scoped_ptr<SpdyFrame> req2(
11495       spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
11496 
11497   MockWrite writes[] = {
11498     CreateMockWrite(*req1, 1),
11499     CreateMockWrite(*req2, 4),
11500   };
11501 
11502   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11503   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11504   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11505   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
11506   MockRead reads[] = {
11507     CreateMockRead(*resp1, 2),
11508     CreateMockRead(*body1, 3),
11509     CreateMockRead(*resp2, 5),
11510     CreateMockRead(*body2, 6),
11511     MockRead(ASYNC, ERR_IO_PENDING, 7)
11512   };
11513 
11514   OrderedSocketData data(reads, arraysize(reads),
11515                          writes, arraysize(writes));
11516 
11517   SSLSocketDataProvider ssl(ASYNC, OK);
11518   ssl.SetNextProto(GetParam());
11519   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11520   session_deps_.socket_factory->AddSocketDataProvider(&data);
11521 
11522   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11523 
11524   // Start the first transaction to set up the SpdySession
11525   HttpRequestInfo request1;
11526   request1.method = "GET";
11527   request1.url = GURL(https_url);
11528   request1.load_flags = 0;
11529   HttpNetworkTransaction trans1(LOWEST, session.get());
11530   TestCompletionCallback callback1;
11531   EXPECT_EQ(ERR_IO_PENDING,
11532             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11533   base::MessageLoop::current()->RunUntilIdle();
11534 
11535   EXPECT_EQ(OK, callback1.WaitForResult());
11536   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11537 
11538   // Now, start the HTTP request
11539   HttpRequestInfo request2;
11540   request2.method = "GET";
11541   request2.url = GURL(http_url);
11542   request2.load_flags = 0;
11543   HttpNetworkTransaction trans2(MEDIUM, session.get());
11544   TestCompletionCallback callback2;
11545   EXPECT_EQ(ERR_IO_PENDING,
11546             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11547   base::MessageLoop::current()->RunUntilIdle();
11548 
11549   EXPECT_EQ(OK, callback2.WaitForResult());
11550   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11551 }
11552 
11553 // Test that in the case where we have a SPDY session to a SPDY proxy
11554 // that we do not pool other origins that resolve to the same IP when
11555 // the certificate does not match the new origin.
11556 // http://crbug.com/134690
TEST_P(HttpNetworkTransactionTest,DoNotUseSpdySessionIfCertDoesNotMatch)11557 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
11558   const std::string url1 = "http://www.google.com/";
11559   const std::string url2 = "https://mail.google.com/";
11560   const std::string ip_addr = "1.2.3.4";
11561 
11562   // SPDY GET for HTTP URL (through SPDY proxy)
11563   scoped_ptr<SpdyHeaderBlock> headers(
11564       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
11565   scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
11566       headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
11567 
11568   MockWrite writes1[] = {
11569     CreateMockWrite(*req1, 0),
11570   };
11571 
11572   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11573   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11574   MockRead reads1[] = {
11575     CreateMockRead(*resp1, 1),
11576     CreateMockRead(*body1, 2),
11577     MockRead(ASYNC, OK, 3) // EOF
11578   };
11579 
11580   scoped_ptr<DeterministicSocketData> data1(
11581       new DeterministicSocketData(reads1, arraysize(reads1),
11582                                   writes1, arraysize(writes1)));
11583   IPAddressNumber ip;
11584   ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11585   IPEndPoint peer_addr = IPEndPoint(ip, 443);
11586   MockConnect connect_data1(ASYNC, OK, peer_addr);
11587   data1->set_connect_data(connect_data1);
11588 
11589   // SPDY GET for HTTPS URL (direct)
11590   scoped_ptr<SpdyFrame> req2(
11591       spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
11592 
11593   MockWrite writes2[] = {
11594     CreateMockWrite(*req2, 0),
11595   };
11596 
11597   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11598   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11599   MockRead reads2[] = {
11600     CreateMockRead(*resp2, 1),
11601     CreateMockRead(*body2, 2),
11602     MockRead(ASYNC, OK, 3) // EOF
11603   };
11604 
11605   scoped_ptr<DeterministicSocketData> data2(
11606       new DeterministicSocketData(reads2, arraysize(reads2),
11607                                   writes2, arraysize(writes2)));
11608   MockConnect connect_data2(ASYNC, OK);
11609   data2->set_connect_data(connect_data2);
11610 
11611   // Set up a proxy config that sends HTTP requests to a proxy, and
11612   // all others direct.
11613   ProxyConfig proxy_config;
11614   proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11615   CapturingProxyResolver* capturing_proxy_resolver =
11616       new CapturingProxyResolver();
11617   session_deps_.proxy_service.reset(new ProxyService(
11618       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11619       NULL));
11620 
11621   // Load a valid cert.  Note, that this does not need to
11622   // be valid for proxy because the MockSSLClientSocket does
11623   // not actually verify it.  But SpdySession will use this
11624   // to see if it is valid for the new origin
11625   base::FilePath certs_dir = GetTestCertsDirectory();
11626   scoped_refptr<X509Certificate> server_cert(
11627       ImportCertFromFile(certs_dir, "ok_cert.pem"));
11628   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11629 
11630   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
11631   ssl1.SetNextProto(GetParam());
11632   ssl1.cert = server_cert;
11633   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11634   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11635       data1.get());
11636 
11637   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
11638   ssl2.SetNextProto(GetParam());
11639   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11640   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11641       data2.get());
11642 
11643   session_deps_.host_resolver.reset(new MockCachingHostResolver());
11644   session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11645   session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
11646 
11647   scoped_refptr<HttpNetworkSession> session(
11648       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11649 
11650   // Start the first transaction to set up the SpdySession
11651   HttpRequestInfo request1;
11652   request1.method = "GET";
11653   request1.url = GURL(url1);
11654   request1.load_flags = 0;
11655   HttpNetworkTransaction trans1(LOWEST, session.get());
11656   TestCompletionCallback callback1;
11657   ASSERT_EQ(ERR_IO_PENDING,
11658             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11659   data1->RunFor(3);
11660 
11661   ASSERT_TRUE(callback1.have_result());
11662   EXPECT_EQ(OK, callback1.WaitForResult());
11663   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11664 
11665   // Now, start the HTTP request
11666   HttpRequestInfo request2;
11667   request2.method = "GET";
11668   request2.url = GURL(url2);
11669   request2.load_flags = 0;
11670   HttpNetworkTransaction trans2(MEDIUM, session.get());
11671   TestCompletionCallback callback2;
11672   EXPECT_EQ(ERR_IO_PENDING,
11673             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11674   base::MessageLoop::current()->RunUntilIdle();
11675   data2->RunFor(3);
11676 
11677   ASSERT_TRUE(callback2.have_result());
11678   EXPECT_EQ(OK, callback2.WaitForResult());
11679   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11680 }
11681 
11682 // Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11683 // error) in SPDY session, removes the socket from pool and closes the SPDY
11684 // session. Verify that new url's from the same HttpNetworkSession (and a new
11685 // SpdySession) do work. http://crbug.com/224701
TEST_P(HttpNetworkTransactionTest,ErrorSocketNotConnected)11686 TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
11687   const std::string https_url = "https://www.google.com/";
11688 
11689   MockRead reads1[] = {
11690     MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11691   };
11692 
11693   scoped_ptr<DeterministicSocketData> data1(
11694       new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11695   data1->SetStop(1);
11696 
11697   scoped_ptr<SpdyFrame> req2(
11698       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
11699   MockWrite writes2[] = {
11700     CreateMockWrite(*req2, 0),
11701   };
11702 
11703   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11704   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11705   MockRead reads2[] = {
11706     CreateMockRead(*resp2, 1),
11707     CreateMockRead(*body2, 2),
11708     MockRead(ASYNC, OK, 3)  // EOF
11709   };
11710 
11711   scoped_ptr<DeterministicSocketData> data2(
11712       new DeterministicSocketData(reads2, arraysize(reads2),
11713                                   writes2, arraysize(writes2)));
11714 
11715   SSLSocketDataProvider ssl1(ASYNC, OK);
11716   ssl1.SetNextProto(GetParam());
11717   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11718   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11719       data1.get());
11720 
11721   SSLSocketDataProvider ssl2(ASYNC, OK);
11722   ssl2.SetNextProto(GetParam());
11723   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11724   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11725       data2.get());
11726 
11727   scoped_refptr<HttpNetworkSession> session(
11728       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11729 
11730   // Start the first transaction to set up the SpdySession and verify that
11731   // connection was closed.
11732   HttpRequestInfo request1;
11733   request1.method = "GET";
11734   request1.url = GURL(https_url);
11735   request1.load_flags = 0;
11736   HttpNetworkTransaction trans1(MEDIUM, session.get());
11737   TestCompletionCallback callback1;
11738   EXPECT_EQ(ERR_IO_PENDING,
11739             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11740   base::MessageLoop::current()->RunUntilIdle();
11741   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11742 
11743   // Now, start the second request and make sure it succeeds.
11744   HttpRequestInfo request2;
11745   request2.method = "GET";
11746   request2.url = GURL(https_url);
11747   request2.load_flags = 0;
11748   HttpNetworkTransaction trans2(MEDIUM, session.get());
11749   TestCompletionCallback callback2;
11750   EXPECT_EQ(ERR_IO_PENDING,
11751             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11752   base::MessageLoop::current()->RunUntilIdle();
11753   data2->RunFor(3);
11754 
11755   ASSERT_TRUE(callback2.have_result());
11756   EXPECT_EQ(OK, callback2.WaitForResult());
11757   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11758 }
11759 
TEST_P(HttpNetworkTransactionTest,CloseIdleSpdySessionToOpenNewOne)11760 TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
11761   session_deps_.next_protos = SpdyNextProtos();
11762   ClientSocketPoolManager::set_max_sockets_per_group(
11763       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11764   ClientSocketPoolManager::set_max_sockets_per_pool(
11765       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11766 
11767   // Use two different hosts with different IPs so they don't get pooled.
11768   session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11769   session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11770   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11771 
11772   SSLSocketDataProvider ssl1(ASYNC, OK);
11773   ssl1.SetNextProto(GetParam());
11774   SSLSocketDataProvider ssl2(ASYNC, OK);
11775   ssl2.SetNextProto(GetParam());
11776   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11777   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11778 
11779   scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
11780       "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11781   MockWrite spdy1_writes[] = {
11782     CreateMockWrite(*host1_req, 1),
11783   };
11784   scoped_ptr<SpdyFrame> host1_resp(
11785       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11786   scoped_ptr<SpdyFrame> host1_resp_body(
11787       spdy_util_.ConstructSpdyBodyFrame(1, true));
11788   MockRead spdy1_reads[] = {
11789     CreateMockRead(*host1_resp, 2),
11790     CreateMockRead(*host1_resp_body, 3),
11791     MockRead(ASYNC, ERR_IO_PENDING, 4),
11792   };
11793 
11794   scoped_ptr<OrderedSocketData> spdy1_data(
11795       new OrderedSocketData(
11796           spdy1_reads, arraysize(spdy1_reads),
11797           spdy1_writes, arraysize(spdy1_writes)));
11798   session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11799 
11800   scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
11801       "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11802   MockWrite spdy2_writes[] = {
11803     CreateMockWrite(*host2_req, 1),
11804   };
11805   scoped_ptr<SpdyFrame> host2_resp(
11806       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11807   scoped_ptr<SpdyFrame> host2_resp_body(
11808       spdy_util_.ConstructSpdyBodyFrame(1, true));
11809   MockRead spdy2_reads[] = {
11810     CreateMockRead(*host2_resp, 2),
11811     CreateMockRead(*host2_resp_body, 3),
11812     MockRead(ASYNC, ERR_IO_PENDING, 4),
11813   };
11814 
11815   scoped_ptr<OrderedSocketData> spdy2_data(
11816       new OrderedSocketData(
11817           spdy2_reads, arraysize(spdy2_reads),
11818           spdy2_writes, arraysize(spdy2_writes)));
11819   session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11820 
11821   MockWrite http_write[] = {
11822     MockWrite("GET / HTTP/1.1\r\n"
11823               "Host: www.a.com\r\n"
11824               "Connection: keep-alive\r\n\r\n"),
11825   };
11826 
11827   MockRead http_read[] = {
11828     MockRead("HTTP/1.1 200 OK\r\n"),
11829     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11830     MockRead("Content-Length: 6\r\n\r\n"),
11831     MockRead("hello!"),
11832   };
11833   StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11834                                      http_write, arraysize(http_write));
11835   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11836 
11837   HostPortPair host_port_pair_a("www.a.com", 443);
11838   SpdySessionKey spdy_session_key_a(
11839       host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11840   EXPECT_FALSE(
11841       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11842 
11843   TestCompletionCallback callback;
11844   HttpRequestInfo request1;
11845   request1.method = "GET";
11846   request1.url = GURL("https://www.a.com/");
11847   request1.load_flags = 0;
11848   scoped_ptr<HttpNetworkTransaction> trans(
11849       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11850 
11851   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11852   EXPECT_EQ(ERR_IO_PENDING, rv);
11853   EXPECT_EQ(OK, callback.WaitForResult());
11854 
11855   const HttpResponseInfo* response = trans->GetResponseInfo();
11856   ASSERT_TRUE(response != NULL);
11857   ASSERT_TRUE(response->headers.get() != NULL);
11858   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11859   EXPECT_TRUE(response->was_fetched_via_spdy);
11860   EXPECT_TRUE(response->was_npn_negotiated);
11861 
11862   std::string response_data;
11863   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11864   EXPECT_EQ("hello!", response_data);
11865   trans.reset();
11866   EXPECT_TRUE(
11867       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11868 
11869   HostPortPair host_port_pair_b("www.b.com", 443);
11870   SpdySessionKey spdy_session_key_b(
11871       host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11872   EXPECT_FALSE(
11873       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11874   HttpRequestInfo request2;
11875   request2.method = "GET";
11876   request2.url = GURL("https://www.b.com/");
11877   request2.load_flags = 0;
11878   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11879 
11880   rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11881   EXPECT_EQ(ERR_IO_PENDING, rv);
11882   EXPECT_EQ(OK, callback.WaitForResult());
11883 
11884   response = trans->GetResponseInfo();
11885   ASSERT_TRUE(response != NULL);
11886   ASSERT_TRUE(response->headers.get() != NULL);
11887   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11888   EXPECT_TRUE(response->was_fetched_via_spdy);
11889   EXPECT_TRUE(response->was_npn_negotiated);
11890   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11891   EXPECT_EQ("hello!", response_data);
11892   EXPECT_FALSE(
11893       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11894   EXPECT_TRUE(
11895       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11896 
11897   HostPortPair host_port_pair_a1("www.a.com", 80);
11898   SpdySessionKey spdy_session_key_a1(
11899       host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11900   EXPECT_FALSE(
11901       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
11902   HttpRequestInfo request3;
11903   request3.method = "GET";
11904   request3.url = GURL("http://www.a.com/");
11905   request3.load_flags = 0;
11906   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11907 
11908   rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11909   EXPECT_EQ(ERR_IO_PENDING, rv);
11910   EXPECT_EQ(OK, callback.WaitForResult());
11911 
11912   response = trans->GetResponseInfo();
11913   ASSERT_TRUE(response != NULL);
11914   ASSERT_TRUE(response->headers.get() != NULL);
11915   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11916   EXPECT_FALSE(response->was_fetched_via_spdy);
11917   EXPECT_FALSE(response->was_npn_negotiated);
11918   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11919   EXPECT_EQ("hello!", response_data);
11920   EXPECT_FALSE(
11921       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11922   EXPECT_FALSE(
11923       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11924 }
11925 
TEST_P(HttpNetworkTransactionTest,HttpSyncConnectError)11926 TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11927   HttpRequestInfo request;
11928   request.method = "GET";
11929   request.url = GURL("http://www.google.com/");
11930   request.load_flags = 0;
11931 
11932   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11933   scoped_ptr<HttpTransaction> trans(
11934       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11935 
11936   MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11937   StaticSocketDataProvider data;
11938   data.set_connect_data(mock_connect);
11939   session_deps_.socket_factory->AddSocketDataProvider(&data);
11940 
11941   TestCompletionCallback callback;
11942 
11943   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11944   EXPECT_EQ(ERR_IO_PENDING, rv);
11945 
11946   rv = callback.WaitForResult();
11947   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11948 
11949   EXPECT_EQ(NULL, trans->GetResponseInfo());
11950 
11951   // We don't care whether this succeeds or fails, but it shouldn't crash.
11952   HttpRequestHeaders request_headers;
11953   trans->GetFullRequestHeaders(&request_headers);
11954 }
11955 
TEST_P(HttpNetworkTransactionTest,HttpAsyncConnectError)11956 TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11957   HttpRequestInfo request;
11958   request.method = "GET";
11959   request.url = GURL("http://www.google.com/");
11960   request.load_flags = 0;
11961 
11962   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11963   scoped_ptr<HttpTransaction> trans(
11964       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11965 
11966   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11967   StaticSocketDataProvider data;
11968   data.set_connect_data(mock_connect);
11969   session_deps_.socket_factory->AddSocketDataProvider(&data);
11970 
11971   TestCompletionCallback callback;
11972 
11973   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11974   EXPECT_EQ(ERR_IO_PENDING, rv);
11975 
11976   rv = callback.WaitForResult();
11977   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11978 
11979   EXPECT_EQ(NULL, trans->GetResponseInfo());
11980 
11981   // We don't care whether this succeeds or fails, but it shouldn't crash.
11982   HttpRequestHeaders request_headers;
11983   trans->GetFullRequestHeaders(&request_headers);
11984 }
11985 
TEST_P(HttpNetworkTransactionTest,HttpSyncWriteError)11986 TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11987   HttpRequestInfo request;
11988   request.method = "GET";
11989   request.url = GURL("http://www.google.com/");
11990   request.load_flags = 0;
11991 
11992   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11993   scoped_ptr<HttpTransaction> trans(
11994       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11995 
11996   MockWrite data_writes[] = {
11997     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11998   };
11999   MockRead data_reads[] = {
12000     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
12001   };
12002 
12003   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12004                                 data_writes, arraysize(data_writes));
12005   session_deps_.socket_factory->AddSocketDataProvider(&data);
12006 
12007   TestCompletionCallback callback;
12008 
12009   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12010   EXPECT_EQ(ERR_IO_PENDING, rv);
12011 
12012   rv = callback.WaitForResult();
12013   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12014 
12015   EXPECT_EQ(NULL, trans->GetResponseInfo());
12016 
12017   HttpRequestHeaders request_headers;
12018   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12019   EXPECT_TRUE(request_headers.HasHeader("Host"));
12020 }
12021 
TEST_P(HttpNetworkTransactionTest,HttpAsyncWriteError)12022 TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12023   HttpRequestInfo request;
12024   request.method = "GET";
12025   request.url = GURL("http://www.google.com/");
12026   request.load_flags = 0;
12027 
12028   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12029   scoped_ptr<HttpTransaction> trans(
12030       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12031 
12032   MockWrite data_writes[] = {
12033     MockWrite(ASYNC, ERR_CONNECTION_RESET),
12034   };
12035   MockRead data_reads[] = {
12036     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
12037   };
12038 
12039   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12040                                 data_writes, arraysize(data_writes));
12041   session_deps_.socket_factory->AddSocketDataProvider(&data);
12042 
12043   TestCompletionCallback callback;
12044 
12045   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12046   EXPECT_EQ(ERR_IO_PENDING, rv);
12047 
12048   rv = callback.WaitForResult();
12049   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12050 
12051   EXPECT_EQ(NULL, trans->GetResponseInfo());
12052 
12053   HttpRequestHeaders request_headers;
12054   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12055   EXPECT_TRUE(request_headers.HasHeader("Host"));
12056 }
12057 
TEST_P(HttpNetworkTransactionTest,HttpSyncReadError)12058 TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12059   HttpRequestInfo request;
12060   request.method = "GET";
12061   request.url = GURL("http://www.google.com/");
12062   request.load_flags = 0;
12063 
12064   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12065   scoped_ptr<HttpTransaction> trans(
12066       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12067 
12068   MockWrite data_writes[] = {
12069     MockWrite("GET / HTTP/1.1\r\n"
12070               "Host: www.google.com\r\n"
12071               "Connection: keep-alive\r\n\r\n"),
12072   };
12073   MockRead data_reads[] = {
12074     MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12075   };
12076 
12077   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12078                                 data_writes, arraysize(data_writes));
12079   session_deps_.socket_factory->AddSocketDataProvider(&data);
12080 
12081   TestCompletionCallback callback;
12082 
12083   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12084   EXPECT_EQ(ERR_IO_PENDING, rv);
12085 
12086   rv = callback.WaitForResult();
12087   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12088 
12089   EXPECT_EQ(NULL, trans->GetResponseInfo());
12090 
12091   HttpRequestHeaders request_headers;
12092   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12093   EXPECT_TRUE(request_headers.HasHeader("Host"));
12094 }
12095 
TEST_P(HttpNetworkTransactionTest,HttpAsyncReadError)12096 TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12097   HttpRequestInfo request;
12098   request.method = "GET";
12099   request.url = GURL("http://www.google.com/");
12100   request.load_flags = 0;
12101 
12102   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12103   scoped_ptr<HttpTransaction> trans(
12104       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12105 
12106   MockWrite data_writes[] = {
12107     MockWrite("GET / HTTP/1.1\r\n"
12108               "Host: www.google.com\r\n"
12109               "Connection: keep-alive\r\n\r\n"),
12110   };
12111   MockRead data_reads[] = {
12112     MockRead(ASYNC, ERR_CONNECTION_RESET),
12113   };
12114 
12115   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12116                                 data_writes, arraysize(data_writes));
12117   session_deps_.socket_factory->AddSocketDataProvider(&data);
12118 
12119   TestCompletionCallback callback;
12120 
12121   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12122   EXPECT_EQ(ERR_IO_PENDING, rv);
12123 
12124   rv = callback.WaitForResult();
12125   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12126 
12127   EXPECT_EQ(NULL, trans->GetResponseInfo());
12128 
12129   HttpRequestHeaders request_headers;
12130   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12131   EXPECT_TRUE(request_headers.HasHeader("Host"));
12132 }
12133 
TEST_P(HttpNetworkTransactionTest,GetFullRequestHeadersIncludesExtraHeader)12134 TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12135   HttpRequestInfo request;
12136   request.method = "GET";
12137   request.url = GURL("http://www.google.com/");
12138   request.load_flags = 0;
12139   request.extra_headers.SetHeader("X-Foo", "bar");
12140 
12141   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12142   scoped_ptr<HttpTransaction> trans(
12143       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12144 
12145   MockWrite data_writes[] = {
12146     MockWrite("GET / HTTP/1.1\r\n"
12147               "Host: www.google.com\r\n"
12148               "Connection: keep-alive\r\n"
12149               "X-Foo: bar\r\n\r\n"),
12150   };
12151   MockRead data_reads[] = {
12152     MockRead("HTTP/1.1 200 OK\r\n"
12153              "Content-Length: 5\r\n\r\n"
12154              "hello"),
12155     MockRead(ASYNC, ERR_UNEXPECTED),
12156   };
12157 
12158   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12159                                 data_writes, arraysize(data_writes));
12160   session_deps_.socket_factory->AddSocketDataProvider(&data);
12161 
12162   TestCompletionCallback callback;
12163 
12164   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12165   EXPECT_EQ(ERR_IO_PENDING, rv);
12166 
12167   rv = callback.WaitForResult();
12168   EXPECT_EQ(OK, rv);
12169 
12170   HttpRequestHeaders request_headers;
12171   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12172   std::string foo;
12173   EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12174   EXPECT_EQ("bar", foo);
12175 }
12176 
12177 namespace {
12178 
12179 // Fake HttpStreamBase that simply records calls to SetPriority().
12180 class FakeStream : public HttpStreamBase,
12181                    public base::SupportsWeakPtr<FakeStream> {
12182  public:
FakeStream(RequestPriority priority)12183   explicit FakeStream(RequestPriority priority) : priority_(priority) {}
~FakeStream()12184   virtual ~FakeStream() {}
12185 
priority() const12186   RequestPriority priority() const { return priority_; }
12187 
InitializeStream(const HttpRequestInfo * request_info,RequestPriority priority,const BoundNetLog & net_log,const CompletionCallback & callback)12188   virtual int InitializeStream(const HttpRequestInfo* request_info,
12189                                RequestPriority priority,
12190                                const BoundNetLog& net_log,
12191                                const CompletionCallback& callback) OVERRIDE {
12192     return ERR_IO_PENDING;
12193   }
12194 
SendRequest(const HttpRequestHeaders & request_headers,HttpResponseInfo * response,const CompletionCallback & callback)12195   virtual int SendRequest(const HttpRequestHeaders& request_headers,
12196                           HttpResponseInfo* response,
12197                           const CompletionCallback& callback) OVERRIDE {
12198     ADD_FAILURE();
12199     return ERR_UNEXPECTED;
12200   }
12201 
ReadResponseHeaders(const CompletionCallback & callback)12202   virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
12203     ADD_FAILURE();
12204     return ERR_UNEXPECTED;
12205   }
12206 
ReadResponseBody(IOBuffer * buf,int buf_len,const CompletionCallback & callback)12207   virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
12208                                const CompletionCallback& callback) OVERRIDE {
12209     ADD_FAILURE();
12210     return ERR_UNEXPECTED;
12211   }
12212 
Close(bool not_reusable)12213   virtual void Close(bool not_reusable) OVERRIDE {}
12214 
IsResponseBodyComplete() const12215   virtual bool IsResponseBodyComplete() const OVERRIDE {
12216     ADD_FAILURE();
12217     return false;
12218   }
12219 
CanFindEndOfResponse() const12220   virtual bool CanFindEndOfResponse() const OVERRIDE {
12221     return false;
12222   }
12223 
IsConnectionReused() const12224   virtual bool IsConnectionReused() const OVERRIDE {
12225     ADD_FAILURE();
12226     return false;
12227   }
12228 
SetConnectionReused()12229   virtual void SetConnectionReused() OVERRIDE {
12230     ADD_FAILURE();
12231   }
12232 
IsConnectionReusable() const12233   virtual bool IsConnectionReusable() const OVERRIDE {
12234     ADD_FAILURE();
12235     return false;
12236   }
12237 
GetTotalReceivedBytes() const12238   virtual int64 GetTotalReceivedBytes() const OVERRIDE {
12239     ADD_FAILURE();
12240     return 0;
12241   }
12242 
GetLoadTimingInfo(LoadTimingInfo * load_timing_info) const12243   virtual bool GetLoadTimingInfo(
12244       LoadTimingInfo* load_timing_info) const OVERRIDE {
12245     ADD_FAILURE();
12246     return false;
12247   }
12248 
GetSSLInfo(SSLInfo * ssl_info)12249   virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
12250     ADD_FAILURE();
12251   }
12252 
GetSSLCertRequestInfo(SSLCertRequestInfo * cert_request_info)12253   virtual void GetSSLCertRequestInfo(
12254       SSLCertRequestInfo* cert_request_info) OVERRIDE {
12255     ADD_FAILURE();
12256   }
12257 
IsSpdyHttpStream() const12258   virtual bool IsSpdyHttpStream() const OVERRIDE {
12259     ADD_FAILURE();
12260     return false;
12261   }
12262 
Drain(HttpNetworkSession * session)12263   virtual void Drain(HttpNetworkSession* session) OVERRIDE {
12264     ADD_FAILURE();
12265   }
12266 
SetPriority(RequestPriority priority)12267   virtual void SetPriority(RequestPriority priority) OVERRIDE {
12268     priority_ = priority;
12269   }
12270 
12271  private:
12272   RequestPriority priority_;
12273 
12274   DISALLOW_COPY_AND_ASSIGN(FakeStream);
12275 };
12276 
12277 // Fake HttpStreamRequest that simply records calls to SetPriority()
12278 // and vends FakeStreams with its current priority.
12279 class FakeStreamRequest : public HttpStreamRequest,
12280                           public base::SupportsWeakPtr<FakeStreamRequest> {
12281  public:
FakeStreamRequest(RequestPriority priority,HttpStreamRequest::Delegate * delegate)12282   FakeStreamRequest(RequestPriority priority,
12283                     HttpStreamRequest::Delegate* delegate)
12284       : priority_(priority),
12285         delegate_(delegate),
12286         websocket_stream_create_helper_(NULL) {}
12287 
FakeStreamRequest(RequestPriority priority,HttpStreamRequest::Delegate * delegate,WebSocketHandshakeStreamBase::CreateHelper * create_helper)12288   FakeStreamRequest(RequestPriority priority,
12289                     HttpStreamRequest::Delegate* delegate,
12290                     WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12291       : priority_(priority),
12292         delegate_(delegate),
12293         websocket_stream_create_helper_(create_helper) {}
12294 
~FakeStreamRequest()12295   virtual ~FakeStreamRequest() {}
12296 
priority() const12297   RequestPriority priority() const { return priority_; }
12298 
12299   const WebSocketHandshakeStreamBase::CreateHelper*
websocket_stream_create_helper() const12300   websocket_stream_create_helper() const {
12301     return websocket_stream_create_helper_;
12302   }
12303 
12304   // Create a new FakeStream and pass it to the request's
12305   // delegate. Returns a weak pointer to the FakeStream.
FinishStreamRequest()12306   base::WeakPtr<FakeStream> FinishStreamRequest() {
12307     FakeStream* fake_stream = new FakeStream(priority_);
12308     // Do this before calling OnStreamReady() as OnStreamReady() may
12309     // immediately delete |fake_stream|.
12310     base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12311     delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12312     return weak_stream;
12313   }
12314 
RestartTunnelWithProxyAuth(const AuthCredentials & credentials)12315   virtual int RestartTunnelWithProxyAuth(
12316       const AuthCredentials& credentials) OVERRIDE {
12317     ADD_FAILURE();
12318     return ERR_UNEXPECTED;
12319   }
12320 
GetLoadState() const12321   virtual LoadState GetLoadState() const OVERRIDE {
12322     ADD_FAILURE();
12323     return LoadState();
12324   }
12325 
SetPriority(RequestPriority priority)12326   virtual void SetPriority(RequestPriority priority) OVERRIDE {
12327     priority_ = priority;
12328   }
12329 
was_npn_negotiated() const12330   virtual bool was_npn_negotiated() const OVERRIDE {
12331     return false;
12332   }
12333 
protocol_negotiated() const12334   virtual NextProto protocol_negotiated() const OVERRIDE {
12335     return kProtoUnknown;
12336   }
12337 
using_spdy() const12338   virtual bool using_spdy() const OVERRIDE {
12339     return false;
12340   }
12341 
12342  private:
12343   RequestPriority priority_;
12344   HttpStreamRequest::Delegate* const delegate_;
12345   WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
12346 
12347   DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12348 };
12349 
12350 // Fake HttpStreamFactory that vends FakeStreamRequests.
12351 class FakeStreamFactory : public HttpStreamFactory {
12352  public:
FakeStreamFactory()12353   FakeStreamFactory() {}
~FakeStreamFactory()12354   virtual ~FakeStreamFactory() {}
12355 
12356   // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12357   // RequestStream() (which may be NULL if it was destroyed already).
last_stream_request()12358   base::WeakPtr<FakeStreamRequest> last_stream_request() {
12359     return last_stream_request_;
12360   }
12361 
RequestStream(const HttpRequestInfo & info,RequestPriority priority,const SSLConfig & server_ssl_config,const SSLConfig & proxy_ssl_config,HttpStreamRequest::Delegate * delegate,const BoundNetLog & net_log)12362   virtual HttpStreamRequest* RequestStream(
12363       const HttpRequestInfo& info,
12364       RequestPriority priority,
12365       const SSLConfig& server_ssl_config,
12366       const SSLConfig& proxy_ssl_config,
12367       HttpStreamRequest::Delegate* delegate,
12368       const BoundNetLog& net_log) OVERRIDE {
12369     FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
12370     last_stream_request_ = fake_request->AsWeakPtr();
12371     return fake_request;
12372   }
12373 
RequestWebSocketHandshakeStream(const HttpRequestInfo & info,RequestPriority priority,const SSLConfig & server_ssl_config,const SSLConfig & proxy_ssl_config,HttpStreamRequest::Delegate * delegate,WebSocketHandshakeStreamBase::CreateHelper * create_helper,const BoundNetLog & net_log)12374   virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
12375       const HttpRequestInfo& info,
12376       RequestPriority priority,
12377       const SSLConfig& server_ssl_config,
12378       const SSLConfig& proxy_ssl_config,
12379       HttpStreamRequest::Delegate* delegate,
12380       WebSocketHandshakeStreamBase::CreateHelper* create_helper,
12381       const BoundNetLog& net_log) OVERRIDE {
12382     FakeStreamRequest* fake_request =
12383         new FakeStreamRequest(priority, delegate, create_helper);
12384     last_stream_request_ = fake_request->AsWeakPtr();
12385     return fake_request;
12386   }
12387 
PreconnectStreams(int num_streams,const HttpRequestInfo & info,RequestPriority priority,const SSLConfig & server_ssl_config,const SSLConfig & proxy_ssl_config)12388   virtual void PreconnectStreams(int num_streams,
12389                                  const HttpRequestInfo& info,
12390                                  RequestPriority priority,
12391                                  const SSLConfig& server_ssl_config,
12392                                  const SSLConfig& proxy_ssl_config) OVERRIDE {
12393     ADD_FAILURE();
12394   }
12395 
GetHostMappingRules() const12396   virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
12397     ADD_FAILURE();
12398     return NULL;
12399   }
12400 
12401  private:
12402   base::WeakPtr<FakeStreamRequest> last_stream_request_;
12403 
12404   DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12405 };
12406 
12407 // TODO(yhirano): Split this class out into a net/websockets file, if it is
12408 // worth doing.
12409 class FakeWebSocketStreamCreateHelper :
12410       public WebSocketHandshakeStreamBase::CreateHelper {
12411  public:
CreateBasicStream(scoped_ptr<ClientSocketHandle> connection,bool using_proxy)12412   virtual WebSocketHandshakeStreamBase* CreateBasicStream(
12413       scoped_ptr<ClientSocketHandle> connection,
12414       bool using_proxy) OVERRIDE {
12415     NOTREACHED();
12416     return NULL;
12417   }
12418 
CreateSpdyStream(const base::WeakPtr<SpdySession> & session,bool use_relative_url)12419   virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12420       const base::WeakPtr<SpdySession>& session,
12421       bool use_relative_url) OVERRIDE {
12422     NOTREACHED();
12423     return NULL;
12424   };
12425 
~FakeWebSocketStreamCreateHelper()12426   virtual ~FakeWebSocketStreamCreateHelper() {}
12427 
Upgrade()12428   virtual scoped_ptr<WebSocketStream> Upgrade() {
12429     NOTREACHED();
12430     return scoped_ptr<WebSocketStream>();
12431   }
12432 };
12433 
12434 }  // namespace
12435 
12436 // Make sure that HttpNetworkTransaction passes on its priority to its
12437 // stream request on start.
TEST_P(HttpNetworkTransactionTest,SetStreamRequestPriorityOnStart)12438 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12439   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12440   HttpNetworkSessionPeer peer(session);
12441   FakeStreamFactory* fake_factory = new FakeStreamFactory();
12442   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
12443 
12444   HttpNetworkTransaction trans(LOW, session);
12445 
12446   ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12447 
12448   HttpRequestInfo request;
12449   TestCompletionCallback callback;
12450   EXPECT_EQ(ERR_IO_PENDING,
12451             trans.Start(&request, callback.callback(), BoundNetLog()));
12452 
12453   base::WeakPtr<FakeStreamRequest> fake_request =
12454       fake_factory->last_stream_request();
12455   ASSERT_TRUE(fake_request != NULL);
12456   EXPECT_EQ(LOW, fake_request->priority());
12457 }
12458 
12459 // Make sure that HttpNetworkTransaction passes on its priority
12460 // updates to its stream request.
TEST_P(HttpNetworkTransactionTest,SetStreamRequestPriority)12461 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12462   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12463   HttpNetworkSessionPeer peer(session);
12464   FakeStreamFactory* fake_factory = new FakeStreamFactory();
12465   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
12466 
12467   HttpNetworkTransaction trans(LOW, session);
12468 
12469   HttpRequestInfo request;
12470   TestCompletionCallback callback;
12471   EXPECT_EQ(ERR_IO_PENDING,
12472             trans.Start(&request, callback.callback(), BoundNetLog()));
12473 
12474   base::WeakPtr<FakeStreamRequest> fake_request =
12475       fake_factory->last_stream_request();
12476   ASSERT_TRUE(fake_request != NULL);
12477   EXPECT_EQ(LOW, fake_request->priority());
12478 
12479   trans.SetPriority(LOWEST);
12480   ASSERT_TRUE(fake_request != NULL);
12481   EXPECT_EQ(LOWEST, fake_request->priority());
12482 }
12483 
12484 // Make sure that HttpNetworkTransaction passes on its priority
12485 // updates to its stream.
TEST_P(HttpNetworkTransactionTest,SetStreamPriority)12486 TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12487   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12488   HttpNetworkSessionPeer peer(session);
12489   FakeStreamFactory* fake_factory = new FakeStreamFactory();
12490   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
12491 
12492   HttpNetworkTransaction trans(LOW, session);
12493 
12494   HttpRequestInfo request;
12495   TestCompletionCallback callback;
12496   EXPECT_EQ(ERR_IO_PENDING,
12497             trans.Start(&request, callback.callback(), BoundNetLog()));
12498 
12499   base::WeakPtr<FakeStreamRequest> fake_request =
12500       fake_factory->last_stream_request();
12501   ASSERT_TRUE(fake_request != NULL);
12502   base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12503   ASSERT_TRUE(fake_stream != NULL);
12504   EXPECT_EQ(LOW, fake_stream->priority());
12505 
12506   trans.SetPriority(LOWEST);
12507   EXPECT_EQ(LOWEST, fake_stream->priority());
12508 }
12509 
TEST_P(HttpNetworkTransactionTest,CreateWebSocketHandshakeStream)12510 TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12511   // The same logic needs to be tested for both ws: and wss: schemes, but this
12512   // test is already parameterised on NextProto, so it uses a loop to verify
12513   // that the different schemes work.
12514   std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12515   for (size_t i = 0; i < arraysize(test_cases); ++i) {
12516     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12517     HttpNetworkSessionPeer peer(session);
12518     FakeStreamFactory* fake_factory = new FakeStreamFactory();
12519     FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
12520     peer.SetHttpStreamFactoryForWebSocket(
12521         scoped_ptr<HttpStreamFactory>(fake_factory));
12522 
12523     HttpNetworkTransaction trans(LOW, session);
12524     trans.SetWebSocketHandshakeStreamCreateHelper(
12525         &websocket_stream_create_helper);
12526 
12527     HttpRequestInfo request;
12528     TestCompletionCallback callback;
12529     request.method = "GET";
12530     request.url = GURL(test_cases[i]);
12531 
12532     EXPECT_EQ(ERR_IO_PENDING,
12533               trans.Start(&request, callback.callback(), BoundNetLog()));
12534 
12535     base::WeakPtr<FakeStreamRequest> fake_request =
12536         fake_factory->last_stream_request();
12537     ASSERT_TRUE(fake_request != NULL);
12538     EXPECT_EQ(&websocket_stream_create_helper,
12539               fake_request->websocket_stream_create_helper());
12540   }
12541 }
12542 
12543 // Tests that when a used socket is returned to the SSL socket pool, it's closed
12544 // if the transport socket pool is stalled on the global socket limit.
TEST_P(HttpNetworkTransactionTest,CloseSSLSocketOnIdleForHttpRequest)12545 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12546   ClientSocketPoolManager::set_max_sockets_per_group(
12547       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12548   ClientSocketPoolManager::set_max_sockets_per_pool(
12549       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12550 
12551   // Set up SSL request.
12552 
12553   HttpRequestInfo ssl_request;
12554   ssl_request.method = "GET";
12555   ssl_request.url = GURL("https://www.google.com/");
12556 
12557   MockWrite ssl_writes[] = {
12558     MockWrite("GET / HTTP/1.1\r\n"
12559               "Host: www.google.com\r\n"
12560               "Connection: keep-alive\r\n\r\n"),
12561   };
12562   MockRead ssl_reads[] = {
12563     MockRead("HTTP/1.1 200 OK\r\n"),
12564     MockRead("Content-Length: 11\r\n\r\n"),
12565     MockRead("hello world"),
12566     MockRead(SYNCHRONOUS, OK),
12567   };
12568   StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12569                                     ssl_writes, arraysize(ssl_writes));
12570   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12571 
12572   SSLSocketDataProvider ssl(ASYNC, OK);
12573   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12574 
12575   // Set up HTTP request.
12576 
12577   HttpRequestInfo http_request;
12578   http_request.method = "GET";
12579   http_request.url = GURL("http://www.google.com/");
12580 
12581   MockWrite http_writes[] = {
12582     MockWrite("GET / HTTP/1.1\r\n"
12583               "Host: www.google.com\r\n"
12584               "Connection: keep-alive\r\n\r\n"),
12585   };
12586   MockRead http_reads[] = {
12587     MockRead("HTTP/1.1 200 OK\r\n"),
12588     MockRead("Content-Length: 7\r\n\r\n"),
12589     MockRead("falafel"),
12590     MockRead(SYNCHRONOUS, OK),
12591   };
12592   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12593                                      http_writes, arraysize(http_writes));
12594   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12595 
12596   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12597 
12598   // Start the SSL request.
12599   TestCompletionCallback ssl_callback;
12600   scoped_ptr<HttpTransaction> ssl_trans(
12601       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12602   ASSERT_EQ(ERR_IO_PENDING,
12603             ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12604             BoundNetLog()));
12605 
12606   // Start the HTTP request.  Pool should stall.
12607   TestCompletionCallback http_callback;
12608   scoped_ptr<HttpTransaction> http_trans(
12609       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12610   ASSERT_EQ(ERR_IO_PENDING,
12611             http_trans->Start(&http_request, http_callback.callback(),
12612                               BoundNetLog()));
12613   EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12614 
12615   // Wait for response from SSL request.
12616   ASSERT_EQ(OK, ssl_callback.WaitForResult());
12617   std::string response_data;
12618   ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12619   EXPECT_EQ("hello world", response_data);
12620 
12621   // The SSL socket should automatically be closed, so the HTTP request can
12622   // start.
12623   EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12624   ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12625 
12626   // The HTTP request can now complete.
12627   ASSERT_EQ(OK, http_callback.WaitForResult());
12628   ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12629   EXPECT_EQ("falafel", response_data);
12630 
12631   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12632 }
12633 
12634 // Tests that when a SSL connection is established but there's no corresponding
12635 // request that needs it, the new socket is closed if the transport socket pool
12636 // is stalled on the global socket limit.
TEST_P(HttpNetworkTransactionTest,CloseSSLSocketOnIdleForHttpRequest2)12637 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12638   ClientSocketPoolManager::set_max_sockets_per_group(
12639       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12640   ClientSocketPoolManager::set_max_sockets_per_pool(
12641       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12642 
12643   // Set up an ssl request.
12644 
12645   HttpRequestInfo ssl_request;
12646   ssl_request.method = "GET";
12647   ssl_request.url = GURL("https://www.foopy.com/");
12648 
12649   // No data will be sent on the SSL socket.
12650   StaticSocketDataProvider ssl_data;
12651   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12652 
12653   SSLSocketDataProvider ssl(ASYNC, OK);
12654   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12655 
12656   // Set up HTTP request.
12657 
12658   HttpRequestInfo http_request;
12659   http_request.method = "GET";
12660   http_request.url = GURL("http://www.google.com/");
12661 
12662   MockWrite http_writes[] = {
12663     MockWrite("GET / HTTP/1.1\r\n"
12664               "Host: www.google.com\r\n"
12665               "Connection: keep-alive\r\n\r\n"),
12666   };
12667   MockRead http_reads[] = {
12668     MockRead("HTTP/1.1 200 OK\r\n"),
12669     MockRead("Content-Length: 7\r\n\r\n"),
12670     MockRead("falafel"),
12671     MockRead(SYNCHRONOUS, OK),
12672   };
12673   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12674                                      http_writes, arraysize(http_writes));
12675   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12676 
12677   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12678 
12679   // Preconnect an SSL socket.  A preconnect is needed because connect jobs are
12680   // cancelled when a normal transaction is cancelled.
12681   net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12682   net::SSLConfig ssl_config;
12683   session->ssl_config_service()->GetSSLConfig(&ssl_config);
12684   http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12685                                          ssl_config, ssl_config);
12686   EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12687 
12688   // Start the HTTP request.  Pool should stall.
12689   TestCompletionCallback http_callback;
12690   scoped_ptr<HttpTransaction> http_trans(
12691       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12692   ASSERT_EQ(ERR_IO_PENDING,
12693             http_trans->Start(&http_request, http_callback.callback(),
12694                               BoundNetLog()));
12695   EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12696 
12697   // The SSL connection will automatically be closed once the connection is
12698   // established, to let the HTTP request start.
12699   ASSERT_EQ(OK, http_callback.WaitForResult());
12700   std::string response_data;
12701   ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12702   EXPECT_EQ("falafel", response_data);
12703 
12704   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12705 }
12706 
TEST_P(HttpNetworkTransactionTest,PostReadsErrorResponseAfterReset)12707 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
12708   ScopedVector<UploadElementReader> element_readers;
12709   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12710   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12711 
12712   HttpRequestInfo request;
12713   request.method = "POST";
12714   request.url = GURL("http://www.foo.com/");
12715   request.upload_data_stream = &upload_data_stream;
12716   request.load_flags = 0;
12717 
12718   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12719   scoped_ptr<HttpTransaction> trans(
12720       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12721   // Send headers successfully, but get an error while sending the body.
12722   MockWrite data_writes[] = {
12723     MockWrite("POST / HTTP/1.1\r\n"
12724               "Host: www.foo.com\r\n"
12725               "Connection: keep-alive\r\n"
12726               "Content-Length: 3\r\n\r\n"),
12727     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12728   };
12729 
12730   MockRead data_reads[] = {
12731     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12732     MockRead("hello world"),
12733     MockRead(SYNCHRONOUS, OK),
12734   };
12735   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12736                                 arraysize(data_writes));
12737   session_deps_.socket_factory->AddSocketDataProvider(&data);
12738 
12739   TestCompletionCallback callback;
12740 
12741   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12742   EXPECT_EQ(ERR_IO_PENDING, rv);
12743 
12744   rv = callback.WaitForResult();
12745   EXPECT_EQ(OK, rv);
12746 
12747   const HttpResponseInfo* response = trans->GetResponseInfo();
12748   ASSERT_TRUE(response != NULL);
12749 
12750   EXPECT_TRUE(response->headers.get() != NULL);
12751   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12752 
12753   std::string response_data;
12754   rv = ReadTransaction(trans.get(), &response_data);
12755   EXPECT_EQ(OK, rv);
12756   EXPECT_EQ("hello world", response_data);
12757 }
12758 
12759 // This test makes sure the retry logic doesn't trigger when reading an error
12760 // response from a server that rejected a POST with a CONNECTION_RESET.
TEST_P(HttpNetworkTransactionTest,PostReadsErrorResponseAfterResetOnReusedSocket)12761 TEST_P(HttpNetworkTransactionTest,
12762        PostReadsErrorResponseAfterResetOnReusedSocket) {
12763   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12764   MockWrite data_writes[] = {
12765     MockWrite("GET / HTTP/1.1\r\n"
12766               "Host: www.foo.com\r\n"
12767               "Connection: keep-alive\r\n\r\n"),
12768     MockWrite("POST / HTTP/1.1\r\n"
12769               "Host: www.foo.com\r\n"
12770               "Connection: keep-alive\r\n"
12771               "Content-Length: 3\r\n\r\n"),
12772     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12773   };
12774 
12775   MockRead data_reads[] = {
12776     MockRead("HTTP/1.1 200 Peachy\r\n"
12777              "Content-Length: 14\r\n\r\n"),
12778     MockRead("first response"),
12779     MockRead("HTTP/1.1 400 Not OK\r\n"
12780              "Content-Length: 15\r\n\r\n"),
12781     MockRead("second response"),
12782     MockRead(SYNCHRONOUS, OK),
12783   };
12784   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12785                                 arraysize(data_writes));
12786   session_deps_.socket_factory->AddSocketDataProvider(&data);
12787 
12788   TestCompletionCallback callback;
12789   HttpRequestInfo request1;
12790   request1.method = "GET";
12791   request1.url = GURL("http://www.foo.com/");
12792   request1.load_flags = 0;
12793 
12794   scoped_ptr<HttpTransaction> trans1(
12795       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12796   int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
12797   EXPECT_EQ(ERR_IO_PENDING, rv);
12798 
12799   rv = callback.WaitForResult();
12800   EXPECT_EQ(OK, rv);
12801 
12802   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12803   ASSERT_TRUE(response1 != NULL);
12804 
12805   EXPECT_TRUE(response1->headers.get() != NULL);
12806   EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
12807 
12808   std::string response_data1;
12809   rv = ReadTransaction(trans1.get(), &response_data1);
12810   EXPECT_EQ(OK, rv);
12811   EXPECT_EQ("first response", response_data1);
12812   // Delete the transaction to release the socket back into the socket pool.
12813   trans1.reset();
12814 
12815   ScopedVector<UploadElementReader> element_readers;
12816   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12817   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12818 
12819   HttpRequestInfo request2;
12820   request2.method = "POST";
12821   request2.url = GURL("http://www.foo.com/");
12822   request2.upload_data_stream = &upload_data_stream;
12823   request2.load_flags = 0;
12824 
12825   scoped_ptr<HttpTransaction> trans2(
12826       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12827   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
12828   EXPECT_EQ(ERR_IO_PENDING, rv);
12829 
12830   rv = callback.WaitForResult();
12831   EXPECT_EQ(OK, rv);
12832 
12833   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
12834   ASSERT_TRUE(response2 != NULL);
12835 
12836   EXPECT_TRUE(response2->headers.get() != NULL);
12837   EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
12838 
12839   std::string response_data2;
12840   rv = ReadTransaction(trans2.get(), &response_data2);
12841   EXPECT_EQ(OK, rv);
12842   EXPECT_EQ("second response", response_data2);
12843 }
12844 
TEST_P(HttpNetworkTransactionTest,PostReadsErrorResponseAfterResetPartialBodySent)12845 TEST_P(HttpNetworkTransactionTest,
12846        PostReadsErrorResponseAfterResetPartialBodySent) {
12847   ScopedVector<UploadElementReader> element_readers;
12848   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12849   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12850 
12851   HttpRequestInfo request;
12852   request.method = "POST";
12853   request.url = GURL("http://www.foo.com/");
12854   request.upload_data_stream = &upload_data_stream;
12855   request.load_flags = 0;
12856 
12857   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12858   scoped_ptr<HttpTransaction> trans(
12859       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12860   // Send headers successfully, but get an error while sending the body.
12861   MockWrite data_writes[] = {
12862     MockWrite("POST / HTTP/1.1\r\n"
12863               "Host: www.foo.com\r\n"
12864               "Connection: keep-alive\r\n"
12865               "Content-Length: 3\r\n\r\n"
12866               "fo"),
12867     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12868   };
12869 
12870   MockRead data_reads[] = {
12871     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12872     MockRead("hello world"),
12873     MockRead(SYNCHRONOUS, OK),
12874   };
12875   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12876                                 arraysize(data_writes));
12877   session_deps_.socket_factory->AddSocketDataProvider(&data);
12878 
12879   TestCompletionCallback callback;
12880 
12881   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12882   EXPECT_EQ(ERR_IO_PENDING, rv);
12883 
12884   rv = callback.WaitForResult();
12885   EXPECT_EQ(OK, rv);
12886 
12887   const HttpResponseInfo* response = trans->GetResponseInfo();
12888   ASSERT_TRUE(response != NULL);
12889 
12890   EXPECT_TRUE(response->headers.get() != NULL);
12891   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12892 
12893   std::string response_data;
12894   rv = ReadTransaction(trans.get(), &response_data);
12895   EXPECT_EQ(OK, rv);
12896   EXPECT_EQ("hello world", response_data);
12897 }
12898 
12899 // This tests the more common case than the previous test, where headers and
12900 // body are not merged into a single request.
TEST_P(HttpNetworkTransactionTest,ChunkedPostReadsErrorResponseAfterReset)12901 TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
12902   ScopedVector<UploadElementReader> element_readers;
12903   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12904   UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
12905 
12906   HttpRequestInfo request;
12907   request.method = "POST";
12908   request.url = GURL("http://www.foo.com/");
12909   request.upload_data_stream = &upload_data_stream;
12910   request.load_flags = 0;
12911 
12912   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12913   scoped_ptr<HttpTransaction> trans(
12914       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12915   // Send headers successfully, but get an error while sending the body.
12916   MockWrite data_writes[] = {
12917     MockWrite("POST / HTTP/1.1\r\n"
12918               "Host: www.foo.com\r\n"
12919               "Connection: keep-alive\r\n"
12920               "Transfer-Encoding: chunked\r\n\r\n"),
12921     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12922   };
12923 
12924   MockRead data_reads[] = {
12925     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12926     MockRead("hello world"),
12927     MockRead(SYNCHRONOUS, OK),
12928   };
12929   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12930                                 arraysize(data_writes));
12931   session_deps_.socket_factory->AddSocketDataProvider(&data);
12932 
12933   TestCompletionCallback callback;
12934 
12935   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12936   EXPECT_EQ(ERR_IO_PENDING, rv);
12937   // Make sure the headers are sent before adding a chunk.  This ensures that
12938   // they can't be merged with the body in a single send.  Not currently
12939   // necessary since a chunked body is never merged with headers, but this makes
12940   // the test more future proof.
12941   base::RunLoop().RunUntilIdle();
12942 
12943   upload_data_stream.AppendChunk("last chunk", 10, true);
12944 
12945   rv = callback.WaitForResult();
12946   EXPECT_EQ(OK, rv);
12947 
12948   const HttpResponseInfo* response = trans->GetResponseInfo();
12949   ASSERT_TRUE(response != NULL);
12950 
12951   EXPECT_TRUE(response->headers.get() != NULL);
12952   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12953 
12954   std::string response_data;
12955   rv = ReadTransaction(trans.get(), &response_data);
12956   EXPECT_EQ(OK, rv);
12957   EXPECT_EQ("hello world", response_data);
12958 }
12959 
TEST_P(HttpNetworkTransactionTest,PostReadsErrorResponseAfterResetAnd100)12960 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
12961   ScopedVector<UploadElementReader> element_readers;
12962   element_readers.push_back(new UploadBytesElementReader("foo", 3));
12963   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
12964 
12965   HttpRequestInfo request;
12966   request.method = "POST";
12967   request.url = GURL("http://www.foo.com/");
12968   request.upload_data_stream = &upload_data_stream;
12969   request.load_flags = 0;
12970 
12971   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12972   scoped_ptr<HttpTransaction> trans(
12973       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12974 
12975   MockWrite data_writes[] = {
12976     MockWrite("POST / HTTP/1.1\r\n"
12977               "Host: www.foo.com\r\n"
12978               "Connection: keep-alive\r\n"
12979               "Content-Length: 3\r\n\r\n"),
12980     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12981   };
12982 
12983   MockRead data_reads[] = {
12984     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
12985     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12986     MockRead("hello world"),
12987     MockRead(SYNCHRONOUS, OK),
12988   };
12989   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12990                                 arraysize(data_writes));
12991   session_deps_.socket_factory->AddSocketDataProvider(&data);
12992 
12993   TestCompletionCallback callback;
12994 
12995   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12996   EXPECT_EQ(ERR_IO_PENDING, rv);
12997 
12998   rv = callback.WaitForResult();
12999   EXPECT_EQ(OK, rv);
13000 
13001   const HttpResponseInfo* response = trans->GetResponseInfo();
13002   ASSERT_TRUE(response != NULL);
13003 
13004   EXPECT_TRUE(response->headers.get() != NULL);
13005   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13006 
13007   std::string response_data;
13008   rv = ReadTransaction(trans.get(), &response_data);
13009   EXPECT_EQ(OK, rv);
13010   EXPECT_EQ("hello world", response_data);
13011 }
13012 
TEST_P(HttpNetworkTransactionTest,PostIgnoresNonErrorResponseAfterReset)13013 TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13014   ScopedVector<UploadElementReader> element_readers;
13015   element_readers.push_back(new UploadBytesElementReader("foo", 3));
13016   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13017 
13018   HttpRequestInfo request;
13019   request.method = "POST";
13020   request.url = GURL("http://www.foo.com/");
13021   request.upload_data_stream = &upload_data_stream;
13022   request.load_flags = 0;
13023 
13024   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13025   scoped_ptr<HttpTransaction> trans(
13026       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13027   // Send headers successfully, but get an error while sending the body.
13028   MockWrite data_writes[] = {
13029     MockWrite("POST / HTTP/1.1\r\n"
13030               "Host: www.foo.com\r\n"
13031               "Connection: keep-alive\r\n"
13032               "Content-Length: 3\r\n\r\n"),
13033     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13034   };
13035 
13036   MockRead data_reads[] = {
13037     MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13038     MockRead("hello world"),
13039     MockRead(SYNCHRONOUS, OK),
13040   };
13041   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13042                                 arraysize(data_writes));
13043   session_deps_.socket_factory->AddSocketDataProvider(&data);
13044 
13045   TestCompletionCallback callback;
13046 
13047   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13048   EXPECT_EQ(ERR_IO_PENDING, rv);
13049 
13050   rv = callback.WaitForResult();
13051   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13052 
13053   const HttpResponseInfo* response = trans->GetResponseInfo();
13054   EXPECT_TRUE(response == NULL);
13055 }
13056 
TEST_P(HttpNetworkTransactionTest,PostIgnoresNonErrorResponseAfterResetAnd100)13057 TEST_P(HttpNetworkTransactionTest,
13058        PostIgnoresNonErrorResponseAfterResetAnd100) {
13059   ScopedVector<UploadElementReader> element_readers;
13060   element_readers.push_back(new UploadBytesElementReader("foo", 3));
13061   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13062 
13063   HttpRequestInfo request;
13064   request.method = "POST";
13065   request.url = GURL("http://www.foo.com/");
13066   request.upload_data_stream = &upload_data_stream;
13067   request.load_flags = 0;
13068 
13069   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13070   scoped_ptr<HttpTransaction> trans(
13071       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13072   // Send headers successfully, but get an error while sending the body.
13073   MockWrite data_writes[] = {
13074     MockWrite("POST / HTTP/1.1\r\n"
13075               "Host: www.foo.com\r\n"
13076               "Connection: keep-alive\r\n"
13077               "Content-Length: 3\r\n\r\n"),
13078     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13079   };
13080 
13081   MockRead data_reads[] = {
13082     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13083     MockRead("HTTP/1.0 302 Redirect\r\n"),
13084     MockRead("Location: http://somewhere-else.com/\r\n"),
13085     MockRead("Content-Length: 0\r\n\r\n"),
13086     MockRead(SYNCHRONOUS, OK),
13087   };
13088   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13089                                 arraysize(data_writes));
13090   session_deps_.socket_factory->AddSocketDataProvider(&data);
13091 
13092   TestCompletionCallback callback;
13093 
13094   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13095   EXPECT_EQ(ERR_IO_PENDING, rv);
13096 
13097   rv = callback.WaitForResult();
13098   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13099 
13100   const HttpResponseInfo* response = trans->GetResponseInfo();
13101   EXPECT_TRUE(response == NULL);
13102 }
13103 
TEST_P(HttpNetworkTransactionTest,PostIgnoresHttp09ResponseAfterReset)13104 TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13105   ScopedVector<UploadElementReader> element_readers;
13106   element_readers.push_back(new UploadBytesElementReader("foo", 3));
13107   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13108 
13109   HttpRequestInfo request;
13110   request.method = "POST";
13111   request.url = GURL("http://www.foo.com/");
13112   request.upload_data_stream = &upload_data_stream;
13113   request.load_flags = 0;
13114 
13115   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13116   scoped_ptr<HttpTransaction> trans(
13117       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13118   // Send headers successfully, but get an error while sending the body.
13119   MockWrite data_writes[] = {
13120     MockWrite("POST / HTTP/1.1\r\n"
13121               "Host: www.foo.com\r\n"
13122               "Connection: keep-alive\r\n"
13123               "Content-Length: 3\r\n\r\n"),
13124     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13125   };
13126 
13127   MockRead data_reads[] = {
13128     MockRead("HTTP 0.9 rocks!"),
13129     MockRead(SYNCHRONOUS, OK),
13130   };
13131   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13132                                 arraysize(data_writes));
13133   session_deps_.socket_factory->AddSocketDataProvider(&data);
13134 
13135   TestCompletionCallback callback;
13136 
13137   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13138   EXPECT_EQ(ERR_IO_PENDING, rv);
13139 
13140   rv = callback.WaitForResult();
13141   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13142 
13143   const HttpResponseInfo* response = trans->GetResponseInfo();
13144   EXPECT_TRUE(response == NULL);
13145 }
13146 
TEST_P(HttpNetworkTransactionTest,PostIgnoresPartial400HeadersAfterReset)13147 TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13148   ScopedVector<UploadElementReader> element_readers;
13149   element_readers.push_back(new UploadBytesElementReader("foo", 3));
13150   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
13151 
13152   HttpRequestInfo request;
13153   request.method = "POST";
13154   request.url = GURL("http://www.foo.com/");
13155   request.upload_data_stream = &upload_data_stream;
13156   request.load_flags = 0;
13157 
13158   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13159   scoped_ptr<HttpTransaction> trans(
13160       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13161   // Send headers successfully, but get an error while sending the body.
13162   MockWrite data_writes[] = {
13163     MockWrite("POST / HTTP/1.1\r\n"
13164               "Host: www.foo.com\r\n"
13165               "Connection: keep-alive\r\n"
13166               "Content-Length: 3\r\n\r\n"),
13167     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13168   };
13169 
13170   MockRead data_reads[] = {
13171     MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13172     MockRead(SYNCHRONOUS, OK),
13173   };
13174   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13175                                 arraysize(data_writes));
13176   session_deps_.socket_factory->AddSocketDataProvider(&data);
13177 
13178   TestCompletionCallback callback;
13179 
13180   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13181   EXPECT_EQ(ERR_IO_PENDING, rv);
13182 
13183   rv = callback.WaitForResult();
13184   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13185 
13186   const HttpResponseInfo* response = trans->GetResponseInfo();
13187   EXPECT_TRUE(response == NULL);
13188 }
13189 
13190 }  // namespace net
13191