// Copyright (c) 2012 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.

// This file contains download browser tests that are known to be runnable
// in a pure content context.  Over time tests should be migrated here.

#include <stddef.h>
#include <stdint.h>
#include <utility>
#include <vector>

#include "base/callback_helpers.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/format_macros.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/download_file_factory.h"
#include "content/browser/download/download_file_impl.h"
#include "content/browser/download/download_item_impl.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/download/download_resource_handler.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/power_save_blocker.h"
#include "content/public/browser/resource_dispatcher_host_delegate.h"
#include "content/public/browser/resource_throttle.h"
#include "content/public/common/content_features.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
#include "content/public/test/test_download_request_handler.h"
#include "content/public/test/test_file_error_injector.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_browser_context.h"
#include "content/shell/browser/shell_download_manager_delegate.h"
#include "content/shell/browser/shell_network_delegate.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/url_request/url_request_mock_http_job.h"
#include "net/test/url_request/url_request_slow_download_job.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

#if defined(ENABLE_PLUGINS)
#include "content/browser/plugin_service_impl.h"
#endif

using ::testing::AllOf;
using ::testing::Field;
using ::testing::InSequence;
using ::testing::Property;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::_;

namespace content {

namespace {

class MockDownloadItemObserver : public DownloadItem::Observer {
 public:
  MockDownloadItemObserver() {}
  virtual ~MockDownloadItemObserver() {}

  MOCK_METHOD1(OnDownloadUpdated, void(DownloadItem*));
  MOCK_METHOD1(OnDownloadOpened, void(DownloadItem*));
  MOCK_METHOD1(OnDownloadRemoved, void(DownloadItem*));
  MOCK_METHOD1(OnDownloadDestroyed, void(DownloadItem*));
};

class MockDownloadManagerObserver : public DownloadManager::Observer {
 public:
  MockDownloadManagerObserver(DownloadManager* manager) {
    manager_ = manager;
    manager->AddObserver(this);
  }
  virtual ~MockDownloadManagerObserver() {
    if (manager_)
      manager_->RemoveObserver(this);
  }

  MOCK_METHOD2(OnDownloadCreated, void(DownloadManager*, DownloadItem*));
  MOCK_METHOD1(ModelChanged, void(DownloadManager*));
  void ManagerGoingDown(DownloadManager* manager) {
    DCHECK_EQ(manager_, manager);
    MockManagerGoingDown(manager);

    manager_->RemoveObserver(this);
    manager_ = NULL;
  }

  MOCK_METHOD1(MockManagerGoingDown, void(DownloadManager*));
 private:
  DownloadManager* manager_;
};

class DownloadFileWithDelayFactory;

static DownloadManagerImpl* DownloadManagerForShell(Shell* shell) {
  // We're in a content_browsertest; we know that the DownloadManager
  // is a DownloadManagerImpl.
  return static_cast<DownloadManagerImpl*>(
      BrowserContext::GetDownloadManager(
          shell->web_contents()->GetBrowserContext()));
}

class DownloadFileWithDelay : public DownloadFileImpl {
 public:
  DownloadFileWithDelay(const DownloadSaveInfo& save_info,
                        const base::FilePath& default_download_directory,
                        const GURL& url,
                        const GURL& referrer_url,
                        bool calculate_hash,
                        base::File file,
                        scoped_ptr<ByteStreamReader> stream,
                        const net::BoundNetLog& bound_net_log,
                        scoped_ptr<PowerSaveBlocker> power_save_blocker,
                        base::WeakPtr<DownloadDestinationObserver> observer,
                        base::WeakPtr<DownloadFileWithDelayFactory> owner);

  ~DownloadFileWithDelay() override;

  // Wraps DownloadFileImpl::Rename* and intercepts the return callback,
  // storing it in the factory that produced this object for later
  // retrieval.
  void RenameAndUniquify(const base::FilePath& full_path,
                         const RenameCompletionCallback& callback) override;
  void RenameAndAnnotate(const base::FilePath& full_path,
                         const RenameCompletionCallback& callback) override;

 private:
  static void RenameCallbackWrapper(
      const base::WeakPtr<DownloadFileWithDelayFactory>& factory,
      const RenameCompletionCallback& original_callback,
      DownloadInterruptReason reason,
      const base::FilePath& path);

  // This variable may only be read on the FILE thread, and may only be
  // indirected through (e.g. methods on DownloadFileWithDelayFactory called)
  // on the UI thread.  This is because after construction,
  // DownloadFileWithDelay lives on the file thread, but
  // DownloadFileWithDelayFactory is purely a UI thread object.
  base::WeakPtr<DownloadFileWithDelayFactory> owner_;

  DISALLOW_COPY_AND_ASSIGN(DownloadFileWithDelay);
};

// All routines on this class must be called on the UI thread.
class DownloadFileWithDelayFactory : public DownloadFileFactory {
 public:
  DownloadFileWithDelayFactory();
  ~DownloadFileWithDelayFactory() override;

  // DownloadFileFactory interface.
  DownloadFile* CreateFile(
      const DownloadSaveInfo& save_info,
      const base::FilePath& default_download_directory,
      const GURL& url,
      const GURL& referrer_url,
      bool calculate_hash,
      base::File file,
      scoped_ptr<ByteStreamReader> stream,
      const net::BoundNetLog& bound_net_log,
      base::WeakPtr<DownloadDestinationObserver> observer) override;

  void AddRenameCallback(base::Closure callback);
  void GetAllRenameCallbacks(std::vector<base::Closure>* results);

  // Do not return until GetAllRenameCallbacks() will return a non-empty list.
  void WaitForSomeCallback();

 private:
  std::vector<base::Closure> rename_callbacks_;
  bool waiting_;
  base::WeakPtrFactory<DownloadFileWithDelayFactory> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(DownloadFileWithDelayFactory);
};

DownloadFileWithDelay::DownloadFileWithDelay(
    const DownloadSaveInfo& save_info,
    const base::FilePath& default_download_directory,
    const GURL& url,
    const GURL& referrer_url,
    bool calculate_hash,
    base::File file,
    scoped_ptr<ByteStreamReader> stream,
    const net::BoundNetLog& bound_net_log,
    scoped_ptr<PowerSaveBlocker> power_save_blocker,
    base::WeakPtr<DownloadDestinationObserver> observer,
    base::WeakPtr<DownloadFileWithDelayFactory> owner)
    : DownloadFileImpl(save_info,
                       default_download_directory,
                       url,
                       referrer_url,
                       calculate_hash,
                       std::move(file),
                       std::move(stream),
                       bound_net_log,
                       observer),
      owner_(owner) {}

DownloadFileWithDelay::~DownloadFileWithDelay() {}

void DownloadFileWithDelay::RenameAndUniquify(
    const base::FilePath& full_path,
    const RenameCompletionCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
  DownloadFileImpl::RenameAndUniquify(
      full_path, base::Bind(DownloadFileWithDelay::RenameCallbackWrapper,
                            owner_, callback));
}

void DownloadFileWithDelay::RenameAndAnnotate(
    const base::FilePath& full_path, const RenameCompletionCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
  DownloadFileImpl::RenameAndAnnotate(
      full_path, base::Bind(DownloadFileWithDelay::RenameCallbackWrapper,
                            owner_, callback));
}

// static
void DownloadFileWithDelay::RenameCallbackWrapper(
    const base::WeakPtr<DownloadFileWithDelayFactory>& factory,
    const RenameCompletionCallback& original_callback,
    DownloadInterruptReason reason,
    const base::FilePath& path) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (!factory)
    return;
  factory->AddRenameCallback(base::Bind(original_callback, reason, path));
}

DownloadFileWithDelayFactory::DownloadFileWithDelayFactory()
    : waiting_(false),
      weak_ptr_factory_(this) {}

DownloadFileWithDelayFactory::~DownloadFileWithDelayFactory() {}

DownloadFile* DownloadFileWithDelayFactory::CreateFile(
    const DownloadSaveInfo& save_info,
    const base::FilePath& default_download_directory,
    const GURL& url,
    const GURL& referrer_url,
    bool calculate_hash,
    base::File file,
    scoped_ptr<ByteStreamReader> stream,
    const net::BoundNetLog& bound_net_log,
    base::WeakPtr<DownloadDestinationObserver> observer) {
  scoped_ptr<PowerSaveBlocker> psb(PowerSaveBlocker::Create(
      PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
      PowerSaveBlocker::kReasonOther, "Download in progress"));
  return new DownloadFileWithDelay(
      save_info, default_download_directory, url, referrer_url, calculate_hash,
      std::move(file), std::move(stream), bound_net_log, std::move(psb),
      observer, weak_ptr_factory_.GetWeakPtr());
}

void DownloadFileWithDelayFactory::AddRenameCallback(base::Closure callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  rename_callbacks_.push_back(callback);
  if (waiting_)
    base::MessageLoopForUI::current()->QuitWhenIdle();
}

void DownloadFileWithDelayFactory::GetAllRenameCallbacks(
    std::vector<base::Closure>* results) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  results->swap(rename_callbacks_);
}

void DownloadFileWithDelayFactory::WaitForSomeCallback() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (rename_callbacks_.empty()) {
    waiting_ = true;
    RunMessageLoop();
    waiting_ = false;
  }
}

