// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/url_request/url_request_unittest.h"

#include "build/build_config.h"

#if defined(OS_WIN)
#include <windows.h>
#include <shlobj.h>
#elif defined(OS_LINUX)
#include "base/nss_init.h"
#endif

#include <algorithm>
#include <string>

#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/string_piece.h"
#include "base/string_util.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/net_module.h"
#include "net/base/net_util.h"
#include "net/base/ssl_test_util.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_layer.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

using base::Time;

namespace {

class URLRequestHttpCacheContext : public URLRequestContext {
 public:
  URLRequestHttpCacheContext() {
    proxy_service_ = net::ProxyService::CreateNull();
    http_transaction_factory_ =
        new net::HttpCache(net::HttpNetworkLayer::CreateFactory(proxy_service_),
                           disk_cache::CreateInMemoryCacheBackend(0));
  }

  virtual ~URLRequestHttpCacheContext() {
    delete http_transaction_factory_;
    delete proxy_service_;
  }
};

class TestURLRequest : public URLRequest {
 public:
   TestURLRequest(const GURL& url, Delegate* delegate)
       : URLRequest(url, delegate) {
     set_context(new URLRequestHttpCacheContext());
   }
};

StringPiece TestNetResourceProvider(int key) {
  return "header";
}

// Do a case-insensitive search through |haystack| for |needle|.
bool ContainsString(const std::string& haystack, const char* needle) {
  std::string::const_iterator it =
      std::search(haystack.begin(),
                  haystack.end(),
                  needle,
                  needle + strlen(needle),
                  CaseInsensitiveCompare<char>());
  return it != haystack.end();
}

}  // namespace

// Inherit PlatformTest since we require the autorelease pool on Mac OS X.f
class URLRequestTest : public PlatformTest {
};

