1// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/url_request/url_request_unittest.h"
6
7#include "build/build_config.h"
8
9#if defined(OS_WIN)
10#include <windows.h>
11#include <shlobj.h>
12#elif defined(USE_NSS)
13#include "base/nss_util.h"
14#endif
15
16#include <algorithm>
17#include <string>
18
19#include "base/file_util.h"
20#include "base/format_macros.h"
21#include "base/message_loop.h"
22#include "base/path_service.h"
23#include "base/process_util.h"
24#include "base/string_piece.h"
25#include "base/string_util.h"
26#include "net/base/cookie_monster.h"
27#include "net/base/cookie_policy.h"
28#include "net/base/load_flags.h"
29#include "net/base/load_log.h"
30#include "net/base/load_log_unittest.h"
31#include "net/base/net_errors.h"
32#include "net/base/net_module.h"
33#include "net/base/net_util.h"
34#include "net/base/upload_data.h"
35#include "net/disk_cache/disk_cache.h"
36#include "net/ftp/ftp_network_layer.h"
37#include "net/http/http_cache.h"
38#include "net/http/http_network_layer.h"
39#include "net/http/http_response_headers.h"
40#include "net/proxy/proxy_service.h"
41#include "net/socket/ssl_test_util.h"
42#include "net/url_request/url_request.h"
43#include "net/url_request/url_request_file_dir_job.h"
44#include "net/url_request/url_request_http_job.h"
45#include "net/url_request/url_request_test_job.h"
46#include "testing/gtest/include/gtest/gtest.h"
47#include "testing/platform_test.h"
48
49using base::Time;
50
51namespace {
52
53base::StringPiece TestNetResourceProvider(int key) {
54  return "header";
55}
56
57// Do a case-insensitive search through |haystack| for |needle|.
58bool ContainsString(const std::string& haystack, const char* needle) {
59  std::string::const_iterator it =
60      std::search(haystack.begin(),
61                  haystack.end(),
62                  needle,
63                  needle + strlen(needle),
64                  CaseInsensitiveCompare<char>());
65  return it != haystack.end();
66}
67
68void FillBuffer(char* buffer, size_t len) {
69  static bool called = false;
70  if (!called) {
71    called = true;
72    int seed = static_cast<int>(Time::Now().ToInternalValue());
73    srand(seed);
74  }
75
76  for (size_t i = 0; i < len; i++) {
77    buffer[i] = static_cast<char>(rand());
78    if (!buffer[i])
79      buffer[i] = 'g';
80  }
81}
82
83scoped_refptr<net::UploadData> CreateSimpleUploadData(const char* data) {
84  scoped_refptr<net::UploadData> upload = new net::UploadData;
85  upload->AppendBytes(data, strlen(data));
86  return upload;
87}
88
89}  // namespace
90
91// Inherit PlatformTest since we require the autorelease pool on Mac OS X.f
92class URLRequestTest : public PlatformTest {
93};
94
95class URLRequestTestHTTP : public URLRequestTest {
96 protected:
97  static void SetUpTestCase() {
98    server_ = HTTPTestServer::CreateForkingServer(
99        L"net/data/url_request_unittest/");
100  }
101
102  static void TearDownTestCase() {
103    server_ = NULL;
104  }
105
106  void HTTPUploadDataOperationTest(const std::string& method) {
107    ASSERT_TRUE(NULL != server_.get());
108    const int kMsgSize = 20000;  // multiple of 10
109    const int kIterations = 50;
110    char *uploadBytes = new char[kMsgSize+1];
111    char *ptr = uploadBytes;
112    char marker = 'a';
113    for (int idx = 0; idx < kMsgSize/10; idx++) {
114      memcpy(ptr, "----------", 10);
115      ptr += 10;
116      if (idx % 100 == 0) {
117        ptr--;
118        *ptr++ = marker;
119        if (++marker > 'z')
120          marker = 'a';
121      }
122    }
123    uploadBytes[kMsgSize] = '\0';
124
125    scoped_refptr<URLRequestContext> context = new URLRequestTestContext();
126
127    for (int i = 0; i < kIterations; ++i) {
128      TestDelegate d;
129      URLRequest r(server_->TestServerPage("echo"), &d);
130      r.set_context(context);
131      r.set_method(method.c_str());
132
133      r.AppendBytesToUpload(uploadBytes, kMsgSize);
134
135      r.Start();
136      EXPECT_TRUE(r.is_pending());
137
138      MessageLoop::current()->Run();
139
140      ASSERT_EQ(1, d.response_started_count()) << "request failed: " <<
141          (int) r.status().status() << ", os error: " << r.status().os_error();
142
143      EXPECT_FALSE(d.received_data_before_response());
144      EXPECT_EQ(uploadBytes, d.data_received());
145      EXPECT_EQ(memcmp(uploadBytes, d.data_received().c_str(), kMsgSize), 0);
146      EXPECT_EQ(d.data_received().compare(uploadBytes), 0);
147    }
148    delete[] uploadBytes;
149  }
150
151  static scoped_refptr<HTTPTestServer> server_;
152};
153
154// static
155scoped_refptr<HTTPTestServer> URLRequestTestHTTP::server_;
156
157TEST_F(URLRequestTestHTTP, ProxyTunnelRedirectTest) {
158  // In this unit test, we're using the HTTPTestServer as a proxy server and
159  // issuing a CONNECT request with the magic host name "www.redirect.com".
160  // The HTTPTestServer will return a 302 response, which we should not
161  // follow.
162  ASSERT_TRUE(NULL != server_.get());
163  TestDelegate d;
164  {
165    URLRequest r(GURL("https://www.redirect.com/"), &d);
166    std::string proxy("localhost:");
167    proxy.append(IntToString(kHTTPDefaultPort));
168    r.set_context(new TestURLRequestContext(proxy));
169
170    r.Start();
171    EXPECT_TRUE(r.is_pending());
172
173    MessageLoop::current()->Run();
174
175    EXPECT_EQ(URLRequestStatus::FAILED, r.status().status());
176    EXPECT_EQ(net::ERR_TUNNEL_CONNECTION_FAILED, r.status().os_error());
177    EXPECT_EQ(1, d.response_started_count());
178    // We should not have followed the redirect.
179    EXPECT_EQ(0, d.received_redirect_count());
180  }
181}
182
183TEST_F(URLRequestTestHTTP, UnexpectedServerAuthTest) {
184  // In this unit test, we're using the HTTPTestServer as a proxy server and
185  // issuing a CONNECT request with the magic host name "www.server-auth.com".
186  // The HTTPTestServer will return a 401 response, which we should balk at.
187  ASSERT_TRUE(NULL != server_.get());
188  TestDelegate d;
189  {
190    URLRequest r(GURL("https://www.server-auth.com/"), &d);
191    std::string proxy("localhost:");
192    proxy.append(IntToString(kHTTPDefaultPort));
193    r.set_context(new TestURLRequestContext(proxy));
194
195    r.Start();
196    EXPECT_TRUE(r.is_pending());
197
198    MessageLoop::current()->Run();
199
200    EXPECT_EQ(URLRequestStatus::FAILED, r.status().status());
201    EXPECT_EQ(net::ERR_TUNNEL_CONNECTION_FAILED, r.status().os_error());
202  }
203}
204
205TEST_F(URLRequestTestHTTP, GetTest_NoCache) {
206  ASSERT_TRUE(NULL != server_.get());
207  TestDelegate d;
208  {
209    TestURLRequest r(server_->TestServerPage(""), &d);
210
211    r.Start();
212    EXPECT_TRUE(r.is_pending());
213
214    MessageLoop::current()->Run();
215
216    EXPECT_EQ(1, d.response_started_count());
217    EXPECT_FALSE(d.received_data_before_response());
218    EXPECT_NE(0, d.bytes_received());
219
220    // The first part of the log will be for URL_REQUEST_START.
221    // After that, there should be an HTTP_TRANSACTION_READ_BODY
222    EXPECT_TRUE(net::LogContainsBeginEvent(
223        *r.load_log(), 0, net::LoadLog::TYPE_URL_REQUEST_START));
224    EXPECT_TRUE(net::LogContainsEndEvent(
225        *r.load_log(), -3, net::LoadLog::TYPE_URL_REQUEST_START));
226    EXPECT_TRUE(net::LogContainsBeginEvent(
227        *r.load_log(), -2, net::LoadLog::TYPE_HTTP_TRANSACTION_READ_BODY));
228    EXPECT_TRUE(net::LogContainsEndEvent(
229        *r.load_log(), -1, net::LoadLog::TYPE_HTTP_TRANSACTION_READ_BODY));
230  }
231}
232
233TEST_F(URLRequestTestHTTP, GetTest) {
234  ASSERT_TRUE(NULL != server_.get());
235  TestDelegate d;
236  {
237    TestURLRequest r(server_->TestServerPage(""), &d);
238
239    r.Start();
240    EXPECT_TRUE(r.is_pending());
241
242    MessageLoop::current()->Run();
243
244    EXPECT_EQ(1, d.response_started_count());
245    EXPECT_FALSE(d.received_data_before_response());
246    EXPECT_NE(0, d.bytes_received());
247  }
248}
249
250TEST_F(URLRequestTestHTTP, HTTPSToHTTPRedirectNoRefererTest) {
251  scoped_refptr<HTTPSTestServer> https_server =
252      HTTPSTestServer::CreateGoodServer(L"net/data/ssl/");
253  ASSERT_TRUE(NULL != https_server.get());
254  ASSERT_TRUE(NULL != server_.get());
255
256  // An https server is sent a request with an https referer,
257  // and responds with a redirect to an http url. The http
258  // server should not be sent the referer.
259  GURL http_destination = server_->TestServerPage("");
260  TestDelegate d;
261  TestURLRequest req(https_server->TestServerPage(
262      "server-redirect?" + http_destination.spec()), &d);
263  req.set_referrer("https://www.referrer.com/");
264  req.Start();
265  MessageLoop::current()->Run();
266
267  EXPECT_EQ(1, d.response_started_count());
268  EXPECT_EQ(1, d.received_redirect_count());
269  EXPECT_EQ(http_destination, req.url());
270  EXPECT_EQ(std::string(), req.referrer());
271}
272
273TEST_F(URLRequestTest, QuitTest) {
274  // Don't use shared server here because we order it to quit.
275  // It would impact other tests.
276  scoped_refptr<HTTPTestServer> server =
277      HTTPTestServer::CreateServer(L"", NULL);
278  ASSERT_TRUE(NULL != server.get());
279  server->SendQuit();
280  EXPECT_TRUE(server->WaitToFinish(20000));
281}
282
283class HTTPSRequestTest : public testing::Test {
284};
285
286#if defined(OS_MACOSX)
287// Status 6/19/09:
288//
289// If these tests are enabled on OSX, the first one (HTTPSGetTest)
290// will fail.  I didn't track it down explicitly, but did observe that
291// the testserver.py kills itself (e.g. "process_util_posix.cc(84)]
292// Unable to terminate process.").  tlslite and testserver.py are hard
293// to debug (redirection of stdout/stderr to a file so you can't see
294// errors; lots of naked "except:" statements, etc), but I did track
295// down an SSL auth failure as one cause of it deciding to die
296// silently.
297//
298// The next test, HTTPSMismatchedTest, will look like it hangs by
299// looping over calls to SSLHandshake() (Security framework call) as
300// called from SSLClientSocketMac::DoHandshake().  Return values are a
301// repeating pattern of -9803 (come back later) and -9812 (cert valid
302// but root not trusted).  If you don't have the cert in your keychain
303// as documented on http://dev.chromium.org/developers/testing, the
304// -9812 becomes a -9813 (no root cert).  Interestingly, the handshake
305// also appears to be a failure point for other disabled tests, such
306// as (SSLClientSocketTest,Connect) in
307// net/base/ssl_client_socket_unittest.cc.
308//
309// Old comment (not sure if obsolete):
310// ssl_client_socket_mac.cc crashes currently in GetSSLInfo
311// when called on a connection with an unrecognized certificate
312#define MAYBE_HTTPSGetTest        DISABLED_HTTPSGetTest
313#define MAYBE_HTTPSMismatchedTest DISABLED_HTTPSMismatchedTest
314#define MAYBE_HTTPSExpiredTest    DISABLED_HTTPSExpiredTest
315#else
316#define MAYBE_HTTPSGetTest        HTTPSGetTest
317#define MAYBE_HTTPSMismatchedTest HTTPSMismatchedTest
318#define MAYBE_HTTPSExpiredTest    HTTPSExpiredTest
319#endif
320
321TEST_F(HTTPSRequestTest, MAYBE_HTTPSGetTest) {
322  // Note: tools/testserver/testserver.py does not need
323  // a working document root to server the pages / and /hello.html,
324  // so this test doesn't really need to specify a document root.
325  // But if it did, a good one would be net/data/ssl.
326  scoped_refptr<HTTPSTestServer> server =
327      HTTPSTestServer::CreateGoodServer(L"net/data/ssl");
328  ASSERT_TRUE(NULL != server.get());
329
330  TestDelegate d;
331  {
332    TestURLRequest r(server->TestServerPage(""), &d);
333
334    r.Start();
335    EXPECT_TRUE(r.is_pending());
336
337    MessageLoop::current()->Run();
338
339    EXPECT_EQ(1, d.response_started_count());
340    EXPECT_FALSE(d.received_data_before_response());
341    EXPECT_NE(0, d.bytes_received());
342  }
343}
344
345TEST_F(HTTPSRequestTest, MAYBE_HTTPSMismatchedTest) {
346  scoped_refptr<HTTPSTestServer> server =
347      HTTPSTestServer::CreateMismatchedServer(L"net/data/ssl");
348  ASSERT_TRUE(NULL != server.get());
349
350  bool err_allowed = true;
351  for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) {
352    TestDelegate d;
353    {
354      d.set_allow_certificate_errors(err_allowed);
355      TestURLRequest r(server->TestServerPage(""), &d);
356
357      r.Start();
358      EXPECT_TRUE(r.is_pending());
359
360      MessageLoop::current()->Run();
361
362      EXPECT_EQ(1, d.response_started_count());
363      EXPECT_FALSE(d.received_data_before_response());
364      EXPECT_TRUE(d.have_certificate_errors());
365      if (err_allowed)
366        EXPECT_NE(0, d.bytes_received());
367      else
368        EXPECT_EQ(0, d.bytes_received());
369    }
370  }
371}
372
373TEST_F(HTTPSRequestTest, MAYBE_HTTPSExpiredTest) {
374  scoped_refptr<HTTPSTestServer> server =
375      HTTPSTestServer::CreateExpiredServer(L"net/data/ssl");
376  ASSERT_TRUE(NULL != server.get());
377
378  // Iterate from false to true, just so that we do the opposite of the
379  // previous test in order to increase test coverage.
380  bool err_allowed = false;
381  for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) {
382    TestDelegate d;
383    {
384      d.set_allow_certificate_errors(err_allowed);
385      TestURLRequest r(server->TestServerPage(""), &d);
386
387      r.Start();
388      EXPECT_TRUE(r.is_pending());
389
390      MessageLoop::current()->Run();
391
392      EXPECT_EQ(1, d.response_started_count());
393      EXPECT_FALSE(d.received_data_before_response());
394      EXPECT_TRUE(d.have_certificate_errors());
395      if (err_allowed)
396        EXPECT_NE(0, d.bytes_received());
397      else
398        EXPECT_EQ(0, d.bytes_received());
399    }
400  }
401}
402
403TEST_F(URLRequestTestHTTP, CancelTest) {
404  TestDelegate d;
405  {
406    TestURLRequest r(GURL("http://www.google.com/"), &d);
407
408    r.Start();
409    EXPECT_TRUE(r.is_pending());
410
411    r.Cancel();
412
413    MessageLoop::current()->Run();
414
415    // We expect to receive OnResponseStarted even though the request has been
416    // cancelled.
417    EXPECT_EQ(1, d.response_started_count());
418    EXPECT_EQ(0, d.bytes_received());
419    EXPECT_FALSE(d.received_data_before_response());
420  }
421}
422
423TEST_F(URLRequestTestHTTP, CancelTest2) {
424  ASSERT_TRUE(NULL != server_.get());
425
426  // error C2446: '!=' : no conversion from 'HTTPTestServer *const '
427  // to 'const int'
428
429  TestDelegate d;
430  {
431    TestURLRequest r(server_->TestServerPage(""), &d);
432
433    d.set_cancel_in_response_started(true);
434
435    r.Start();
436    EXPECT_TRUE(r.is_pending());
437
438    MessageLoop::current()->Run();
439
440    EXPECT_EQ(1, d.response_started_count());
441    EXPECT_EQ(0, d.bytes_received());
442    EXPECT_FALSE(d.received_data_before_response());
443    EXPECT_EQ(URLRequestStatus::CANCELED, r.status().status());
444  }
445}
446
447TEST_F(URLRequestTestHTTP, CancelTest3) {
448  ASSERT_TRUE(NULL != server_.get());
449  TestDelegate d;
450  {
451    TestURLRequest r(server_->TestServerPage(""), &d);
452
453    d.set_cancel_in_received_data(true);
454
455    r.Start();
456    EXPECT_TRUE(r.is_pending());
457
458    MessageLoop::current()->Run();
459
460    EXPECT_EQ(1, d.response_started_count());
461    // There is no guarantee about how much data was received
462    // before the cancel was issued.  It could have been 0 bytes,
463    // or it could have been all the bytes.
464    // EXPECT_EQ(0, d.bytes_received());
465    EXPECT_FALSE(d.received_data_before_response());
466    EXPECT_EQ(URLRequestStatus::CANCELED, r.status().status());
467  }
468}
469
470TEST_F(URLRequestTestHTTP, CancelTest4) {
471  ASSERT_TRUE(NULL != server_.get());
472  TestDelegate d;
473  {
474    TestURLRequest r(server_->TestServerPage(""), &d);
475
476    r.Start();
477    EXPECT_TRUE(r.is_pending());
478
479    // The request will be implicitly canceled when it is destroyed. The
480    // test delegate must not post a quit message when this happens because
481    // this test doesn't actually have a message loop. The quit message would
482    // get put on this thread's message queue and the next test would exit
483    // early, causing problems.
484    d.set_quit_on_complete(false);
485  }
486  // expect things to just cleanup properly.
487
488  // we won't actually get a received reponse here because we've never run the
489  // message loop
490  EXPECT_FALSE(d.received_data_before_response());
491  EXPECT_EQ(0, d.bytes_received());
492}
493
494TEST_F(URLRequestTestHTTP, CancelTest5) {
495  ASSERT_TRUE(NULL != server_.get());
496  scoped_refptr<URLRequestContext> context = new URLRequestTestContext();
497
498  // populate cache
499  {
500    TestDelegate d;
501    URLRequest r(server_->TestServerPage("cachetime"), &d);
502    r.set_context(context);
503    r.Start();
504    MessageLoop::current()->Run();
505    EXPECT_EQ(URLRequestStatus::SUCCESS, r.status().status());
506  }
507
508  // cancel read from cache (see bug 990242)
509  {
510    TestDelegate d;
511    URLRequest r(server_->TestServerPage("cachetime"), &d);
512    r.set_context(context);
513    r.Start();
514    r.Cancel();
515    MessageLoop::current()->Run();
516
517    EXPECT_EQ(URLRequestStatus::CANCELED, r.status().status());
518    EXPECT_EQ(1, d.response_started_count());
519    EXPECT_EQ(0, d.bytes_received());
520    EXPECT_FALSE(d.received_data_before_response());
521  }
522}
523
524TEST_F(URLRequestTestHTTP, PostTest) {
525  HTTPUploadDataOperationTest("POST");
526}
527
528TEST_F(URLRequestTestHTTP, PutTest) {
529  HTTPUploadDataOperationTest("PUT");
530}
531
532TEST_F(URLRequestTestHTTP, PostEmptyTest) {
533  ASSERT_TRUE(NULL != server_.get());
534  TestDelegate d;
535  {
536    TestURLRequest r(server_->TestServerPage("echo"), &d);
537    r.set_method("POST");
538
539    r.Start();
540    EXPECT_TRUE(r.is_pending());
541
542    MessageLoop::current()->Run();
543
544    ASSERT_EQ(1, d.response_started_count()) << "request failed: " <<
545        (int) r.status().status() << ", os error: " << r.status().os_error();
546
547    EXPECT_FALSE(d.received_data_before_response());
548    EXPECT_TRUE(d.data_received().empty());
549  }
550}
551
552TEST_F(URLRequestTestHTTP, PostFileTest) {
553  ASSERT_TRUE(NULL != server_.get());
554  TestDelegate d;
555  {
556    TestURLRequest r(server_->TestServerPage("echo"), &d);
557    r.set_method("POST");
558
559    FilePath dir;
560    PathService::Get(base::DIR_EXE, &dir);
561    file_util::SetCurrentDirectory(dir);
562
563    FilePath path;
564    PathService::Get(base::DIR_SOURCE_ROOT, &path);
565    path = path.Append(FILE_PATH_LITERAL("net"));
566    path = path.Append(FILE_PATH_LITERAL("data"));
567    path = path.Append(FILE_PATH_LITERAL("url_request_unittest"));
568    path = path.Append(FILE_PATH_LITERAL("with-headers.html"));
569    r.AppendFileToUpload(path);
570
571    // This file should just be ignored in the upload stream.
572    r.AppendFileToUpload(FilePath(FILE_PATH_LITERAL(
573        "c:\\path\\to\\non\\existant\\file.randomness.12345")));
574
575    r.Start();
576    EXPECT_TRUE(r.is_pending());
577
578    MessageLoop::current()->Run();
579
580    int64 longsize;
581    ASSERT_EQ(true, file_util::GetFileSize(path, &longsize));
582    int size = static_cast<int>(longsize);
583    scoped_array<char> buf(new char[size]);
584
585    int size_read = static_cast<int>(file_util::ReadFile(path,
586        buf.get(), size));
587    ASSERT_EQ(size, size_read);
588
589    ASSERT_EQ(1, d.response_started_count()) << "request failed: " <<
590        (int) r.status().status() << ", os error: " << r.status().os_error();
591
592    EXPECT_FALSE(d.received_data_before_response());
593
594    ASSERT_EQ(size, d.bytes_received());
595    EXPECT_EQ(0, memcmp(d.data_received().c_str(), buf.get(), size));
596  }
597}
598
599TEST_F(URLRequestTest, AboutBlankTest) {
600  TestDelegate d;
601  {
602    TestURLRequest r(GURL("about:blank"), &d);
603
604    r.Start();
605    EXPECT_TRUE(r.is_pending());
606
607    MessageLoop::current()->Run();
608
609    EXPECT_TRUE(!r.is_pending());
610    EXPECT_FALSE(d.received_data_before_response());
611    EXPECT_EQ(d.bytes_received(), 0);
612  }
613}
614
615TEST_F(URLRequestTest, DataURLImageTest) {
616  TestDelegate d;
617  {
618    // Use our nice little Chrome logo.
619    TestURLRequest r(GURL(
620        "data:image/png;base64,"
621        "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADVklEQVQ4jX2TfUwUBBjG3"
622        "w1y+HGcd9dxhXR8T4awOccJGgOSWclHImznLkTlSw0DDQXkrmgYgbUYnlQTqQxIEVxitD"
623        "5UMCATRA1CEEg+Qjw3bWDxIauJv/5oumqs39/P827vnucRmYN0gyF01GI5MpCVdW0gO7t"
624        "vNC+vqSEtbZefk5NuLv1jdJ46p/zw0HeH4+PHr3h7c1mjoV2t5rKzMx1+fg9bAgK6zHq9"
625        "cU5z+LpA3xOtx34+vTeT21onRuzssC3zxbbSwC13d/pFuC7CkIMDxQpF7r/MWq12UctI1"
626        "dWWm99ypqSYmRUBdKem8MkrO/kgaTt1O7YzlpzE5GIVd0WYUqt57yWf2McHTObYPbVD+Z"
627        "wbtlLTVMZ3BW+TnLyXLaWtmEq6WJVbT3HBh3Svj2HQQcm43XwmtoYM6vVKleh0uoWvnzW"
628        "3v3MpidruPTQPf0bia7sJOtBM0ufTWNvus/nkDFHF9ZS+uYVjRUasMeHUmyLYtcklTvzW"
629        "GFZnNOXczThvpKIzjcahSqIzkvDLayDq6D3eOjtBbNUEIZYyqsvj4V4wY92eNJ4IoyhTb"
630        "xXX1T5xsV9tm9r4TQwHLiZw/pdDZJea8TKmsmR/K0uLh/GwnCHghTja6lPhphezPfO5/5"
631        "MrVvMzNaI3+ERHfrFzPKQukrQGI4d/3EFD/3E2mVNYvi4at7CXWREaxZGD+3hg28zD3gV"
632        "Md6q5c8GdosynKmSeRuGzpjyl1/9UDGtPR5HeaKT8Wjo17WXk579BXVUhN64ehF9fhRtq"
633        "/uxxZKzNiZFGD0wRC3NFROZ5mwIPL/96K/rKMMLrIzF9uhHr+/sYH7DAbwlgC4J+R2Z7F"
634        "Ux1qLnV7MGF40smVSoJ/jvHRfYhQeUJd/SnYtGWhPHR0Sz+GE2F2yth0B36Vcz2KpnufB"
635        "JbsysjjW4kblBUiIjiURUWqJY65zxbnTy57GQyH58zgy0QBtTQv5gH15XMdKkYu+TGaJM"
636        "nlm2O34uI4b9tflqp1+QEFGzoW/ulmcofcpkZCYJhDfSpme7QcrHa+Xfji8paEQkTkSfm"
637        "moRWRNZr/F1KfVMjW+IKEnv2FwZfKdzt0BQR6lClcZR0EfEXEfv/G6W9iLiIyCoReV5En"
638        "hORIBHx+ufPj/gLB/zGI/G4Bk0AAAAASUVORK5CYII="),
639        &d);
640
641    r.Start();
642    EXPECT_TRUE(r.is_pending());
643
644    MessageLoop::current()->Run();
645
646    EXPECT_TRUE(!r.is_pending());
647    EXPECT_FALSE(d.received_data_before_response());
648    EXPECT_EQ(d.bytes_received(), 911);
649  }
650}
651
652TEST_F(URLRequestTest, FileTest) {
653  FilePath app_path;
654  PathService::Get(base::FILE_EXE, &app_path);
655  GURL app_url = net::FilePathToFileURL(app_path);
656
657  TestDelegate d;
658  {
659    TestURLRequest r(app_url, &d);
660
661    r.Start();
662    EXPECT_TRUE(r.is_pending());
663
664    MessageLoop::current()->Run();
665
666    int64 file_size = -1;
667    EXPECT_TRUE(file_util::GetFileSize(app_path, &file_size));
668
669    EXPECT_TRUE(!r.is_pending());
670    EXPECT_EQ(1, d.response_started_count());
671    EXPECT_FALSE(d.received_data_before_response());
672    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
673  }
674}
675
676TEST_F(URLRequestTest, FileTestFullSpecifiedRange) {
677  const size_t buffer_size = 4000;
678  scoped_array<char> buffer(new char[buffer_size]);
679  FillBuffer(buffer.get(), buffer_size);
680
681  FilePath temp_path;
682  EXPECT_TRUE(file_util::CreateTemporaryFile(&temp_path));
683  GURL temp_url = net::FilePathToFileURL(temp_path);
684  EXPECT_TRUE(file_util::WriteFile(temp_path, buffer.get(), buffer_size));
685
686  int64 file_size;
687  EXPECT_TRUE(file_util::GetFileSize(temp_path, &file_size));
688
689  const size_t first_byte_position = 500;
690  const size_t last_byte_position = buffer_size - first_byte_position;
691  const size_t content_length = last_byte_position - first_byte_position + 1;
692  std::string partial_buffer_string(buffer.get() + first_byte_position,
693                                    buffer.get() + last_byte_position + 1);
694
695  TestDelegate d;
696  {
697    TestURLRequest r(temp_url, &d);
698
699    r.SetExtraRequestHeaders(
700        StringPrintf("Range: bytes=%" PRIuS "-%" PRIuS "\n",
701                     first_byte_position, last_byte_position));
702    r.Start();
703    EXPECT_TRUE(r.is_pending());
704
705    MessageLoop::current()->Run();
706    EXPECT_TRUE(!r.is_pending());
707    EXPECT_EQ(1, d.response_started_count());
708    EXPECT_FALSE(d.received_data_before_response());
709    EXPECT_EQ(static_cast<int>(content_length), d.bytes_received());
710    // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed.
711    EXPECT_TRUE(partial_buffer_string == d.data_received());
712  }
713
714  EXPECT_TRUE(file_util::Delete(temp_path, false));
715}
716
717TEST_F(URLRequestTest, FileTestHalfSpecifiedRange) {
718  const size_t buffer_size = 4000;
719  scoped_array<char> buffer(new char[buffer_size]);
720  FillBuffer(buffer.get(), buffer_size);
721
722  FilePath temp_path;
723  EXPECT_TRUE(file_util::CreateTemporaryFile(&temp_path));
724  GURL temp_url = net::FilePathToFileURL(temp_path);
725  EXPECT_TRUE(file_util::WriteFile(temp_path, buffer.get(), buffer_size));
726
727  int64 file_size;
728  EXPECT_TRUE(file_util::GetFileSize(temp_path, &file_size));
729
730  const size_t first_byte_position = 500;
731  const size_t last_byte_position = buffer_size - 1;
732  const size_t content_length = last_byte_position - first_byte_position + 1;
733  std::string partial_buffer_string(buffer.get() + first_byte_position,
734                                    buffer.get() + last_byte_position + 1);
735
736  TestDelegate d;
737  {
738    TestURLRequest r(temp_url, &d);
739
740    r.SetExtraRequestHeaders(StringPrintf("Range: bytes=%" PRIuS "-\n",
741                                          first_byte_position));
742    r.Start();
743    EXPECT_TRUE(r.is_pending());
744
745    MessageLoop::current()->Run();
746    EXPECT_TRUE(!r.is_pending());
747    EXPECT_EQ(1, d.response_started_count());
748    EXPECT_FALSE(d.received_data_before_response());
749    EXPECT_EQ(static_cast<int>(content_length), d.bytes_received());
750    // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed.
751    EXPECT_TRUE(partial_buffer_string == d.data_received());
752  }
753
754  EXPECT_TRUE(file_util::Delete(temp_path, false));
755}
756
757TEST_F(URLRequestTest, FileTestMultipleRanges) {
758  const size_t buffer_size = 400000;
759  scoped_array<char> buffer(new char[buffer_size]);
760  FillBuffer(buffer.get(), buffer_size);
761
762  FilePath temp_path;
763  EXPECT_TRUE(file_util::CreateTemporaryFile(&temp_path));
764  GURL temp_url = net::FilePathToFileURL(temp_path);
765  EXPECT_TRUE(file_util::WriteFile(temp_path, buffer.get(), buffer_size));
766
767  int64 file_size;
768  EXPECT_TRUE(file_util::GetFileSize(temp_path, &file_size));
769
770  TestDelegate d;
771  {
772    TestURLRequest r(temp_url, &d);
773
774    r.SetExtraRequestHeaders(StringPrintf("Range: bytes=0-0,10-200,200-300\n"));
775    r.Start();
776    EXPECT_TRUE(r.is_pending());
777
778    MessageLoop::current()->Run();
779    EXPECT_TRUE(d.request_failed());
780  }
781
782  EXPECT_TRUE(file_util::Delete(temp_path, false));
783}
784
785TEST_F(URLRequestTest, InvalidUrlTest) {
786  TestDelegate d;
787  {
788    TestURLRequest r(GURL("invalid url"), &d);
789
790    r.Start();
791    EXPECT_TRUE(r.is_pending());
792
793    MessageLoop::current()->Run();
794    EXPECT_TRUE(d.request_failed());
795  }
796}
797
798// This test is disabled because it fails on some computers due to proxies
799// returning a page in response to this request rather than reporting failure.
800TEST_F(URLRequestTest, DISABLED_DnsFailureTest) {
801  TestDelegate d;
802  {
803    URLRequest r(GURL("http://thisisnotavalidurl0123456789foo.com/"), &d);
804
805    r.Start();
806    EXPECT_TRUE(r.is_pending());
807
808    MessageLoop::current()->Run();
809    EXPECT_TRUE(d.request_failed());
810  }
811}
812
813TEST_F(URLRequestTestHTTP, ResponseHeadersTest) {
814  ASSERT_TRUE(NULL != server_.get());
815  TestDelegate d;
816  TestURLRequest req(server_->TestServerPage("files/with-headers.html"), &d);
817  req.Start();
818  MessageLoop::current()->Run();
819
820  const net::HttpResponseHeaders* headers = req.response_headers();
821
822  // Simple sanity check that response_info() accesses the same data.
823  EXPECT_EQ(headers, req.response_info().headers.get());
824
825  std::string header;
826  EXPECT_TRUE(headers->GetNormalizedHeader("cache-control", &header));
827  EXPECT_EQ("private", header);
828
829  header.clear();
830  EXPECT_TRUE(headers->GetNormalizedHeader("content-type", &header));
831  EXPECT_EQ("text/html; charset=ISO-8859-1", header);
832
833  // The response has two "X-Multiple-Entries" headers.
834  // This verfies our output has them concatenated together.
835  header.clear();
836  EXPECT_TRUE(headers->GetNormalizedHeader("x-multiple-entries", &header));
837  EXPECT_EQ("a, b", header);
838}
839
840#if defined(OS_WIN)
841TEST_F(URLRequestTest, ResolveShortcutTest) {
842  FilePath app_path;
843  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
844  app_path = app_path.AppendASCII("net");
845  app_path = app_path.AppendASCII("data");
846  app_path = app_path.AppendASCII("url_request_unittest");
847  app_path = app_path.AppendASCII("with-headers.html");
848
849  std::wstring lnk_path = app_path.value() + L".lnk";
850
851  HRESULT result;
852  IShellLink *shell = NULL;
853  IPersistFile *persist = NULL;
854
855  CoInitialize(NULL);
856  // Temporarily create a shortcut for test
857  result = CoCreateInstance(CLSID_ShellLink, NULL,
858                            CLSCTX_INPROC_SERVER, IID_IShellLink,
859                            reinterpret_cast<LPVOID*>(&shell));
860  ASSERT_TRUE(SUCCEEDED(result));
861  result = shell->QueryInterface(IID_IPersistFile,
862                                reinterpret_cast<LPVOID*>(&persist));
863  ASSERT_TRUE(SUCCEEDED(result));
864  result = shell->SetPath(app_path.value().c_str());
865  EXPECT_TRUE(SUCCEEDED(result));
866  result = shell->SetDescription(L"ResolveShortcutTest");
867  EXPECT_TRUE(SUCCEEDED(result));
868  result = persist->Save(lnk_path.c_str(), TRUE);
869  EXPECT_TRUE(SUCCEEDED(result));
870  if (persist)
871    persist->Release();
872  if (shell)
873    shell->Release();
874
875  TestDelegate d;
876  {
877    TestURLRequest r(net::FilePathToFileURL(FilePath(lnk_path)), &d);
878
879    r.Start();
880    EXPECT_TRUE(r.is_pending());
881
882    MessageLoop::current()->Run();
883
884    WIN32_FILE_ATTRIBUTE_DATA data;
885    GetFileAttributesEx(app_path.value().c_str(),
886                        GetFileExInfoStandard, &data);
887    HANDLE file = CreateFile(app_path.value().c_str(), GENERIC_READ,
888                             FILE_SHARE_READ, NULL, OPEN_EXISTING,
889                             FILE_ATTRIBUTE_NORMAL, NULL);
890    EXPECT_NE(INVALID_HANDLE_VALUE, file);
891    scoped_array<char> buffer(new char[data.nFileSizeLow]);
892    DWORD read_size;
893    BOOL result;
894    result = ReadFile(file, buffer.get(), data.nFileSizeLow,
895                      &read_size, NULL);
896    std::string content(buffer.get(), read_size);
897    CloseHandle(file);
898
899    EXPECT_TRUE(!r.is_pending());
900    EXPECT_EQ(1, d.received_redirect_count());
901    EXPECT_EQ(content, d.data_received());
902  }
903
904  // Clean the shortcut
905  DeleteFile(lnk_path.c_str());
906  CoUninitialize();
907}
908#endif  // defined(OS_WIN)
909
910TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) {
911  ASSERT_TRUE(NULL != server_.get());
912
913  TestDelegate d;
914  TestURLRequest req(server_->TestServerPage(
915      "files/content-type-normalization.html"), &d);
916  req.Start();
917  MessageLoop::current()->Run();
918
919  std::string mime_type;
920  req.GetMimeType(&mime_type);
921  EXPECT_EQ("text/html", mime_type);
922
923  std::string charset;
924  req.GetCharset(&charset);
925  EXPECT_EQ("utf-8", charset);
926  req.Cancel();
927}
928
929TEST_F(URLRequestTest, FileDirCancelTest) {
930  // Put in mock resource provider.
931  net::NetModule::SetResourceProvider(TestNetResourceProvider);
932
933  TestDelegate d;
934  {
935    FilePath file_path;
936    PathService::Get(base::DIR_SOURCE_ROOT, &file_path);
937    file_path = file_path.Append(FILE_PATH_LITERAL("net"));
938    file_path = file_path.Append(FILE_PATH_LITERAL("data"));
939
940    TestURLRequest req(net::FilePathToFileURL(file_path), &d);
941    req.Start();
942    EXPECT_TRUE(req.is_pending());
943
944    d.set_cancel_in_received_data_pending(true);
945
946    MessageLoop::current()->Run();
947  }
948
949  // Take out mock resource provider.
950  net::NetModule::SetResourceProvider(NULL);
951}
952
953TEST_F(URLRequestTest, FileDirRedirectNoCrash) {
954  // There is an implicit redirect when loading a file path that matches a
955  // directory and does not end with a slash.  Ensure that following such
956  // redirects does not crash.  See http://crbug.com/18686.
957
958  FilePath path;
959  PathService::Get(base::DIR_SOURCE_ROOT, &path);
960  path = path.Append(FILE_PATH_LITERAL("net"));
961  path = path.Append(FILE_PATH_LITERAL("data"));
962  path = path.Append(FILE_PATH_LITERAL("url_request_unittest"));
963
964  TestDelegate d;
965  d.set_quit_on_redirect(true);
966  TestURLRequest req(net::FilePathToFileURL(path), &d);
967  req.Start();
968  MessageLoop::current()->Run();
969
970  // Let the directory lister have time to finish its work, which will
971  // cause the URLRequestFileDirJob's ref count to drop to 1.
972  URLRequestFileDirJob* job = static_cast<URLRequestFileDirJob*>(req.job());
973  while (!job->list_complete()) {
974    PlatformThread::Sleep(10);
975    MessageLoop::current()->RunAllPending();
976  }
977
978  // Should not crash during this call!
979  req.FollowDeferredRedirect();
980
981  // Flush event queue.
982  MessageLoop::current()->RunAllPending();
983}
984
985TEST_F(URLRequestTestHTTP, RestrictRedirects) {
986  ASSERT_TRUE(NULL != server_.get());
987
988  TestDelegate d;
989  TestURLRequest req(server_->TestServerPage(
990      "files/redirect-to-file.html"), &d);
991  req.Start();
992  MessageLoop::current()->Run();
993
994  EXPECT_EQ(URLRequestStatus::FAILED, req.status().status());
995  EXPECT_EQ(net::ERR_UNSAFE_REDIRECT, req.status().os_error());
996}
997
998TEST_F(URLRequestTestHTTP, RedirectToInvalidURL) {
999  ASSERT_TRUE(NULL != server_.get());
1000
1001  TestDelegate d;
1002  TestURLRequest req(server_->TestServerPage(
1003      "files/redirect-to-invalid-url.html"), &d);
1004  req.Start();
1005  MessageLoop::current()->Run();
1006
1007  EXPECT_EQ(URLRequestStatus::FAILED, req.status().status());
1008  EXPECT_EQ(net::ERR_INVALID_URL, req.status().os_error());
1009}
1010
1011TEST_F(URLRequestTestHTTP, NoUserPassInReferrer) {
1012  ASSERT_TRUE(NULL != server_.get());
1013  TestDelegate d;
1014  TestURLRequest req(server_->TestServerPage(
1015      "echoheader?Referer"), &d);
1016  req.set_referrer("http://user:pass@foo.com/");
1017  req.Start();
1018  MessageLoop::current()->Run();
1019
1020  EXPECT_EQ(std::string("http://foo.com/"), d.data_received());
1021}
1022
1023TEST_F(URLRequestTestHTTP, CancelRedirect) {
1024  ASSERT_TRUE(NULL != server_.get());
1025  TestDelegate d;
1026  {
1027    d.set_cancel_in_received_redirect(true);
1028    TestURLRequest req(server_->TestServerPage(
1029        "files/redirect-test.html"), &d);
1030    req.Start();
1031    MessageLoop::current()->Run();
1032
1033    EXPECT_EQ(1, d.response_started_count());
1034    EXPECT_EQ(0, d.bytes_received());
1035    EXPECT_FALSE(d.received_data_before_response());
1036    EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
1037  }
1038}
1039
1040TEST_F(URLRequestTestHTTP, DeferredRedirect) {
1041  ASSERT_TRUE(NULL != server_.get());
1042  TestDelegate d;
1043  {
1044    d.set_quit_on_redirect(true);
1045    TestURLRequest req(server_->TestServerPage(
1046        "files/redirect-test.html"), &d);
1047    req.Start();
1048    MessageLoop::current()->Run();
1049
1050    EXPECT_EQ(1, d.received_redirect_count());
1051
1052    req.FollowDeferredRedirect();
1053    MessageLoop::current()->Run();
1054
1055    EXPECT_EQ(1, d.response_started_count());
1056    EXPECT_FALSE(d.received_data_before_response());
1057    EXPECT_EQ(URLRequestStatus::SUCCESS, req.status().status());
1058
1059    FilePath path;
1060    PathService::Get(base::DIR_SOURCE_ROOT, &path);
1061    path = path.Append(FILE_PATH_LITERAL("net"));
1062    path = path.Append(FILE_PATH_LITERAL("data"));
1063    path = path.Append(FILE_PATH_LITERAL("url_request_unittest"));
1064    path = path.Append(FILE_PATH_LITERAL("with-headers.html"));
1065
1066    std::string contents;
1067    EXPECT_TRUE(file_util::ReadFileToString(path, &contents));
1068    EXPECT_EQ(contents, d.data_received());
1069  }
1070}
1071
1072TEST_F(URLRequestTestHTTP, CancelDeferredRedirect) {
1073  ASSERT_TRUE(NULL != server_.get());
1074  TestDelegate d;
1075  {
1076    d.set_quit_on_redirect(true);
1077    TestURLRequest req(server_->TestServerPage(
1078        "files/redirect-test.html"), &d);
1079    req.Start();
1080    MessageLoop::current()->Run();
1081
1082    EXPECT_EQ(1, d.received_redirect_count());
1083
1084    req.Cancel();
1085    MessageLoop::current()->Run();
1086
1087    EXPECT_EQ(1, d.response_started_count());
1088    EXPECT_EQ(0, d.bytes_received());
1089    EXPECT_FALSE(d.received_data_before_response());
1090    EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
1091  }
1092}
1093
1094TEST_F(URLRequestTestHTTP, VaryHeader) {
1095  ASSERT_TRUE(NULL != server_.get());
1096
1097  scoped_refptr<URLRequestContext> context = new URLRequestTestContext();
1098
1099  // populate the cache
1100  {
1101    TestDelegate d;
1102    URLRequest req(server_->TestServerPage("echoheader?foo"), &d);
1103    req.set_context(context);
1104    req.SetExtraRequestHeaders("foo:1");
1105    req.Start();
1106    MessageLoop::current()->Run();
1107  }
1108
1109  // expect a cache hit
1110  {
1111    TestDelegate d;
1112    URLRequest req(server_->TestServerPage("echoheader?foo"), &d);
1113    req.set_context(context);
1114    req.SetExtraRequestHeaders("foo:1");
1115    req.Start();
1116    MessageLoop::current()->Run();
1117
1118    EXPECT_TRUE(req.was_cached());
1119  }
1120
1121  // expect a cache miss
1122  {
1123    TestDelegate d;
1124    URLRequest req(server_->TestServerPage("echoheader?foo"), &d);
1125    req.set_context(context);
1126    req.SetExtraRequestHeaders("foo:2");
1127    req.Start();
1128    MessageLoop::current()->Run();
1129
1130    EXPECT_FALSE(req.was_cached());
1131  }
1132}
1133
1134TEST_F(URLRequestTestHTTP, BasicAuth) {
1135  scoped_refptr<URLRequestContext> context = new URLRequestTestContext();
1136  ASSERT_TRUE(NULL != server_.get());
1137
1138  // populate the cache
1139  {
1140    TestDelegate d;
1141    d.set_username(L"user");
1142    d.set_password(L"secret");
1143
1144    URLRequest r(server_->TestServerPage("auth-basic"), &d);
1145    r.set_context(context);
1146    r.Start();
1147
1148    MessageLoop::current()->Run();
1149
1150    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);
1151  }
1152
1153  // repeat request with end-to-end validation.  since auth-basic results in a
1154  // cachable page, we expect this test to result in a 304.  in which case, the
1155  // response should be fetched from the cache.
1156  {
1157    TestDelegate d;
1158    d.set_username(L"user");
1159    d.set_password(L"secret");
1160
1161    URLRequest r(server_->TestServerPage("auth-basic"), &d);
1162    r.set_context(context);
1163    r.set_load_flags(net::LOAD_VALIDATE_CACHE);
1164    r.Start();
1165
1166    MessageLoop::current()->Run();
1167
1168    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);
1169
1170    // Should be the same cached document.
1171    EXPECT_TRUE(r.was_cached());
1172  }
1173}
1174
1175// Check that Set-Cookie headers in 401 responses are respected.
1176// http://crbug.com/6450
1177TEST_F(URLRequestTestHTTP, BasicAuthWithCookies) {
1178  ASSERT_TRUE(NULL != server_.get());
1179
1180  GURL url_requiring_auth =
1181      server_->TestServerPage("auth-basic?set-cookie-if-challenged");
1182
1183  // Request a page that will give a 401 containing a Set-Cookie header.
1184  // Verify that when the transaction is restarted, it includes the new cookie.
1185  {
1186    scoped_refptr<URLRequestContext> context = new URLRequestTestContext();
1187    TestDelegate d;
1188    d.set_username(L"user");
1189    d.set_password(L"secret");
1190
1191    URLRequest r(url_requiring_auth, &d);
1192    r.set_context(context);
1193    r.Start();
1194
1195    MessageLoop::current()->Run();
1196
1197    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);
1198
1199    // Make sure we sent the cookie in the restarted transaction.
1200    EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true")
1201        != std::string::npos);
1202  }
1203
1204  // Same test as above, except this time the restart is initiated earlier
1205  // (without user intervention since identity is embedded in the URL).
1206  {
1207    scoped_refptr<URLRequestContext> context = new URLRequestTestContext();
1208    TestDelegate d;
1209
1210    GURL::Replacements replacements;
1211    std::string username("user2");
1212    std::string password("secret");
1213    replacements.SetUsernameStr(username);
1214    replacements.SetPasswordStr(password);
1215    GURL url_with_identity = url_requiring_auth.ReplaceComponents(replacements);
1216
1217    URLRequest r(url_with_identity, &d);
1218    r.set_context(context);
1219    r.Start();
1220
1221    MessageLoop::current()->Run();
1222
1223    EXPECT_TRUE(d.data_received().find("user2/secret") != std::string::npos);
1224
1225    // Make sure we sent the cookie in the restarted transaction.
1226    EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true")
1227        != std::string::npos);
1228  }
1229}
1230
1231TEST_F(URLRequestTest, DoNotSendCookies) {
1232  scoped_refptr<HTTPTestServer> server =
1233      HTTPTestServer::CreateServer(L"", NULL);
1234  ASSERT_TRUE(NULL != server.get());
1235  scoped_refptr<URLRequestContext> context = new URLRequestTestContext();
1236
1237  // Set up a cookie.
1238  {
1239    TestDelegate d;
1240    URLRequest req(server->TestServerPage("set-cookie?CookieToNotSend=1"), &d);
1241    req.set_context(context);
1242    req.Start();
1243    MessageLoop::current()->Run();
1244  }
1245
1246  // Verify that the cookie is set.
1247  {
1248    TestDelegate d;
1249    TestURLRequest req(server->TestServerPage("echoheader?Cookie"), &d);
1250    req.set_context(context);
1251    req.Start();
1252    MessageLoop::current()->Run();
1253
1254    EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
1255                != std::string::npos);
1256  }
1257
1258  // Verify that the cookie isn't sent when LOAD_DO_NOT_SEND_COOKIES is set.
1259  {
1260    TestDelegate d;
1261    TestURLRequest req(server->TestServerPage("echoheader?Cookie"), &d);
1262    req.set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES);
1263    req.set_context(context);
1264    req.Start();
1265    MessageLoop::current()->Run();
1266
1267    EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1")
1268                == std::string::npos);
1269  }
1270}
1271
1272TEST_F(URLRequestTest, DoNotSaveCookies) {
1273  scoped_refptr<HTTPTestServer> server =
1274      HTTPTestServer::CreateServer(L"", NULL);
1275  ASSERT_TRUE(NULL != server.get());
1276  scoped_refptr<URLRequestContext> context = new URLRequestTestContext();
1277
1278  // Set up a cookie.
1279  {
1280    TestDelegate d;
1281    URLRequest req(server->TestServerPage("set-cookie?CookieToNotUpdate=2"),
1282                   &d);
1283    req.set_context(context);
1284    req.Start();
1285    MessageLoop::current()->Run();
1286  }
1287
1288  // Try to set-up another cookie and update the previous cookie.
1289  {
1290    TestDelegate d;
1291    URLRequest req(server->TestServerPage(
1292        "set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), &d);
1293    req.set_load_flags(net::LOAD_DO_NOT_SAVE_COOKIES);
1294    req.set_context(context);
1295    req.Start();
1296
1297    MessageLoop::current()->Run();
1298  }
1299
1300  // Verify the cookies weren't saved or updated.
1301  {
1302    TestDelegate d;
1303    TestURLRequest req(server->TestServerPage("echoheader?Cookie"), &d);
1304    req.set_context(context);
1305    req.Start();
1306    MessageLoop::current()->Run();
1307
1308    EXPECT_TRUE(d.data_received().find("CookieToNotSave=1")
1309                == std::string::npos);
1310    EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2")
1311                != std::string::npos);
1312  }
1313}
1314
1315TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy) {
1316  scoped_refptr<HTTPTestServer> server =
1317      HTTPTestServer::CreateServer(L"", NULL);
1318  ASSERT_TRUE(NULL != server.get());
1319  scoped_refptr<URLRequestTestContext> context = new URLRequestTestContext();
1320
1321  // Set up a cookie.
1322  {
1323    TestDelegate d;
1324    URLRequest req(server->TestServerPage("set-cookie?CookieToNotSend=1"), &d);
1325    req.set_context(context);
1326    req.Start();
1327    MessageLoop::current()->Run();
1328  }
1329
1330  // Verify that the cookie is set.
1331  {
1332    TestDelegate d;
1333    TestURLRequest req(server->TestServerPage("echoheader?Cookie"), &d);
1334    req.set_context(context);
1335    req.Start();
1336    MessageLoop::current()->Run();
1337
1338    EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
1339                != std::string::npos);
1340  }
1341
1342  // Verify that the cookie isn't sent.
1343  {
1344    TestCookiePolicy cookie_policy(TestCookiePolicy::NO_GET_COOKIES);
1345    context->set_cookie_policy(&cookie_policy);
1346
1347    TestDelegate d;
1348    TestURLRequest req(server->TestServerPage("echoheader?Cookie"), &d);
1349    req.set_context(context);
1350    req.Start();
1351    MessageLoop::current()->Run();
1352
1353    EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1")
1354                == std::string::npos);
1355
1356    context->set_cookie_policy(NULL);
1357  }
1358}
1359
1360TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy) {
1361  scoped_refptr<HTTPTestServer> server =
1362      HTTPTestServer::CreateServer(L"", NULL);
1363  ASSERT_TRUE(NULL != server.get());
1364  scoped_refptr<URLRequestTestContext> context = new URLRequestTestContext();
1365
1366  // Set up a cookie.
1367  {
1368    TestDelegate d;
1369    URLRequest req(server->TestServerPage("set-cookie?CookieToNotUpdate=2"),
1370                   &d);
1371    req.set_context(context);
1372    req.Start();
1373    MessageLoop::current()->Run();
1374  }
1375
1376  // Try to set-up another cookie and update the previous cookie.
1377  {
1378    TestCookiePolicy cookie_policy(TestCookiePolicy::NO_SET_COOKIE);
1379    context->set_cookie_policy(&cookie_policy);
1380
1381    TestDelegate d;
1382    URLRequest req(server->TestServerPage(
1383        "set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), &d);
1384    req.set_context(context);
1385    req.Start();
1386
1387    MessageLoop::current()->Run();
1388
1389    context->set_cookie_policy(NULL);
1390  }
1391
1392
1393  // Verify the cookies weren't saved or updated.
1394  {
1395    TestDelegate d;
1396    TestURLRequest req(server->TestServerPage("echoheader?Cookie"), &d);
1397    req.set_context(context);
1398    req.Start();
1399    MessageLoop::current()->Run();
1400
1401    EXPECT_TRUE(d.data_received().find("CookieToNotSave=1")
1402                == std::string::npos);
1403    EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2")
1404                != std::string::npos);
1405  }
1406}
1407
1408TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy_Async) {
1409  scoped_refptr<HTTPTestServer> server =
1410      HTTPTestServer::CreateServer(L"", NULL);
1411  ASSERT_TRUE(NULL != server.get());
1412  scoped_refptr<URLRequestTestContext> context = new URLRequestTestContext();
1413
1414  // Set up a cookie.
1415  {
1416    TestDelegate d;
1417    URLRequest req(server->TestServerPage("set-cookie?CookieToNotSend=1"), &d);
1418    req.set_context(context);
1419    req.Start();
1420    MessageLoop::current()->Run();
1421  }
1422
1423  // Verify that the cookie is set.
1424  {
1425    TestDelegate d;
1426    TestURLRequest req(server->TestServerPage("echoheader?Cookie"), &d);
1427    req.set_context(context);
1428    req.Start();
1429    MessageLoop::current()->Run();
1430
1431    EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
1432                != std::string::npos);
1433  }
1434
1435  // Verify that the cookie isn't sent.
1436  {
1437    TestCookiePolicy cookie_policy(TestCookiePolicy::NO_GET_COOKIES |
1438                                   TestCookiePolicy::ASYNC);
1439    context->set_cookie_policy(&cookie_policy);
1440
1441    TestDelegate d;
1442    TestURLRequest req(server->TestServerPage("echoheader?Cookie"), &d);
1443    req.set_context(context);
1444    req.Start();
1445    MessageLoop::current()->Run();
1446
1447    EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1")
1448                == std::string::npos);
1449
1450    context->set_cookie_policy(NULL);
1451  }
1452}
1453
1454TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy_Async) {
1455  scoped_refptr<HTTPTestServer> server =
1456      HTTPTestServer::CreateServer(L"", NULL);
1457  ASSERT_TRUE(NULL != server.get());
1458  scoped_refptr<URLRequestTestContext> context = new URLRequestTestContext();
1459
1460  // Set up a cookie.
1461  {
1462    TestDelegate d;
1463    URLRequest req(server->TestServerPage("set-cookie?CookieToNotUpdate=2"),
1464                   &d);
1465    req.set_context(context);
1466    req.Start();
1467    MessageLoop::current()->Run();
1468  }
1469
1470  // Try to set-up another cookie and update the previous cookie.
1471  {
1472    TestCookiePolicy cookie_policy(TestCookiePolicy::NO_SET_COOKIE |
1473                                   TestCookiePolicy::ASYNC);
1474    context->set_cookie_policy(&cookie_policy);
1475
1476    TestDelegate d;
1477    URLRequest req(server->TestServerPage(
1478        "set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), &d);
1479    req.set_context(context);
1480    req.Start();
1481
1482    MessageLoop::current()->Run();
1483
1484    context->set_cookie_policy(NULL);
1485  }
1486
1487  // Verify the cookies weren't saved or updated.
1488  {
1489    TestDelegate d;
1490    TestURLRequest req(server->TestServerPage("echoheader?Cookie"), &d);
1491    req.set_context(context);
1492    req.Start();
1493    MessageLoop::current()->Run();
1494
1495    EXPECT_TRUE(d.data_received().find("CookieToNotSave=1")
1496                == std::string::npos);
1497    EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2")
1498                != std::string::npos);
1499  }
1500}
1501
1502TEST_F(URLRequestTest, CancelTest_DuringCookiePolicy) {
1503  scoped_refptr<HTTPTestServer> server =
1504      HTTPTestServer::CreateServer(L"", NULL);
1505  ASSERT_TRUE(NULL != server.get());
1506  scoped_refptr<URLRequestTestContext> context = new URLRequestTestContext();
1507
1508  TestCookiePolicy cookie_policy(TestCookiePolicy::ASYNC);
1509  context->set_cookie_policy(&cookie_policy);
1510
1511  // Set up a cookie.
1512  {
1513    TestDelegate d;
1514    URLRequest req(server->TestServerPage("set-cookie?A=1&B=2&C=3"),
1515                   &d);
1516    req.set_context(context);
1517    req.Start();  // Triggers an asynchronous cookie policy check.
1518
1519    // But, now we cancel the request.  This should not cause a crash.
1520  }
1521
1522  context->set_cookie_policy(NULL);
1523}
1524
1525// In this test, we do a POST which the server will 302 redirect.
1526// The subsequent transaction should use GET, and should not send the
1527// Content-Type header.
1528// http://code.google.com/p/chromium/issues/detail?id=843
1529TEST_F(URLRequestTestHTTP, Post302RedirectGet) {
1530  const char kData[] = "hello world";
1531  ASSERT_TRUE(NULL != server_.get());
1532  TestDelegate d;
1533  TestURLRequest req(server_->TestServerPage("files/redirect-to-echoall"), &d);
1534  req.set_method("POST");
1535  req.set_upload(CreateSimpleUploadData(kData));
1536
1537  // Set headers (some of which are specific to the POST).
1538  req.SetExtraRequestHeaders(
1539    "Content-Type: multipart/form-data; "
1540    "boundary=----WebKitFormBoundaryAADeAA+NAAWMAAwZ\r\n"
1541    "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,"
1542    "text/plain;q=0.8,image/png,*/*;q=0.5\r\n"
1543    "Accept-Language: en-US,en\r\n"
1544    "Accept-Charset: ISO-8859-1,*,utf-8\r\n"
1545    "Content-Length: 11\r\n"
1546    "Origin: http://localhost:1337/");
1547  req.Start();
1548  MessageLoop::current()->Run();
1549
1550  std::string mime_type;
1551  req.GetMimeType(&mime_type);
1552  EXPECT_EQ("text/html", mime_type);
1553
1554  const std::string& data = d.data_received();
1555
1556  // Check that the post-specific headers were stripped:
1557  EXPECT_FALSE(ContainsString(data, "Content-Length:"));
1558  EXPECT_FALSE(ContainsString(data, "Content-Type:"));
1559  EXPECT_FALSE(ContainsString(data, "Origin:"));
1560
1561  // These extra request headers should not have been stripped.
1562  EXPECT_TRUE(ContainsString(data, "Accept:"));
1563  EXPECT_TRUE(ContainsString(data, "Accept-Language:"));
1564  EXPECT_TRUE(ContainsString(data, "Accept-Charset:"));
1565}
1566
1567TEST_F(URLRequestTestHTTP, Post307RedirectPost) {
1568  const char kData[] = "hello world";
1569  ASSERT_TRUE(NULL != server_.get());
1570  TestDelegate d;
1571  TestURLRequest req(server_->TestServerPage("files/redirect307-to-echo"),
1572      &d);
1573  req.set_method("POST");
1574  req.set_upload(CreateSimpleUploadData(kData).get());
1575  req.SetExtraRequestHeaders(
1576      "Content-Length: " + UintToString(sizeof(kData) - 1));
1577  req.Start();
1578  MessageLoop::current()->Run();
1579  EXPECT_EQ("POST", req.method());
1580  EXPECT_EQ(kData, d.data_received());
1581}
1582
1583// Custom URLRequestJobs for use with interceptor tests
1584class RestartTestJob : public URLRequestTestJob {
1585 public:
1586  explicit RestartTestJob(URLRequest* request)
1587    : URLRequestTestJob(request, true) {}
1588 protected:
1589  virtual void StartAsync() {
1590    this->NotifyRestartRequired();
1591  }
1592 private:
1593   ~RestartTestJob() {}
1594};
1595
1596class CancelTestJob : public URLRequestTestJob {
1597 public:
1598  explicit CancelTestJob(URLRequest* request)
1599    : URLRequestTestJob(request, true) {}
1600 protected:
1601  virtual void StartAsync() {
1602    request_->Cancel();
1603  }
1604 private:
1605  ~CancelTestJob() {}
1606};
1607
1608class CancelThenRestartTestJob : public URLRequestTestJob {
1609 public:
1610  explicit CancelThenRestartTestJob(URLRequest* request)
1611      : URLRequestTestJob(request, true) {
1612  }
1613 protected:
1614  virtual void StartAsync() {
1615    request_->Cancel();
1616    this->NotifyRestartRequired();
1617  }
1618 private:
1619  ~CancelThenRestartTestJob() {}
1620};
1621
1622// An Interceptor for use with interceptor tests
1623class TestInterceptor : URLRequest::Interceptor {
1624 public:
1625  TestInterceptor()
1626      : intercept_main_request_(false), restart_main_request_(false),
1627        cancel_main_request_(false), cancel_then_restart_main_request_(false),
1628        simulate_main_network_error_(false),
1629        intercept_redirect_(false), cancel_redirect_request_(false),
1630        intercept_final_response_(false), cancel_final_request_(false),
1631        did_intercept_main_(false), did_restart_main_(false),
1632        did_cancel_main_(false), did_cancel_then_restart_main_(false),
1633        did_simulate_error_main_(false),
1634        did_intercept_redirect_(false), did_cancel_redirect_(false),
1635        did_intercept_final_(false), did_cancel_final_(false) {
1636    URLRequest::RegisterRequestInterceptor(this);
1637  }
1638
1639  ~TestInterceptor() {
1640    URLRequest::UnregisterRequestInterceptor(this);
1641  }
1642
1643  virtual URLRequestJob* MaybeIntercept(URLRequest* request) {
1644    if (restart_main_request_) {
1645      restart_main_request_ = false;
1646      did_restart_main_ = true;
1647      return new RestartTestJob(request);
1648    }
1649    if (cancel_main_request_) {
1650      cancel_main_request_ = false;
1651      did_cancel_main_ = true;
1652      return new CancelTestJob(request);
1653    }
1654    if (cancel_then_restart_main_request_) {
1655      cancel_then_restart_main_request_ = false;
1656      did_cancel_then_restart_main_ = true;
1657      return new CancelThenRestartTestJob(request);
1658    }
1659    if (simulate_main_network_error_) {
1660      simulate_main_network_error_ = false;
1661      did_simulate_error_main_ = true;
1662      // will error since the requeted url is not one of its canned urls
1663      return new URLRequestTestJob(request, true);
1664    }
1665    if (!intercept_main_request_)
1666      return NULL;
1667    intercept_main_request_ = false;
1668    did_intercept_main_ = true;
1669    return new URLRequestTestJob(request,
1670                                 main_headers_,
1671                                 main_data_,
1672                                 true);
1673  }
1674
1675  virtual URLRequestJob* MaybeInterceptRedirect(URLRequest* request,
1676                                                const GURL& location) {
1677    if (cancel_redirect_request_) {
1678      cancel_redirect_request_ = false;
1679      did_cancel_redirect_ = true;
1680      return new CancelTestJob(request);
1681    }
1682    if (!intercept_redirect_)
1683      return NULL;
1684    intercept_redirect_ = false;
1685    did_intercept_redirect_ = true;
1686    return new URLRequestTestJob(request,
1687                                 redirect_headers_,
1688                                 redirect_data_,
1689                                 true);
1690  }
1691
1692  virtual URLRequestJob* MaybeInterceptResponse(URLRequest* request) {
1693    if (cancel_final_request_) {
1694      cancel_final_request_ = false;
1695      did_cancel_final_ = true;
1696      return new CancelTestJob(request);
1697    }
1698    if (!intercept_final_response_)
1699      return NULL;
1700    intercept_final_response_ = false;
1701    did_intercept_final_ = true;
1702    return new URLRequestTestJob(request,
1703                                 final_headers_,
1704                                 final_data_,
1705                                 true);
1706  }
1707
1708  // Whether to intercept the main request, and if so the response to return.
1709  bool intercept_main_request_;
1710  std::string main_headers_;
1711  std::string main_data_;
1712
1713  // Other actions we take at MaybeIntercept time
1714  bool restart_main_request_;
1715  bool cancel_main_request_;
1716  bool cancel_then_restart_main_request_;
1717  bool simulate_main_network_error_;
1718
1719  // Whether to intercept redirects, and if so the response to return.
1720  bool intercept_redirect_;
1721  std::string redirect_headers_;
1722  std::string redirect_data_;
1723
1724  // Other actions we can take at MaybeInterceptRedirect time
1725  bool cancel_redirect_request_;
1726
1727  // Whether to intercept final response, and if so the response to return.
1728  bool intercept_final_response_;
1729  std::string final_headers_;
1730  std::string final_data_;
1731
1732  // Other actions we can take at MaybeInterceptResponse time
1733  bool cancel_final_request_;
1734
1735  // If we did something or not
1736  bool did_intercept_main_;
1737  bool did_restart_main_;
1738  bool did_cancel_main_;
1739  bool did_cancel_then_restart_main_;
1740  bool did_simulate_error_main_;
1741  bool did_intercept_redirect_;
1742  bool did_cancel_redirect_;
1743  bool did_intercept_final_;
1744  bool did_cancel_final_;
1745
1746  // Static getters for canned response header and data strings
1747
1748  static std::string ok_data() {
1749    return URLRequestTestJob::test_data_1();
1750  }
1751
1752  static std::string ok_headers() {
1753    return URLRequestTestJob::test_headers();
1754  }
1755
1756  static std::string redirect_data() {
1757    return std::string();
1758  }
1759
1760  static std::string redirect_headers() {
1761    return URLRequestTestJob::test_redirect_headers();
1762  }
1763
1764  static std::string error_data() {
1765    return std::string("ohhh nooooo mr. bill!");
1766  }
1767
1768  static std::string error_headers() {
1769    return URLRequestTestJob::test_error_headers();
1770  }
1771};
1772
1773TEST_F(URLRequestTest, Intercept) {
1774  TestInterceptor interceptor;
1775
1776  // intercept the main request and respond with a simple response
1777  interceptor.intercept_main_request_ = true;
1778  interceptor.main_headers_ = TestInterceptor::ok_headers();
1779  interceptor.main_data_ = TestInterceptor::ok_data();
1780
1781  TestDelegate d;
1782  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
1783  URLRequest::UserData* user_data0 = new URLRequest::UserData();
1784  URLRequest::UserData* user_data1 = new URLRequest::UserData();
1785  URLRequest::UserData* user_data2 = new URLRequest::UserData();
1786  req.SetUserData(NULL, user_data0);
1787  req.SetUserData(&user_data1, user_data1);
1788  req.SetUserData(&user_data2, user_data2);
1789  req.set_method("GET");
1790  req.Start();
1791  MessageLoop::current()->Run();
1792
1793  // Make sure we can retrieve our specific user data
1794  EXPECT_EQ(user_data0, req.GetUserData(NULL));
1795  EXPECT_EQ(user_data1, req.GetUserData(&user_data1));
1796  EXPECT_EQ(user_data2, req.GetUserData(&user_data2));
1797
1798  // Check the interceptor got called as expected
1799  EXPECT_TRUE(interceptor.did_intercept_main_);
1800
1801  // Check we got one good response
1802  EXPECT_TRUE(req.status().is_success());
1803  EXPECT_EQ(200, req.response_headers()->response_code());
1804  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
1805  EXPECT_EQ(1, d.response_started_count());
1806  EXPECT_EQ(0, d.received_redirect_count());
1807}
1808
1809TEST_F(URLRequestTest, InterceptRedirect) {
1810  TestInterceptor interceptor;
1811
1812  // intercept the main request and respond with a redirect
1813  interceptor.intercept_main_request_ = true;
1814  interceptor.main_headers_ = TestInterceptor::redirect_headers();
1815  interceptor.main_data_ = TestInterceptor::redirect_data();
1816
1817  // intercept that redirect and respond a final OK response
1818  interceptor.intercept_redirect_ = true;
1819  interceptor.redirect_headers_ =  TestInterceptor::ok_headers();
1820  interceptor.redirect_data_ = TestInterceptor::ok_data();
1821
1822  TestDelegate d;
1823  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
1824  req.set_method("GET");
1825  req.Start();
1826  MessageLoop::current()->Run();
1827
1828  // Check the interceptor got called as expected
1829  EXPECT_TRUE(interceptor.did_intercept_main_);
1830  EXPECT_TRUE(interceptor.did_intercept_redirect_);
1831
1832  // Check we got one good response
1833  EXPECT_TRUE(req.status().is_success());
1834  if (req.status().is_success()) {
1835    EXPECT_EQ(200, req.response_headers()->response_code());
1836  }
1837  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
1838  EXPECT_EQ(1, d.response_started_count());
1839  EXPECT_EQ(0, d.received_redirect_count());
1840}
1841
1842TEST_F(URLRequestTest, InterceptServerError) {
1843  TestInterceptor interceptor;
1844
1845  // intercept the main request to generate a server error response
1846  interceptor.intercept_main_request_ = true;
1847  interceptor.main_headers_ = TestInterceptor::error_headers();
1848  interceptor.main_data_ = TestInterceptor::error_data();
1849
1850  // intercept that error and respond with an OK response
1851  interceptor.intercept_final_response_ = true;
1852  interceptor.final_headers_ = TestInterceptor::ok_headers();
1853  interceptor.final_data_ = TestInterceptor::ok_data();
1854
1855  TestDelegate d;
1856  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
1857  req.set_method("GET");
1858  req.Start();
1859  MessageLoop::current()->Run();
1860
1861  // Check the interceptor got called as expected
1862  EXPECT_TRUE(interceptor.did_intercept_main_);
1863  EXPECT_TRUE(interceptor.did_intercept_final_);
1864
1865  // Check we got one good response
1866  EXPECT_TRUE(req.status().is_success());
1867  EXPECT_EQ(200, req.response_headers()->response_code());
1868  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
1869  EXPECT_EQ(1, d.response_started_count());
1870  EXPECT_EQ(0, d.received_redirect_count());
1871}
1872
1873TEST_F(URLRequestTest, InterceptNetworkError) {
1874  TestInterceptor interceptor;
1875
1876  // intercept the main request to simulate a network error
1877  interceptor.simulate_main_network_error_ = true;
1878
1879  // intercept that error and respond with an OK response
1880  interceptor.intercept_final_response_ = true;
1881  interceptor.final_headers_ = TestInterceptor::ok_headers();
1882  interceptor.final_data_ = TestInterceptor::ok_data();
1883
1884  TestDelegate d;
1885  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
1886  req.set_method("GET");
1887  req.Start();
1888  MessageLoop::current()->Run();
1889
1890  // Check the interceptor got called as expected
1891  EXPECT_TRUE(interceptor.did_simulate_error_main_);
1892  EXPECT_TRUE(interceptor.did_intercept_final_);
1893
1894  // Check we received one good response
1895  EXPECT_TRUE(req.status().is_success());
1896  EXPECT_EQ(200, req.response_headers()->response_code());
1897  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
1898  EXPECT_EQ(1, d.response_started_count());
1899  EXPECT_EQ(0, d.received_redirect_count());
1900}
1901
1902TEST_F(URLRequestTest, InterceptRestartRequired) {
1903  TestInterceptor interceptor;
1904
1905  // restart the main request
1906  interceptor.restart_main_request_ = true;
1907
1908  // then intercept the new main request and respond with an OK response
1909  interceptor.intercept_main_request_ = true;
1910  interceptor.main_headers_ = TestInterceptor::ok_headers();
1911  interceptor.main_data_ = TestInterceptor::ok_data();
1912
1913  TestDelegate d;
1914  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
1915  req.set_method("GET");
1916  req.Start();
1917  MessageLoop::current()->Run();
1918
1919  // Check the interceptor got called as expected
1920  EXPECT_TRUE(interceptor.did_restart_main_);
1921  EXPECT_TRUE(interceptor.did_intercept_main_);
1922
1923  // Check we received one good response
1924  EXPECT_TRUE(req.status().is_success());
1925  if (req.status().is_success()) {
1926    EXPECT_EQ(200, req.response_headers()->response_code());
1927  }
1928  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
1929  EXPECT_EQ(1, d.response_started_count());
1930  EXPECT_EQ(0, d.received_redirect_count());
1931}
1932
1933TEST_F(URLRequestTest, InterceptRespectsCancelMain) {
1934  TestInterceptor interceptor;
1935
1936  // intercept the main request and cancel from within the restarted job
1937  interceptor.cancel_main_request_ = true;
1938
1939  // setup to intercept final response and override it with an OK response
1940  interceptor.intercept_final_response_ = true;
1941  interceptor.final_headers_ = TestInterceptor::ok_headers();
1942  interceptor.final_data_ = TestInterceptor::ok_data();
1943
1944  TestDelegate d;
1945  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
1946  req.set_method("GET");
1947  req.Start();
1948  MessageLoop::current()->Run();
1949
1950  // Check the interceptor got called as expected
1951  EXPECT_TRUE(interceptor.did_cancel_main_);
1952  EXPECT_FALSE(interceptor.did_intercept_final_);
1953
1954  // Check we see a canceled request
1955  EXPECT_FALSE(req.status().is_success());
1956  EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
1957}
1958
1959TEST_F(URLRequestTest, InterceptRespectsCancelRedirect) {
1960  TestInterceptor interceptor;
1961
1962  // intercept the main request and respond with a redirect
1963  interceptor.intercept_main_request_ = true;
1964  interceptor.main_headers_ = TestInterceptor::redirect_headers();
1965  interceptor.main_data_ = TestInterceptor::redirect_data();
1966
1967  // intercept the redirect and cancel from within that job
1968  interceptor.cancel_redirect_request_ = true;
1969
1970  // setup to intercept final response and override it with an OK response
1971  interceptor.intercept_final_response_ = true;
1972  interceptor.final_headers_ = TestInterceptor::ok_headers();
1973  interceptor.final_data_ = TestInterceptor::ok_data();
1974
1975  TestDelegate d;
1976  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
1977  req.set_method("GET");
1978  req.Start();
1979  MessageLoop::current()->Run();
1980
1981  // Check the interceptor got called as expected
1982  EXPECT_TRUE(interceptor.did_intercept_main_);
1983  EXPECT_TRUE(interceptor.did_cancel_redirect_);
1984  EXPECT_FALSE(interceptor.did_intercept_final_);
1985
1986  // Check we see a canceled request
1987  EXPECT_FALSE(req.status().is_success());
1988  EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
1989}
1990
1991TEST_F(URLRequestTest, InterceptRespectsCancelFinal) {
1992  TestInterceptor interceptor;
1993
1994  // intercept the main request to simulate a network error
1995  interceptor.simulate_main_network_error_ = true;
1996
1997  // setup to intercept final response and cancel from within that job
1998  interceptor.cancel_final_request_ = true;
1999
2000  TestDelegate d;
2001  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
2002  req.set_method("GET");
2003  req.Start();
2004  MessageLoop::current()->Run();
2005
2006  // Check the interceptor got called as expected
2007  EXPECT_TRUE(interceptor.did_simulate_error_main_);
2008  EXPECT_TRUE(interceptor.did_cancel_final_);
2009
2010  // Check we see a canceled request
2011  EXPECT_FALSE(req.status().is_success());
2012  EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
2013}
2014
2015TEST_F(URLRequestTest, InterceptRespectsCancelInRestart) {
2016  TestInterceptor interceptor;
2017
2018  // intercept the main request and cancel then restart from within that job
2019  interceptor.cancel_then_restart_main_request_ = true;
2020
2021  // setup to intercept final response and override it with an OK response
2022  interceptor.intercept_final_response_ = true;
2023  interceptor.final_headers_ = TestInterceptor::ok_headers();
2024  interceptor.final_data_ = TestInterceptor::ok_data();
2025
2026  TestDelegate d;
2027  TestURLRequest req(GURL("http://test_intercept/foo"), &d);
2028  req.set_method("GET");
2029  req.Start();
2030  MessageLoop::current()->Run();
2031
2032  // Check the interceptor got called as expected
2033  EXPECT_TRUE(interceptor.did_cancel_then_restart_main_);
2034  EXPECT_FALSE(interceptor.did_intercept_final_);
2035
2036  // Check we see a canceled request
2037  EXPECT_FALSE(req.status().is_success());
2038  EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
2039}
2040
2041class URLRequestTestFTP : public URLRequestTest {
2042 protected:
2043  static void SetUpTestCase() {
2044    server_ = FTPTestServer::CreateServer(L"");
2045  }
2046
2047  static void TearDownTestCase() {
2048    server_ = NULL;
2049  }
2050
2051  static scoped_refptr<FTPTestServer> server_;
2052};
2053
2054// static
2055scoped_refptr<FTPTestServer> URLRequestTestFTP::server_;
2056
2057// Flaky, see http://crbug.com/25045.
2058TEST_F(URLRequestTestFTP, FLAKY_FTPDirectoryListing) {
2059  ASSERT_TRUE(NULL != server_.get());
2060  TestDelegate d;
2061  {
2062    TestURLRequest r(server_->TestServerPage("/"), &d);
2063    r.Start();
2064    EXPECT_TRUE(r.is_pending());
2065
2066    MessageLoop::current()->Run();
2067
2068    EXPECT_FALSE(r.is_pending());
2069    EXPECT_EQ(1, d.response_started_count());
2070    EXPECT_FALSE(d.received_data_before_response());
2071    EXPECT_LT(0, d.bytes_received());
2072  }
2073}
2074
2075// Flaky, see http://crbug.com/25045.
2076TEST_F(URLRequestTestFTP, FLAKY_FTPGetTestAnonymous) {
2077  ASSERT_TRUE(NULL != server_.get());
2078  FilePath app_path;
2079  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2080  app_path = app_path.AppendASCII("LICENSE");
2081  TestDelegate d;
2082  {
2083    TestURLRequest r(server_->TestServerPage("/LICENSE"), &d);
2084    r.Start();
2085    EXPECT_TRUE(r.is_pending());
2086
2087    MessageLoop::current()->Run();
2088
2089    int64 file_size = 0;
2090    file_util::GetFileSize(app_path, &file_size);
2091
2092    EXPECT_FALSE(r.is_pending());
2093    EXPECT_EQ(1, d.response_started_count());
2094    EXPECT_FALSE(d.received_data_before_response());
2095    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
2096  }
2097}
2098
2099// Flaky, see http://crbug.com/25045.
2100TEST_F(URLRequestTestFTP, FLAKY_FTPGetTest) {
2101  ASSERT_TRUE(NULL != server_.get());
2102  FilePath app_path;
2103  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2104  app_path = app_path.AppendASCII("LICENSE");
2105  TestDelegate d;
2106  {
2107    TestURLRequest r(server_->TestServerPage("/LICENSE", "chrome", "chrome"),
2108                     &d);
2109    r.Start();
2110    EXPECT_TRUE(r.is_pending());
2111
2112    MessageLoop::current()->Run();
2113
2114    int64 file_size = 0;
2115    file_util::GetFileSize(app_path, &file_size);
2116
2117    EXPECT_FALSE(r.is_pending());
2118    EXPECT_EQ(1, d.response_started_count());
2119    EXPECT_FALSE(d.received_data_before_response());
2120    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
2121  }
2122}
2123
2124TEST_F(URLRequestTestFTP, FTPCheckWrongPassword) {
2125  ASSERT_TRUE(NULL != server_.get());
2126  FilePath app_path;
2127  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2128  app_path = app_path.AppendASCII("LICENSE");
2129  TestDelegate d;
2130  {
2131    TestURLRequest r(server_->TestServerPage("/LICENSE",
2132                                             "chrome", "wrong_password"), &d);
2133    r.Start();
2134    EXPECT_TRUE(r.is_pending());
2135
2136    MessageLoop::current()->Run();
2137
2138    int64 file_size = 0;
2139    file_util::GetFileSize(app_path, &file_size);
2140
2141    EXPECT_FALSE(r.is_pending());
2142    EXPECT_EQ(1, d.response_started_count());
2143    EXPECT_FALSE(d.received_data_before_response());
2144    EXPECT_EQ(d.bytes_received(), 0);
2145  }
2146}
2147
2148// Flaky, see http://crbug.com/25045.
2149TEST_F(URLRequestTestFTP, FLAKY_FTPCheckWrongPasswordRestart) {
2150  ASSERT_TRUE(NULL != server_.get());
2151  FilePath app_path;
2152  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2153  app_path = app_path.AppendASCII("LICENSE");
2154  TestDelegate d;
2155  // Set correct login credentials. The delegate will be asked for them when
2156  // the initial login with wrong credentials will fail.
2157  d.set_username(L"chrome");
2158  d.set_password(L"chrome");
2159  {
2160    TestURLRequest r(server_->TestServerPage("/LICENSE",
2161                                             "chrome", "wrong_password"), &d);
2162    r.Start();
2163    EXPECT_TRUE(r.is_pending());
2164
2165    MessageLoop::current()->Run();
2166
2167    int64 file_size = 0;
2168    file_util::GetFileSize(app_path, &file_size);
2169
2170    EXPECT_FALSE(r.is_pending());
2171    EXPECT_EQ(1, d.response_started_count());
2172    EXPECT_FALSE(d.received_data_before_response());
2173    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
2174  }
2175}
2176
2177TEST_F(URLRequestTestFTP, FTPCheckWrongUser) {
2178  ASSERT_TRUE(NULL != server_.get());
2179  FilePath app_path;
2180  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2181  app_path = app_path.AppendASCII("LICENSE");
2182  TestDelegate d;
2183  {
2184    TestURLRequest r(server_->TestServerPage("/LICENSE",
2185                                             "wrong_user", "chrome"), &d);
2186    r.Start();
2187    EXPECT_TRUE(r.is_pending());
2188
2189    MessageLoop::current()->Run();
2190
2191    int64 file_size = 0;
2192    file_util::GetFileSize(app_path, &file_size);
2193
2194    EXPECT_FALSE(r.is_pending());
2195    EXPECT_EQ(1, d.response_started_count());
2196    EXPECT_FALSE(d.received_data_before_response());
2197    EXPECT_EQ(d.bytes_received(), 0);
2198  }
2199}
2200
2201// Flaky, see http://crbug.com/25045.
2202TEST_F(URLRequestTestFTP, FLAKY_FTPCheckWrongUserRestart) {
2203  ASSERT_TRUE(NULL != server_.get());
2204  FilePath app_path;
2205  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2206  app_path = app_path.AppendASCII("LICENSE");
2207  TestDelegate d;
2208  // Set correct login credentials. The delegate will be asked for them when
2209  // the initial login with wrong credentials will fail.
2210  d.set_username(L"chrome");
2211  d.set_password(L"chrome");
2212  {
2213    TestURLRequest r(server_->TestServerPage("/LICENSE",
2214                                             "wrong_user", "chrome"), &d);
2215    r.Start();
2216    EXPECT_TRUE(r.is_pending());
2217
2218    MessageLoop::current()->Run();
2219
2220    int64 file_size = 0;
2221    file_util::GetFileSize(app_path, &file_size);
2222
2223    EXPECT_FALSE(r.is_pending());
2224    EXPECT_EQ(1, d.response_started_count());
2225    EXPECT_FALSE(d.received_data_before_response());
2226    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
2227  }
2228}
2229
2230// Flaky, see http://crbug.com/25045.
2231TEST_F(URLRequestTestFTP, FLAKY_FTPCacheURLCredentials) {
2232  ASSERT_TRUE(NULL != server_.get());
2233  FilePath app_path;
2234  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2235  app_path = app_path.AppendASCII("LICENSE");
2236
2237  scoped_ptr<TestDelegate> d(new TestDelegate);
2238  {
2239    // Pass correct login identity in the URL.
2240    TestURLRequest r(server_->TestServerPage("/LICENSE",
2241                                             "chrome", "chrome"),
2242                     d.get());
2243    r.Start();
2244    EXPECT_TRUE(r.is_pending());
2245
2246    MessageLoop::current()->Run();
2247
2248    int64 file_size = 0;
2249    file_util::GetFileSize(app_path, &file_size);
2250
2251    EXPECT_FALSE(r.is_pending());
2252    EXPECT_EQ(1, d->response_started_count());
2253    EXPECT_FALSE(d->received_data_before_response());
2254    EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size));
2255  }
2256
2257  d.reset(new TestDelegate);
2258  {
2259    // This request should use cached identity from previous request.
2260    TestURLRequest r(server_->TestServerPage("/LICENSE"), d.get());
2261    r.Start();
2262    EXPECT_TRUE(r.is_pending());
2263
2264    MessageLoop::current()->Run();
2265
2266    int64 file_size = 0;
2267    file_util::GetFileSize(app_path, &file_size);
2268
2269    EXPECT_FALSE(r.is_pending());
2270    EXPECT_EQ(1, d->response_started_count());
2271    EXPECT_FALSE(d->received_data_before_response());
2272    EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size));
2273  }
2274}
2275
2276// Flaky, see http://crbug.com/25045.
2277TEST_F(URLRequestTestFTP, FLAKY_FTPCacheLoginBoxCredentials) {
2278  ASSERT_TRUE(NULL != server_.get());
2279  FilePath app_path;
2280  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
2281  app_path = app_path.AppendASCII("LICENSE");
2282
2283  scoped_ptr<TestDelegate> d(new TestDelegate);
2284  // Set correct login credentials. The delegate will be asked for them when
2285  // the initial login with wrong credentials will fail.
2286  d->set_username(L"chrome");
2287  d->set_password(L"chrome");
2288  {
2289    TestURLRequest r(server_->TestServerPage("/LICENSE",
2290                                             "chrome", "wrong_password"),
2291                     d.get());
2292    r.Start();
2293    EXPECT_TRUE(r.is_pending());
2294
2295    MessageLoop::current()->Run();
2296
2297    int64 file_size = 0;
2298    file_util::GetFileSize(app_path, &file_size);
2299
2300    EXPECT_FALSE(r.is_pending());
2301    EXPECT_EQ(1, d->response_started_count());
2302    EXPECT_FALSE(d->received_data_before_response());
2303    EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size));
2304  }
2305
2306  // Use a new delegate without explicit credentials. The cached ones should be
2307  // used.
2308  d.reset(new TestDelegate);
2309  {
2310    // Don't pass wrong credentials in the URL, they would override valid cached
2311    // ones.
2312    TestURLRequest r(server_->TestServerPage("/LICENSE"), d.get());
2313    r.Start();
2314    EXPECT_TRUE(r.is_pending());
2315
2316    MessageLoop::current()->Run();
2317
2318    int64 file_size = 0;
2319    file_util::GetFileSize(app_path, &file_size);
2320
2321    EXPECT_FALSE(r.is_pending());
2322    EXPECT_EQ(1, d->response_started_count());
2323    EXPECT_FALSE(d->received_data_before_response());
2324    EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size));
2325  }
2326}
2327
2328// Check that default A-L header is sent.
2329TEST_F(URLRequestTestHTTP, DefaultAcceptLanguage) {
2330  ASSERT_TRUE(NULL != server_.get());
2331  TestDelegate d;
2332  TestURLRequest req(server_->TestServerPage("echoheader?Accept-Language"), &d);
2333  req.set_context(new URLRequestTestContext());
2334  req.Start();
2335  MessageLoop::current()->Run();
2336  EXPECT_EQ(req.context()->accept_language(), d.data_received());
2337}
2338
2339// Check that if request overrides the A-L header, the default is not appended.
2340// See http://crbug.com/20894
2341TEST_F(URLRequestTestHTTP, OverrideAcceptLanguage) {
2342  ASSERT_TRUE(NULL != server_.get());
2343  TestDelegate d;
2344  TestURLRequest
2345      req(server_->TestServerPage("echoheaderoverride?Accept-Language"), &d);
2346  req.set_context(new URLRequestTestContext());
2347  req.SetExtraRequestHeaders("Accept-Language: ru");
2348  req.Start();
2349  MessageLoop::current()->Run();
2350  EXPECT_EQ(std::string("ru"), d.data_received());
2351}
2352
2353// Check that default A-C header is sent.
2354TEST_F(URLRequestTestHTTP, DefaultAcceptCharset) {
2355  ASSERT_TRUE(NULL != server_.get());
2356  TestDelegate d;
2357  TestURLRequest req(server_->TestServerPage("echoheader?Accept-Charset"), &d);
2358  req.set_context(new URLRequestTestContext());
2359  req.Start();
2360  MessageLoop::current()->Run();
2361  EXPECT_EQ(req.context()->accept_charset(), d.data_received());
2362}
2363
2364// Check that if request overrides the A-C header, the default is not appended.
2365// See http://crbug.com/20894
2366TEST_F(URLRequestTestHTTP, OverrideAcceptCharset) {
2367  ASSERT_TRUE(NULL != server_.get());
2368  TestDelegate d;
2369  TestURLRequest
2370      req(server_->TestServerPage("echoheaderoverride?Accept-Charset"), &d);
2371  req.set_context(new URLRequestTestContext());
2372  req.SetExtraRequestHeaders("Accept-Charset: koi-8r");
2373  req.Start();
2374  MessageLoop::current()->Run();
2375  EXPECT_EQ(std::string("koi-8r"), d.data_received());
2376}
2377