class CountingDownloadFile : public DownloadFileImpl {
 public:
  CountingDownloadFile(const DownloadSaveInfo& save_info,
                       const base::FilePath& default_downloads_directory,
                       const GURL& url,
                       const GURL& referrer_url,
                       bool calculate_hash,
                       base::File file,
                       scoped_ptr<ByteStreamReader> stream,
                       const net::BoundNetLog& bound_net_log,
                       scoped_ptr<PowerSaveBlocker> power_save_blocker,
                       base::WeakPtr<DownloadDestinationObserver> observer)
      : DownloadFileImpl(save_info,
                         default_downloads_directory,
                         url,
                         referrer_url,
                         calculate_hash,
                         std::move(file),
                         std::move(stream),
                         bound_net_log,
                         observer) {}

  ~CountingDownloadFile() override {
    DCHECK_CURRENTLY_ON(BrowserThread::FILE);
    active_files_--;
  }

  void Initialize(const InitializeCallback& callback) override {
    DCHECK_CURRENTLY_ON(BrowserThread::FILE);
    active_files_++;
    return DownloadFileImpl::Initialize(callback);
  }

  static void GetNumberActiveFiles(int* result) {
    DCHECK_CURRENTLY_ON(BrowserThread::FILE);
    *result = active_files_;
  }

  // Can be called on any thread, and will block (running message loop)
  // until data is returned.
  static int GetNumberActiveFilesFromFileThread() {
    int result = -1;
    BrowserThread::PostTaskAndReply(
        BrowserThread::FILE, FROM_HERE,
        base::Bind(&CountingDownloadFile::GetNumberActiveFiles, &result),
        base::MessageLoop::current()->QuitWhenIdleClosure());
    base::MessageLoop::current()->Run();
    DCHECK_NE(-1, result);
    return result;
  }

 private:
  static int active_files_;
};

int CountingDownloadFile::active_files_ = 0;

class CountingDownloadFileFactory : public DownloadFileFactory {
 public:
  CountingDownloadFileFactory() {}
  ~CountingDownloadFileFactory() override {}

  // DownloadFileFactory interface.
  DownloadFile* CreateFile(
      const DownloadSaveInfo& save_info,
      const base::FilePath& default_downloads_directory,
      const GURL& url,
      const GURL& referrer_url,
      bool calculate_hash,
      base::File file,
      scoped_ptr<ByteStreamReader> stream,
      const net::BoundNetLog& bound_net_log,
      base::WeakPtr<DownloadDestinationObserver> observer) override {
    scoped_ptr<PowerSaveBlocker> psb(PowerSaveBlocker::Create(
        PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
        PowerSaveBlocker::kReasonOther, "Download in progress"));
    return new CountingDownloadFile(save_info, default_downloads_directory, url,
                                    referrer_url, calculate_hash,
                                    std::move(file), std::move(stream),
                                    bound_net_log, std::move(psb), observer);
  }
};

class TestShellDownloadManagerDelegate : public ShellDownloadManagerDelegate {
 public:
  TestShellDownloadManagerDelegate()
      : delay_download_open_(false) {}
  ~TestShellDownloadManagerDelegate() override {}

  bool ShouldOpenDownload(
      DownloadItem* item,
      const DownloadOpenDelayedCallback& callback) override {
    if (delay_download_open_) {
      delayed_callbacks_.push_back(callback);
      return false;
    }
    return true;
  }

  bool GenerateFileHash() override { return true; }

  void SetDelayedOpen(bool delay) {
    delay_download_open_ = delay;
  }

  void GetDelayedCallbacks(
      std::vector<DownloadOpenDelayedCallback>* callbacks) {
    callbacks->swap(delayed_callbacks_);
  }
 private:
  bool delay_download_open_;
  std::vector<DownloadOpenDelayedCallback> delayed_callbacks_;
};

// Get the next created download.
class DownloadCreateObserver : DownloadManager::Observer {
 public:
  DownloadCreateObserver(DownloadManager* manager)
      : manager_(manager), item_(NULL) {
    manager_->AddObserver(this);
  }

  ~DownloadCreateObserver() override {
    if (manager_)
      manager_->RemoveObserver(this);
    manager_ = NULL;
  }

  void ManagerGoingDown(DownloadManager* manager) override {
    DCHECK_EQ(manager_, manager);
    manager_->RemoveObserver(this);
    manager_ = NULL;
  }

  void OnDownloadCreated(DownloadManager* manager,
                         DownloadItem* download) override {
    if (!item_)
      item_ = download;

    if (!completion_closure_.is_null())
      base::ResetAndReturn(&completion_closure_).Run();
  }

  DownloadItem* WaitForFinished() {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    if (!item_) {
      base::RunLoop run_loop;
      completion_closure_ = run_loop.QuitClosure();
      run_loop.Run();
    }
    return item_;
  }

 private:
  DownloadManager* manager_;
  DownloadItem* item_;
  base::Closure completion_closure_;
};

bool IsDownloadInState(DownloadItem::DownloadState state, DownloadItem* item) {
  return item->GetState() == state;
}

// Request handler to be used with CreateRedirectHandler().
scoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendRedirectResponse(
    const std::string& relative_url,
    const GURL& target_url,
    const net::test_server::HttpRequest& request) {
  scoped_ptr<net::test_server::BasicHttpResponse> response;
  if (request.relative_url == relative_url) {
    response.reset(new net::test_server::BasicHttpResponse);
    response->set_code(net::HTTP_FOUND);
    response->AddCustomHeader("Location", target_url.spec());
  }
  return std::move(response);
}

// Creates a request handler for EmbeddedTestServer that responds with a HTTP
// 302 redirect if the request URL matches |relative_url|.
net::EmbeddedTestServer::HandleRequestCallback CreateRedirectHandler(
    const std::string& relative_url,
    const GURL& target_url) {
  return base::Bind(
      &HandleRequestAndSendRedirectResponse, relative_url, target_url);
}

// Request handler to be used with CreateBasicResponseHandler().
scoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendBasicResponse(
    const std::string& relative_url,
    const base::StringPairs& headers,
    const std::string& content_type,
    const std::string& body,
    const net::test_server::HttpRequest& request) {
  scoped_ptr<net::test_server::BasicHttpResponse> response;
  if (request.relative_url == relative_url) {
    response.reset(new net::test_server::BasicHttpResponse);
    for (const auto& pair : headers)
      response->AddCustomHeader(pair.first, pair.second);
    response->set_content_type(content_type);
    response->set_content(body);
  }
  return std::move(response);
}

// Creates a request handler for an EmbeddedTestServer that response with an
// HTTP 200 status code, a Content-Type header and a body.
net::EmbeddedTestServer::HandleRequestCallback CreateBasicResponseHandler(
    const std::string& relative_url,
    const base::StringPairs& headers,
    const std::string& content_type,
    const std::string& body) {
  return base::Bind(&HandleRequestAndSendBasicResponse, relative_url, headers,
                    content_type, body);
}

// Helper class to "flatten" handling of
// TestDownloadRequestHandler::OnStartHandler.
class TestRequestStartHandler {
 public:
  // Construct an OnStartHandler that can be set as the on_start_handler for
  // TestDownloadRequestHandler::Parameters.
  TestDownloadRequestHandler::OnStartHandler GetOnStartHandler() {
    EXPECT_FALSE(used_) << "GetOnStartHandler() should only be called once for "
                           "an instance of TestRequestStartHandler.";
    used_ = true;
    return base::Bind(&TestRequestStartHandler::OnStartHandler,
                      base::Unretained(this));
  }

  // Wait until the OnStartHandlers returned in a prior call to
  // GetOnStartHandler() is invoked.
  void WaitForCallback() {
    if (response_callback_.is_null())
      run_loop_.Run();
  }

  // Respond to the OnStartHandler() invocation using |headers| and |error|.
  void RespondWith(const std::string& headers, net::Error error) {
    ASSERT_FALSE(response_callback_.is_null());
    response_callback_.Run(headers, error);
  }

  // Return the headers returned from the invocation of OnStartHandler.
  const net::HttpRequestHeaders& headers() const {
    EXPECT_FALSE(response_callback_.is_null());
    return request_headers_;
  }

 private:
  void OnStartHandler(const net::HttpRequestHeaders& headers,
                      const TestDownloadRequestHandler::OnStartResponseCallback&
                          response_callback) {
    request_headers_ = headers;
    response_callback_ = response_callback;
    if (run_loop_.running())
      run_loop_.Quit();
  }

  bool used_ = false;
  base::RunLoop run_loop_;
  net::HttpRequestHeaders request_headers_;
  TestDownloadRequestHandler::OnStartResponseCallback response_callback_;
};

class DownloadContentTest : public ContentBrowserTest {
 protected:
  void SetUpOnMainThread() override {
    ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());

