1// Copyright (c) 2011 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 "build/build_config.h"
6
7#if defined(OS_WIN)
8#include <shlobj.h>
9#include <windows.h>
10#endif
11
12#include <algorithm>
13#include <string>
14
15#include "base/file_util.h"
16#include "base/format_macros.h"
17#include "base/message_loop.h"
18#include "base/path_service.h"
19#include "base/process_util.h"
20#include "base/string_number_conversions.h"
21#include "base/string_piece.h"
22#include "base/string_util.h"
23#include "base/stringprintf.h"
24#include "base/utf_string_conversions.h"
25#include "net/base/cookie_monster.h"
26#include "net/base/cookie_policy.h"
27#include "net/base/load_flags.h"
28#include "net/base/mock_host_resolver.h"
29#include "net/base/net_errors.h"
30#include "net/base/net_log.h"
31#include "net/base/net_log_unittest.h"
32#include "net/base/net_module.h"
33#include "net/base/net_util.h"
34#include "net/base/ssl_connection_status_flags.h"
35#include "net/base/upload_data.h"
36#include "net/disk_cache/disk_cache.h"
37#include "net/ftp/ftp_network_layer.h"
38#include "net/http/http_cache.h"
39#include "net/http/http_network_layer.h"
40#include "net/http/http_request_headers.h"
41#include "net/http/http_response_headers.h"
42#include "net/proxy/proxy_service.h"
43#include "net/test/test_server.h"
44#include "net/url_request/url_request.h"
45#include "net/url_request/url_request_file_dir_job.h"
46#include "net/url_request/url_request_http_job.h"
47#include "net/url_request/url_request_test_job.h"
48#include "net/url_request/url_request_test_util.h"
49#include "testing/gtest/include/gtest/gtest.h"
50#include "testing/platform_test.h"
51
52using base::Time;
53
54// We don't need a refcount because we are guaranteed the test will not proceed
55// until its task is run.
56namespace net {
57class BlockingNetworkDelegate;
58}  // namespace net
59DISABLE_RUNNABLE_METHOD_REFCOUNT(net::BlockingNetworkDelegate);
60
61namespace net {
62
63namespace {
64
65const string16 kChrome(ASCIIToUTF16("chrome"));
66const string16 kSecret(ASCIIToUTF16("secret"));
67const string16 kUser(ASCIIToUTF16("user"));
68
69base::StringPiece TestNetResourceProvider(int key) {
70  return "header";
71}
72
73// Do a case-insensitive search through |haystack| for |needle|.
74bool ContainsString(const std::string& haystack, const char* needle) {
75  std::string::const_iterator it =
76      std::search(haystack.begin(),
77                  haystack.end(),
78                  needle,
79                  needle + strlen(needle),
80                  base::CaseInsensitiveCompare<char>());
81  return it != haystack.end();
82}
83
84void FillBuffer(char* buffer, size_t len) {
85  static bool called = false;
86  if (!called) {
87    called = true;
88    int seed = static_cast<int>(Time::Now().ToInternalValue());
89    srand(seed);
90  }
91
92  for (size_t i = 0; i < len; i++) {
93    buffer[i] = static_cast<char>(rand());
94    if (!buffer[i])
95      buffer[i] = 'g';
96  }
97}
98
99scoped_refptr<UploadData> CreateSimpleUploadData(const char* data) {
100  scoped_refptr<UploadData> upload(new UploadData);
101  upload->AppendBytes(data, strlen(data));
102  return upload;
103}
104
105// Verify that the SSLInfo of a successful SSL connection has valid values.
106void CheckSSLInfo(const SSLInfo& ssl_info) {
107  // Allow ChromeFrame fake SSLInfo to get through.
108  if (ssl_info.cert.get() &&
109      ssl_info.cert.get()->issuer().GetDisplayName() == "Chrome Internal") {
110    // -1 means unknown.
111    EXPECT_EQ(ssl_info.security_bits, -1);
112    return;
113  }
114
115  // -1 means unknown.  0 means no encryption.
116  EXPECT_GT(ssl_info.security_bits, 0);
117
118  // The cipher suite TLS_NULL_WITH_NULL_NULL (0) must not be negotiated.
119  int cipher_suite = SSLConnectionStatusToCipherSuite(
120      ssl_info.connection_status);
121  EXPECT_NE(0, cipher_suite);
122}
123
124}  // namespace
125
126// A network delegate that blocks requests, optionally cancelling or redirecting
127// them.
128class BlockingNetworkDelegate : public TestNetworkDelegate {
129 public:
130  BlockingNetworkDelegate() : callback_retval_(net::OK) {}
131
132  void set_callback_retval(int retval) { callback_retval_ = retval; }
133  void set_redirect_url(const GURL& url) { redirect_url_ = url; }
134
135 private:
136  // TestNetworkDelegate:
137  virtual int OnBeforeURLRequest(net::URLRequest* request,
138                                 net::CompletionCallback* callback,
139                                 GURL* new_url) {
140    TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url);
141
142    if (!redirect_url_.is_empty())
143      *new_url = redirect_url_;
144    MessageLoop::current()->PostTask(FROM_HERE,
145        NewRunnableMethod(this, &BlockingNetworkDelegate::DoCallback,
146                          callback));
147    return net::ERR_IO_PENDING;
148  }
149
150  void DoCallback(net::CompletionCallback* callback) {
151    callback->Run(callback_retval_);
152  }
153
154  int callback_retval_;
155  GURL redirect_url_;
156};
157
158// Inherit PlatformTest since we require the autorelease pool on Mac OS X.f
159class URLRequestTest : public PlatformTest {
160 public:
161  static void SetUpTestCase() {
162    URLRequest::AllowFileAccess();
163  }
164};
165
166class URLRequestTestHTTP : public URLRequestTest {
167 public:
168  URLRequestTestHTTP()
169      : test_server_(TestServer::TYPE_HTTP,
170                     FilePath(FILE_PATH_LITERAL(
171                                  "net/data/url_request_unittest"))) {
172  }
173
174 protected:
175  void HTTPUploadDataOperationTest(const std::string& method) {
176    const int kMsgSize = 20000;  // multiple of 10
177    const int kIterations = 50;
178    char *uploadBytes = new char[kMsgSize+1];
179    char *ptr = uploadBytes;
180    char marker = 'a';
181    for (int idx = 0; idx < kMsgSize/10; idx++) {
182      memcpy(ptr, "----------", 10);
183      ptr += 10;
184      if (idx % 100 == 0) {
185        ptr--;
186        *ptr++ = marker;
187        if (++marker > 'z')
188          marker = 'a';
189      }
190    }
191    uploadBytes[kMsgSize] = '\0';
192
193    scoped_refptr<URLRequestContext> context(new TestURLRequestContext());
194
195    for (int i = 0; i < kIterations; ++i) {
196      TestDelegate d;
197      URLRequest r(test_server_.GetURL("echo"), &d);
198      r.set_context(context);
199      r.set_method(method.c_str());
200
201      r.AppendBytesToUpload(uploadBytes, kMsgSize);
202
203      r.Start();
204      EXPECT_TRUE(r.is_pending());
205
206      MessageLoop::current()->Run();
207
208      ASSERT_EQ(1, d.response_started_count()) << "request failed: " <<
209          (int) r.status().status() << ", os error: " << r.status().os_error();
210
211      EXPECT_FALSE(d.received_data_before_response());
212      EXPECT_EQ(uploadBytes, d.data_received());
213      EXPECT_EQ(memcmp(uploadBytes, d.data_received().c_str(), kMsgSize), 0);
214      EXPECT_EQ(d.data_received().compare(uploadBytes), 0);
215    }
216    delete[] uploadBytes;
217  }
218
219  void AddChunksToUpload(TestURLRequest* r) {
220    r->AppendChunkToUpload("a", 1, false);
221    r->AppendChunkToUpload("bcd", 3, false);
222    r->AppendChunkToUpload("this is a longer chunk than before.", 35, false);
223    r->AppendChunkToUpload("\r\n\r\n", 4, false);
224    r->AppendChunkToUpload("0", 1, false);
225    r->AppendChunkToUpload("2323", 4, true);
226  }
227
228  void VerifyReceivedDataMatchesChunks(TestURLRequest* r, TestDelegate* d) {
229    // This should match the chunks sent by AddChunksToUpload().
230    const char* expected_data =
231        "abcdthis is a longer chunk than before.\r\n\r\n02323";
232
233    ASSERT_EQ(1, d->response_started_count()) << "request failed: " <<
234        (int) r->status().status() << ", os error: " << r->status().os_error();
235
236    EXPECT_FALSE(d->received_data_before_response());
237
238    ASSERT_EQ(strlen(expected_data), static_cast<size_t>(d->bytes_received()));
239    EXPECT_EQ(0, memcmp(d->data_received().c_str(), expected_data,
240                        strlen(expected_data)));
241  }
242
243  TestServer test_server_;
244};
245
246// In this unit test, we're using the HTTPTestServer as a proxy server and
247// issuing a CONNECT request with the magic host name "www.redirect.com".
248// The HTTPTestServer will return a 302 response, which we should not
249// follow.
250TEST_F(URLRequestTestHTTP, ProxyTunnelRedirectTest) {
251  ASSERT_TRUE(test_server_.Start());
252
253  TestDelegate d;
254  {
255    URLRequest r(GURL("https://www.redirect.com/"), &d);
256    r.set_context(
257        new TestURLRequestContext(test_server_.host_port_pair().ToString()));
258
259    r.Start();
260    EXPECT_TRUE(r.is_pending());
261
262    MessageLoop::current()->Run();
263
264    EXPECT_EQ(URLRequestStatus::FAILED, r.status().status());
265    EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r.status().os_error());
266    EXPECT_EQ(1, d.response_started_count());
267    // We should not have followed the redirect.
268    EXPECT_EQ(0, d.received_redirect_count());
269  }
270}
271
272// This is the same as the previous test, but checks that the network delegate
273// registers the error.
274TEST_F(URLRequestTestHTTP, NetworkDelegateTunnelConnectionFailed) {
275  ASSERT_TRUE(test_server_.Start());
276
277  TestDelegate d;
278  {
279    TestNetworkDelegate network_delegate;  // must outlive URLRequest
280    URLRequest r(GURL("https://www.redirect.com/"), &d);
281    scoped_refptr<TestURLRequestContext> context(
282        new TestURLRequestContext(test_server_.host_port_pair().ToString()));
283    context->set_network_delegate(&network_delegate);
284    r.set_context(context);
285
286    r.Start();
287    EXPECT_TRUE(r.is_pending());
288
289    MessageLoop::current()->Run();
290
291    EXPECT_EQ(URLRequestStatus::FAILED, r.status().status());
292    EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r.status().os_error());
293    EXPECT_EQ(1, d.response_started_count());
294    // We should not have followed the redirect.
295    EXPECT_EQ(0, d.received_redirect_count());
296
297    EXPECT_EQ(1, network_delegate.error_count());
298    EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED,
299              network_delegate.last_os_error());
300  }
301}
302
303// Tests that the network delegate can block and cancel a request.
304TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequest) {
305  ASSERT_TRUE(test_server_.Start());
306
307  TestDelegate d;
308  BlockingNetworkDelegate network_delegate;
309  network_delegate.set_callback_retval(ERR_EMPTY_RESPONSE);
310
311  {
312    TestURLRequest r(test_server_.GetURL(""), &d);
313    scoped_refptr<TestURLRequestContext> context(
314        new TestURLRequestContext(test_server_.host_port_pair().ToString()));
315    context->set_network_delegate(&network_delegate);
316    r.set_context(context);
317
318    r.Start();
319    MessageLoop::current()->Run();
320
321    EXPECT_EQ(URLRequestStatus::FAILED, r.status().status());
322    EXPECT_EQ(ERR_EMPTY_RESPONSE, r.status().os_error());
323    EXPECT_EQ(1, network_delegate.created_requests());
324    EXPECT_EQ(0, network_delegate.destroyed_requests());
325  }
326  EXPECT_EQ(1, network_delegate.destroyed_requests());
327}
328
329// Tests that the network delegate can block and redirect a request to a new
330// URL.
331TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequest) {
332  ASSERT_TRUE(test_server_.Start());
333
334  TestDelegate d;
335  BlockingNetworkDelegate network_delegate;
336  GURL redirect_url(test_server_.GetURL("simple.html"));
337  network_delegate.set_redirect_url(redirect_url);
338
339  {
340    GURL original_url(test_server_.GetURL("empty.html"));
341    TestURLRequest r(original_url, &d);
342    scoped_refptr<TestURLRequestContext> context(
343        new TestURLRequestContext(test_server_.host_port_pair().ToString()));
344    context->set_network_delegate(&network_delegate);
345    r.set_context(context);
346
347    r.Start();
348    MessageLoop::current()->Run();
349
350    EXPECT_EQ(URLRequestStatus::SUCCESS, r.status().status());
351    EXPECT_EQ(0, r.status().os_error());
352    EXPECT_EQ(redirect_url, r.url());
353    EXPECT_EQ(original_url, r.original_url());
354    EXPECT_EQ(2U, r.url_chain().size());
355    EXPECT_EQ(1, network_delegate.created_requests());
356    EXPECT_EQ(0, network_delegate.destroyed_requests());
357  }
358  EXPECT_EQ(1, network_delegate.destroyed_requests());
359}
360
361// In this unit test, we're using the HTTPTestServer as a proxy server and
362// issuing a CONNECT request with the magic host name "www.server-auth.com".
363// The HTTPTestServer will return a 401 response, which we should balk at.
364TEST_F(URLRequestTestHTTP, UnexpectedServerAuthTest) {
365  ASSERT_TRUE(test_server_.Start());
366
367  TestDelegate d;
368  {
369    URLRequest r(GURL("https://www.server-auth.com/"), &d);
370    r.set_context(
371        new TestURLRequestContext(test_server_.host_port_pair().ToString()));
372
373    r.Start();
374    EXPECT_TRUE(r.is_pending());
375
376    MessageLoop::current()->Run();
377
378    EXPECT_EQ(URLRequestStatus::FAILED, r.status().status());
379    EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r.status().os_error());
380  }
381}
382
383TEST_F(URLRequestTestHTTP, GetTest_NoCache) {
384  ASSERT_TRUE(test_server_.Start());
385
386  TestDelegate d;
387  {
388    TestURLRequest r(test_server_.GetURL(""), &d);
389
390    r.Start();
391    EXPECT_TRUE(r.is_pending());
392
393    MessageLoop::current()->Run();
394
395    EXPECT_EQ(1, d.response_started_count());
396    EXPECT_FALSE(d.received_data_before_response());
397    EXPECT_NE(0, d.bytes_received());
398    EXPECT_EQ(test_server_.host_port_pair().host(),
399              r.GetSocketAddress().host());
400    EXPECT_EQ(test_server_.host_port_pair().port(),
401              r.GetSocketAddress().port());
402
403    // TODO(eroman): Add back the NetLog tests...
404  }
405}
406
407TEST_F(URLRequestTestHTTP, GetTest) {
408  ASSERT_TRUE(test_server_.Start());
409
410  TestDelegate d;
411  {
412    TestURLRequest r(test_server_.GetURL(""), &d);
413
414    r.Start();
415    EXPECT_TRUE(r.is_pending());
416
417    MessageLoop::current()->Run();
418
419    EXPECT_EQ(1, d.response_started_count());
420    EXPECT_FALSE(d.received_data_before_response());
421    EXPECT_NE(0, d.bytes_received());
422    EXPECT_EQ(test_server_.host_port_pair().host(),
423              r.GetSocketAddress().host());
424    EXPECT_EQ(test_server_.host_port_pair().port(),
425              r.GetSocketAddress().port());
426  }
427}
428
429TEST_F(URLRequestTestHTTP, HTTPSToHTTPRedirectNoRefererTest) {
430  ASSERT_TRUE(test_server_.Start());
431
432  TestServer https_test_server(
433      TestServer::TYPE_HTTPS, FilePath(FILE_PATH_LITERAL("net/data/ssl")));
434  ASSERT_TRUE(https_test_server.Start());
435
436  // An https server is sent a request with an https referer,
437  // and responds with a redirect to an http url. The http
438  // server should not be sent the referer.
439  GURL http_destination = test_server_.GetURL("");
440  TestDelegate d;
441  TestURLRequest req(https_test_server.GetURL(
442      "server-redirect?" + http_destination.spec()), &d);
443  req.set_referrer("https://www.referrer.com/");
444  req.Start();
445  MessageLoop::current()->Run();
446
447  EXPECT_EQ(1, d.response_started_count());
448  EXPECT_EQ(1, d.received_redirect_count());
449  EXPECT_EQ(http_destination, req.url());
450  EXPECT_EQ(std::string(), req.referrer());
451}
452
453TEST_F(URLRequestTestHTTP, MultipleRedirectTest) {
454  ASSERT_TRUE(test_server_.Start());
455
456  GURL destination_url = test_server_.GetURL("");
457  GURL middle_redirect_url = test_server_.GetURL(
458      "server-redirect?" + destination_url.spec());
459  GURL original_url = test_server_.GetURL(
460      "server-redirect?" + middle_redirect_url.spec());
461  TestDelegate d;
462  TestURLRequest req(original_url, &d);
463  req.Start();
464  MessageLoop::current()->Run();
465
466  EXPECT_EQ(1, d.response_started_count());
467  EXPECT_EQ(2, d.received_redirect_count());
468  EXPECT_EQ(destination_url, req.url());
469  EXPECT_EQ(original_url, req.original_url());
470  ASSERT_EQ(3U, req.url_chain().size());
471  EXPECT_EQ(original_url, req.url_chain()[0]);
472  EXPECT_EQ(middle_redirect_url, req.url_chain()[1]);
473  EXPECT_EQ(destination_url, req.url_chain()[2]);
474}
475
476class HTTPSRequestTest : public testing::Test {
477};
478
479TEST_F(HTTPSRequestTest, HTTPSGetTest) {
480  TestServer test_server(TestServer::TYPE_HTTPS,
481                              FilePath(FILE_PATH_LITERAL("net/data/ssl")));
482  ASSERT_TRUE(test_server.Start());
483
484  TestDelegate d;
485  {
486    TestURLRequest r(test_server.GetURL(""), &d);
487
488    r.Start();
489    EXPECT_TRUE(r.is_pending());
490
491    MessageLoop::current()->Run();
492
493    EXPECT_EQ(1, d.response_started_count());
494    EXPECT_FALSE(d.received_data_before_response());
495    EXPECT_NE(0, d.bytes_received());
496    CheckSSLInfo(r.ssl_info());
497    EXPECT_EQ(test_server.host_port_pair().host(),
498              r.GetSocketAddress().host());
499    EXPECT_EQ(test_server.host_port_pair().port(),
500              r.GetSocketAddress().port());
501  }
502}
503
504TEST_F(HTTPSRequestTest, HTTPSMismatchedTest) {
505  TestServer::HTTPSOptions https_options(
506      TestServer::HTTPSOptions::CERT_MISMATCHED_NAME);
507  TestServer test_server(https_options,
508                              FilePath(FILE_PATH_LITERAL("net/data/ssl")));
509  ASSERT_TRUE(test_server.Start());
510
511  bool err_allowed = true;
512  for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) {
513    TestDelegate d;
514    {
515      d.set_allow_certificate_errors(err_allowed);
516      TestURLRequest r(test_server.GetURL(""), &d);
517
518      r.Start();
519      EXPECT_TRUE(r.is_pending());
520
521      MessageLoop::current()->Run();
522
523      EXPECT_EQ(1, d.response_started_count());
524      EXPECT_FALSE(d.received_data_before_response());
525      EXPECT_TRUE(d.have_certificate_errors());
526      if (err_allowed) {
527        EXPECT_NE(0, d.bytes_received());
528        CheckSSLInfo(r.ssl_info());
529      } else {
530        EXPECT_EQ(0, d.bytes_received());
531      }
532    }
533  }
534}
535
536TEST_F(HTTPSRequestTest, HTTPSExpiredTest) {
537  TestServer::HTTPSOptions https_options(
538      TestServer::HTTPSOptions::CERT_EXPIRED);
539  TestServer test_server(https_options,
540                              FilePath(FILE_PATH_LITERAL("net/data/ssl")));
541  ASSERT_TRUE(test_server.Start());
542
543  // Iterate from false to true, just so that we do the opposite of the
544  // previous test in order to increase test coverage.
545  bool err_allowed = false;
546  for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) {
547    TestDelegate d;
548    {
549      d.set_allow_certificate_errors(err_allowed);
550      TestURLRequest r(test_server.GetURL(""), &d);
551
552      r.Start();
553      EXPECT_TRUE(r.is_pending());
554
555      MessageLoop::current()->Run();
556
557      EXPECT_EQ(1, d.response_started_count());
558      EXPECT_FALSE(d.received_data_before_response());
559      EXPECT_TRUE(d.have_certificate_errors());
560      if (err_allowed) {
561        EXPECT_NE(0, d.bytes_received());
562        CheckSSLInfo(r.ssl_info());
563      } else {
564        EXPECT_EQ(0, d.bytes_received());
565      }
566    }
567  }
568}
569
570namespace {
571
572class SSLClientAuthTestDelegate : public TestDelegate {
573 public:
574  SSLClientAuthTestDelegate() : on_certificate_requested_count_(0) {
575  }
576  virtual void OnCertificateRequested(
577      URLRequest* request,
578      SSLCertRequestInfo* cert_request_info) {
579    on_certificate_requested_count_++;
580    MessageLoop::current()->Quit();
581  }
582  int on_certificate_requested_count() {
583    return on_certificate_requested_count_;
584  }
585 private:
586  int on_certificate_requested_count_;
587};
588
589}  // namespace
590
591// TODO(davidben): Test the rest of the code. Specifically,
592// - Filtering which certificates to select.
593// - Sending a certificate back.
594// - Getting a certificate request in an SSL renegotiation sending the
595//   HTTP request.
596TEST_F(HTTPSRequestTest, ClientAuthTest) {
597  TestServer::HTTPSOptions https_options;
598  https_options.request_client_certificate = true;
599  TestServer test_server(https_options,
600                              FilePath(FILE_PATH_LITERAL("net/data/ssl")));
601  ASSERT_TRUE(test_server.Start());
602
603  SSLClientAuthTestDelegate d;
604  {
605    TestURLRequest r(test_server.GetURL(""), &d);
606
607    r.Start();
608    EXPECT_TRUE(r.is_pending());
609
610    MessageLoop::current()->Run();
611
612    EXPECT_EQ(1, d.on_certificate_requested_count());
613    EXPECT_FALSE(d.received_data_before_response());
614    EXPECT_EQ(0, d.bytes_received());
615
616    // Send no certificate.
617    // TODO(davidben): Get temporary client cert import (with keys) working on
618    // all platforms so we can test sending a cert as well.
619    r.ContinueWithCertificate(NULL);
620
621    MessageLoop::current()->Run();
622
623    EXPECT_EQ(1, d.response_started_count());
624    EXPECT_FALSE(d.received_data_before_response());
625    EXPECT_NE(0, d.bytes_received());
626  }
627}
628
629TEST_F(URLRequestTestHTTP, CancelTest) {
630  TestDelegate d;
631  {
632    TestURLRequest r(GURL("http://www.google.com/"), &d);
633
634    r.Start();
635    EXPECT_TRUE(r.is_pending());
636
637    r.Cancel();
638
639    MessageLoop::current()->Run();
640
641    // We expect to receive OnResponseStarted even though the request has been
642    // cancelled.
643    EXPECT_EQ(1, d.response_started_count());
644    EXPECT_EQ(0, d.bytes_received());
645    EXPECT_FALSE(d.received_data_before_response());
646  }
647}
648
649TEST_F(URLRequestTestHTTP, CancelTest2) {
650  ASSERT_TRUE(test_server_.Start());
651
652  TestDelegate d;
653  {
654    TestURLRequest r(test_server_.GetURL(""), &d);
655
656    d.set_cancel_in_response_started(true);
657
658    r.Start();
659    EXPECT_TRUE(r.is_pending());
660
661    MessageLoop::current()->Run();
662
663    EXPECT_EQ(1, d.response_started_count());
664    EXPECT_EQ(0, d.bytes_received());
665    EXPECT_FALSE(d.received_data_before_response());
666    EXPECT_EQ(URLRequestStatus::CANCELED, r.status().status());
667  }
668}
669
670TEST_F(URLRequestTestHTTP, CancelTest3) {
671  ASSERT_TRUE(test_server_.Start());
672
673  TestDelegate d;
674  {
675    TestURLRequest r(test_server_.GetURL(""), &d);
676
677    d.set_cancel_in_received_data(true);
678
679    r.Start();
680    EXPECT_TRUE(r.is_pending());
681
682    MessageLoop::current()->Run();
683
684    EXPECT_EQ(1, d.response_started_count());
685    // There is no guarantee about how much data was received
686    // before the cancel was issued.  It could have been 0 bytes,
687    // or it could have been all the bytes.
688    // EXPECT_EQ(0, d.bytes_received());
689    EXPECT_FALSE(d.received_data_before_response());
690    EXPECT_EQ(URLRequestStatus::CANCELED, r.status().status());
691  }
692}
693
694TEST_F(URLRequestTestHTTP, CancelTest4) {
695  ASSERT_TRUE(test_server_.Start());
696
697  TestDelegate d;
698  {
699    TestURLRequest r(test_server_.GetURL(""), &d);
700
701    r.Start();
702    EXPECT_TRUE(r.is_pending());
703
704    // The request will be implicitly canceled when it is destroyed. The
705    // test delegate must not post a quit message when this happens because
706    // this test doesn't actually have a message loop. The quit message would
707    // get put on this thread's message queue and the next test would exit
708    // early, causing problems.
709    d.set_quit_on_complete(false);
710  }
711  // expect things to just cleanup properly.
712
713  // we won't actually get a received reponse here because we've never run the
714  // message loop
715  EXPECT_FALSE(d.received_data_before_response());
716  EXPECT_EQ(0, d.bytes_received());
717}
718
719TEST_F(URLRequestTestHTTP, CancelTest5) {
720  ASSERT_TRUE(test_server_.Start());
721
722  scoped_refptr<URLRequestContext> context(new TestURLRequestContext());
723
724  // populate cache
725  {
726    TestDelegate d;
727    URLRequest r(test_server_.GetURL("cachetime"), &d);
728    r.set_context(context);
729    r.Start();
730    MessageLoop::current()->Run();
731    EXPECT_EQ(URLRequestStatus::SUCCESS, r.status().status());
732  }
733
734  // cancel read from cache (see bug 990242)
735  {
736    TestDelegate d;
737    URLRequest r(test_server_.GetURL("cachetime"), &d);
738    r.set_context(context);
739    r.Start();
740    r.Cancel();
741    MessageLoop::current()->Run();
742
743    EXPECT_EQ(URLRequestStatus::CANCELED, r.status().status());
744    EXPECT_EQ(1, d.response_started_count());
745    EXPECT_EQ(0, d.bytes_received());
746    EXPECT_FALSE(d.received_data_before_response());
747  }
748}
749
750TEST_F(URLRequestTestHTTP, PostTest) {
751  ASSERT_TRUE(test_server_.Start());
752  HTTPUploadDataOperationTest("POST");
753}
754
755TEST_F(URLRequestTestHTTP, PutTest) {
756  ASSERT_TRUE(test_server_.Start());
757  HTTPUploadDataOperationTest("PUT");
758}
759
760TEST_F(URLRequestTestHTTP, PostEmptyTest) {
761  ASSERT_TRUE(test_server_.Start());
762
763  TestDelegate d;
764  {
765    TestURLRequest r(test_server_.GetURL("echo"), &d);
766    r.set_method("POST");
767
768    r.Start();
769    EXPECT_TRUE(r.is_pending());
770
771    MessageLoop::current()->Run();
772
773    ASSERT_EQ(1, d.response_started_count()) << "request failed: " <<
774        (int) r.status().status() << ", os error: " << r.status().os_error();
775
776    EXPECT_FALSE(d.received_data_before_response());
777    EXPECT_TRUE(d.data_received().empty());
778  }
779}
780
781TEST_F(URLRequestTestHTTP, PostFileTest) {
782  ASSERT_TRUE(test_server_.Start());
783
784  TestDelegate d;
785  {
786    TestURLRequest r(test_server_.GetURL("echo"), &d);
787    r.set_method("POST");
788
789    FilePath dir;
790    PathService::Get(base::DIR_EXE, &dir);
791    file_util::SetCurrentDirectory(dir);
792
793    FilePath path;
794    PathService::Get(base::DIR_SOURCE_ROOT, &path);
795    path = path.Append(FILE_PATH_LITERAL("net"));
796    path = path.Append(FILE_PATH_LITERAL("data"));
797    path = path.Append(FILE_PATH_LITERAL("url_request_unittest"));
798    path = path.Append(FILE_PATH_LITERAL("with-headers.html"));
799    r.AppendFileToUpload(path);
800
801    // This file should just be ignored in the upload stream.
802    r.AppendFileToUpload(FilePath(FILE_PATH_LITERAL(
803        "c:\\path\\to\\non\\existant\\file.randomness.12345")));
804
805    r.Start();
806    EXPECT_TRUE(r.is_pending());
807
808    MessageLoop::current()->Run();
809
810    int64 longsize;
811    ASSERT_EQ(true, file_util::GetFileSize(path, &longsize));
812    int size = static_cast<int>(longsize);
813    scoped_array<char> buf(new char[size]);
814
815    int size_read = static_cast<int>(file_util::ReadFile(path,
816        buf.get(), size));
817    ASSERT_EQ(size, size_read);
818
819    ASSERT_EQ(1, d.response_started_count()) << "request failed: " <<
820        (int) r.status().status() << ", os error: " << r.status().os_error();
821
822    EXPECT_FALSE(d.received_data_before_response());
823
824    ASSERT_EQ(size, d.bytes_received());
825    EXPECT_EQ(0, memcmp(d.data_received().c_str(), buf.get(), size));
826  }
827}
828
829TEST_F(URLRequestTestHTTP, TestPostChunkedDataBeforeStart) {
830  ASSERT_TRUE(test_server_.Start());
831
832  TestDelegate d;
833  {
834    TestURLRequest r(test_server_.GetURL("echo"), &d);
835    r.EnableChunkedUpload();
836    r.set_method("POST");
837    AddChunksToUpload(&r);
838    r.Start();
839    EXPECT_TRUE(r.is_pending());
840
841    MessageLoop::current()->Run();
842
843    VerifyReceivedDataMatchesChunks(&r, &d);
844  }
845}
846
847TEST_F(URLRequestTestHTTP, TestPostChunkedDataAfterStart) {
848  ASSERT_TRUE(test_server_.Start());
849
850  TestDelegate d;
851  {
852    TestURLRequest r(test_server_.GetURL("echo"), &d);
853    r.EnableChunkedUpload();
854    r.set_method("POST");
855    r.Start();
856    EXPECT_TRUE(r.is_pending());
857
858    MessageLoop::current()->RunAllPending();
859    AddChunksToUpload(&r);
860    MessageLoop::current()->Run();
861
862    VerifyReceivedDataMatchesChunks(&r, &d);
863  }
864}
865
866TEST_F(URLRequestTest, AboutBlankTest) {
867  TestDelegate d;
868  {
869    TestURLRequest r(GURL("about:blank"), &d);
870
871    r.Start();
872    EXPECT_TRUE(r.is_pending());
873
874    MessageLoop::current()->Run();
875
876    EXPECT_TRUE(!r.is_pending());
877    EXPECT_FALSE(d.received_data_before_response());
878    EXPECT_EQ(d.bytes_received(), 0);
879    EXPECT_EQ("", r.GetSocketAddress().host());
880    EXPECT_EQ(0, r.GetSocketAddress().port());
881  }
882}
883
884TEST_F(URLRequestTest, DataURLImageTest) {
885  TestDelegate d;
886  {
887    // Use our nice little Chrome logo.
888    TestURLRequest r(GURL(
889        "data:image/png;base64,"
890        "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADVklEQVQ4jX2TfUwUBBjG3"
891        "w1y+HGcd9dxhXR8T4awOccJGgOSWclHImznLkTlSw0DDQXkrmgYgbUYnlQTqQxIEVxitD"
892        "5UMCATRA1CEEg+Qjw3bWDxIauJv/5oumqs39/P827vnucRmYN0gyF01GI5MpCVdW0gO7t"
893        "vNC+vqSEtbZefk5NuLv1jdJ46p/zw0HeH4+PHr3h7c1mjoV2t5rKzMx1+fg9bAgK6zHq9"
894        "cU5z+LpA3xOtx34+vTeT21onRuzssC3zxbbSwC13d/pFuC7CkIMDxQpF7r/MWq12UctI1"
895        "dWWm99ypqSYmRUBdKem8MkrO/kgaTt1O7YzlpzE5GIVd0WYUqt57yWf2McHTObYPbVD+Z"
896        "wbtlLTVMZ3BW+TnLyXLaWtmEq6WJVbT3HBh3Svj2HQQcm43XwmtoYM6vVKleh0uoWvnzW"
897        "3v3MpidruPTQPf0bia7sJOtBM0ufTWNvus/nkDFHF9ZS+uYVjRUasMeHUmyLYtcklTvzW"
898        "GFZnNOXczThvpKIzjcahSqIzkvDLayDq6D3eOjtBbNUEIZYyqsvj4V4wY92eNJ4IoyhTb"
899        "xXX1T5xsV9tm9r4TQwHLiZw/pdDZJea8TKmsmR/K0uLh/GwnCHghTja6lPhphezPfO5/5"
900        "MrVvMzNaI3+ERHfrFzPKQukrQGI4d/3EFD/3E2mVNYvi4at7CXWREaxZGD+3hg28zD3gV"
901        "Md6q5c8GdosynKmSeRuGzpjyl1/9UDGtPR5HeaKT8Wjo17WXk579BXVUhN64ehF9fhRtq"
902        "/uxxZKzNiZFGD0wRC3NFROZ5mwIPL/96K/rKMMLrIzF9uhHr+/sYH7DAbwlgC4J+R2Z7F"
903        "Ux1qLnV7MGF40smVSoJ/jvHRfYhQeUJd/SnYtGWhPHR0Sz+GE2F2yth0B36Vcz2KpnufB"
904        "JbsysjjW4kblBUiIjiURUWqJY65zxbnTy57GQyH58zgy0QBtTQv5gH15XMdKkYu+TGaJM"
905        "nlm2O34uI4b9tflqp1+QEFGzoW/ulmcofcpkZCYJhDfSpme7QcrHa+Xfji8paEQkTkSfm"
906        "moRWRNZr/F1KfVMjW+IKEnv2FwZfKdzt0BQR6lClcZR0EfEXEfv/G6W9iLiIyCoReV5En"
907        "hORIBHx+ufPj/gLB/zGI/G4Bk0AAAAASUVORK5CYII="),
908        &d);
909
910    r.Start();
911    EXPECT_TRUE(r.is_pending());
912
913    MessageLoop::current()->Run();
914
915    EXPECT_TRUE(!r.is_pending());
916    EXPECT_FALSE(d.received_data_before_response());
917    EXPECT_EQ(d.bytes_received(), 911);
918    EXPECT_EQ("", r.GetSocketAddress().host());
919    EXPECT_EQ(0, r.GetSocketAddress().port());
920  }
921}
922
923TEST_F(URLRequestTest, FileTest) {
924  FilePath app_path;
925  PathService::Get(base::FILE_EXE, &app_path);
926  GURL app_url = FilePathToFileURL(app_path);
927
928  TestDelegate d;
929  {
930    TestURLRequest r(app_url, &d);
931
932    r.Start();
933    EXPECT_TRUE(r.is_pending());
934
935    MessageLoop::current()->Run();
936
937    int64 file_size = -1;
938    EXPECT_TRUE(file_util::GetFileSize(app_path, &file_size));
939
940    EXPECT_TRUE(!r.is_pending());
941    EXPECT_EQ(1, d.response_started_count());
942    EXPECT_FALSE(d.received_data_before_response());
943    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
944    EXPECT_EQ("", r.GetSocketAddress().host());
945    EXPECT_EQ(0, r.GetSocketAddress().port());
946  }
947}
948
949TEST_F(URLRequestTest, FileTestFullSpecifiedRange) {
950  const size_t buffer_size = 4000;
951  scoped_array<char> buffer(new char[buffer_size]);
952  FillBuffer(buffer.get(), buffer_size);
953
954  FilePath temp_path;
955  EXPECT_TRUE(file_util::CreateTemporaryFile(&temp_path));
956  GURL temp_url = FilePathToFileURL(temp_path);
957  EXPECT_TRUE(file_util::WriteFile(temp_path, buffer.get(), buffer_size));
958
959  int64 file_size;
960  EXPECT_TRUE(file_util::GetFileSize(temp_path, &file_size));
961
962  const size_t first_byte_position = 500;
963  const size_t last_byte_position = buffer_size - first_byte_position;
964  const size_t content_length = last_byte_position - first_byte_position + 1;
965  std::string partial_buffer_string(buffer.get() + first_byte_position,
966                                    buffer.get() + last_byte_position + 1);
967
968  TestDelegate d;
969  {
970    TestURLRequest r(temp_url, &d);
971
972    HttpRequestHeaders headers;
973    headers.SetHeader(HttpRequestHeaders::kRange,
974                      base::StringPrintf(
975                           "bytes=%" PRIuS "-%" PRIuS,
976                           first_byte_position, last_byte_position));
977    r.SetExtraRequestHeaders(headers);
978    r.Start();
979    EXPECT_TRUE(r.is_pending());
980
981    MessageLoop::current()->Run();
982    EXPECT_TRUE(!r.is_pending());
983    EXPECT_EQ(1, d.response_started_count());
984    EXPECT_FALSE(d.received_data_before_response());
985    EXPECT_EQ(static_cast<int>(content_length), d.bytes_received());
986    // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed.
987    EXPECT_TRUE(partial_buffer_string == d.data_received());
988  }
989
990  EXPECT_TRUE(file_util::Delete(temp_path, false));
991}
992
993TEST_F(URLRequestTest, FileTestHalfSpecifiedRange) {
994  const size_t buffer_size = 4000;
995  scoped_array<char> buffer(new char[buffer_size]);
996  FillBuffer(buffer.get(), buffer_size);
997
998  FilePath temp_path;
999  EXPECT_TRUE(file_util::CreateTemporaryFile(&temp_path));
1000  GURL temp_url = FilePathToFileURL(temp_path);
1001  EXPECT_TRUE(file_util::WriteFile(temp_path, buffer.get(), buffer_size));
1002
1003  int64 file_size;
1004  EXPECT_TRUE(file_util::GetFileSize(temp_path, &file_size));
1005
1006  const size_t first_byte_position = 500;
1007  const size_t last_byte_position = buffer_size - 1;
1008  const size_t content_length = last_byte_position - first_byte_position + 1;
1009  std::string partial_buffer_string(buffer.get() + first_byte_position,
1010                                    buffer.get() + last_byte_position + 1);
1011
1012  TestDelegate d;
1013  {
1014    TestURLRequest r(temp_url, &d);
1015
1016    HttpRequestHeaders headers;
1017    headers.SetHeader(HttpRequestHeaders::kRange,
1018                      base::StringPrintf("bytes=%" PRIuS "-",
1019                                         first_byte_position));
1020    r.SetExtraRequestHeaders(headers);
1021    r.Start();
1022    EXPECT_TRUE(r.is_pending());
1023
1024    MessageLoop::current()->Run();
1025    EXPECT_TRUE(!r.is_pending());
1026    EXPECT_EQ(1, d.response_started_count());
1027    EXPECT_FALSE(d.received_data_before_response());
1028    EXPECT_EQ(static_cast<int>(content_length), d.bytes_received());
1029    // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed.
1030    EXPECT_TRUE(partial_buffer_string == d.data_received());
1031  }
1032
1033  EXPECT_TRUE(file_util::Delete(temp_path, false));
1034}
1035
1036TEST_F(URLRequestTest, FileTestMultipleRanges) {
1037  const size_t buffer_size = 400000;
1038  scoped_array<char> buffer(new char[buffer_size]);
1039  FillBuffer(buffer.get(), buffer_size);
1040
1041  FilePath temp_path;
1042  EXPECT_TRUE(file_util::CreateTemporaryFile(&temp_path));
1043  GURL temp_url = FilePathToFileURL(temp_path);
1044  EXPECT_TRUE(file_util::WriteFile(temp_path, buffer.get(), buffer_size));
1045
1046  int64 file_size;
1047  EXPECT_TRUE(file_util::GetFileSize(temp_path, &file_size));
1048
1049  TestDelegate d;
1050  {
1051    TestURLRequest r(temp_url, &d);
1052
1053    HttpRequestHeaders headers;
1054    headers.SetHeader(HttpRequestHeaders::kRange,
1055                      "bytes=0-0,10-200,200-300");
1056    r.SetExtraRequestHeaders(headers);
1057    r.Start();
1058    EXPECT_TRUE(r.is_pending());
1059
1060    MessageLoop::current()->Run();
1061    EXPECT_TRUE(d.request_failed());
1062  }
1063
1064  EXPECT_TRUE(file_util::Delete(temp_path, false));
1065}
1066
1067TEST_F(URLRequestTest, InvalidUrlTest) {
1068  TestDelegate d;
1069  {
1070    TestURLRequest r(GURL("invalid url"), &d);
1071
1072    r.Start();
1073    EXPECT_TRUE(r.is_pending());
1074
1075    MessageLoop::current()->Run();
1076    EXPECT_TRUE(d.request_failed());
1077  }
1078}
1079
1080TEST_F(URLRequestTestHTTP, ResponseHeadersTest) {
1081  ASSERT_TRUE(test_server_.Start());
1082
1083  TestDelegate d;
1084  TestURLRequest req(test_server_.GetURL("files/with-headers.html"), &d);
1085  req.Start();
1086  MessageLoop::current()->Run();
1087
1088  const HttpResponseHeaders* headers = req.response_headers();
1089
1090  // Simple sanity check that response_info() accesses the same data.
1091  EXPECT_EQ(headers, req.response_info().headers.get());
1092
1093  std::string header;
1094  EXPECT_TRUE(headers->GetNormalizedHeader("cache-control", &header));
1095  EXPECT_EQ("private", header);
1096
1097  header.clear();
1098  EXPECT_TRUE(headers->GetNormalizedHeader("content-type", &header));
1099  EXPECT_EQ("text/html; charset=ISO-8859-1", header);
1100
1101  // The response has two "X-Multiple-Entries" headers.
1102  // This verfies our output has them concatenated together.
1103  header.clear();
1104  EXPECT_TRUE(headers->GetNormalizedHeader("x-multiple-entries", &header));
1105  EXPECT_EQ("a, b", header);
1106}
1107
1108#if defined(OS_WIN)
1109TEST_F(URLRequestTest, ResolveShortcutTest) {
1110  FilePath app_path;
1111  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
1112  app_path = app_path.AppendASCII("net");
1113  app_path = app_path.AppendASCII("data");
1114  app_path = app_path.AppendASCII("url_request_unittest");
1115  app_path = app_path.AppendASCII("with-headers.html");
1116
1117  std::wstring lnk_path = app_path.value() + L".lnk";
1118
1119  HRESULT result;
1120  IShellLink *shell = NULL;
1121  IPersistFile *persist = NULL;
1122
1123  CoInitialize(NULL);
1124  // Temporarily create a shortcut for test
1125  result = CoCreateInstance(CLSID_ShellLink, NULL,
1126                            CLSCTX_INPROC_SERVER, IID_IShellLink,
1127                            reinterpret_cast<LPVOID*>(&shell));
1128  ASSERT_TRUE(SUCCEEDED(result));
1129  result = shell->QueryInterface(IID_IPersistFile,
1130                                reinterpret_cast<LPVOID*>(&persist));
1131  ASSERT_TRUE(SUCCEEDED(result));
1132  result = shell->SetPath(app_path.value().c_str());
1133  EXPECT_TRUE(SUCCEEDED(result));
1134  result = shell->SetDescription(L"ResolveShortcutTest");
1135  EXPECT_TRUE(SUCCEEDED(result));
1136  result = persist->Save(lnk_path.c_str(), TRUE);
1137  EXPECT_TRUE(SUCCEEDED(result));
1138  if (persist)
1139    persist->Release();
1140  if (shell)
1141    shell->Release();
1142
1143  TestDelegate d;
1144  {
1145    TestURLRequest r(FilePathToFileURL(FilePath(lnk_path)), &d);
1146
1147    r.Start();
1148    EXPECT_TRUE(r.is_pending());
1149
1150    MessageLoop::current()->Run();
1151
1152    WIN32_FILE_ATTRIBUTE_DATA data;
1153    GetFileAttributesEx(app_path.value().c_str(),
1154                        GetFileExInfoStandard, &data);
1155    HANDLE file = CreateFile(app_path.value().c_str(), GENERIC_READ,
1156                             FILE_SHARE_READ, NULL, OPEN_EXISTING,
1157                             FILE_ATTRIBUTE_NORMAL, NULL);
1158    EXPECT_NE(INVALID_HANDLE_VALUE, file);
1159    scoped_array<char> buffer(new char[data.nFileSizeLow]);
1160    DWORD read_size;
1161    BOOL result;
1162    result = ReadFile(file, buffer.get(), data.nFileSizeLow,
1163                      &read_size, NULL);
1164    std::string content(buffer.get(), read_size);
1165    CloseHandle(file);
1166
1167    EXPECT_TRUE(!r.is_pending());
1168    EXPECT_EQ(1, d.received_redirect_count());
1169    EXPECT_EQ(content, d.data_received());
1170  }
1171
1172  // Clean the shortcut
1173  DeleteFile(lnk_path.c_str());
1174  CoUninitialize();
1175}
1176#endif  // defined(OS_WIN)
1177
1178TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) {
1179  ASSERT_TRUE(test_server_.Start());
1180
1181  TestDelegate d;
1182  TestURLRequest req(test_server_.GetURL(
1183      "files/content-type-normalization.html"), &d);
1184  req.Start();
1185  MessageLoop::current()->Run();
1186
1187  std::string mime_type;
1188  req.GetMimeType(&mime_type);
1189  EXPECT_EQ("text/html", mime_type);
1190
1191  std::string charset;
1192  req.GetCharset(&charset);
1193  EXPECT_EQ("utf-8", charset);
1194  req.Cancel();
1195}
1196
1197TEST_F(URLRequestTest, FileDirCancelTest) {
1198  // Put in mock resource provider.
1199  NetModule::SetResourceProvider(TestNetResourceProvider);
1200
1201  TestDelegate d;
1202  {
1203    FilePath file_path;
1204    PathService::Get(base::DIR_SOURCE_ROOT, &file_path);
1205    file_path = file_path.Append(FILE_PATH_LITERAL("net"));
1206    file_path = file_path.Append(FILE_PATH_LITERAL("data"));
1207
1208    TestURLRequest req(FilePathToFileURL(file_path), &d);
1209    req.Start();
1210    EXPECT_TRUE(req.is_pending());
1211
1212    d.set_cancel_in_received_data_pending(true);
1213
1214    MessageLoop::current()->Run();
1215  }
1216
1217  // Take out mock resource provider.
1218  NetModule::SetResourceProvider(NULL);
1219}
1220
1221TEST_F(URLRequestTest, FileDirRedirectNoCrash) {
1222  // There is an implicit redirect when loading a file path that matches a
1223  // directory and does not end with a slash.  Ensure that following such
1224  // redirects does not crash.  See http://crbug.com/18686.
1225
1226  FilePath path;
1227  PathService::Get(base::DIR_SOURCE_ROOT, &path);
1228  path = path.Append(FILE_PATH_LITERAL("net"));
1229  path = path.Append(FILE_PATH_LITERAL("data"));
1230  path = path.Append(FILE_PATH_LITERAL("url_request_unittest"));
1231
1232  TestDelegate d;
1233  TestURLRequest req(FilePathToFileURL(path), &d);
1234  req.Start();
1235  MessageLoop::current()->Run();
1236
1237  ASSERT_EQ(1, d.received_redirect_count());
1238  ASSERT_LT(0, d.bytes_received());
1239  ASSERT_FALSE(d.request_failed());
1240  ASSERT_TRUE(req.status().is_success());
1241}
1242
1243#if defined(OS_WIN)
1244// Don't accept the url "file:///" on windows. See http://crbug.com/1474.
1245TEST_F(URLRequestTest, FileDirRedirectSingleSlash) {
1246  TestDelegate d;
1247  TestURLRequest req(GURL("file:///"), &d);
1248  req.Start();
1249  MessageLoop::current()->Run();
1250
1251  ASSERT_EQ(1, d.received_redirect_count());
1252  ASSERT_FALSE(req.status().is_success());
1253}
1254#endif
1255
1256TEST_F(URLRequestTestHTTP, RestrictRedirects) {
1257  ASSERT_TRUE(test_server_.Start());
1258
1259  TestDelegate d;
1260  TestURLRequest req(test_server_.GetURL(
1261      "files/redirect-to-file.html"), &d);
1262  req.Start();
1263  MessageLoop::current()->Run();
1264
1265  EXPECT_EQ(URLRequestStatus::FAILED, req.status().status());
1266  EXPECT_EQ(ERR_UNSAFE_REDIRECT, req.status().os_error());
1267}
1268
1269TEST_F(URLRequestTestHTTP, RedirectToInvalidURL) {
1270  ASSERT_TRUE(test_server_.Start());
1271
1272  TestDelegate d;
1273  TestURLRequest req(test_server_.GetURL(
1274      "files/redirect-to-invalid-url.html"), &d);
1275  req.Start();
1276  MessageLoop::current()->Run();
1277
1278  EXPECT_EQ(URLRequestStatus::FAILED, req.status().status());
1279  EXPECT_EQ(ERR_INVALID_URL, req.status().os_error());
1280}
1281
1282TEST_F(URLRequestTestHTTP, NoUserPassInReferrer) {
1283  ASSERT_TRUE(test_server_.Start());
1284
1285  TestDelegate d;
1286  TestURLRequest req(test_server_.GetURL(
1287      "echoheader?Referer"), &d);
1288  req.set_referrer("http://user:pass@foo.com/");
1289  req.Start();
1290  MessageLoop::current()->Run();
1291
1292  EXPECT_EQ(std::string("http://foo.com/"), d.data_received());
1293}
1294
1295TEST_F(URLRequestTestHTTP, CancelRedirect) {
1296  ASSERT_TRUE(test_server_.Start());
1297
1298  TestDelegate d;
1299  {
1300    d.set_cancel_in_received_redirect(true);
1301    TestURLRequest req(test_server_.GetURL(
1302        "files/redirect-test.html"), &d);
1303    req.Start();
1304    MessageLoop::current()->Run();
1305
1306    EXPECT_EQ(1, d.response_started_count());
1307    EXPECT_EQ(0, d.bytes_received());
1308    EXPECT_FALSE(d.received_data_before_response());
1309    EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
1310  }
1311}
1312
1313TEST_F(URLRequestTestHTTP, DeferredRedirect) {
1314  ASSERT_TRUE(test_server_.Start());
1315
1316  TestDelegate d;
1317  {
1318    d.set_quit_on_redirect(true);
1319    TestURLRequest req(test_server_.GetURL(
1320        "files/redirect-test.html"), &d);
1321    req.Start();
1322    MessageLoop::current()->Run();
1323
1324    EXPECT_EQ(1, d.received_redirect_count());
1325
1326    req.FollowDeferredRedirect();
1327    MessageLoop::current()->Run();
1328
1329    EXPECT_EQ(1, d.response_started_count());
1330    EXPECT_FALSE(d.received_data_before_response());
1331    EXPECT_EQ(URLRequestStatus::SUCCESS, req.status().status());
1332
1333    FilePath path;
1334    PathService::Get(base::DIR_SOURCE_ROOT, &path);
1335    path = path.Append(FILE_PATH_LITERAL("net"));
1336    path = path.Append(FILE_PATH_LITERAL("data"));
1337    path = path.Append(FILE_PATH_LITERAL("url_request_unittest"));
1338    path = path.Append(FILE_PATH_LITERAL("with-headers.html"));
1339
1340    std::string contents;
1341    EXPECT_TRUE(file_util::ReadFileToString(path, &contents));
1342    EXPECT_EQ(contents, d.data_received());
1343  }
1344}
1345
1346TEST_F(URLRequestTestHTTP, CancelDeferredRedirect) {
1347  ASSERT_TRUE(test_server_.Start());
1348
1349  TestDelegate d;
1350  {
1351    d.set_quit_on_redirect(true);
1352    TestURLRequest req(test_server_.GetURL(
1353        "files/redirect-test.html"), &d);
1354    req.Start();
1355    MessageLoop::current()->Run();
1356
1357    EXPECT_EQ(1, d.received_redirect_count());
1358
1359    req.Cancel();
1360    MessageLoop::current()->Run();
1361
1362    EXPECT_EQ(1, d.response_started_count());
1363    EXPECT_EQ(0, d.bytes_received());
1364    EXPECT_FALSE(d.received_data_before_response());
1365    EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
1366  }
1367}
1368
1369TEST_F(URLRequestTestHTTP, VaryHeader) {
1370  ASSERT_TRUE(test_server_.Start());
1371
1372  scoped_refptr<URLRequestContext> context(new TestURLRequestContext());
1373
1374  // populate the cache
1375  {
1376    TestDelegate d;
1377    URLRequest req(test_server_.GetURL("echoheadercache?foo"), &d);
1378    req.set_context(context);
1379    HttpRequestHeaders headers;
1380    headers.SetHeader("foo", "1");
1381    req.SetExtraRequestHeaders(headers);
1382    req.Start();
1383    MessageLoop::current()->Run();
1384  }
1385
1386  // expect a cache hit
1387  {
1388    TestDelegate d;
1389    URLRequest req(test_server_.GetURL("echoheadercache?foo"), &d);
1390    req.set_context(context);
1391    HttpRequestHeaders headers;
1392    headers.SetHeader("foo", "1");
1393    req.SetExtraRequestHeaders(headers);
1394    req.Start();
1395    MessageLoop::current()->Run();
1396
1397    EXPECT_TRUE(req.was_cached());
1398  }
1399
1400  // expect a cache miss
1401  {
1402    TestDelegate d;
1403    URLRequest req(test_server_.GetURL("echoheadercache?foo"), &d);
1404    req.set_context(context);
1405    HttpRequestHeaders headers;
1406    headers.SetHeader("foo", "2");
1407    req.SetExtraRequestHeaders(headers);
1408    req.Start();
1409    MessageLoop::current()->Run();
1410
1411    EXPECT_FALSE(req.was_cached());
1412  }
1413}
1414
1415TEST_F(URLRequestTestHTTP, BasicAuth) {
1416  ASSERT_TRUE(test_server_.Start());
1417
1418  scoped_refptr<URLRequestContext> context(new TestURLRequestContext());
1419
1420  // populate the cache
1421  {
1422    TestDelegate d;
1423    d.set_username(kUser);
1424    d.set_password(kSecret);
1425
1426    URLRequest r(test_server_.GetURL("auth-basic"), &d);
1427    r.set_context(context);
1428    r.Start();
1429
1430    MessageLoop::current()->Run();
1431
1432    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);
1433  }
1434
1435  // repeat request with end-to-end validation.  since auth-basic results in a
1436  // cachable page, we expect this test to result in a 304.  in which case, the
1437  // response should be fetched from the cache.
1438  {
1439    TestDelegate d;
1440    d.set_username(kUser);
1441    d.set_password(kSecret);
1442
1443    URLRequest r(test_server_.GetURL("auth-basic"), &d);
1444    r.set_context(context);
1445    r.set_load_flags(LOAD_VALIDATE_CACHE);
1446    r.Start();
1447
1448    MessageLoop::current()->Run();
1449
1450    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);
1451
1452    // Should be the same cached document.
1453    EXPECT_TRUE(r.was_cached());
1454  }
1455}
1456
1457// Check that Set-Cookie headers in 401 responses are respected.
1458// http://crbug.com/6450
1459TEST_F(URLRequestTestHTTP, BasicAuthWithCookies) {
1460  ASSERT_TRUE(test_server_.Start());
1461
1462  GURL url_requiring_auth =
1463      test_server_.GetURL("auth-basic?set-cookie-if-challenged");
1464
1465  // Request a page that will give a 401 containing a Set-Cookie header.
1466  // Verify that when the transaction is restarted, it includes the new cookie.
1467  {
1468    scoped_refptr<URLRequestContext> context(new TestURLRequestContext());
1469    TestDelegate d;
1470    d.set_username(kUser);
1471    d.set_password(kSecret);
1472
1473    URLRequest r(url_requiring_auth, &d);
1474    r.set_context(context);
1475    r.Start();
1476
1477    MessageLoop::current()->Run();
1478
1479    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);
1480
1481    // Make sure we sent the cookie in the restarted transaction.
1482    EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true")
1483        != std::string::npos);
1484  }
1485
1486  // Same test as above, except this time the restart is initiated earlier
1487  // (without user intervention since identity is embedded in the URL).
1488  {
1489    scoped_refptr<URLRequestContext> context(new TestURLRequestContext());
1490    TestDelegate d;
1491
1492    GURL::Replacements replacements;
1493    std::string username("user2");
1494    std::string password("secret");
1495    replacements.SetUsernameStr(username);
1496    replacements.SetPasswordStr(password);
1497    GURL url_with_identity = url_requiring_auth.ReplaceComponents(replacements);
1498
1499    URLRequest r(url_with_identity, &d);
1500    r.set_context(context);
1501    r.Start();
1502
1503    MessageLoop::current()->Run();
1504
1505    EXPECT_TRUE(d.data_received().find("user2/secret") != std::string::npos);
1506
1507    // Make sure we sent the cookie in the restarted transaction.
1508    EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true")
1509        != std::string::npos);
1510  }
1511}
1512
1513TEST_F(URLRequestTest, DoNotSendCookies) {
1514  TestServer test_server(TestServer::TYPE_HTTP, FilePath());
1515  ASSERT_TRUE(test_server.Start());
1516
1517  scoped_refptr<URLRequestContext> context(new TestURLRequestContext());
1518
1519  // Set up a cookie.
1520  {
1521    TestDelegate d;
1522    URLRequest req(test_server.GetURL("set-cookie?CookieToNotSend=1"), &d);
1523    req.set_context(context);
1524    req.Start();
1525    MessageLoop::current()->Run();
1526    EXPECT_EQ(0, d.blocked_get_cookies_count());
1527    EXPECT_EQ(0, d.blocked_set_cookie_count());
1528  }
1529
1530  // Verify that the cookie is set.
1531  {
1532    TestDelegate d;
1533    TestURLRequest req(test_server.GetURL("echoheader?Cookie"), &d);
1534    req.set_context(context);
1535    req.Start();
1536    MessageLoop::current()->Run();
1537
1538    EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
1539                != std::string::npos);
1540    EXPECT_EQ(0, d.blocked_get_cookies_count());
1541    EXPECT_EQ(0, d.blocked_set_cookie_count());
1542  }
1543
1544  // Verify that the cookie isn't sent when LOAD_DO_NOT_SEND_COOKIES is set.
1545  {
1546    TestDelegate d;
1547    TestURLRequest req(test_server.GetURL("echoheader?Cookie"), &d);
1548    req.set_load_flags(LOAD_DO_NOT_SEND_COOKIES);
1549    req.set_context(context);
1550    req.Start();
1551    MessageLoop::current()->Run();
1552
1553    EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1")
1554                == std::string::npos);
1555
1556    // LOAD_DO_NOT_SEND_COOKIES does not trigger OnGetCookies.
1557    EXPECT_EQ(0, d.blocked_get_cookies_count());
1558    EXPECT_EQ(0, d.blocked_set_cookie_count());
1559  }
1560}
1561
1562TEST_F(URLRequestTest, DoNotSaveCookies) {
1563  TestServer test_server(TestServer::TYPE_HTTP, FilePath());
1564  ASSERT_TRUE(test_server.Start());
1565
1566  scoped_refptr<URLRequestContext> context(new TestURLRequestContext());
1567
1568  // Set up a cookie.
1569  {
1570    TestDelegate d;
1571    URLRequest req(test_server.GetURL("set-cookie?CookieToNotUpdate=2"),
1572                        &d);
1573    req.set_context(context);
1574    req.Start();
1575    MessageLoop::current()->Run();
1576
1577    EXPECT_EQ(0, d.blocked_get_cookies_count());
1578    EXPECT_EQ(0, d.blocked_set_cookie_count());
1579    EXPECT_EQ(1, d.set_cookie_count());
1580  }
1581
1582  // Try to set-up another cookie and update the previous cookie.
1583  {
1584    TestDelegate d;
1585    URLRequest req(test_server.GetURL(
1586        "set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), &d);
1587    req.set_load_flags(LOAD_DO_NOT_SAVE_COOKIES);
1588    req.set_context(context);
1589    req.Start();
1590
1591    MessageLoop::current()->Run();
1592
1593    // LOAD_DO_NOT_SAVE_COOKIES does not trigger OnSetCookie.
1594    EXPECT_EQ(0, d.blocked_get_cookies_count());
1595    EXPECT_EQ(0, d.blocked_set_cookie_count());
1596    EXPECT_EQ(0, d.set_cookie_count());
1597  }
1598
1599  // Verify the cookies weren't saved or updated.
1600  {
1601    TestDelegate d;
1602    TestURLRequest req(test_server.GetURL("echoheader?Cookie"), &d);
1603    req.set_context(context);
1604    req.Start();
1605    MessageLoop::current()->Run();
1606
1607    EXPECT_TRUE(d.data_received().find("CookieToNotSave=1")
1608                == std::string::npos);
1609    EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2")
1610                != std::string::npos);
1611
1612    EXPECT_EQ(0, d.blocked_get_cookies_count());
1613    EXPECT_EQ(0, d.blocked_set_cookie_count());
1614    EXPECT_EQ(0, d.set_cookie_count());
1615  }
1616}
1617
1618TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy) {
1619  TestServer test_server(TestServer::TYPE_HTTP, FilePath());
1620  ASSERT_TRUE(test_server.Start());
1621
1622  scoped_refptr<TestURLRequestContext> context(new TestURLRequestContext());
1623
1624  // Set up a cookie.
1625  {
1626    TestDelegate d;
1627    URLRequest req(test_server.GetURL("set-cookie?CookieToNotSend=1"), &d);
1628    req.set_context(context);
1629    req.Start();
1630    MessageLoop::current()->Run();
1631
1632    EXPECT_EQ(0, d.blocked_get_cookies_count());
1633    EXPECT_EQ(0, d.blocked_set_cookie_count());
1634  }
1635
1636  // Verify that the cookie is set.
1637  {
1638    TestDelegate d;
1639    TestURLRequest req(test_server.GetURL("echoheader?Cookie"), &d);
1640    req.set_context(context);
1641    req.Start();
1642    MessageLoop::current()->Run();
1643
1644    EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
1645                != std::string::npos);
1646
1647    EXPECT_EQ(0, d.blocked_get_cookies_count());
1648    EXPECT_EQ(0, d.blocked_set_cookie_count());
1649  }
1650
1651  // Verify that the cookie isn't sent.
1652  {
1653    TestCookiePolicy cookie_policy(TestCookiePolicy::NO_GET_COOKIES);
1654    context->set_cookie_policy(&cookie_policy);
1655
1656    TestDelegate d;
1657    TestURLRequest req(test_server.GetURL("echoheader?Cookie"), &d);
1658    req.set_context(context);
1659    req.Start();
1660    MessageLoop::current()->Run();
1661
1662    EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1")
1663                == std::string::npos);
1664
1665    context->set_cookie_policy(NULL);
1666
1667    EXPECT_EQ(1, d.blocked_get_cookies_count());
1668    EXPECT_EQ(0, d.blocked_set_cookie_count());
1669  }
1670}
1671
1672TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy) {
1673  TestServer test_server(TestServer::TYPE_HTTP, FilePath());
1674  ASSERT_TRUE(test_server.Start());
1675
1676  scoped_refptr<TestURLRequestContext> context(new TestURLRequestContext());
1677
1678  // Set up a cookie.
1679  {
1680    TestDelegate d;
1681    URLRequest req(test_server.GetURL("set-cookie?CookieToNotUpdate=2"),
1682                        &d);
1683    req.set_context(context);
1684    req.Start();
1685    MessageLoop::current()->Run();
1686
1687    EXPECT_EQ(0, d.blocked_get_cookies_count());
1688    EXPECT_EQ(0, d.blocked_set_cookie_count());
1689  }
1690
1691  // Try to set-up another cookie and update the previous cookie.
1692  {
1693    TestCookiePolicy cookie_policy(TestCookiePolicy::NO_SET_COOKIE);
1694    context->set_cookie_policy(&cookie_policy);
1695
1696    TestDelegate d;
1697    URLRequest req(test_server.GetURL(
1698        "set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), &d);
1699    req.set_context(context);
1700    req.Start();
1701
1702    MessageLoop::current()->Run();
1703
1704    context->set_cookie_policy(NULL);
1705
1706    EXPECT_EQ(0, d.blocked_get_cookies_count());
1707    EXPECT_EQ(2, d.blocked_set_cookie_count());
1708  }
1709
1710
1711  // Verify the cookies weren't saved or updated.
1712  {
1713    TestDelegate d;
1714    TestURLRequest req(test_server.GetURL("echoheader?Cookie"), &d);
1715    req.set_context(context);
1716    req.Start();
1717    MessageLoop::current()->Run();
1718
1719    EXPECT_TRUE(d.data_received().find("CookieToNotSave=1")
1720                == std::string::npos);
1721    EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2")
1722                != std::string::npos);
1723
1724    EXPECT_EQ(0, d.blocked_get_cookies_count());
1725    EXPECT_EQ(0, d.blocked_set_cookie_count());
1726  }
1727}
1728
1729TEST_F(URLRequestTest, DoNotSaveEmptyCookies) {
1730  TestServer test_server(TestServer::TYPE_HTTP, FilePath());
1731  ASSERT_TRUE(test_server.Start());
1732
1733  scoped_refptr<TestURLRequestContext> context(new TestURLRequestContext());
1734
1735  // Set up an empty cookie.
1736  {
1737    TestDelegate d;
1738    URLRequest req(test_server.GetURL("set-cookie"), &d);
1739    req.set_context(context);
1740    req.Start();
1741    MessageLoop::current()->Run();
1742
1743    EXPECT_EQ(0, d.blocked_get_cookies_count());
1744    EXPECT_EQ(0, d.blocked_set_cookie_count());
1745    EXPECT_EQ(0, d.set_cookie_count());
1746  }
1747}
1748
1749TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy_Async) {
1750  TestServer test_server(TestServer::TYPE_HTTP, FilePath());
1751  ASSERT_TRUE(test_server.Start());
1752
1753  scoped_refptr<TestURLRequestContext> context(new TestURLRequestContext());
1754
1755  // Set up a cookie.
1756  {
1757    TestDelegate d;
1758    URLRequest req(test_server.GetURL("set-cookie?CookieToNotSend=1"), &d);
1759    req.set_context(context);
1760    req.Start();
1761    MessageLoop::current()->Run();
1762
1763    EXPECT_EQ(0, d.blocked_get_cookies_count());
1764    EXPECT_EQ(0, d.blocked_set_cookie_count());
1765  }
1766
1767  // Verify that the cookie is set.
1768  {
1769    TestDelegate d;
1770    TestURLRequest req(test_server.GetURL("echoheader?Cookie"), &d);
1771    req.set_context(context);
1772    req.Start();
1773    MessageLoop::current()->Run();
1774
1775    EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
1776                != std::string::npos);
1777
1778    EXPECT_EQ(0, d.blocked_get_cookies_count());
1779    EXPECT_EQ(0, d.blocked_set_cookie_count());
1780  }
1781
1782  // Verify that the cookie isn't sent.
1783  {
1784    TestCookiePolicy cookie_policy(TestCookiePolicy::NO_GET_COOKIES);
1785    context->set_cookie_policy(&cookie_policy);
1786
1787    TestDelegate d;
1788    TestURLRequest req(test_server.GetURL("echoheader?Cookie"), &d);
1789    req.set_context(context);
1790    req.Start();
1791    MessageLoop::current()->Run();
1792
1793    EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1")
1794                == std::string::npos);
1795
1796    context->set_cookie_policy(NULL);
1797
1798    EXPECT_EQ(1, d.blocked_get_cookies_count());
1799    EXPECT_EQ(0, d.blocked_set_cookie_count());
1800  }
1801}
1802
1803TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy_Async) {
1804  TestServer test_server(TestServer::TYPE_HTTP, FilePath());
1805  ASSERT_TRUE(test_server.Start());
1806
1807  scoped_refptr<TestURLRequestContext> context(new TestURLRequestContext());
1808
1809  // Set up a cookie.
1810  {
1811    TestDelegate d;
1812    URLRequest req(test_server.GetURL("set-cookie?CookieToNotUpdate=2"),
1813                        &d);
1814    req.set_context(context);
1815    req.Start();
1816    MessageLoop::current()->Run();
1817
1818    EXPECT_EQ(0, d.blocked_get_cookies_count());
1819    EXPECT_EQ(0, d.blocked_set_cookie_count());
1820  }
1821
1822  // Try to set-up another cookie and update the previous cookie.
1823  {
1824    TestCookiePolicy cookie_policy(TestCookiePolicy::NO_SET_COOKIE);
1825    context->set_cookie_policy(&cookie_policy);
1826
1827    TestDelegate d;
1828    URLRequest req(test_server.GetURL(
1829        "set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), &d);
1830    req.set_context(context);
1831    req.Start();
1832
1833    MessageLoop::current()->Run();
1834
1835    context->set_cookie_policy(NULL);
1836
1837    EXPECT_EQ(0, d.blocked_get_cookies_count());
1838    EXPECT_EQ(2, d.blocked_set_cookie_count());
1839  }
1840
1841  // Verify the cookies weren't saved or updated.
1842  {
1843    TestDelegate d;
1844    TestURLRequest req(test_server.GetURL("echoheader?Cookie"), &d);
1845    req.set_context(context);
1846    req.Start();
1847    MessageLoop::current()->Run();
1848
1849    EXPECT_TRUE(d.data_received().find("CookieToNotSave=1")
1850                == std::string::npos);
1851    EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2")
1852                != std::string::npos);
1853
1854    EXPECT_EQ(0, d.blocked_get_cookies_count());
1855    EXPECT_EQ(0, d.blocked_set_cookie_count());
1856  }
1857}
1858
1859TEST_F(URLRequestTest, CookiePolicy_ForceSession) {
1860  TestServer test_server(TestServer::TYPE_HTTP, FilePath());
1861  ASSERT_TRUE(test_server.Start());
1862
1863  scoped_refptr<TestURLRequestContext> context(new TestURLRequestContext());
1864
1865  TestCookiePolicy cookie_policy(TestCookiePolicy::FORCE_SESSION);
1866  context->set_cookie_policy(&cookie_policy);
1867
1868  // Set up a cookie.
1869  {
1870    TestDelegate d;
1871    URLRequest req(test_server.GetURL(
1872        "set-cookie?A=1;expires=\"Fri, 05 Feb 2010 23:42:01 GMT\""), &d);
1873    req.set_context(context);
1874    req.Start();  // Triggers an asynchronous cookie policy check.
1875
1876    MessageLoop::current()->Run();
1877
1878    EXPECT_EQ(0, d.blocked_get_cookies_count());
1879    EXPECT_EQ(0, d.blocked_set_cookie_count());
1880  }
1881
1882  // Now, check the cookie store.
1883  CookieList cookies =
1884      context->cookie_store()->GetCookieMonster()->GetAllCookies();
1885  EXPECT_EQ(1U, cookies.size());
1886  EXPECT_FALSE(cookies[0].IsPersistent());
1887
1888  context->set_cookie_policy(NULL);
1889}
1890
1891// In this test, we do a POST which the server will 302 redirect.
1892// The subsequent transaction should use GET, and should not send the
1893// Content-Type header.
1894// http://code.google.com/p/chromium/issues/detail?id=843
1895TEST_F(URLRequestTestHTTP, Post302RedirectGet) {
1896  ASSERT_TRUE(test_server_.Start());
1897
1898  const char kData[] = "hello world";
1899
1900  TestDelegate d;
1901  TestURLRequest req(test_server_.GetURL("files/redirect-to-echoall"), &d);
1902  req.set_method("POST");
1903  req.set_upload(CreateSimpleUploadData(kData));
1904
1905  // Set headers (some of which are specific to the POST).
1906  HttpRequestHeaders headers;
1907  headers.AddHeadersFromString(
1908    "Content-Type: multipart/form-data; "
1909    "boundary=----WebKitFormBoundaryAADeAA+NAAWMAAwZ\r\n"
1910    "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,"
1911    "text/plain;q=0.8,image/png,*/*;q=0.5\r\n"
1912    "Accept-Language: en-US,en\r\n"
1913    "Accept-Charset: ISO-8859-1,*,utf-8\r\n"
1914    "Content-Length: 11\r\n"
1915    "Origin: http://localhost:1337/");
1916  req.SetExtraRequestHeaders(headers);
1917  req.Start();
1918  MessageLoop::current()->Run();
1919
1920  std::string mime_type;
1921  req.GetMimeType(&mime_type);
1922  EXPECT_EQ("text/html", mime_type);
1923
1924  const std::string& data = d.data_received();
1925
1926  // Check that the post-specific headers were stripped:
1927  EXPECT_FALSE(ContainsString(data, "Content-Length:"));
1928  EXPECT_FALSE(ContainsString(data, "Content-Type:"));
1929  EXPECT_FALSE(ContainsString(data, "Origin:"));
1930
1931  // These extra request headers should not have been stripped.
1932  EXPECT_TRUE(ContainsString(data, "Accept:"));
1933  EXPECT_TRUE(ContainsString(data, "Accept-Language:"));
1934  EXPECT_TRUE(ContainsString(data, "Accept-Charset:"));
1935}
1936
1937TEST_F(URLRequestTestHTTP, Post307RedirectPost) {
1938  ASSERT_TRUE(test_server_.Start());
1939
1940  const char kData[] = "hello world";
1941
1942  TestDelegate d;
1943  TestURLRequest req(test_server_.GetURL("files/redirect307-to-echo"),
1944      &d);
1945  req.set_method("POST");
1946  req.set_upload(CreateSimpleUploadData(kData).get());
1947  HttpRequestHeaders headers;
1948  headers.SetHeader(HttpRequestHeaders::kContentLength,
1949                    base::UintToString(arraysize(kData) - 1));
1950  req.SetExtraRequestHeaders(headers);
1951  req.Start();
1952  MessageLoop::current()->Run();
1953  EXPECT_EQ("POST", req.method());
1954  EXPECT_EQ(kData, d.data_received());
1955}
1956
1957// Custom URLRequestJobs for use with interceptor tests
1958class RestartTestJob : public URLRequestTestJob {
1959 public:
1960  explicit RestartTestJob(URLRequest* request)
1961    : URLRequestTestJob(request, true) {}
1962 protected:
1963  virtual void StartAsync() {
1964    this->NotifyRestartRequired();
1965  }
1966 private:
1967  ~RestartTestJob() {}
1968};
1969
1970class CancelTestJob : public URLRequestTestJob {
1971 public:
1972  explicit CancelTestJob(URLRequest* request)
1973    : URLRequestTestJob(request, true) {}
1974 protected:
1975  virtual void StartAsync() {
1976    request_->Cancel();
1977  }
1978 private:
1979  ~CancelTestJob() {}
1980};
1981
1982class CancelThenRestartTestJob : public URLRequestTestJob {
1983 public:
1984  explicit CancelThenRestartTestJob(URLRequest* request)
1985      : URLRequestTestJob(request, true) {
1986  }
1987 protected:
1988  virtual void StartAsync() {
1989    request_->Cancel();
1990    this->NotifyRestartRequired();
1991  }
1992 private:
1993  ~CancelThenRestartTestJob() {}
1994};
1995
1996// An Interceptor for use with interceptor tests
1997class TestInterceptor : URLRequest::Interceptor {
1998 public:
1999  TestInterceptor()
2000      : intercept_main_request_(false), restart_main_request_(false),
2001        cancel_main_request_(false), cancel_then_restart_main_request_(false),
2002        simulate_main_network_error_(false),
2003        intercept_redirect_(false), cancel_redirect_request_(false),
2004        intercept_final_response_(false), cancel_final_request_(false),
2005        did_intercept_main_(false), did_restart_main_(false),
2006        did_cancel_main_(false), did_cancel_then_restart_main_(false),
2007        did_simulate_error_main_(false),
2008        did_intercept_redirect_(false), did_cancel_redirect_(false),
2009        did_intercept_final_(false), did_cancel_final_(false) {
2010    URLRequest::RegisterRequestInterceptor(this);
2011  }
2012
2013  ~TestInterceptor() {
2014    URLRequest::UnregisterRequestInterceptor(this);
2015  }
2016
2017  virtual URLRequestJob* MaybeIntercept(URLRequest* request) {
2018    if (restart_main_request_) {
2019      restart_main_request_ = false;
2020      did_restart_main_ = true;
2021      return new RestartTestJob(request);
2022    }
2023    if (cancel_main_request_) {
2024      cancel_main_request_ = false;
2025      did_cancel_main_ = true;
2026      return new CancelTestJob(request);
2027    }
2028    if (cancel_then_restart_main_request_) {
2029      cancel_then_restart_main_request_ = false;
2030      did_cancel_then_restart_main_ = true;
2031      return new CancelThenRestartTestJob(request);
2032    }
2033    if (simulate_main_network_error_) {
2034      simulate_main_network_error_ = false;
2035      did_simulate_error_main_ = true;
2036      // will error since the requeted url is not one of its canned urls
2037      return new URLRequestTestJob(request, true);
2038    }
2039    if (!intercept_main_request_)
2040      return NULL;
2041    intercept_main_request_ = false;
2042    did_intercept_main_ = true;
2043    return new URLRequestTestJob(request,
2044                                      main_headers_,
2045                                      main_data_,
2046                                      true);
2047  }
2048
2049  virtual URLRequestJob* MaybeInterceptRedirect(URLRequest* request,
2050                                                     const GURL& location) {
2051    if (cancel_redirect_request_) {
2052      cancel_redirect_request_ = false;
2053      did_cancel_redirect_ = true;
2054      return new CancelTestJob(request);
2055    }
2056    if (!intercept_redirect_)
2057      return NULL;
2058    intercept_redirect_ = false;
2059    did_intercept_redirect_ = true;
2060    return new URLRequestTestJob(request,
2061                                      redirect_headers_,
2062                                      redirect_data_,
2063                                      true);
2064  }
2065
2066  virtual URLRequestJob* MaybeInterceptResponse(URLRequest* request) {
2067    if (cancel_final_request_) {
2068      cancel_final_request_ = false;
2069      did_cancel_final_ = true;
2070      return new CancelTestJob(request);
2071    }
2072    if (!intercept_final_response_)
2073      return NULL;
2074    intercept_final_response_ = false;
2075    did_intercept_final_ = true;
2076    return new URLRequestTestJob(request,
2077                                      final_headers_,
2078                                      final_data_,
2079                                      true);
2080  }
2081
2082  // Whether to intercept the main request, and if so the response to return.
2083  bool intercept_main_request_;
2084  std::string main_headers_;
2085  std::string main_data_;
2086
2087  // Other actions we take at MaybeIntercept time
2088  bool restart_main_request_;
2089  bool cancel_main_request_;
2090  bool cancel_then_restart_main_request_;
2091  bool simulate_main_network_error_;
2092
2093  // Whether to intercept redirects, and if so the response to return.
2094  bool intercept_redirect_;
2095  std::string redirect_headers_;
2096  std::string redirect_data_;
2097
2098  // Other actions we can take at MaybeInterceptRedirect time
2099  bool cancel_redirect_request_;
2100
2101  // Whether to intercept final response, and if so the response to return.
2102  bool intercept_final_response_;
2103  std::string final_headers_;
2104  std::string final_data_;
2105
2106  // Other actions we can take at MaybeInterceptResponse time
2107  bool cancel_final_request_;
2108
2109  // If we did something or not
2110  bool did_intercept_main_;
2111  bool did_restart_main_;
2112  bool did_cancel_main_;
2113  bool did_cancel_then_restart_main_;
2114  bool did_simulate_error_main_;
2115  bool did_intercept_redirect_;
2116  bool did_cancel_redirect_;
2117  bool did_intercept_final_;
2118  bool did_cancel_final_;
2119
2120  // Static getters for canned response header and data strings
2121
2122  static std::string ok_data() {
2123    return URLRequestTestJob::test_data_1();
2124  }
2125
2126  static std::string ok_headers() {
2127    return URLRequestTestJob::test_headers();
2128  }
2129
2130  static std::string redirect_data() {
2131    return std::string();
2132  }
2133
2134  static std::string redirect_headers() {
2135    return URLRequestTestJob::test_redirect_headers();
2136  }
2137
2138  static std::string error_data() {
2139    return std::string("ohhh nooooo mr. bill!");
2140  }
2141
2142  static std::string error_headers() {
2143    return URLRequestTestJob::test_error_headers();
2144  }
2145};
2146
2147TEST_F(URLRequestTest, Intercept) {
2148  TestInterceptor interceptor;
2149
2150  // intercept the main request and respond with a simple response
2151  interceptor.intercept_main_request_ = true;
2152  interceptor.main_headers_ = TestInterceptor::ok_headers();
2153  interceptor.main_data_ = TestInterceptor::ok_data();
2154
2155  TestDelegate d;
2156  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
2157  URLRequest::UserData* user_data0 = new URLRequest::UserData();
2158  URLRequest::UserData* user_data1 = new URLRequest::UserData();
2159  URLRequest::UserData* user_data2 = new URLRequest::UserData();
2160  req.SetUserData(NULL, user_data0);
2161  req.SetUserData(&user_data1, user_data1);
2162  req.SetUserData(&user_data2, user_data2);
2163  req.set_method("GET");
2164  req.Start();
2165  MessageLoop::current()->Run();
2166
2167  // Make sure we can retrieve our specific user data
2168  EXPECT_EQ(user_data0, req.GetUserData(NULL));
2169  EXPECT_EQ(user_data1, req.GetUserData(&user_data1));
2170  EXPECT_EQ(user_data2, req.GetUserData(&user_data2));
2171
2172  // Check the interceptor got called as expected
2173  EXPECT_TRUE(interceptor.did_intercept_main_);
2174
2175  // Check we got one good response
2176  EXPECT_TRUE(req.status().is_success());
2177  EXPECT_EQ(200, req.response_headers()->response_code());
2178  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
2179  EXPECT_EQ(1, d.response_started_count());
2180  EXPECT_EQ(0, d.received_redirect_count());
2181}
2182
2183TEST_F(URLRequestTest, InterceptRedirect) {
2184  TestInterceptor interceptor;
2185
2186  // intercept the main request and respond with a redirect
2187  interceptor.intercept_main_request_ = true;
2188  interceptor.main_headers_ = TestInterceptor::redirect_headers();
2189  interceptor.main_data_ = TestInterceptor::redirect_data();
2190
2191  // intercept that redirect and respond a final OK response
2192  interceptor.intercept_redirect_ = true;
2193  interceptor.redirect_headers_ =  TestInterceptor::ok_headers();
2194  interceptor.redirect_data_ = TestInterceptor::ok_data();
2195
2196  TestDelegate d;
2197  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
2198  req.set_method("GET");
2199  req.Start();
2200  MessageLoop::current()->Run();
2201
2202  // Check the interceptor got called as expected
2203  EXPECT_TRUE(interceptor.did_intercept_main_);
2204  EXPECT_TRUE(interceptor.did_intercept_redirect_);
2205
2206  // Check we got one good response
2207  EXPECT_TRUE(req.status().is_success());
2208  if (req.status().is_success()) {
2209    EXPECT_EQ(200, req.response_headers()->response_code());
2210  }
2211  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
2212  EXPECT_EQ(1, d.response_started_count());
2213  EXPECT_EQ(0, d.received_redirect_count());
2214}
2215
2216TEST_F(URLRequestTest, InterceptServerError) {
2217  TestInterceptor interceptor;
2218
2219  // intercept the main request to generate a server error response
2220  interceptor.intercept_main_request_ = true;
2221  interceptor.main_headers_ = TestInterceptor::error_headers();
2222  interceptor.main_data_ = TestInterceptor::error_data();
2223
2224  // intercept that error and respond with an OK response
2225  interceptor.intercept_final_response_ = true;
2226  interceptor.final_headers_ = TestInterceptor::ok_headers();
2227  interceptor.final_data_ = TestInterceptor::ok_data();
2228
2229  TestDelegate d;
2230  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
2231  req.set_method("GET");
2232  req.Start();
2233  MessageLoop::current()->Run();
2234
2235  // Check the interceptor got called as expected
2236  EXPECT_TRUE(interceptor.did_intercept_main_);
2237  EXPECT_TRUE(interceptor.did_intercept_final_);
2238
2239  // Check we got one good response
2240  EXPECT_TRUE(req.status().is_success());
2241  EXPECT_EQ(200, req.response_headers()->response_code());
2242  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
2243  EXPECT_EQ(1, d.response_started_count());
2244  EXPECT_EQ(0, d.received_redirect_count());
2245}
2246
2247TEST_F(URLRequestTest, InterceptNetworkError) {
2248  TestInterceptor interceptor;
2249
2250  // intercept the main request to simulate a network error
2251  interceptor.simulate_main_network_error_ = true;
2252
2253  // intercept that error and respond with an OK response
2254  interceptor.intercept_final_response_ = true;
2255  interceptor.final_headers_ = TestInterceptor::ok_headers();
2256  interceptor.final_data_ = TestInterceptor::ok_data();
2257
2258  TestDelegate d;
2259  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
2260  req.set_method("GET");
2261  req.Start();
2262  MessageLoop::current()->Run();
2263
2264  // Check the interceptor got called as expected
2265  EXPECT_TRUE(interceptor.did_simulate_error_main_);
2266  EXPECT_TRUE(interceptor.did_intercept_final_);
2267
2268  // Check we received one good response
2269  EXPECT_TRUE(req.status().is_success());
2270  EXPECT_EQ(200, req.response_headers()->response_code());
2271  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
2272  EXPECT_EQ(1, d.response_started_count());
2273  EXPECT_EQ(0, d.received_redirect_count());
2274}
2275
2276TEST_F(URLRequestTest, InterceptRestartRequired) {
2277  TestInterceptor interceptor;
2278
2279  // restart the main request
2280  interceptor.restart_main_request_ = true;
2281
2282  // then intercept the new main request and respond with an OK response
2283  interceptor.intercept_main_request_ = true;
2284  interceptor.main_headers_ = TestInterceptor::ok_headers();
2285  interceptor.main_data_ = TestInterceptor::ok_data();
2286
2287  TestDelegate d;
2288  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
2289  req.set_method("GET");
2290  req.Start();
2291  MessageLoop::current()->Run();
2292
2293  // Check the interceptor got called as expected
2294  EXPECT_TRUE(interceptor.did_restart_main_);
2295  EXPECT_TRUE(interceptor.did_intercept_main_);
2296
2297  // Check we received one good response
2298  EXPECT_TRUE(req.status().is_success());
2299  if (req.status().is_success()) {
2300    EXPECT_EQ(200, req.response_headers()->response_code());
2301  }
2302  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
2303  EXPECT_EQ(1, d.response_started_count());
2304  EXPECT_EQ(0, d.received_redirect_count());
2305}
2306
2307TEST_F(URLRequestTest, InterceptRespectsCancelMain) {
2308  TestInterceptor interceptor;
2309
2310  // intercept the main request and cancel from within the restarted job
2311  interceptor.cancel_main_request_ = true;
2312
2313  // setup to intercept final response and override it with an OK response
2314  interceptor.intercept_final_response_ = true;
2315  interceptor.final_headers_ = TestInterceptor::ok_headers();
2316  interceptor.final_data_ = TestInterceptor::ok_data();
2317
2318  TestDelegate d;
2319  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
2320  req.set_method("GET");
2321  req.Start();
2322  MessageLoop::current()->Run();
2323
2324  // Check the interceptor got called as expected
2325  EXPECT_TRUE(interceptor.did_cancel_main_);
2326  EXPECT_FALSE(interceptor.did_intercept_final_);
2327
2328  // Check we see a canceled request
2329  EXPECT_FALSE(req.status().is_success());
2330  EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
2331}
2332
2333TEST_F(URLRequestTest, InterceptRespectsCancelRedirect) {
2334  TestInterceptor interceptor;
2335
2336  // intercept the main request and respond with a redirect
2337  interceptor.intercept_main_request_ = true;
2338  interceptor.main_headers_ = TestInterceptor::redirect_headers();
2339  interceptor.main_data_ = TestInterceptor::redirect_data();
2340
2341  // intercept the redirect and cancel from within that job
2342  interceptor.cancel_redirect_request_ = true;
2343
2344  // setup to intercept final response and override it with an OK response
2345  interceptor.intercept_final_response_ = true;
2346  interceptor.final_headers_ = TestInterceptor::ok_headers();
2347  interceptor.final_data_ = TestInterceptor::ok_data();
2348
2349  TestDelegate d;
2350  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
2351  req.set_method("GET");
2352  req.Start();
2353  MessageLoop::current()->Run();
2354
2355  // Check the interceptor got called as expected
2356  EXPECT_TRUE(interceptor.did_intercept_main_);
2357  EXPECT_TRUE(interceptor.did_cancel_redirect_);
2358  EXPECT_FALSE(interceptor.did_intercept_final_);
2359
2360  // Check we see a canceled request
2361  EXPECT_FALSE(req.status().is_success());
2362  EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
2363}
2364
2365TEST_F(URLRequestTest, InterceptRespectsCancelFinal) {
2366  TestInterceptor interceptor;
2367
2368  // intercept the main request to simulate a network error
2369  interceptor.simulate_main_network_error_ = true;
2370
2371  // setup to intercept final response and cancel from within that job
2372  interceptor.cancel_final_request_ = true;
2373
2374  TestDelegate d;
2375  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
2376  req.set_method("GET");
2377  req.Start();
2378  MessageLoop::current()->Run();
2379
2380  // Check the interceptor got called as expected
2381  EXPECT_TRUE(interceptor.did_simulate_error_main_);
2382  EXPECT_TRUE(interceptor.did_cancel_final_);
2383
2384  // Check we see a canceled request
2385  EXPECT_FALSE(req.status().is_success());
2386  EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
2387}
2388
2389TEST_F(URLRequestTest, InterceptRespectsCancelInRestart) {
2390  TestInterceptor interceptor;
2391
2392  // intercept the main request and cancel then restart from within that job
2393  interceptor.cancel_then_restart_main_request_ = true;
2394
2395  // setup to intercept final response and override it with an OK response
2396  interceptor.intercept_final_response_ = true;
2397  interceptor.final_headers_ = TestInterceptor::ok_headers();
2398  interceptor.final_data_ = TestInterceptor::ok_data();
2399
2400  TestDelegate d;
2401  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
2402  req.set_method("GET");
2403  req.Start();
2404  MessageLoop::current()->Run();
2405
2406  // Check the interceptor got called as expected
2407  EXPECT_TRUE(interceptor.did_cancel_then_restart_main_);
2408  EXPECT_FALSE(interceptor.did_intercept_final_);
2409
2410  // Check we see a canceled request
2411  EXPECT_FALSE(req.status().is_success());
2412  EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
2413}
2414
2415// Check that two different URL requests have different identifiers.
2416TEST_F(URLRequestTest, Identifiers) {
2417  TestDelegate d;
2418  TestURLRequest req(GURL("http://example.com"), &d);
2419  TestURLRequest other_req(GURL("http://example.com"), &d);
2420
2421  ASSERT_NE(req.identifier(), other_req.identifier());
2422}
2423
2424// Check that a failure to connect to the proxy is reported to the network
2425// delegate.
2426TEST_F(URLRequestTest, NetworkDelegateProxyError) {
2427  TestDelegate d;
2428  TestNetworkDelegate network_delegate;
2429  TestURLRequest req(GURL("http://example.com"), &d);
2430  req.set_method("GET");
2431
2432  scoped_ptr<MockHostResolverBase> host_resolver(
2433      new MockHostResolver);
2434  host_resolver->rules()->AddSimulatedFailure("*");
2435  scoped_refptr<TestURLRequestContext> context(
2436      new TestURLRequestContext("myproxy:70", host_resolver.release()));
2437  context->set_network_delegate(&network_delegate);
2438  req.set_context(context);
2439
2440  req.Start();
2441  MessageLoop::current()->Run();
2442
2443  // Check we see a failed request.
2444  EXPECT_FALSE(req.status().is_success());
2445  EXPECT_EQ(URLRequestStatus::FAILED, req.status().status());
2446  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, req.status().os_error());
2447
2448  EXPECT_EQ(1, network_delegate.error_count());
2449  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, network_delegate.last_os_error());
2450}
2451
2452class URLRequestTestFTP : public URLRequestTest {
2453 public:
2454  URLRequestTestFTP() : test_server_(TestServer::TYPE_FTP, FilePath()) {
2455  }
2456
2457 protected:
2458  TestServer test_server_;
2459};
2460
2461// Flaky, see http://crbug.com/25045.
2462TEST_F(URLRequestTestFTP, FLAKY_FTPDirectoryListing) {
2463  ASSERT_TRUE(test_server_.Start());
2464
2465  TestDelegate d;
2466  {
2467    TestURLRequest r(test_server_.GetURL("/"), &d);
2468    r.Start();
2469    EXPECT_TRUE(r.is_pending());
2470
2471    MessageLoop::current()->Run();
2472
2473    EXPECT_FALSE(r.is_pending());
2474    EXPECT_EQ(1, d.response_started_count());
2475    EXPECT_FALSE(d.received_data_before_response());
2476    EXPECT_LT(0, d.bytes_received());
2477    EXPECT_EQ(test_server_.host_port_pair().host(),
2478              r.GetSocketAddress().host());
2479    EXPECT_EQ(test_server_.host_port_pair().port(),
2480              r.GetSocketAddress().port());
2481  }
2482}
2483
2484// Flaky, see http://crbug.com/25045.
2485TEST_F(URLRequestTestFTP, FLAKY_FTPGetTestAnonymous) {
2486  ASSERT_TRUE(test_server_.Start());
2487
2488  FilePath app_path;
2489  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2490  app_path = app_path.AppendASCII("LICENSE");
2491  TestDelegate d;
2492  {
2493    TestURLRequest r(test_server_.GetURL("/LICENSE"), &d);
2494    r.Start();
2495    EXPECT_TRUE(r.is_pending());
2496
2497    MessageLoop::current()->Run();
2498
2499    int64 file_size = 0;
2500    file_util::GetFileSize(app_path, &file_size);
2501
2502    EXPECT_FALSE(r.is_pending());
2503    EXPECT_EQ(1, d.response_started_count());
2504    EXPECT_FALSE(d.received_data_before_response());
2505    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
2506    EXPECT_EQ(test_server_.host_port_pair().host(),
2507              r.GetSocketAddress().host());
2508    EXPECT_EQ(test_server_.host_port_pair().port(),
2509              r.GetSocketAddress().port());
2510  }
2511}
2512
2513// Flaky, see http://crbug.com/25045.
2514TEST_F(URLRequestTestFTP, FLAKY_FTPGetTest) {
2515  ASSERT_TRUE(test_server_.Start());
2516
2517  FilePath app_path;
2518  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2519  app_path = app_path.AppendASCII("LICENSE");
2520  TestDelegate d;
2521  {
2522    TestURLRequest r(
2523        test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", "chrome"),
2524        &d);
2525    r.Start();
2526    EXPECT_TRUE(r.is_pending());
2527
2528    MessageLoop::current()->Run();
2529
2530    int64 file_size = 0;
2531    file_util::GetFileSize(app_path, &file_size);
2532
2533    EXPECT_FALSE(r.is_pending());
2534    EXPECT_EQ(test_server_.host_port_pair().host(),
2535              r.GetSocketAddress().host());
2536    EXPECT_EQ(test_server_.host_port_pair().port(),
2537              r.GetSocketAddress().port());
2538    EXPECT_EQ(1, d.response_started_count());
2539    EXPECT_FALSE(d.received_data_before_response());
2540    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
2541  }
2542}
2543
2544// Flaky, see http://crbug.com/25045.
2545TEST_F(URLRequestTestFTP, FLAKY_FTPCheckWrongPassword) {
2546  ASSERT_TRUE(test_server_.Start());
2547
2548  FilePath app_path;
2549  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2550  app_path = app_path.AppendASCII("LICENSE");
2551  TestDelegate d;
2552  {
2553    TestURLRequest r(
2554        test_server_.GetURLWithUserAndPassword("/LICENSE",
2555                                               "chrome",
2556                                               "wrong_password"),
2557        &d);
2558    r.Start();
2559    EXPECT_TRUE(r.is_pending());
2560
2561    MessageLoop::current()->Run();
2562
2563    int64 file_size = 0;
2564    file_util::GetFileSize(app_path, &file_size);
2565
2566    EXPECT_FALSE(r.is_pending());
2567    EXPECT_EQ(1, d.response_started_count());
2568    EXPECT_FALSE(d.received_data_before_response());
2569    EXPECT_EQ(d.bytes_received(), 0);
2570  }
2571}
2572
2573// Flaky, see http://crbug.com/25045.
2574TEST_F(URLRequestTestFTP, FLAKY_FTPCheckWrongPasswordRestart) {
2575  ASSERT_TRUE(test_server_.Start());
2576
2577  FilePath app_path;
2578  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2579  app_path = app_path.AppendASCII("LICENSE");
2580  TestDelegate d;
2581  // Set correct login credentials. The delegate will be asked for them when
2582  // the initial login with wrong credentials will fail.
2583  d.set_username(kChrome);
2584  d.set_password(kChrome);
2585  {
2586    TestURLRequest r(
2587        test_server_.GetURLWithUserAndPassword("/LICENSE",
2588                                               "chrome",
2589                                               "wrong_password"),
2590        &d);
2591    r.Start();
2592    EXPECT_TRUE(r.is_pending());
2593
2594    MessageLoop::current()->Run();
2595
2596    int64 file_size = 0;
2597    file_util::GetFileSize(app_path, &file_size);
2598
2599    EXPECT_FALSE(r.is_pending());
2600    EXPECT_EQ(1, d.response_started_count());
2601    EXPECT_FALSE(d.received_data_before_response());
2602    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
2603  }
2604}
2605
2606// Flaky, see http://crbug.com/25045.
2607TEST_F(URLRequestTestFTP, FLAKY_FTPCheckWrongUser) {
2608  ASSERT_TRUE(test_server_.Start());
2609
2610  FilePath app_path;
2611  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2612  app_path = app_path.AppendASCII("LICENSE");
2613  TestDelegate d;
2614  {
2615    TestURLRequest r(
2616        test_server_.GetURLWithUserAndPassword("/LICENSE",
2617                                               "wrong_user",
2618                                               "chrome"),
2619        &d);
2620    r.Start();
2621    EXPECT_TRUE(r.is_pending());
2622
2623    MessageLoop::current()->Run();
2624
2625    int64 file_size = 0;
2626    file_util::GetFileSize(app_path, &file_size);
2627
2628    EXPECT_FALSE(r.is_pending());
2629    EXPECT_EQ(1, d.response_started_count());
2630    EXPECT_FALSE(d.received_data_before_response());
2631    EXPECT_EQ(d.bytes_received(), 0);
2632  }
2633}
2634
2635// Flaky, see http://crbug.com/25045.
2636TEST_F(URLRequestTestFTP, FLAKY_FTPCheckWrongUserRestart) {
2637  ASSERT_TRUE(test_server_.Start());
2638
2639  FilePath app_path;
2640  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2641  app_path = app_path.AppendASCII("LICENSE");
2642  TestDelegate d;
2643  // Set correct login credentials. The delegate will be asked for them when
2644  // the initial login with wrong credentials will fail.
2645  d.set_username(kChrome);
2646  d.set_password(kChrome);
2647  {
2648    TestURLRequest r(
2649        test_server_.GetURLWithUserAndPassword("/LICENSE",
2650                                               "wrong_user",
2651                                               "chrome"),
2652        &d);
2653    r.Start();
2654    EXPECT_TRUE(r.is_pending());
2655
2656    MessageLoop::current()->Run();
2657
2658    int64 file_size = 0;
2659    file_util::GetFileSize(app_path, &file_size);
2660
2661    EXPECT_FALSE(r.is_pending());
2662    EXPECT_EQ(1, d.response_started_count());
2663    EXPECT_FALSE(d.received_data_before_response());
2664    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
2665  }
2666}
2667
2668// Flaky, see http://crbug.com/25045.
2669TEST_F(URLRequestTestFTP, FLAKY_FTPCacheURLCredentials) {
2670  ASSERT_TRUE(test_server_.Start());
2671
2672  FilePath app_path;
2673  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2674  app_path = app_path.AppendASCII("LICENSE");
2675
2676  scoped_ptr<TestDelegate> d(new TestDelegate);
2677  {
2678    // Pass correct login identity in the URL.
2679    TestURLRequest r(
2680        test_server_.GetURLWithUserAndPassword("/LICENSE",
2681                                               "chrome",
2682                                               "chrome"),
2683        d.get());
2684    r.Start();
2685    EXPECT_TRUE(r.is_pending());
2686
2687    MessageLoop::current()->Run();
2688
2689    int64 file_size = 0;
2690    file_util::GetFileSize(app_path, &file_size);
2691
2692    EXPECT_FALSE(r.is_pending());
2693    EXPECT_EQ(1, d->response_started_count());
2694    EXPECT_FALSE(d->received_data_before_response());
2695    EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size));
2696  }
2697
2698  d.reset(new TestDelegate);
2699  {
2700    // This request should use cached identity from previous request.
2701    TestURLRequest r(test_server_.GetURL("/LICENSE"), d.get());
2702    r.Start();
2703    EXPECT_TRUE(r.is_pending());
2704
2705    MessageLoop::current()->Run();
2706
2707    int64 file_size = 0;
2708    file_util::GetFileSize(app_path, &file_size);
2709
2710    EXPECT_FALSE(r.is_pending());
2711    EXPECT_EQ(1, d->response_started_count());
2712    EXPECT_FALSE(d->received_data_before_response());
2713    EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size));
2714  }
2715}
2716
2717// Flaky, see http://crbug.com/25045.
2718TEST_F(URLRequestTestFTP, FLAKY_FTPCacheLoginBoxCredentials) {
2719  ASSERT_TRUE(test_server_.Start());
2720
2721  FilePath app_path;
2722  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2723  app_path = app_path.AppendASCII("LICENSE");
2724
2725  scoped_ptr<TestDelegate> d(new TestDelegate);
2726  // Set correct login credentials. The delegate will be asked for them when
2727  // the initial login with wrong credentials will fail.
2728  d->set_username(kChrome);
2729  d->set_password(kChrome);
2730  {
2731    TestURLRequest r(
2732        test_server_.GetURLWithUserAndPassword("/LICENSE",
2733                                               "chrome",
2734                                               "wrong_password"),
2735        d.get());
2736    r.Start();
2737    EXPECT_TRUE(r.is_pending());
2738
2739    MessageLoop::current()->Run();
2740
2741    int64 file_size = 0;
2742    file_util::GetFileSize(app_path, &file_size);
2743
2744    EXPECT_FALSE(r.is_pending());
2745    EXPECT_EQ(1, d->response_started_count());
2746    EXPECT_FALSE(d->received_data_before_response());
2747    EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size));
2748  }
2749
2750  // Use a new delegate without explicit credentials. The cached ones should be
2751  // used.
2752  d.reset(new TestDelegate);
2753  {
2754    // Don't pass wrong credentials in the URL, they would override valid cached
2755    // ones.
2756    TestURLRequest r(test_server_.GetURL("/LICENSE"), d.get());
2757    r.Start();
2758    EXPECT_TRUE(r.is_pending());
2759
2760    MessageLoop::current()->Run();
2761
2762    int64 file_size = 0;
2763    file_util::GetFileSize(app_path, &file_size);
2764
2765    EXPECT_FALSE(r.is_pending());
2766    EXPECT_EQ(1, d->response_started_count());
2767    EXPECT_FALSE(d->received_data_before_response());
2768    EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size));
2769  }
2770}
2771
2772// Check that default A-L header is sent.
2773TEST_F(URLRequestTestHTTP, DefaultAcceptLanguage) {
2774  ASSERT_TRUE(test_server_.Start());
2775
2776  TestDelegate d;
2777  TestURLRequest req(test_server_.GetURL("echoheader?Accept-Language"), &d);
2778  scoped_refptr<URLRequestContext> context = new TestURLRequestContext;
2779  context->set_accept_language("en");
2780  req.set_context(context);
2781  req.Start();
2782  MessageLoop::current()->Run();
2783  EXPECT_EQ("en", d.data_received());
2784}
2785
2786// Check that an empty A-L header is not sent. http://crbug.com/77365.
2787TEST_F(URLRequestTestHTTP, EmptyAcceptLanguage) {
2788  ASSERT_TRUE(test_server_.Start());
2789
2790  TestDelegate d;
2791  TestURLRequest req(test_server_.GetURL("echoheader?Accept-Language"),
2792                                         &d);
2793  scoped_refptr<URLRequestContext> context = new TestURLRequestContext;
2794  context->set_accept_language("");
2795  req.set_context(context);
2796  req.Start();
2797  MessageLoop::current()->Run();
2798  EXPECT_EQ("None", d.data_received());
2799}
2800
2801// Check that if request overrides the A-L header, the default is not appended.
2802// See http://crbug.com/20894
2803TEST_F(URLRequestTestHTTP, OverrideAcceptLanguage) {
2804  ASSERT_TRUE(test_server_.Start());
2805
2806  TestDelegate d;
2807  TestURLRequest
2808      req(test_server_.GetURL("echoheader?Accept-Language"), &d);
2809  req.set_context(new TestURLRequestContext());
2810  HttpRequestHeaders headers;
2811  headers.SetHeader(HttpRequestHeaders::kAcceptLanguage, "ru");
2812  req.SetExtraRequestHeaders(headers);
2813  req.Start();
2814  MessageLoop::current()->Run();
2815  EXPECT_EQ(std::string("ru"), d.data_received());
2816}
2817
2818// Check that default A-C header is sent.
2819TEST_F(URLRequestTestHTTP, DefaultAcceptCharset) {
2820  ASSERT_TRUE(test_server_.Start());
2821
2822  TestDelegate d;
2823  TestURLRequest req(test_server_.GetURL("echoheader?Accept-Charset"), &d);
2824  scoped_refptr<URLRequestContext> context = new TestURLRequestContext;
2825  context->set_accept_charset("en");
2826  req.set_context(context);
2827  req.Start();
2828  MessageLoop::current()->Run();
2829  EXPECT_EQ("en", d.data_received());
2830}
2831
2832// Check that an empty A-C header is not sent. http://crbug.com/77365.
2833TEST_F(URLRequestTestHTTP, EmptyAcceptCharset) {
2834  ASSERT_TRUE(test_server_.Start());
2835
2836  TestDelegate d;
2837  TestURLRequest req(test_server_.GetURL("echoheader?Accept-Charset"),
2838                                         &d);
2839  scoped_refptr<URLRequestContext> context = new TestURLRequestContext;
2840  context->set_accept_charset("");
2841  req.set_context(context);
2842  req.Start();
2843  MessageLoop::current()->Run();
2844  EXPECT_EQ("None", d.data_received());
2845}
2846
2847// Check that if request overrides the A-C header, the default is not appended.
2848// See http://crbug.com/20894
2849TEST_F(URLRequestTestHTTP, OverrideAcceptCharset) {
2850  ASSERT_TRUE(test_server_.Start());
2851
2852  TestDelegate d;
2853  TestURLRequest
2854      req(test_server_.GetURL("echoheader?Accept-Charset"), &d);
2855  req.set_context(new TestURLRequestContext());
2856  HttpRequestHeaders headers;
2857  headers.SetHeader(HttpRequestHeaders::kAcceptCharset, "koi-8r");
2858  req.SetExtraRequestHeaders(headers);
2859  req.Start();
2860  MessageLoop::current()->Run();
2861  EXPECT_EQ(std::string("koi-8r"), d.data_received());
2862}
2863
2864// Check that default User-Agent header is sent.
2865TEST_F(URLRequestTestHTTP, DefaultUserAgent) {
2866  ASSERT_TRUE(test_server_.Start());
2867
2868  TestDelegate d;
2869  TestURLRequest req(test_server_.GetURL("echoheader?User-Agent"), &d);
2870  req.set_context(new TestURLRequestContext());
2871  req.Start();
2872  MessageLoop::current()->Run();
2873  EXPECT_EQ(req.context()->GetUserAgent(req.url()), d.data_received());
2874}
2875
2876// Check that if request overrides the User-Agent header,
2877// the default is not appended.
2878TEST_F(URLRequestTestHTTP, OverrideUserAgent) {
2879  ASSERT_TRUE(test_server_.Start());
2880
2881  TestDelegate d;
2882  TestURLRequest
2883      req(test_server_.GetURL("echoheader?User-Agent"), &d);
2884  req.set_context(new TestURLRequestContext());
2885  HttpRequestHeaders headers;
2886  headers.SetHeader(HttpRequestHeaders::kUserAgent, "Lynx (textmode)");
2887  req.SetExtraRequestHeaders(headers);
2888  req.Start();
2889  MessageLoop::current()->Run();
2890  // If the net tests are being run with ChromeFrame then we need to allow for
2891  // the 'chromeframe' suffix which is added to the user agent before the
2892  // closing parentheses.
2893  EXPECT_TRUE(StartsWithASCII(d.data_received(), "Lynx (textmode", true));
2894}
2895
2896}  // namespace net
2897