TEST_F(URLRequestTest, GetTest_NoCache) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"");
  ASSERT_TRUE(NULL != server.get());
  TestDelegate d;
  {
    TestURLRequest r(server->TestServerPage(""), &d);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_NE(0, d.bytes_received());
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

TEST_F(URLRequestTest, GetTest) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"");
  ASSERT_TRUE(NULL != server.get());
  TestDelegate d;
  {
    TestURLRequest r(server->TestServerPage(""), &d);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_NE(0, d.bytes_received());
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

class HTTPSRequestTest : public testing::Test {
 protected:
   HTTPSRequestTest() : util_() {};

   SSLTestUtil util_;
};

#if defined(OS_MACOSX)
// TODO(port): support temporary root cert on mac
#define MAYBE_HTTPSGetTest DISABLED_HTTPSGetTest
#else
#define MAYBE_HTTPSGetTest HTTPSGetTest
#endif

TEST_F(HTTPSRequestTest, MAYBE_HTTPSGetTest) {
  // Note: tools/testserver/testserver.py does not need
  // a working document root to server the pages / and /hello.html,
  // so this test doesn't really need to specify a document root.
  // But if it did, a good one would be net/data/ssl.
  scoped_refptr<HTTPSTestServer> server =
      HTTPSTestServer::CreateServer(util_.kHostName, util_.kOKHTTPSPort,
      L"net/data/ssl", util_.GetOKCertPath().ToWStringHack());
  ASSERT_TRUE(NULL != server.get());

  EXPECT_TRUE(util_.CheckCATrusted());
  TestDelegate d;
  {
    TestURLRequest r(server->TestServerPage(""), &d);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_NE(0, d.bytes_received());
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

TEST_F(URLRequestTest, CancelTest) {
  TestDelegate d;
  {
    TestURLRequest r(GURL("http://www.google.com/"), &d);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    r.Cancel();

    MessageLoop::current()->Run();

    // We expect to receive OnResponseStarted even though the request has been
    // cancelled.
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_EQ(0, d.bytes_received());
    EXPECT_FALSE(d.received_data_before_response());
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

TEST_F(URLRequestTest, CancelTest2) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"");
  ASSERT_TRUE(NULL != server.get());

  // error C2446: '!=' : no conversion from 'HTTPTestServer *const '
  // to 'const int'

  TestDelegate d;
  {
    TestURLRequest r(server->TestServerPage(""), &d);

    d.set_cancel_in_response_started(true);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_EQ(0, d.bytes_received());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(URLRequestStatus::CANCELED, r.status().status());
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

TEST_F(URLRequestTest, CancelTest3) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"");
  ASSERT_TRUE(NULL != server.get());
  TestDelegate d;
  {
    TestURLRequest r(server->TestServerPage(""), &d);

    d.set_cancel_in_received_data(true);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    EXPECT_EQ(1, d.response_started_count());
    // There is no guarantee about how much data was received
    // before the cancel was issued.  It could have been 0 bytes,
    // or it could have been all the bytes.
    // EXPECT_EQ(0, d.bytes_received());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(URLRequestStatus::CANCELED, r.status().status());
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

TEST_F(URLRequestTest, CancelTest4) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"");
  ASSERT_TRUE(NULL != server.get());
  TestDelegate d;
  {
    TestURLRequest r(server->TestServerPage(""), &d);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    // The request will be implicitly canceled when it is destroyed. The
    // test delegate must not post a quit message when this happens because
    // this test doesn't actually have a message loop. The quit message would
    // get put on this thread's message queue and the next test would exit
    // early, causing problems.
    d.set_quit_on_complete(false);
  }
  // expect things to just cleanup properly.

  // we won't actually get a received reponse here because we've never run the
  // message loop
  EXPECT_FALSE(d.received_data_before_response());
  EXPECT_EQ(0, d.bytes_received());
}

TEST_F(URLRequestTest, CancelTest5) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"");
  ASSERT_TRUE(NULL != server.get());
  scoped_refptr<URLRequestContext> context = new URLRequestHttpCacheContext();

  // populate cache
  {
    TestDelegate d;
    URLRequest r(server->TestServerPage("cachetime"), &d);
    r.set_context(context);
    r.Start();
    MessageLoop::current()->Run();
    EXPECT_EQ(URLRequestStatus::SUCCESS, r.status().status());
  }

  // cancel read from cache (see bug 990242)
  {
    TestDelegate d;
    URLRequest r(server->TestServerPage("cachetime"), &d);
    r.set_context(context);
    r.Start();
    r.Cancel();
    MessageLoop::current()->Run();

    EXPECT_EQ(URLRequestStatus::CANCELED, r.status().status());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_EQ(0, d.bytes_received());
    EXPECT_FALSE(d.received_data_before_response());
  }

#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count, 0);
#endif
}

TEST_F(URLRequestTest, PostTest) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data");
  ASSERT_TRUE(NULL != server.get());
  const int kMsgSize = 20000;  // multiple of 10
  const int kIterations = 50;
  char *uploadBytes = new char[kMsgSize+1];
  char *ptr = uploadBytes;
  char marker = 'a';
  for(int idx=0; idx<kMsgSize/10; idx++) {
    memcpy(ptr, "----------", 10);
    ptr += 10;
    if (idx % 100 == 0) {
      ptr--;
      *ptr++ = marker;
      if (++marker > 'z')
        marker = 'a';
    }

  }
  uploadBytes[kMsgSize] = '\0';

  scoped_refptr<URLRequestContext> context =
      new URLRequestHttpCacheContext();

  for (int i = 0; i < kIterations; ++i) {
    TestDelegate d;
    URLRequest r(server->TestServerPage("echo"), &d);
    r.set_context(context);
    r.set_method("POST");

    r.AppendBytesToUpload(uploadBytes, kMsgSize);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    ASSERT_EQ(1, d.response_started_count()) << "request failed: " <<
        (int) r.status().status() << ", os error: " << r.status().os_error();

    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(uploadBytes, d.data_received());
    EXPECT_EQ(memcmp(uploadBytes, d.data_received().c_str(), kMsgSize),0);
    EXPECT_EQ(d.data_received().compare(uploadBytes), 0);
  }
  delete[] uploadBytes;
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

TEST_F(URLRequestTest, PostEmptyTest) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data");
  ASSERT_TRUE(NULL != server.get());
  TestDelegate d;
  {
    TestURLRequest r(server->TestServerPage("echo"), &d);
    r.set_method("POST");

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    ASSERT_EQ(1, d.response_started_count()) << "request failed: " <<
        (int) r.status().status() << ", os error: " << r.status().os_error();

    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_TRUE(d.data_received().empty());
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

TEST_F(URLRequestTest, PostFileTest) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data");
  ASSERT_TRUE(NULL != server.get());
  TestDelegate d;
  {
    TestURLRequest r(server->TestServerPage("echo"), &d);
    r.set_method("POST");

    std::wstring dir;
    PathService::Get(base::DIR_EXE, &dir);
    file_util::SetCurrentDirectory(dir);

    std::wstring path;
    PathService::Get(base::DIR_SOURCE_ROOT, &path);
    file_util::AppendToPath(&path, L"net");
    file_util::AppendToPath(&path, L"data");
    file_util::AppendToPath(&path, L"url_request_unittest");
    file_util::AppendToPath(&path, L"with-headers.html");
    r.AppendFileToUpload(path);

    // This file should just be ignored in the upload stream.
    r.AppendFileToUpload(L"c:\\path\\to\\non\\existant\\file.randomness.12345");

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    int64 longsize;
    ASSERT_EQ(true, file_util::GetFileSize(path, &longsize));
    int size = static_cast<int>(longsize);
    scoped_array<char> buf(new char[size]);

    int size_read = static_cast<int>(file_util::ReadFile(path,
        buf.get(), size));
    ASSERT_EQ(size, size_read);

    ASSERT_EQ(1, d.response_started_count()) << "request failed: " <<
        (int) r.status().status() << ", os error: " << r.status().os_error();

    EXPECT_FALSE(d.received_data_before_response());

    ASSERT_EQ(size, d.bytes_received());
    EXPECT_EQ(0, memcmp(d.data_received().c_str(), buf.get(), size));
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

TEST_F(URLRequestTest, AboutBlankTest) {
  TestDelegate d;
  {
    TestURLRequest r(GURL("about:blank"), &d);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    EXPECT_TRUE(!r.is_pending());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(d.bytes_received(), 0);
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

TEST_F(URLRequestTest, FileTest) {
  FilePath app_path;
  PathService::Get(base::FILE_EXE, &app_path);
  GURL app_url = net::FilePathToFileURL(app_path.ToWStringHack());

  TestDelegate d;
  {
    TestURLRequest r(app_url, &d);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    int64 file_size;
    file_util::GetFileSize(app_path, &file_size);

    EXPECT_TRUE(!r.is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

TEST_F(URLRequestTest, InvalidUrlTest) {
  TestDelegate d;
  {
    TestURLRequest r(GURL("invalid url"), &d);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();
    EXPECT_TRUE(d.request_failed());
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

// This test is disabled because it fails on some computers due to proxies
// returning a page in response to this request rather than reporting failure.
TEST_F(URLRequestTest, DISABLED_DnsFailureTest) {
  TestDelegate d;
  {
    URLRequest r(GURL("http://thisisnotavalidurl0123456789foo.com/"), &d);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();
    EXPECT_TRUE(d.request_failed());
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}

TEST_F(URLRequestTest, ResponseHeadersTest) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data/url_request_unittest");
  ASSERT_TRUE(NULL != server.get());
  TestDelegate d;
  TestURLRequest req(server->TestServerPage("files/with-headers.html"), &d);
  req.Start();
  MessageLoop::current()->Run();

  const net::HttpResponseHeaders* headers = req.response_headers();
  std::string header;
  EXPECT_TRUE(headers->GetNormalizedHeader("cache-control", &header));
  EXPECT_EQ("private", header);

  header.clear();
  EXPECT_TRUE(headers->GetNormalizedHeader("content-type", &header));
  EXPECT_EQ("text/html; charset=ISO-8859-1", header);

  // The response has two "X-Multiple-Entries" headers.
  // This verfies our output has them concatenated together.
  header.clear();
  EXPECT_TRUE(headers->GetNormalizedHeader("x-multiple-entries", &header));
  EXPECT_EQ("a, b", header);
}

TEST_F(URLRequestTest, BZip2ContentTest) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data/filter_unittests");
  ASSERT_TRUE(NULL != server.get());

  // for localhost domain, we also should support bzip2 encoding
  // first, get the original file
  TestDelegate d1;
  TestURLRequest req1(server->TestServerPage("realfiles/google.txt"), &d1);
  req1.Start();
  MessageLoop::current()->Run();

  const std::string& got_content = d1.data_received();

  // second, get bzip2 content
  TestDelegate d2;
  TestURLRequest req2(server->TestServerPage("realbz2files/google.txt"), &d2);
  req2.Start();
  MessageLoop::current()->Run();

  const std::string& got_bz2_content = d2.data_received();

  // compare those two results
  EXPECT_EQ(got_content, got_bz2_content);
}

TEST_F(URLRequestTest, BZip2ContentTest_IncrementalHeader) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data/filter_unittests");
  ASSERT_TRUE(NULL != server.get());

  // for localhost domain, we also should support bzip2 encoding
  // first, get the original file
  TestDelegate d1;
  TestURLRequest req1(server->TestServerPage("realfiles/google.txt"), &d1);
  req1.Start();
  MessageLoop::current()->Run();

  const std::string& got_content = d1.data_received();

  // second, get bzip2 content.  ask the testserver to send the BZ2 header in
  // two chunks with a delay between them.  this tests our fix for bug 867161.
  TestDelegate d2;
  TestURLRequest req2(server->TestServerPage(
      "realbz2files/google.txt?incremental-header"), &d2);
  req2.Start();
  MessageLoop::current()->Run();

  const std::string& got_bz2_content = d2.data_received();

  // compare those two results
  EXPECT_EQ(got_content, got_bz2_content);
}

#if defined(OS_WIN)
TEST_F(URLRequestTest, ResolveShortcutTest) {
  std::wstring app_path;
  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
  file_util::AppendToPath(&app_path, L"net");
  file_util::AppendToPath(&app_path, L"data");
  file_util::AppendToPath(&app_path, L"url_request_unittest");
  file_util::AppendToPath(&app_path, L"with-headers.html");

  std::wstring lnk_path = app_path + L".lnk";

  HRESULT result;
  IShellLink *shell = NULL;
  IPersistFile *persist = NULL;

  CoInitialize(NULL);
  // Temporarily create a shortcut for test
  result = CoCreateInstance(CLSID_ShellLink, NULL,
                          CLSCTX_INPROC_SERVER, IID_IShellLink,
                          reinterpret_cast<LPVOID*>(&shell));
  EXPECT_TRUE(SUCCEEDED(result));
  result = shell->QueryInterface(IID_IPersistFile,
                             reinterpret_cast<LPVOID*>(&persist));
  EXPECT_TRUE(SUCCEEDED(result));
  result = shell->SetPath(app_path.c_str());
  EXPECT_TRUE(SUCCEEDED(result));
  result = shell->SetDescription(L"ResolveShortcutTest");
  EXPECT_TRUE(SUCCEEDED(result));
  result = persist->Save(lnk_path.c_str(), TRUE);
  EXPECT_TRUE(SUCCEEDED(result));
  if (persist)
    persist->Release();
  if (shell)
    shell->Release();

  TestDelegate d;
  {
    TestURLRequest r(net::FilePathToFileURL(lnk_path), &d);

    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    WIN32_FILE_ATTRIBUTE_DATA data;
    GetFileAttributesEx(app_path.c_str(), GetFileExInfoStandard, &data);
    HANDLE file = CreateFile(app_path.c_str(), GENERIC_READ,
                             FILE_SHARE_READ, NULL, OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL, NULL);
    EXPECT_NE(INVALID_HANDLE_VALUE, file);
    scoped_array<char> buffer(new char[data.nFileSizeLow]);
    DWORD read_size;
    BOOL result;
    result = ReadFile(file, buffer.get(), data.nFileSizeLow,
                      &read_size, NULL);
    std::string content(buffer.get(), read_size);
    CloseHandle(file);

    EXPECT_TRUE(!r.is_pending());
    EXPECT_EQ(1, d.received_redirect_count());
    EXPECT_EQ(content, d.data_received());
  }

  // Clean the shortcut
  DeleteFile(lnk_path.c_str());
  CoUninitialize();

#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif
}
#endif  // defined(OS_WIN)

TEST_F(URLRequestTest, ContentTypeNormalizationTest) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data/url_request_unittest");
  ASSERT_TRUE(NULL != server.get());

  TestDelegate d;
  TestURLRequest req(server->TestServerPage(
      "files/content-type-normalization.html"), &d);
  req.Start();
  MessageLoop::current()->Run();

  std::string mime_type;
  req.GetMimeType(&mime_type);
  EXPECT_EQ("text/html", mime_type);

  std::string charset;
  req.GetCharset(&charset);
  EXPECT_EQ("utf-8", charset);
  req.Cancel();
}

TEST_F(URLRequestTest, FileDirCancelTest) {
  // Put in mock resource provider.
  net::NetModule::SetResourceProvider(TestNetResourceProvider);

  TestDelegate d;
  {
    std::wstring file_path;
    PathService::Get(base::DIR_SOURCE_ROOT, &file_path);
    file_util::AppendToPath(&file_path, L"net");
    file_util::AppendToPath(&file_path, L"data");
    file_util::AppendToPath(&file_path, L"");

    TestURLRequest req(net::FilePathToFileURL(file_path), &d);
    req.Start();
    EXPECT_TRUE(req.is_pending());

    d.set_cancel_in_received_data_pending(true);

    MessageLoop::current()->Run();
  }
#ifndef NDEBUG
  DCHECK_EQ(url_request_metrics.object_count,0);
#endif

  // Take out mock resource provider.
  net::NetModule::SetResourceProvider(NULL);
}

TEST_F(URLRequestTest, RestrictRedirects) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data/url_request_unittest");
  ASSERT_TRUE(NULL != server.get());

  TestDelegate d;
  TestURLRequest req(server->TestServerPage(
      "files/redirect-to-file.html"), &d);
  req.Start();
  MessageLoop::current()->Run();

  EXPECT_EQ(URLRequestStatus::FAILED, req.status().status());
  EXPECT_EQ(net::ERR_UNSAFE_REDIRECT, req.status().os_error());
}

TEST_F(URLRequestTest, NoUserPassInReferrer) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data/url_request_unittest");
  ASSERT_TRUE(NULL != server.get());
  TestDelegate d;
  TestURLRequest req(server->TestServerPage(
      "echoheader?Referer"), &d);
  req.set_referrer("http://user:pass@foo.com/");
  req.Start();
  MessageLoop::current()->Run();

  EXPECT_EQ(std::string("http://foo.com/"), d.data_received());
}

TEST_F(URLRequestTest, CancelRedirect) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data/url_request_unittest");
  ASSERT_TRUE(NULL != server.get());
  TestDelegate d;
  {
    d.set_cancel_in_received_redirect(true);
    TestURLRequest req(server->TestServerPage(
        "files/redirect-test.html"), &d);
    req.Start();
    MessageLoop::current()->Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_EQ(0, d.bytes_received());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status());
  }
}

TEST_F(URLRequestTest, VaryHeader) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data/url_request_unittest");
  ASSERT_TRUE(NULL != server.get());

  scoped_refptr<URLRequestContext> context = new URLRequestHttpCacheContext();

  Time response_time;

  // populate the cache
  {
    TestDelegate d;
    URLRequest req(server->TestServerPage("echoheader?foo"), &d);
    req.set_context(context);
    req.SetExtraRequestHeaders("foo:1");
    req.Start();
    MessageLoop::current()->Run();

    response_time = req.response_time();
  }

  // Make sure that the response time of a future response will be in the
  // future!
  PlatformThread::Sleep(10);

  // expect a cache hit
  {
    TestDelegate d;
    URLRequest req(server->TestServerPage("echoheader?foo"), &d);
    req.set_context(context);
    req.SetExtraRequestHeaders("foo:1");
    req.Start();
    MessageLoop::current()->Run();

    EXPECT_TRUE(req.response_time() == response_time);
  }

  // expect a cache miss
  {
    TestDelegate d;
    URLRequest req(server->TestServerPage("echoheader?foo"), &d);
    req.set_context(context);
    req.SetExtraRequestHeaders("foo:2");
    req.Start();
    MessageLoop::current()->Run();

    EXPECT_FALSE(req.response_time() == response_time);
  }
}

TEST_F(URLRequestTest, BasicAuth) {
  scoped_refptr<URLRequestContext> context = new URLRequestHttpCacheContext();
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"");
  ASSERT_TRUE(NULL != server.get());

  Time response_time;

  // populate the cache
  {
    TestDelegate d;
    d.set_username(L"user");
    d.set_password(L"secret");

    URLRequest r(server->TestServerPage("auth-basic"), &d);
    r.set_context(context);
    r.Start();

    MessageLoop::current()->Run();

    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);

    response_time = r.response_time();
  }

  // Let some time pass so we can ensure that a future response will have a
  // response time value in the future.
  PlatformThread::Sleep(10 /* milliseconds */);

  // repeat request with end-to-end validation.  since auth-basic results in a
  // cachable page, we expect this test to result in a 304.  in which case, the
  // response should be fetched from the cache.
  {
    TestDelegate d;
    d.set_username(L"user");
    d.set_password(L"secret");

    URLRequest r(server->TestServerPage("auth-basic"), &d);
    r.set_context(context);
    r.set_load_flags(net::LOAD_VALIDATE_CACHE);
    r.Start();

    MessageLoop::current()->Run();

    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);

    // Should be the same cached document, which means that the response time
    // should not have changed.
    EXPECT_TRUE(response_time == r.response_time());
  }
}