    test_delegate_.reset(new TestShellDownloadManagerDelegate());
    test_delegate_->SetDownloadBehaviorForTesting(downloads_directory_.path());
    DownloadManager* manager = DownloadManagerForShell(shell());
    manager->GetDelegate()->Shutdown();
    manager->SetDelegate(test_delegate_.get());
    test_delegate_->SetDownloadManager(manager);

    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&net::URLRequestSlowDownloadJob::AddUrlHandler));
    base::FilePath mock_base(GetTestFilePath("download", ""));
    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(
            &net::URLRequestMockHTTPJob::AddUrlHandlers, mock_base,
            make_scoped_refptr(content::BrowserThread::GetBlockingPool())));
  }

  TestShellDownloadManagerDelegate* GetDownloadManagerDelegate() {
    return test_delegate_.get();
  }

  // Create a DownloadTestObserverTerminal that will wait for the
  // specified number of downloads to finish.
  DownloadTestObserver* CreateWaiter(
      Shell* shell, int num_downloads) {
    DownloadManager* download_manager = DownloadManagerForShell(shell);
    return new DownloadTestObserverTerminal(download_manager, num_downloads,
        DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
  }

  void WaitForInterrupt(DownloadItem* download) {
    DownloadUpdatedObserver(
        download, base::Bind(&IsDownloadInState, DownloadItem::INTERRUPTED))
        .WaitForEvent();
  }

  void WaitForInProgress(DownloadItem* download) {
    DownloadUpdatedObserver(
        download, base::Bind(&IsDownloadInState, DownloadItem::IN_PROGRESS))
        .WaitForEvent();
  }

  void WaitForCompletion(DownloadItem* download) {
    DownloadUpdatedObserver(
        download, base::Bind(&IsDownloadInState, DownloadItem::COMPLETE))
        .WaitForEvent();
  }

  void WaitForCancel(DownloadItem* download) {
    DownloadUpdatedObserver(
        download, base::Bind(&IsDownloadInState, DownloadItem::CANCELLED))
        .WaitForEvent();
  }

  // Note: Cannot be used with other alternative DownloadFileFactorys
  void SetupEnsureNoPendingDownloads() {
    DownloadManagerForShell(shell())->SetDownloadFileFactoryForTesting(
        scoped_ptr<DownloadFileFactory>(new CountingDownloadFileFactory()));
  }

  bool EnsureNoPendingDownloads() {
    bool result = true;
    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result));
    base::MessageLoop::current()->Run();
    return result &&
           (CountingDownloadFile::GetNumberActiveFilesFromFileThread() == 0);
  }

  void NavigateToURLAndWaitForDownload(
      Shell* shell,
      const GURL& url,
      DownloadItem::DownloadState expected_terminal_state) {
    scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell, 1));
    NavigateToURL(shell, url);
    observer->WaitForFinished();
    EXPECT_EQ(1u, observer->NumDownloadsSeenInState(expected_terminal_state));
  }

  // Checks that |path| is has |file_size| bytes, and matches the |value|
  // string.
  bool VerifyFile(const base::FilePath& path,
                  const std::string& value,
                  const int64_t file_size) {
    std::string file_contents;

    bool read = base::ReadFileToString(path, &file_contents);
    EXPECT_TRUE(read) << "Failed reading file: " << path.value() << std::endl;
    if (!read)
      return false;  // Couldn't read the file.

    // Note: we don't handle really large files (more than size_t can hold)
    // so we will fail in that case.
    size_t expected_size = static_cast<size_t>(file_size);

    // Check the size.
    EXPECT_EQ(expected_size, file_contents.size());
    if (expected_size != file_contents.size())
      return false;

    // Check the contents.
    EXPECT_EQ(value, file_contents);
    if (memcmp(file_contents.c_str(), value.c_str(), expected_size) != 0)
      return false;

    return true;
  }

  // Start a download and return the item.
  DownloadItem* StartDownloadAndReturnItem(Shell* shell, GURL url) {
    scoped_ptr<DownloadCreateObserver> observer(
        new DownloadCreateObserver(DownloadManagerForShell(shell)));
    shell->LoadURL(url);
    return observer->WaitForFinished();
  }

  static void ReadAndVerifyFileContents(int seed,
                                        int64_t expected_size,
                                        const base::FilePath& path) {
    base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
    ASSERT_TRUE(file.IsValid());
    int64_t file_length = file.GetLength();
    ASSERT_EQ(expected_size, file_length);

    const int64_t kBufferSize = 64 * 1024;
    std::vector<char> pattern;
    std::vector<char> data;
    pattern.resize(kBufferSize);
    data.resize(kBufferSize);
    for (int64_t offset = 0; offset < file_length;) {
      int bytes_read = file.Read(offset, &data.front(), kBufferSize);
      ASSERT_LT(0, bytes_read);
      ASSERT_GE(kBufferSize, bytes_read);

      TestDownloadRequestHandler::GetPatternBytes(seed, offset, bytes_read,
                                                  &pattern.front());
      ASSERT_EQ(0, memcmp(&pattern.front(), &data.front(), bytes_read))
          << "Comparing block at offset " << offset << " and length "
          << bytes_read;
      offset += bytes_read;
    }
  }

 private:
  static void EnsureNoPendingDownloadJobsOnIO(bool* result) {
    if (net::URLRequestSlowDownloadJob::NumberOutstandingRequests())
      *result = false;
    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                            base::MessageLoop::QuitWhenIdleClosure());
  }

  // Location of the downloads directory for these tests
  base::ScopedTempDir downloads_directory_;
  scoped_ptr<TestShellDownloadManagerDelegate> test_delegate_;
};

// Parameters for DownloadResumptionContentTest.
enum class DownloadResumptionTestType {
  RESUME_WITH_RENDERER,  // Resume() is called while the originating WebContents
                         // is still alive.
  RESUME_WITHOUT_RENDERER  // Resume() is called after the originating
                           // WebContents has been deleted.
};

// Parameterized test for download resumption. Tests using this fixure will be
// run once with RESUME_WITH_RENDERER and once with RESUME_WITHOUT_RENDERER.
// Use initiator_shell_for_resumption() to retrieve the Shell object that should
// be used as the originator for the initial download. Prior to calling
// Resume(), call PrepareToResume() which will cause the originating Shell to be
// deleted if the test parameter is RESUME_WITHOUT_RENDERER.
class DownloadResumptionContentTest
    : public DownloadContentTest,
      public ::testing::WithParamInterface<DownloadResumptionTestType> {
 public:
  void SetUpOnMainThread() override {
    base::FeatureList::ClearInstanceForTesting();
    scoped_ptr<base::FeatureList> feature_list(new base::FeatureList);
    feature_list->InitializeFromCommandLine(
        features::kDownloadResumption.name, std::string());
    base::FeatureList::SetInstance(std::move(feature_list));

    DownloadContentTest::SetUpOnMainThread();

    if (GetParam() == DownloadResumptionTestType::RESUME_WITHOUT_RENDERER)
      initiator_shell_for_resumption_ = CreateBrowser();
    else
      initiator_shell_for_resumption_ = shell();

    ASSERT_EQ(DownloadManagerForShell(shell()),
              DownloadManagerForShell(initiator_shell_for_resumption()));
  }

  // Shell to use for initiating a download. Only valid *before*
  // PrepareToResume() is called.
  Shell* initiator_shell_for_resumption() const {
    DCHECK(initiator_shell_for_resumption_);
    return initiator_shell_for_resumption_;
  }

  // Should be called once before calling DownloadItem::Resume() on an
  // interrupted download. This may cause initiator_shell_for_resumption() to
  // become invalidated.
  void PrepareToResume() {
    if (GetParam() == DownloadResumptionTestType::RESUME_WITH_RENDERER)
      return;
    DCHECK_NE(initiator_shell_for_resumption(), shell());
    DCHECK(initiator_shell_for_resumption());
    initiator_shell_for_resumption_->Close();
    initiator_shell_for_resumption_ = nullptr;
  }

 private:
  Shell* initiator_shell_for_resumption_ = nullptr;
};

INSTANTIATE_TEST_CASE_P(
    _,
    DownloadResumptionContentTest,
    ::testing::Values(DownloadResumptionTestType::RESUME_WITH_RENDERER,
                      DownloadResumptionTestType::RESUME_WITHOUT_RENDERER));

}  // namespace

IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) {
  SetupEnsureNoPendingDownloads();

  // Create a download, wait until it's started, and confirm
  // we're in the expected state.
  DownloadItem* download = StartDownloadAndReturnItem(
      shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
  ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState());

  // Cancel the download and wait for download system quiesce.
  download->Cancel(true);
  scoped_refptr<DownloadTestFlushObserver> flush_observer(
      new DownloadTestFlushObserver(DownloadManagerForShell(shell())));
  flush_observer->WaitForFlush();

  // Get the important info from other threads and check it.
  EXPECT_TRUE(EnsureNoPendingDownloads());
}

// Check that downloading multiple (in this case, 2) files does not result in
// corrupted files.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, MultiDownload) {
  SetupEnsureNoPendingDownloads();

  // Create a download, wait until it's started, and confirm
  // we're in the expected state.
  DownloadItem* download1 = StartDownloadAndReturnItem(
      shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
  ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState());

  // Start the second download and wait until it's done.
  GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
  DownloadItem* download2 = StartDownloadAndReturnItem(shell(), url);
  WaitForCompletion(download2);

  ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState());
  ASSERT_EQ(DownloadItem::COMPLETE, download2->GetState());

  // Allow the first request to finish.
  scoped_ptr<DownloadTestObserver> observer2(CreateWaiter(shell(), 1));
  NavigateToURL(shell(),
                GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl));
  observer2->WaitForFinished();  // Wait for the third request.
  EXPECT_EQ(1u, observer2->NumDownloadsSeenInState(DownloadItem::COMPLETE));

  // Get the important info from other threads and check it.
  EXPECT_TRUE(EnsureNoPendingDownloads());

  // The |DownloadItem|s should now be done and have the final file names.
  // Verify that the files have the expected data and size.
  // |file1| should be full of '*'s, and |file2| should be the same as the
  // source file.
  base::FilePath file1(download1->GetTargetFilePath());
  size_t file_size1 = net::URLRequestSlowDownloadJob::kFirstDownloadSize +
                      net::URLRequestSlowDownloadJob::kSecondDownloadSize;
  std::string expected_contents(file_size1, '*');
  ASSERT_TRUE(VerifyFile(file1, expected_contents, file_size1));

  base::FilePath file2(download2->GetTargetFilePath());
  ASSERT_TRUE(base::ContentsEqual(
      file2, GetTestFilePath("download", "download-test.lib")));
}

#if defined(ENABLE_PLUGINS)
// Content served with a MIME type of application/octet-stream should be
// downloaded even when a plugin can be found that handles the file type.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadOctetStream) {
  const char kTestPluginName[] = "TestPlugin";
  const char kTestMimeType[] = "application/x-test-mime-type";
  const char kTestFileType[] = "abc";

  WebPluginInfo plugin_info;
  plugin_info.name = base::ASCIIToUTF16(kTestPluginName);
  plugin_info.mime_types.push_back(
      WebPluginMimeType(kTestMimeType, kTestFileType, ""));
  plugin_info.type = WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS;
  PluginServiceImpl::GetInstance()->RegisterInternalPlugin(plugin_info, false);

  // The following is served with a Content-Type of application/octet-stream.
  GURL url(
      net::URLRequestMockHTTPJob::GetMockUrl("octet-stream.abc"));
  NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE);
}
#endif

// Try to cancel just before we release the download file, by delaying final
// rename callback.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtFinalRename) {
  // Setup new factory.
  DownloadFileWithDelayFactory* file_factory =
      new DownloadFileWithDelayFactory();
  DownloadManagerImpl* download_manager(DownloadManagerForShell(shell()));
  download_manager->SetDownloadFileFactoryForTesting(
      scoped_ptr<DownloadFileFactory>(file_factory));

  // Create a download
  NavigateToURL(shell(),
                net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));

  // Wait until the first (intermediate file) rename and execute the callback.
  file_factory->WaitForSomeCallback();
  std::vector<base::Closure> callbacks;
  file_factory->GetAllRenameCallbacks(&callbacks);
  ASSERT_EQ(1u, callbacks.size());
  callbacks[0].Run();
  callbacks.clear();

  // Wait until the second (final) rename callback is posted.
  file_factory->WaitForSomeCallback();
  file_factory->GetAllRenameCallbacks(&callbacks);
  ASSERT_EQ(1u, callbacks.size());

  // Cancel it.
  std::vector<DownloadItem*> items;
  download_manager->GetAllDownloads(&items);
  ASSERT_EQ(1u, items.size());
  items[0]->Cancel(true);
  RunAllPendingInMessageLoop();

  // Check state.
  EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState());

  // Run final rename callback.
  callbacks[0].Run();
  callbacks.clear();

  // Check state.
  EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState());
}

// Try to cancel just after we release the download file, by delaying
// in ShouldOpenDownload.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtRelease) {
  DownloadManagerImpl* download_manager(DownloadManagerForShell(shell()));

  // Mark delegate for delayed open.
  GetDownloadManagerDelegate()->SetDelayedOpen(true);

  // Setup new factory.
  DownloadFileWithDelayFactory* file_factory =
      new DownloadFileWithDelayFactory();
  download_manager->SetDownloadFileFactoryForTesting(
      scoped_ptr<DownloadFileFactory>(file_factory));

  // Create a download
  NavigateToURL(shell(),
                net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));

  // Wait until the first (intermediate file) rename and execute the callback.
  file_factory->WaitForSomeCallback();
  std::vector<base::Closure> callbacks;
  file_factory->GetAllRenameCallbacks(&callbacks);
  ASSERT_EQ(1u, callbacks.size());
  callbacks[0].Run();
  callbacks.clear();

  // Wait until the second (final) rename callback is posted.
  file_factory->WaitForSomeCallback();
  file_factory->GetAllRenameCallbacks(&callbacks);
  ASSERT_EQ(1u, callbacks.size());

  // Call it.
  callbacks[0].Run();
  callbacks.clear();

  // Confirm download still IN_PROGRESS (internal state COMPLETING).
  std::vector<DownloadItem*> items;
  download_manager->GetAllDownloads(&items);
  EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());

  // Cancel the download; confirm cancel fails.
  ASSERT_EQ(1u, items.size());
  items[0]->Cancel(true);
  EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());

  // Need to complete open test.
  std::vector<DownloadOpenDelayedCallback> delayed_callbacks;
  GetDownloadManagerDelegate()->GetDelayedCallbacks(
      &delayed_callbacks);
  ASSERT_EQ(1u, delayed_callbacks.size());
  delayed_callbacks[0].Run(true);

  // *Now* the download should be complete.
  EXPECT_EQ(DownloadItem::COMPLETE, items[0]->GetState());
}

#if defined(OS_ANDROID)
// Flaky on android: https://crbug.com/324525
#define MAYBE_ShutdownInProgress DISABLED_ShutdownInProgress
#else
#define MAYBE_ShutdownInProgress ShutdownInProgress
#endif

// Try to shutdown with a download in progress to make sure shutdown path
// works properly.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, MAYBE_ShutdownInProgress) {
  // Create a download that won't complete.
  DownloadItem* download = StartDownloadAndReturnItem(
      shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));

  EXPECT_EQ(DownloadItem::IN_PROGRESS, download->GetState());

  // Shutdown the download manager and make sure we get the right
  // notifications in the right order.
  StrictMock<MockDownloadItemObserver> item_observer;
  download->AddObserver(&item_observer);
  MockDownloadManagerObserver manager_observer(
      DownloadManagerForShell(shell()));
  // Don't care about ModelChanged() events.
  EXPECT_CALL(manager_observer, ModelChanged(_))
      .WillRepeatedly(Return());
  {
    InSequence notifications;

    EXPECT_CALL(manager_observer, MockManagerGoingDown(
        DownloadManagerForShell(shell())))
        .WillOnce(Return());
    EXPECT_CALL(
        item_observer,
        OnDownloadUpdated(AllOf(download, Property(&DownloadItem::GetState,
                                                   DownloadItem::CANCELLED))))
        .WillOnce(Return());
    EXPECT_CALL(item_observer, OnDownloadDestroyed(download))
        .WillOnce(Return());
  }

  // See http://crbug.com/324525.  If we have a refcount release/post task
  // race, the second post will stall the IO thread long enough so that we'll
  // lose the race and crash.  The first stall is just to give the UI thread
  // a chance to get the second stall onto the IO thread queue after the cancel
  // message created by Shutdown and before the notification callback
  // created by the IO thread in canceling the request.
  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
                          base::Bind(&base::PlatformThread::Sleep,
                                     base::TimeDelta::FromMilliseconds(25)));
  DownloadManagerForShell(shell())->Shutdown();
  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
                          base::Bind(&base::PlatformThread::Sleep,
                                     base::TimeDelta::FromMilliseconds(25)));
}

// Try to shutdown just after we release the download file, by delaying
// release.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownAtRelease) {
  DownloadManagerImpl* download_manager(DownloadManagerForShell(shell()));

  // Mark delegate for delayed open.
  GetDownloadManagerDelegate()->SetDelayedOpen(true);

  // Setup new factory.
  DownloadFileWithDelayFactory* file_factory =
      new DownloadFileWithDelayFactory();
  download_manager->SetDownloadFileFactoryForTesting(
      scoped_ptr<DownloadFileFactory>(file_factory));

  // Create a download
  NavigateToURL(shell(),
                net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));

  // Wait until the first (intermediate file) rename and execute the callback.
  file_factory->WaitForSomeCallback();
  std::vector<base::Closure> callbacks;
  file_factory->GetAllRenameCallbacks(&callbacks);
  ASSERT_EQ(1u, callbacks.size());
  callbacks[0].Run();
  callbacks.clear();

  // Wait until the second (final) rename callback is posted.
  file_factory->WaitForSomeCallback();
  file_factory->GetAllRenameCallbacks(&callbacks);
  ASSERT_EQ(1u, callbacks.size());

  // Call it.
  callbacks[0].Run();
  callbacks.clear();

  // Confirm download isn't complete yet.
  std::vector<DownloadItem*> items;
  DownloadManagerForShell(shell())->GetAllDownloads(&items);
  EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());

  // Cancel the download; confirm cancel fails anyway.
  ASSERT_EQ(1u, items.size());
  items[0]->Cancel(true);
  EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
  RunAllPendingInMessageLoop();
  EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());

  MockDownloadItemObserver observer;
  items[0]->AddObserver(&observer);
  EXPECT_CALL(observer, OnDownloadDestroyed(items[0]));

  // Shutdown the download manager.  Mostly this is confirming a lack of
  // crashes.
  DownloadManagerForShell(shell())->Shutdown();
}