// In this test, we do a POST which the server will 302 redirect.
// The subsequent transaction should use GET, and should not send the
// Content-Type header.
// http://code.google.com/p/chromium/issues/detail?id=843
TEST_F(URLRequestTest, Post302RedirectGet) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data/url_request_unittest");
  ASSERT_TRUE(NULL != server.get());
  TestDelegate d;
  TestURLRequest req(server->TestServerPage("files/redirect-to-echoall"), &d);
  req.set_method("POST");

  // Set headers (some of which are specific to the POST).
  // ("Content-Length: 10" is just a junk value to make sure it gets stripped).
  req.SetExtraRequestHeaders(
    "Content-Type: multipart/form-data; "
    "boundary=----WebKitFormBoundaryAADeAA+NAAWMAAwZ\r\n"
    "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,"
    "text/plain;q=0.8,image/png,*/*;q=0.5\r\n"
    "Accept-Language: en-US,en\r\n"
    "Accept-Charset: ISO-8859-1,*,utf-8\r\n"
    "Content-Length: 10\r\n"
    "Origin: http://localhost:1337/"
  );
  req.Start();
  MessageLoop::current()->Run();

  std::string mime_type;
  req.GetMimeType(&mime_type);
  EXPECT_EQ("text/html", mime_type);

  const std::string& data = d.data_received();

  // Check that the post-specific headers were stripped:
  EXPECT_FALSE(ContainsString(data, "Content-Length:"));
  EXPECT_FALSE(ContainsString(data, "Content-Type:"));
  EXPECT_FALSE(ContainsString(data, "Origin:"));

  // These extra request headers should not have been stripped.
  EXPECT_TRUE(ContainsString(data, "Accept:"));
  EXPECT_TRUE(ContainsString(data, "Accept-Language:"));
  EXPECT_TRUE(ContainsString(data, "Accept-Charset:"));
}