// Test resumption with a response that contains strong validators.
IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, StrongValidators) {
  TestDownloadRequestHandler request_handler;
  TestDownloadRequestHandler::Parameters parameters =
      TestDownloadRequestHandler::Parameters::WithSingleInterruption();
  const TestDownloadRequestHandler::InjectedError interruption =
      parameters.injected_errors.front();
  request_handler.StartServing(parameters);

  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url());
  WaitForInterrupt(download);

  ASSERT_EQ(interruption.offset, download->GetReceivedBytes());
  ASSERT_EQ(parameters.size, download->GetTotalBytes());

  PrepareToResume();
  download->Resume();
  WaitForCompletion(download);

  ASSERT_EQ(parameters.size, download->GetReceivedBytes());
  ASSERT_EQ(parameters.size, download->GetTotalBytes());
  ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents(
      parameters.pattern_generator_seed, parameters.size,
      download->GetTargetFilePath()));

  // Characterization risk: The next portion of the test examines the requests
  // that were sent out while downloading our resource. These requests
  // correspond to the requests that were generated by the browser and the
  // downloads system and may change as implementation details change.
  TestDownloadRequestHandler::CompletedRequests requests;
  request_handler.GetCompletedRequestInfo(&requests);

  ASSERT_EQ(2u, requests.size());

  // The first request only transferrs bytes up until the interruption point.
  EXPECT_EQ(interruption.offset, requests[0].transferred_byte_count);

  // The next request should only have transferred the remainder of the
  // resource.
  EXPECT_EQ(parameters.size - interruption.offset,
            requests[1].transferred_byte_count);

  std::string value;
  ASSERT_TRUE(requests[1].request_headers.GetHeader(
      net::HttpRequestHeaders::kIfRange, &value));
  EXPECT_EQ(parameters.etag, value);

  ASSERT_TRUE(requests[1].request_headers.GetHeader(
      net::HttpRequestHeaders::kRange, &value));
  EXPECT_EQ(base::StringPrintf("bytes=%" PRId64 "-", interruption.offset),
            value);
}

// Resumption should only attempt to contact the final URL if the download has a
// URL chain.
IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, RedirectBeforeResume) {
  TestDownloadRequestHandler request_handler_1(
      GURL("http://example.com/first-url"));
  request_handler_1.StartServingStaticResponse(
      "HTTP/1.1 302 Redirect\r\n"
      "Location: http://example.com/second-url\r\n"
      "\r\n");

  TestDownloadRequestHandler request_handler_2(
      GURL("http://example.com/second-url"));
  request_handler_2.StartServingStaticResponse(
      "HTTP/1.1 302 Redirect\r\n"
      "Location: http://example.com/third-url\r\n"
      "\r\n");

  TestDownloadRequestHandler request_handler_3(
      GURL("http://example.com/third-url"));
  request_handler_3.StartServingStaticResponse(
      "HTTP/1.1 302 Redirect\r\n"
      "Location: http://example.com/download\r\n"
      "\r\n");

  TestDownloadRequestHandler resumable_request_handler(
      GURL("http://example.com/download"));
  TestDownloadRequestHandler::Parameters parameters =
      TestDownloadRequestHandler::Parameters::WithSingleInterruption();
  resumable_request_handler.StartServing(parameters);

  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler_1.url());
  WaitForInterrupt(download);

  EXPECT_EQ(4u, download->GetUrlChain().size());
  EXPECT_EQ(request_handler_1.url(), download->GetOriginalUrl());
  EXPECT_EQ(resumable_request_handler.url(), download->GetURL());

  // Now that the download is interrupted, make all intermediate servers return
  // a 404. The only way a resumption request would succeed if the resumption
  // request is sent to the final server in the chain.
  const char k404Response[] = "HTTP/1.1 404 Not found\r\n\r\n";
  request_handler_1.StartServingStaticResponse(k404Response);
  request_handler_2.StartServingStaticResponse(k404Response);
  request_handler_3.StartServingStaticResponse(k404Response);

  PrepareToResume();
  download->Resume();
  WaitForCompletion(download);

  ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents(
      parameters.pattern_generator_seed, parameters.size,
      download->GetTargetFilePath()));
}

// If a resumption request results in a redirect, the response should be ignored
// and the download should be marked as interrupted again.
IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, RedirectWhileResume) {
  TestDownloadRequestHandler request_handler(
      GURL("http://example.com/first-url"));
  TestDownloadRequestHandler::Parameters parameters =
      TestDownloadRequestHandler::Parameters::WithSingleInterruption();
  ++parameters.pattern_generator_seed;
  request_handler.StartServing(parameters);

  // We should never send a request to the decoy. If we do, the request will
  // always succeed, which results in behavior that diverges from what we want,
  // which is for the download to return to being interrupted.
  TestDownloadRequestHandler decoy_request_handler(
      GURL("http://example.com/decoy"));
  decoy_request_handler.StartServing(TestDownloadRequestHandler::Parameters());

  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url());
  WaitForInterrupt(download);

  // Upon resumption, the server starts responding with a redirect. This
  // response should not be accepted.
  request_handler.StartServingStaticResponse(
      "HTTP/1.1 302 Redirect\r\n"
      "Location: http://example.com/decoy\r\n"
      "\r\n");
  PrepareToResume();
  download->Resume();
  WaitForInterrupt(download);
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE,
            download->GetLastReason());

  // Back to the original request handler. Resumption should now succeed, and
  // use the partial data it had prior to the first interruption.
  request_handler.StartServing(parameters);
  download->Resume();
  WaitForCompletion(download);

  ASSERT_EQ(parameters.size, download->GetReceivedBytes());
  ASSERT_EQ(parameters.size, download->GetTotalBytes());
  ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents(
      parameters.pattern_generator_seed, parameters.size,
      download->GetTargetFilePath()));

  // Characterization risk: The next portion of the test examines the requests
  // that were sent out while downloading our resource. These requests
  // correspond to the requests that were generated by the browser and the
  // downloads system and may change as implementation details change.
  TestDownloadRequestHandler::CompletedRequests requests;
  request_handler.GetCompletedRequestInfo(&requests);

  ASSERT_EQ(3u, requests.size());

  // None of the request should have transferred the entire resource. The
  // redirect response shows up as a response with 0 bytes transferred.
  EXPECT_GT(parameters.size, requests[0].transferred_byte_count);
  EXPECT_EQ(0, requests[1].transferred_byte_count);
  EXPECT_GT(parameters.size, requests[2].transferred_byte_count);
}

// If the server response for the resumption request specifies a bad range (i.e.
// not the range that was requested or an invalid or missing Content-Range
// header), then the download should be marked as interrupted again without
// discarding the partial state.
IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, BadRangeHeader) {
  TestDownloadRequestHandler request_handler;
  TestDownloadRequestHandler::Parameters parameters =
      TestDownloadRequestHandler::Parameters::WithSingleInterruption();
  request_handler.StartServing(parameters);

  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url());
  WaitForInterrupt(download);

  // Upon resumption, the server starts responding with a bad range header.
  request_handler.StartServingStaticResponse(
      "HTTP/1.1 206 Partial Content\r\n"
      "Content-Range: bytes 1000000-2000000/3000000\r\n"
      "\r\n");
  PrepareToResume();
  download->Resume();
  WaitForInterrupt(download);
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
            download->GetLastReason());

  // Or this time, the server sends a response with an invalid Content-Range
  // header.
  request_handler.StartServingStaticResponse(
      "HTTP/1.1 206 Partial Content\r\n"
      "Content-Range: ooga-booga-booga-booga\r\n"
      "\r\n");
  download->Resume();
  WaitForInterrupt(download);
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
            download->GetLastReason());

  // Or no Content-Range header at all.
  request_handler.StartServingStaticResponse(
      "HTTP/1.1 206 Partial Content\r\n"
      "Some-Headers: ooga-booga-booga-booga\r\n"
      "\r\n");
  download->Resume();
  WaitForInterrupt(download);
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
            download->GetLastReason());

  // Back to the original request handler. Resumption should now succeed, and
  // use the partial data it had prior to the first interruption.
  request_handler.StartServing(parameters);
  download->Resume();
  WaitForCompletion(download);

  ASSERT_EQ(parameters.size, download->GetReceivedBytes());
  ASSERT_EQ(parameters.size, download->GetTotalBytes());
  ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents(
      parameters.pattern_generator_seed, parameters.size,
      download->GetTargetFilePath()));

  // Characterization risk: The next portion of the test examines the requests
  // that were sent out while downloading our resource. These requests
  // correspond to the requests that were generated by the browser and the
  // downloads system and may change as implementation details change.
  TestDownloadRequestHandler::CompletedRequests requests;
  request_handler.GetCompletedRequestInfo(&requests);

  ASSERT_EQ(5u, requests.size());

  // None of the request should have transferred the entire resource.
  EXPECT_GT(parameters.size, requests[0].transferred_byte_count);
  EXPECT_EQ(0, requests[1].transferred_byte_count);
  EXPECT_EQ(0, requests[2].transferred_byte_count);
  EXPECT_EQ(0, requests[3].transferred_byte_count);
  EXPECT_GT(parameters.size, requests[4].transferred_byte_count);
}

// A partial resumption results in an HTTP 200 response. I.e. the server ignored
// the range request and sent the entire resource instead. For If-Range requests
// (as opposed to If-Match), the behavior for a precondition failure is also to
// respond with a 200. So this test case covers both validation failure and
// ignoring the range request.
IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest,
                       RestartIfNotPartialResponse) {
  const int kOriginalPatternGeneratorSeed = 1;
  const int kNewPatternGeneratorSeed = 2;

  TestDownloadRequestHandler::Parameters parameters =
      TestDownloadRequestHandler::Parameters::WithSingleInterruption();
  parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed;
  const TestDownloadRequestHandler::InjectedError interruption =
      parameters.injected_errors.front();

  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(parameters);

  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url());
  WaitForInterrupt(download);

  ASSERT_EQ(interruption.offset, download->GetReceivedBytes());
  ASSERT_EQ(parameters.size, download->GetTotalBytes());

  parameters = TestDownloadRequestHandler::Parameters();
  parameters.support_byte_ranges = false;
  parameters.pattern_generator_seed = kNewPatternGeneratorSeed;
  request_handler.StartServing(parameters);

  PrepareToResume();
  download->Resume();
  WaitForCompletion(download);

  ASSERT_EQ(parameters.size, download->GetReceivedBytes());
  ASSERT_EQ(parameters.size, download->GetTotalBytes());
  ASSERT_NO_FATAL_FAILURE(
      ReadAndVerifyFileContents(kNewPatternGeneratorSeed, parameters.size,
                                download->GetTargetFilePath()));

  // When the downloads system sees the full response, it should accept the
  // response without restarting. On the network, we should deterministically
  // see two requests:
  // * The original request which transfers upto our interruption point.
  // * The resumption attempt, which receives the entire entity.
  TestDownloadRequestHandler::CompletedRequests requests;
  request_handler.GetCompletedRequestInfo(&requests);

  ASSERT_EQ(2u, requests.size());

  // The first request only transfers data up to the interruption point.
  EXPECT_EQ(interruption.offset, requests[0].transferred_byte_count);

  // The second request transfers the entire response.
  EXPECT_EQ(parameters.size, requests[1].transferred_byte_count);

  std::string value;
  ASSERT_TRUE(requests[1].request_headers.GetHeader(
      net::HttpRequestHeaders::kIfRange, &value));
  EXPECT_EQ(parameters.etag, value);

  ASSERT_TRUE(requests[1].request_headers.GetHeader(
      net::HttpRequestHeaders::kRange, &value));
  EXPECT_EQ(base::StringPrintf("bytes=%" PRId64 "-", interruption.offset),
            value);
}

// Confirm we restart if we don't have a verifier.
IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, RestartIfNoETag) {
  const int kOriginalPatternGeneratorSeed = 1;
  const int kNewPatternGeneratorSeed = 2;

  TestDownloadRequestHandler::Parameters parameters =
      TestDownloadRequestHandler::Parameters::WithSingleInterruption();
  ASSERT_EQ(1u, parameters.injected_errors.size());
  parameters.etag.clear();
  parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed;

  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(parameters);
  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url());
  WaitForInterrupt(download);

  parameters.pattern_generator_seed = kNewPatternGeneratorSeed;
  parameters.ClearInjectedErrors();
  request_handler.StartServing(parameters);

  PrepareToResume();
  download->Resume();
  WaitForCompletion(download);

  ASSERT_EQ(parameters.size, download->GetReceivedBytes());
  ASSERT_EQ(parameters.size, download->GetTotalBytes());
  ASSERT_NO_FATAL_FAILURE(
      ReadAndVerifyFileContents(kNewPatternGeneratorSeed, parameters.size,
                                download->GetTargetFilePath()));

  TestDownloadRequestHandler::CompletedRequests requests;
  request_handler.GetCompletedRequestInfo(&requests);

  // Neither If-Range nor Range headers should be present in the second request.
  ASSERT_EQ(2u, requests.size());
  std::string value;
  EXPECT_FALSE(requests[1].request_headers.GetHeader(
      net::HttpRequestHeaders::kIfRange, &value));
  EXPECT_FALSE(requests[1].request_headers.GetHeader(
      net::HttpRequestHeaders::kRange, &value));
}

// Partial file goes missing before the download is resumed. The download should
// restart.
IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, RestartIfNoPartialFile) {
  TestDownloadRequestHandler::Parameters parameters =
      TestDownloadRequestHandler::Parameters::WithSingleInterruption();

  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(parameters);
  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url());
  WaitForInterrupt(download);

  // Delete the intermediate file.
  ASSERT_TRUE(base::PathExists(download->GetFullPath()));
  ASSERT_TRUE(base::DeleteFile(download->GetFullPath(), false));

  parameters.ClearInjectedErrors();
  request_handler.StartServing(parameters);

  PrepareToResume();
  download->Resume();
  WaitForCompletion(download);

  ASSERT_EQ(parameters.size, download->GetReceivedBytes());
  ASSERT_EQ(parameters.size, download->GetTotalBytes());
  ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents(
      parameters.pattern_generator_seed, parameters.size,
      download->GetTargetFilePath()));
}

IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest,
                       RecoverFromInitFileError) {
  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(TestDownloadRequestHandler::Parameters());

  // Setup the error injector.
  scoped_refptr<TestFileErrorInjector> injector(TestFileErrorInjector::Create(
      DownloadManagerForShell(initiator_shell_for_resumption())));

  const TestFileErrorInjector::FileErrorInfo err = {
      TestFileErrorInjector::FILE_OPERATION_INITIALIZE, 0,
      DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE};
  injector->InjectError(err);

  // Start and watch for interrupt.
  DownloadItem* download(StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url()));
  WaitForInterrupt(download);
  ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
            download->GetLastReason());
  EXPECT_EQ(0, download->GetReceivedBytes());
  EXPECT_TRUE(download->GetFullPath().empty());
  EXPECT_FALSE(download->GetTargetFilePath().empty());

  // We need to make sure that any cross-thread downloads communication has
  // quiesced before clearing and injecting the new errors, as the
  // InjectErrors() routine alters the currently in use download file
  // factory, which is a file thread object.
  RunAllPendingInMessageLoop(BrowserThread::FILE);
  RunAllPendingInMessageLoop();

  // Clear the old errors list.
  injector->ClearError();

  // Resume and watch completion.
  PrepareToResume();
  download->Resume();
  WaitForCompletion(download);
  EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}

IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest,
                       RecoverFromIntermediateFileRenameError) {
  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(TestDownloadRequestHandler::Parameters());

  // Setup the error injector.
  scoped_refptr<TestFileErrorInjector> injector(TestFileErrorInjector::Create(
      DownloadManagerForShell(initiator_shell_for_resumption())));

  const TestFileErrorInjector::FileErrorInfo err = {
      TestFileErrorInjector::FILE_OPERATION_RENAME_UNIQUIFY, 0,
      DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE};
  injector->InjectError(err);

  // Start and watch for interrupt.
  DownloadItem* download(StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url()));
  WaitForInterrupt(download);
  ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
            download->GetLastReason());
  EXPECT_TRUE(download->GetFullPath().empty());
  // Target path will have been set after file name determination. GetFullPath()
  // being empty is sufficient to signal that filename determination needs to be
  // redone.
  EXPECT_FALSE(download->GetTargetFilePath().empty());

  // We need to make sure that any cross-thread downloads communication has
  // quiesced before clearing and injecting the new errors, as the
  // InjectErrors() routine alters the currently in use download file
  // factory, which is a file thread object.
  RunAllPendingInMessageLoop(BrowserThread::FILE);
  RunAllPendingInMessageLoop();

  // Clear the old errors list.
  injector->ClearError();

  PrepareToResume();
  download->Resume();
  WaitForCompletion(download);
  EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}

IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest,
                       RecoverFromFinalRenameError) {
  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(TestDownloadRequestHandler::Parameters());

  // Setup the error injector.
  scoped_refptr<TestFileErrorInjector> injector(TestFileErrorInjector::Create(
      DownloadManagerForShell(initiator_shell_for_resumption())));

  DownloadManagerForShell(initiator_shell_for_resumption())
      ->RemoveAllDownloads();
  TestFileErrorInjector::FileErrorInfo err = {
      TestFileErrorInjector::FILE_OPERATION_RENAME_ANNOTATE, 0,
      DOWNLOAD_INTERRUPT_REASON_FILE_FAILED};
  injector->InjectError(err);

  // Start and watch for interrupt.
  DownloadItem* download(StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url()));
  WaitForInterrupt(download);
  ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, download->GetLastReason());
  EXPECT_TRUE(download->GetFullPath().empty());
  // Target path should still be intact.
  EXPECT_FALSE(download->GetTargetFilePath().empty());

  // We need to make sure that any cross-thread downloads communication has
  // quiesced before clearing and injecting the new errors, as the
  // InjectErrors() routine alters the currently in use download file
  // factory, which is a file thread object.
  RunAllPendingInMessageLoop(BrowserThread::FILE);
  RunAllPendingInMessageLoop();

  // Clear the old errors list.
  injector->ClearError();

  PrepareToResume();
  download->Resume();
  WaitForCompletion(download);
  EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}

IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, Resume_Hash) {
  using InjectedError = TestDownloadRequestHandler::InjectedError;
  const char kExpectedHash[] =
      "\xa7\x44\x49\x86\x24\xc6\x84\x6c\x89\xdf\xd8\xec\xa0\xe0\x61\x12\xdc\x80"
      "\x13\xf2\x83\x49\xa9\x14\x52\x32\xf0\x95\x20\xca\x5b\x30";
  std::string expected_hash(kExpectedHash);
  TestDownloadRequestHandler request_handler;
  TestDownloadRequestHandler::Parameters parameters;

  // As a control, let's try GetHash() on an uninterrupted download.
  request_handler.StartServing(parameters);
  DownloadItem* uninterrupted_download(StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url()));
  WaitForCompletion(uninterrupted_download);
  EXPECT_EQ(expected_hash, uninterrupted_download->GetHash());

  // Now with interruptions.
  parameters.injected_errors.push(
      InjectedError(100, net::ERR_CONNECTION_RESET));
  parameters.injected_errors.push(
      InjectedError(211, net::ERR_CONNECTION_RESET));
  parameters.injected_errors.push(
      InjectedError(337, net::ERR_CONNECTION_RESET));
  parameters.injected_errors.push(
      InjectedError(400, net::ERR_CONNECTION_RESET));
  parameters.injected_errors.push(
      InjectedError(512, net::ERR_CONNECTION_RESET));
  request_handler.StartServing(parameters);

  // Start and watch for interrupt.
  DownloadItem* download(StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url()));
  WaitForInterrupt(download);

  PrepareToResume();
  download->Resume();
  WaitForInterrupt(download);

  download->Resume();
  WaitForInterrupt(download);

  download->Resume();
  WaitForInterrupt(download);

  download->Resume();
  WaitForInterrupt(download);

  download->Resume();
  WaitForCompletion(download);

  EXPECT_EQ(expected_hash, download->GetHash());
}

// An interrupted download should remove the intermediate file when it is
// cancelled.
IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest,
                       CancelInterruptedDownload) {
  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(
      TestDownloadRequestHandler::Parameters::WithSingleInterruption());

  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url());
  WaitForInterrupt(download);

  base::FilePath intermediate_path = download->GetFullPath();
  ASSERT_FALSE(intermediate_path.empty());
  ASSERT_TRUE(base::PathExists(intermediate_path));

  download->Cancel(true /* user_cancel */);
  RunAllPendingInMessageLoop(BrowserThread::FILE);
  RunAllPendingInMessageLoop();

  // The intermediate file should now be gone.
  EXPECT_FALSE(base::PathExists(intermediate_path));
  EXPECT_TRUE(download->GetFullPath().empty());
}

IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest,
                       RemoveInterruptedDownload) {
  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(
      TestDownloadRequestHandler::Parameters::WithSingleInterruption());

  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url());
  WaitForInterrupt(download);

  base::FilePath intermediate_path = download->GetFullPath();
  ASSERT_FALSE(intermediate_path.empty());
  ASSERT_TRUE(base::PathExists(intermediate_path));

  download->Remove();
  RunAllPendingInMessageLoop(BrowserThread::FILE);
  RunAllPendingInMessageLoop();

  // The intermediate file should now be gone.
  EXPECT_FALSE(base::PathExists(intermediate_path));
}

IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveCompletedDownload) {
  // A completed download shouldn't delete the downloaded file when it is
  // removed.
  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(TestDownloadRequestHandler::Parameters());
  scoped_ptr<DownloadTestObserver> completion_observer(
      CreateWaiter(shell(), 1));
  DownloadItem* download(
      StartDownloadAndReturnItem(shell(), request_handler.url()));
  completion_observer->WaitForFinished();

  // The target path should exist.
  base::FilePath target_path(download->GetTargetFilePath());
  EXPECT_TRUE(base::PathExists(target_path));
  download->Remove();
  RunAllPendingInMessageLoop(BrowserThread::FILE);
  RunAllPendingInMessageLoop();

  // The file should still exist.
  EXPECT_TRUE(base::PathExists(target_path));
}

IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, RemoveResumingDownload) {
  TestDownloadRequestHandler::Parameters parameters =
      TestDownloadRequestHandler::Parameters::WithSingleInterruption();
  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(parameters);

  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url());
  WaitForInterrupt(download);

  base::FilePath intermediate_path(download->GetFullPath());
  ASSERT_FALSE(intermediate_path.empty());
  EXPECT_TRUE(base::PathExists(intermediate_path));

  // Resume and remove download. We expect only a single OnDownloadCreated()
  // call, and that's for the second download created below.
  MockDownloadManagerObserver dm_observer(
      DownloadManagerForShell(initiator_shell_for_resumption()));
  EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);

  TestRequestStartHandler request_start_handler;
  parameters.on_start_handler = request_start_handler.GetOnStartHandler();
  request_handler.StartServing(parameters);

  PrepareToResume();
  download->Resume();
  request_start_handler.WaitForCallback();

  // At this point, the download resumption request has been sent out, but the
  // reponse hasn't been received yet.
  download->Remove();

  request_start_handler.RespondWith(std::string(), net::OK);

  // The intermediate file should now be gone.
  RunAllPendingInMessageLoop(BrowserThread::FILE);
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(base::PathExists(intermediate_path));

  parameters.ClearInjectedErrors();
  parameters.on_start_handler.Reset();
  request_handler.StartServing(parameters);

  // Start the second download and wait until it's done. This exercises the
  // entire downloads stack and effectively flushes all of our worker threads.
  // We are testing whether the URL request created in the previous
  // DownloadItem::Resume() call reulted in a new download or not.
  NavigateToURLAndWaitForDownload(shell(), request_handler.url(),
                                  DownloadItem::COMPLETE);
  EXPECT_TRUE(EnsureNoPendingDownloads());
}

IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, CancelResumingDownload) {
  TestDownloadRequestHandler::Parameters parameters =
      TestDownloadRequestHandler::Parameters::WithSingleInterruption();
  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(parameters);

  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url());
  WaitForInterrupt(download);

  base::FilePath intermediate_path(download->GetFullPath());
  ASSERT_FALSE(intermediate_path.empty());
  EXPECT_TRUE(base::PathExists(intermediate_path));

  // Resume and cancel download. We expect only a single OnDownloadCreated()
  // call, and that's for the second download created below.
  MockDownloadManagerObserver dm_observer(
      DownloadManagerForShell(initiator_shell_for_resumption()));
  EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);

  TestRequestStartHandler request_start_handler;
  parameters.on_start_handler = request_start_handler.GetOnStartHandler();
  request_handler.StartServing(parameters);

  PrepareToResume();
  download->Resume();
  request_start_handler.WaitForCallback();

  // At this point, the download item has initiated a network request for the
  // resumption attempt, but hasn't received a response yet.
  download->Cancel(true /* user_cancel */);

  request_start_handler.RespondWith(std::string(), net::OK);

  // The intermediate file should now be gone.
  RunAllPendingInMessageLoop(BrowserThread::IO);
  RunAllPendingInMessageLoop(BrowserThread::FILE);
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(base::PathExists(intermediate_path));

  parameters.ClearInjectedErrors();
  parameters.on_start_handler.Reset();
  request_handler.StartServing(parameters);

  // Start the second download and wait until it's done. This exercises the
  // entire downloads stack and effectively flushes all of our worker threads.
  // We are testing whether the URL request created in the previous
  // DownloadItem::Resume() call reulted in a new download or not.
  NavigateToURLAndWaitForDownload(shell(), request_handler.url(),
                                  DownloadItem::COMPLETE);
  EXPECT_TRUE(EnsureNoPendingDownloads());
}

IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, RemoveResumedDownload) {
  TestDownloadRequestHandler::Parameters parameters =
      TestDownloadRequestHandler::Parameters::WithSingleInterruption();
  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(parameters);

  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url());
  WaitForInterrupt(download);

  base::FilePath intermediate_path(download->GetFullPath());
  base::FilePath target_path(download->GetTargetFilePath());
  ASSERT_FALSE(intermediate_path.empty());
  EXPECT_TRUE(base::PathExists(intermediate_path));
  EXPECT_FALSE(base::PathExists(target_path));

  // Resume and remove download. We don't expect OnDownloadCreated() calls.
  MockDownloadManagerObserver dm_observer(
      DownloadManagerForShell(initiator_shell_for_resumption()));
  EXPECT_CALL(dm_observer, OnDownloadCreated(_, _)).Times(0);

  PrepareToResume();
  download->Resume();
  WaitForInProgress(download);

  download->Remove();

  // The intermediate file should now be gone.
  RunAllPendingInMessageLoop(BrowserThread::FILE);
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(base::PathExists(intermediate_path));
  EXPECT_FALSE(base::PathExists(target_path));
  EXPECT_TRUE(EnsureNoPendingDownloads());
}

IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, CancelResumedDownload) {
  TestDownloadRequestHandler::Parameters parameters =
      TestDownloadRequestHandler::Parameters::WithSingleInterruption();
  TestDownloadRequestHandler request_handler;
  request_handler.StartServing(parameters);

  DownloadItem* download = StartDownloadAndReturnItem(
      initiator_shell_for_resumption(), request_handler.url());
  WaitForInterrupt(download);

  base::FilePath intermediate_path(download->GetFullPath());
  base::FilePath target_path(download->GetTargetFilePath());
  ASSERT_FALSE(intermediate_path.empty());
  EXPECT_TRUE(base::PathExists(intermediate_path));
  EXPECT_FALSE(base::PathExists(target_path));

  // Resume and remove download. We don't expect OnDownloadCreated() calls.
  MockDownloadManagerObserver dm_observer(
      DownloadManagerForShell(initiator_shell_for_resumption()));
  EXPECT_CALL(dm_observer, OnDownloadCreated(_, _)).Times(0);

  PrepareToResume();
  download->Resume();
  WaitForInProgress(download);

  download->Cancel(true);

  // The intermediate file should now be gone.
  RunAllPendingInMessageLoop(BrowserThread::FILE);
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(base::PathExists(intermediate_path));
  EXPECT_FALSE(base::PathExists(target_path));
  EXPECT_TRUE(EnsureNoPendingDownloads());
}