TEST_F(URLRequestTest, Post307RedirectPost) {
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(L"net/data/url_request_unittest");
  ASSERT_TRUE(NULL != server.get());
  TestDelegate d;
  TestURLRequest req(server->TestServerPage("files/redirect307-to-echoall"),
      &d);
  req.set_method("POST");
  req.Start();
  MessageLoop::current()->Run();
  EXPECT_EQ(req.method(), "POST");
}

// FTP tests appear to be hanging some of the time
#if 1  // !defined(OS_WIN)
  #define MAYBE_FTPGetTestAnonymous   DISABLED_FTPGetTestAnonymous
  #define MAYBE_FTPGetTest            DISABLED_FTPGetTest
  #define MAYBE_FTPCheckWrongUser     DISABLED_FTPCheckWrongUser
  #define MAYBE_FTPCheckWrongPassword DISABLED_FTPCheckWrongPassword
#else
  #define MAYBE_FTPGetTestAnonymous   FTPGetTestAnonymous
  #define MAYBE_FTPGetTest            FTPGetTest
  #define MAYBE_FTPCheckWrongUser     FTPCheckWrongUser
  #define MAYBE_FTPCheckWrongPassword FTPCheckWrongPassword
#endif

TEST_F(URLRequestTest, MAYBE_FTPGetTestAnonymous) {
  scoped_refptr<FTPTestServer> server = FTPTestServer::CreateServer(L"");
  ASSERT_TRUE(NULL != server.get());
  std::wstring app_path;
  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
  app_path.append(L"\\LICENSE");
  TestDelegate d;
  {
    TestURLRequest r(server->TestServerPage("/LICENSE"), &d);
    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    int64 file_size = 0;
    file_util::GetFileSize(app_path, &file_size);

    EXPECT_TRUE(!r.is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
  }
}

TEST_F(URLRequestTest, MAYBE_FTPGetTest) {
  scoped_refptr<FTPTestServer> server =
      FTPTestServer::CreateServer(L"", "chrome", "chrome");
  ASSERT_TRUE(NULL != server.get());
  std::wstring app_path;
  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
  app_path.append(L"\\LICENSE");
  TestDelegate d;
  {
    TestURLRequest r(server->TestServerPage("/LICENSE"), &d);
    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    int64 file_size = 0;
    file_util::GetFileSize(app_path, &file_size);

    EXPECT_TRUE(!r.is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
  }
}

TEST_F(URLRequestTest, MAYBE_FTPCheckWrongPassword) {
  scoped_refptr<FTPTestServer> server =
      FTPTestServer::CreateServer(L"", "chrome", "wrong_password");
  ASSERT_TRUE(NULL != server.get());
  std::wstring app_path;
  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
  app_path.append(L"\\LICENSE");
  TestDelegate d;
  {
    TestURLRequest r(server->TestServerPage("/LICENSE"), &d);
    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    int64 file_size = 0;
    file_util::GetFileSize(app_path, &file_size);

    EXPECT_TRUE(!r.is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(d.bytes_received(), 0);
  }
}

TEST_F(URLRequestTest, MAYBE_FTPCheckWrongUser) {
  scoped_refptr<FTPTestServer> server =
      FTPTestServer::CreateServer(L"", "wrong_user", "chrome");
  ASSERT_TRUE(NULL != server.get());
  std::wstring app_path;
  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
  app_path.append(L"\\LICENSE");
  TestDelegate d;
  {
    TestURLRequest r(server->TestServerPage("/LICENSE"), &d);
    r.Start();
    EXPECT_TRUE(r.is_pending());

    MessageLoop::current()->Run();

    int64 file_size = 0;
    file_util::GetFileSize(app_path, &file_size);

    EXPECT_TRUE(!r.is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(d.bytes_received(), 0);
  }
}