// Check that the cookie policy is correctly updated when downloading a file
// that redirects cross origin.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) {
  net::EmbeddedTestServer origin_one;
  net::EmbeddedTestServer origin_two;
  ASSERT_TRUE(origin_one.Start());
  ASSERT_TRUE(origin_two.Start());

  // Block third-party cookies.
  ShellNetworkDelegate::SetAcceptAllCookies(false);

  // |url| redirects to a different origin |download| which tries to set a
  // cookie.
  base::StringPairs cookie_header;
  cookie_header.push_back(
      std::make_pair(std::string("Set-Cookie"), std::string("A=B")));
  origin_one.RegisterRequestHandler(CreateBasicResponseHandler(
      "/foo", cookie_header, "application/octet-stream", "abcd"));
  origin_two.RegisterRequestHandler(
      CreateRedirectHandler("/bar", origin_one.GetURL("/foo")));

  // Download the file.
  SetupEnsureNoPendingDownloads();
  scoped_ptr<DownloadUrlParameters> download_parameters(
      DownloadUrlParameters::FromWebContents(shell()->web_contents(),
                                             origin_two.GetURL("/bar")));
  scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1));
  DownloadManagerForShell(shell())->DownloadUrl(std::move(download_parameters));
  observer->WaitForFinished();

  // Get the important info from other threads and check it.
  EXPECT_TRUE(EnsureNoPendingDownloads());

  std::vector<DownloadItem*> downloads;
  DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
  ASSERT_EQ(1u, downloads.size());
  ASSERT_EQ(DownloadItem::COMPLETE, downloads[0]->GetState());

  // Check that the cookies were correctly set.
  EXPECT_EQ("A=B",
            content::GetCookies(shell()->web_contents()->GetBrowserContext(),
                                origin_one.GetURL("/")));
}

// A filename suggestion specified via a @download attribute should not be
// effective if the final download URL is in another origin from the original
// download URL.
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
                       DownloadAttributeCrossOriginRedirect) {
  net::EmbeddedTestServer origin_one;
  net::EmbeddedTestServer origin_two;
  ASSERT_TRUE(origin_one.Start());
  ASSERT_TRUE(origin_two.Start());

  // The download-attribute.html page contains an anchor element whose href is
  // set to the value of the query parameter (specified as |target| in the URL
  // below). The suggested filename for the anchor is 'suggested-filename'. When
  // the page is loaded, a script simulates a click on the anchor, triggering a
  // download of the target URL.
  //
  // We construct two test servers; origin_one and origin_two. Once started, the
  // server URLs will differ by the port number. Therefore they will be in
  // different origins.
  GURL download_url = origin_one.GetURL("/ping");
  GURL referrer_url = origin_one.GetURL(
      std::string("/download-attribute.html?target=") + download_url.spec());

  // <origin_one>/download-attribute.html initiates a download of
  // <origin_one>/ping, which redirects to <origin_two>/download.
  origin_one.ServeFilesFromDirectory(GetTestFilePath("download", ""));
  origin_one.RegisterRequestHandler(
      CreateRedirectHandler("/ping", origin_two.GetURL("/download")));
  origin_two.RegisterRequestHandler(CreateBasicResponseHandler(
      "/download", base::StringPairs(), "application/octet-stream", "Hello"));

  NavigateToURLAndWaitForDownload(
      shell(), referrer_url, DownloadItem::COMPLETE);

  std::vector<DownloadItem*> downloads;
  DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
  ASSERT_EQ(1u, downloads.size());

  EXPECT_EQ(FILE_PATH_LITERAL("download"),
            downloads[0]->GetTargetFilePath().BaseName().value());
  ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete());
  ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete());
}

// A filename suggestion specified via a @download attribute should be effective
// if the final download URL is in the same origin as the initial download URL.
// Test that this holds even if there are cross origin redirects in the middle
// of the redirect chain.
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
                       DownloadAttributeSameOriginRedirect) {
  net::EmbeddedTestServer origin_one;
  net::EmbeddedTestServer origin_two;
  ASSERT_TRUE(origin_one.Start());
  ASSERT_TRUE(origin_two.Start());

  // The download-attribute.html page contains an anchor element whose href is
  // set to the value of the query parameter (specified as |target| in the URL
  // below). The suggested filename for the anchor is 'suggested-filename'. When
  // the page is loaded, a script simulates a click on the anchor, triggering a
  // download of the target URL.
  //
  // We construct two test servers; origin_one and origin_two. Once started, the
  // server URLs will differ by the port number. Therefore they will be in
  // different origins.
  GURL download_url = origin_one.GetURL("/ping");
  GURL referrer_url = origin_one.GetURL(
      std::string("/download-attribute.html?target=") + download_url.spec());
  origin_one.ServeFilesFromDirectory(GetTestFilePath("download", ""));

  // <origin_one>/download-attribute.html initiates a download of
  // <origin_one>/ping, which redirects to <origin_two>/pong, and then finally
  // to <origin_one>/download.
  origin_one.RegisterRequestHandler(
      CreateRedirectHandler("/ping", origin_two.GetURL("/pong")));
  origin_two.RegisterRequestHandler(
      CreateRedirectHandler("/pong", origin_one.GetURL("/download")));
  origin_one.RegisterRequestHandler(CreateBasicResponseHandler(
      "/download", base::StringPairs(), "application/octet-stream", "Hello"));

  NavigateToURLAndWaitForDownload(
      shell(), referrer_url, DownloadItem::COMPLETE);

  std::vector<DownloadItem*> downloads;
  DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
  ASSERT_EQ(1u, downloads.size());

  EXPECT_EQ(FILE_PATH_LITERAL("suggested-filename"),
            downloads[0]->GetTargetFilePath().BaseName().value());
  ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete());
  ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete());
}

// A request for a non-existent resource should still result in a DownloadItem
// that's created in an interrupted state.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeServerError) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL download_url =
      embedded_test_server()->GetURL("/download/does-not-exist");
  GURL document_url = embedded_test_server()->GetURL(
      std::string("/download/download-attribute.html?target=") +
      download_url.spec());

  DownloadItem* download = StartDownloadAndReturnItem(shell(), document_url);
  WaitForInterrupt(download);

  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
            download->GetLastReason());
}

namespace {

void ErrorReturningRequestHandler(
    const net::HttpRequestHeaders& headers,
    const TestDownloadRequestHandler::OnStartResponseCallback& callback) {
  callback.Run(std::string(), net::ERR_INTERNET_DISCONNECTED);
}

}  // namespace

// A request that fails before it gets a response from the server should also
// result in a DownloadItem that's created in an interrupted state.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeNetworkError) {
  ASSERT_TRUE(embedded_test_server()->Start());
  TestDownloadRequestHandler request_handler;
  TestDownloadRequestHandler::Parameters parameters;

  parameters.on_start_handler = base::Bind(&ErrorReturningRequestHandler);
  request_handler.StartServing(parameters);

  GURL document_url = embedded_test_server()->GetURL(
      std::string("/download/download-attribute.html?target=") +
      request_handler.url().spec());
  DownloadItem* download = StartDownloadAndReturnItem(shell(), document_url);
  WaitForInterrupt(download);

  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
            download->GetLastReason());
}

// A request that fails due to it being rejected by policy should result in a
// DownloadItem that's marked as interrupted.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeInvalidURL) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL document_url = embedded_test_server()->GetURL(
      "/download/download-attribute.html?target=about:version");
  DownloadItem* download = StartDownloadAndReturnItem(shell(), document_url);
  WaitForInterrupt(download);

  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST,
            download->GetLastReason());
  EXPECT_FALSE(download->CanResume());
}

// The file empty.bin is served with a MIME type of application/octet-stream.
// The content body is empty. Make sure this case is handled properly and we
// don't regress on http://crbug.com/320394.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadGZipWithNoContent) {
  GURL url = net::URLRequestMockHTTPJob::GetMockUrl("empty.bin");
  NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE);
  // That's it. This should work without crashing.
}

// Make sure that sniffed MIME types are correctly passed through to the
// download item.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, SniffedMimeType) {
  GURL url = net::URLRequestMockHTTPJob::GetMockUrl("gzip-content.gz");
  DownloadItem* item = StartDownloadAndReturnItem(shell(), url);
  WaitForCompletion(item);

  EXPECT_STREQ("application/x-gzip", item->GetMimeType().c_str());
  EXPECT_TRUE(item->GetOriginalMimeType().empty());
}

IN_PROC_BROWSER_TEST_F(DownloadContentTest, DuplicateContentDisposition) {
  ASSERT_TRUE(embedded_test_server()->Start());

  // double-content-disposition.txt is served with two Content-Disposition
  // headers, both of which are identical.
  NavigateToURLAndWaitForDownload(
      shell(),
      embedded_test_server()->GetURL(
          "/download/double-content-disposition.txt"),
      DownloadItem::COMPLETE);

  std::vector<DownloadItem*> downloads;
  DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
  ASSERT_EQ(1u, downloads.size());

  EXPECT_EQ(FILE_PATH_LITERAL("Jumboshrimp.txt"),
            downloads[0]->GetTargetFilePath().BaseName().value());
}

}  // namespace content
