// Copyright 2017 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 "content/browser/file_url_loader_factory.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/feature_list.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/file_url_loader.h"
#include "content/public/browser/shared_cors_origin_access_list.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/file_data_pipe_producer.h"
#include "mojo/public/cpp/system/string_data_pipe_producer.h"
#include "net/base/directory_lister.h"
#include "net/base/directory_listing.h"
#include "net/base/filename_util.h"
#include "net/base/mime_sniffer.h"
#include "net/base/mime_util.h"
#include "net/base/net_errors.h"
#include "net/http/http_byte_range.h"
#include "net/http/http_util.h"
#include "net/url_request/redirect_info.h"
#include "services/network/public/cpp/cors/cors_error_status.h"
#include "services/network/public/cpp/cors/origin_access_list.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/cors.mojom-shared.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "storage/common/fileapi/file_system_util.h"
#include "url/gurl.h"

#if defined(OS_WIN)
#include "base/win/shortcut.h"
#endif

namespace content {
namespace {

constexpr size_t kDefaultFileUrlPipeSize = 65536;

// Because this makes things simpler.
static_assert(kDefaultFileUrlPipeSize >= net::kMaxBytesToSniff,
              "Default file data pipe size must be at least as large as a MIME-"
              "type sniffing buffer.");

// Policy to control how a FileURLLoader will handle directory URLs.
enum class DirectoryLoadingPolicy {
  // File paths which refer to directories are allowed and will load as an
  // HTML directory listing.
  kRespondWithListing,

  // File paths which refer to directories are treated as non-existent and
  // will result in FILE_NOT_FOUND errors.
  kFail,
};

// Policy to control whether or not file access constraints imposed by content
// or its embedder should be honored by a FileURLLoader.
enum class FileAccessPolicy {
  // Enforces file acccess policy defined by content and/or its embedder.
  kRestricted,

  // Ignores file access policy, allowing contents to be loaded from any
  // resolvable file path given.
  kUnrestricted,
};

// Policy to control whether or not a FileURLLoader should follow filesystem
// links (e.g. Windows shortcuts) where applicable.
enum class LinkFollowingPolicy {
  kFollow,
  kDoNotFollow,
};

GURL AppendUrlSeparator(const GURL& url) {
  std::string new_path = url.path() + '/';
  GURL::Replacements replacements;
  replacements.SetPathStr(new_path);
  return url.ReplaceComponents(replacements);
}

// This function checks the CORS origin access lists on the IO thread only when
// NetworkService is disabled. If NetworkService is enabled, callers can access
// the lists directly on the main thread.
bool AskIfSharedCorsOriginAccessListNotAllowOnIO(
    scoped_refptr<const SharedCorsOriginAccessList>
        shared_cors_origin_access_list,
    const url::Origin origin,
    const GURL url) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
  return shared_cors_origin_access_list->GetOriginAccessList().CheckAccessState(
             origin, url) !=
         network::cors::OriginAccessList::AccessState::kAllowed;
}

class FileURLDirectoryLoader
    : public network::mojom::URLLoader,
      public net::DirectoryLister::DirectoryListerDelegate {
 public:
  static void CreateAndStart(
      const base::FilePath& profile_path,
      const network::ResourceRequest& request,
      network::mojom::URLLoaderRequest loader,
      network::mojom::URLLoaderClientPtrInfo client_info,
      std::unique_ptr<FileURLLoaderObserver> observer,
      scoped_refptr<net::HttpResponseHeaders> response_headers) {
    // Owns itself. Will live as long as its URLLoader and URLLoaderClientPtr
    // bindings are alive - essentially until either the client gives up or all
    // file data has been sent to it.
    auto* file_url_loader = new FileURLDirectoryLoader;
    file_url_loader->Start(profile_path, request, std::move(loader),
                           std::move(client_info), std::move(observer),
                           std::move(response_headers));
  }

  // network::mojom::URLLoader:
  void FollowRedirect(const std::vector<std::string>& removed_headers,
                      const net::HttpRequestHeaders& modified_headers,
                      const base::Optional<GURL>& new_url) override {}
  void ProceedWithResponse() override { NOTREACHED(); }
  void SetPriority(net::RequestPriority priority,
                   int32_t intra_priority_value) override {}
  void PauseReadingBodyFromNet() override {}
  void ResumeReadingBodyFromNet() override {}

 private:
  FileURLDirectoryLoader() : binding_(this) {}
  ~FileURLDirectoryLoader() override = default;

  void Start(const base::FilePath& profile_path,
             const network::ResourceRequest& request,
             network::mojom::URLLoaderRequest loader,
             network::mojom::URLLoaderClientPtrInfo client_info,
             std::unique_ptr<content::FileURLLoaderObserver> observer,
             scoped_refptr<net::HttpResponseHeaders> response_headers) {
    binding_.Bind(std::move(loader));
    binding_.set_connection_error_handler(base::BindOnce(
        &FileURLDirectoryLoader::OnConnectionError, base::Unretained(this)));

    network::mojom::URLLoaderClientPtr client;
    client.Bind(std::move(client_info));

    if (!net::FileURLToFilePath(request.url, &path_)) {
      client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
      return;
    }

    base::File::Info info;
    if (!base::GetFileInfo(path_, &info) || !info.is_directory) {
      client->OnComplete(
          network::URLLoaderCompletionStatus(net::ERR_FILE_NOT_FOUND));
      return;
    }

    if (!GetContentClient()->browser()->IsFileAccessAllowed(
            path_, base::MakeAbsoluteFilePath(path_), profile_path)) {
      client->OnComplete(
          network::URLLoaderCompletionStatus(net::ERR_ACCESS_DENIED));
      return;
    }

    mojo::DataPipe pipe(kDefaultFileUrlPipeSize);
    if (!pipe.consumer_handle.is_valid()) {
      client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
      return;
    }

    network::ResourceResponseHead head;
    head.mime_type = "text/html";
    head.charset = "utf-8";
    client->OnReceiveResponse(head);
    client->OnStartLoadingResponseBody(std::move(pipe.consumer_handle));
    client_ = std::move(client);

    lister_ = std::make_unique<net::DirectoryLister>(path_, this);
    lister_->Start();

    data_producer_ = std::make_unique<mojo::StringDataPipeProducer>(
        std::move(pipe.producer_handle));
  }

  void OnConnectionError() {
    binding_.Close();
    MaybeDeleteSelf();
  }

  void MaybeDeleteSelf() {
    if (!binding_.is_bound() && !client_.is_bound() && !lister_)
      delete this;
  }

  // net::DirectoryLister::DirectoryListerDelegate:
  void OnListFile(
      const net::DirectoryLister::DirectoryListerData& data) override {
    if (!wrote_header_) {
      wrote_header_ = true;

#if defined(OS_WIN)
      const base::string16& title = path_.value();
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
      const base::string16& title =
          base::WideToUTF16(base::SysNativeMBToWide(path_.value()));
#endif
      pending_data_.append(net::GetDirectoryListingHeader(title));

      // If not a top-level directory, add a link to the parent directory. To
      // figure this out, first normalize |path_| by stripping trailing
      // separators. Then compare the result to its DirName(). For the top-level
      // directory, e.g. "/" or "c:\\", the normalized path is equal to its own
      // DirName().
      base::FilePath stripped_path = path_.StripTrailingSeparators();
      if (stripped_path != stripped_path.DirName())
        pending_data_.append(net::GetParentDirectoryLink());
    }

    // Skip current / parent links from the listing.
    base::FilePath filename = data.info.GetName();
    if (filename.value() != base::FilePath::kCurrentDirectory &&
        filename.value() != base::FilePath::kParentDirectory) {
#if defined(OS_WIN)
      std::string raw_bytes;  // Empty on Windows means UTF-8 encoded name.
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
      const std::string& raw_bytes = filename.value();
#endif
      pending_data_.append(net::GetDirectoryListingEntry(
          filename.LossyDisplayName(), raw_bytes, data.info.IsDirectory(),
          data.info.GetSize(), data.info.GetLastModifiedTime()));
    }

    MaybeTransferPendingData();
  }

  void OnListDone(int error) override {
    listing_result_ = error;
    lister_.reset();
    MaybeDeleteSelf();
  }

  void MaybeTransferPendingData() {
    if (transfer_in_progress_)
      return;

    transfer_in_progress_ = true;
    data_producer_->Write(pending_data_,
                          mojo::StringDataPipeProducer::AsyncWritingMode::
                              STRING_MAY_BE_INVALIDATED_BEFORE_COMPLETION,
                          base::BindOnce(&FileURLDirectoryLoader::OnDataWritten,
                                         base::Unretained(this)));
    // The producer above will have already copied any parts of |pending_data_|
    // that couldn't be written immediately, so we can wipe it out here to begin
    // accumulating more data.
    pending_data_.clear();
  }

  void OnDataWritten(MojoResult result) {
    transfer_in_progress_ = false;

    int completion_status;
    if (result == MOJO_RESULT_OK) {
      if (!pending_data_.empty()) {
        // Keep flushing the data buffer as long as it's non-empty and pipe
        // writes are succeeding.
        MaybeTransferPendingData();
        return;
      }

      // If there's no pending data but the lister is still active, we simply
      // wait for more listing results.
      if (lister_)
        return;

      // At this point we know the listing is complete and all available data
      // has been transferred. We inherit the status of the listing operation.
      completion_status = listing_result_;
    } else {
      completion_status = net::ERR_FAILED;
    }

    // All the data has been written now. Close the data pipe. The consumer will
    // be notified that there will be no more data to read from now.
    data_producer_.reset();

    client_->OnComplete(network::URLLoaderCompletionStatus(completion_status));
    client_.reset();

    MaybeDeleteSelf();
  }

  base::FilePath path_;
  std::unique_ptr<net::DirectoryLister> lister_;
  bool wrote_header_ = false;
  int listing_result_;

  mojo::Binding<network::mojom::URLLoader> binding_;
  network::mojom::URLLoaderClientPtr client_;

  std::unique_ptr<mojo::StringDataPipeProducer> data_producer_;
  std::string pending_data_;
  bool transfer_in_progress_ = false;

  DISALLOW_COPY_AND_ASSIGN(FileURLDirectoryLoader);
};

class FileURLLoader : public network::mojom::URLLoader {
 public:
  static void CreateAndStart(
      const base::FilePath& profile_path,
      const network::ResourceRequest& request,
      network::mojom::URLLoaderRequest loader,
      network::mojom::URLLoaderClientPtrInfo client_info,
      DirectoryLoadingPolicy directory_loading_policy,
      FileAccessPolicy file_access_policy,
      LinkFollowingPolicy link_following_policy,
      std::unique_ptr<FileURLLoaderObserver> observer,
      scoped_refptr<net::HttpResponseHeaders> extra_response_headers) {
    // Owns itself. Will live as long as its URLLoader and URLLoaderClientPtr
    // bindings are alive - essentially until either the client gives up or all
    // file data has been sent to it.
    auto* file_url_loader = new FileURLLoader;
    file_url_loader->Start(
        profile_path, request, std::move(loader), std::move(client_info),
        directory_loading_policy, file_access_policy, link_following_policy,
        std::move(observer), std::move(extra_response_headers));
  }

  // network::mojom::URLLoader:
  void FollowRedirect(const std::vector<std::string>& removed_headers,
                      const net::HttpRequestHeaders& modified_headers,
                      const base::Optional<GURL>& new_url) override {
    // |removed_headers| and |modified_headers| are unused. It doesn't make
    // sense for files. The FileURLLoader can redirect only to another file.
    std::unique_ptr<RedirectData> redirect_data = std::move(redirect_data_);
    if (redirect_data->is_directory) {
      FileURLDirectoryLoader::CreateAndStart(
          redirect_data->profile_path, redirect_data->request,
          binding_.Unbind(), client_.PassInterface(),
          std::move(redirect_data->observer),
          std::move(redirect_data->extra_response_headers));
    } else {
      FileURLLoader::CreateAndStart(
          redirect_data->profile_path, redirect_data->request,
          binding_.Unbind(), client_.PassInterface(),
          redirect_data->directory_loading_policy,
          redirect_data->file_access_policy,
          redirect_data->link_following_policy,
          std::move(redirect_data->observer),
          std::move(redirect_data->extra_response_headers));
    }
    MaybeDeleteSelf();
  }
  void ProceedWithResponse() override {}
  void SetPriority(net::RequestPriority priority,
                   int32_t intra_priority_value) override {}
  void PauseReadingBodyFromNet() override {}
  void ResumeReadingBodyFromNet() override {}

 private:
  // Used to save outstanding redirect data while waiting for FollowRedirect
  // to be called. Values default to their most restrictive in case they are
  // not set.
  struct RedirectData {
    bool is_directory = false;
    base::FilePath profile_path;
    network::ResourceRequest request;
    network::mojom::URLLoaderRequest loader;
    DirectoryLoadingPolicy directory_loading_policy =
        DirectoryLoadingPolicy::kFail;
    FileAccessPolicy file_access_policy = FileAccessPolicy::kRestricted;
    LinkFollowingPolicy link_following_policy =
        LinkFollowingPolicy::kDoNotFollow;
    std::unique_ptr<FileURLLoaderObserver> observer;
    scoped_refptr<net::HttpResponseHeaders> extra_response_headers;
  };

  FileURLLoader() : binding_(this) {}
  ~FileURLLoader() override = default;

  void Start(const base::FilePath& profile_path,
             const network::ResourceRequest& request,
             network::mojom::URLLoaderRequest loader,
             network::mojom::URLLoaderClientPtrInfo client_info,
             DirectoryLoadingPolicy directory_loading_policy,
             FileAccessPolicy file_access_policy,
             LinkFollowingPolicy link_following_policy,
             std::unique_ptr<FileURLLoaderObserver> observer,
             scoped_refptr<net::HttpResponseHeaders> extra_response_headers) {
    network::ResourceResponseHead head;
    head.request_start = base::TimeTicks::Now();
    head.response_start = base::TimeTicks::Now();
    head.headers = extra_response_headers;
    binding_.Bind(std::move(loader));
    binding_.set_connection_error_handler(base::BindOnce(
        &FileURLLoader::OnConnectionError, base::Unretained(this)));

    client_.Bind(std::move(client_info));

    base::FilePath path;
    if (!net::FileURLToFilePath(request.url, &path)) {
      OnClientComplete(net::ERR_FAILED, std::move(observer));
      return;
    }

    base::File::Info info;
    if (!base::GetFileInfo(path, &info)) {
      OnClientComplete(net::ERR_FILE_NOT_FOUND, std::move(observer));
      return;
    }

    if (info.is_directory) {
      if (directory_loading_policy == DirectoryLoadingPolicy::kFail) {
        OnClientComplete(net::ERR_FILE_NOT_FOUND, std::move(observer));
        return;
      }

      DCHECK_EQ(directory_loading_policy,
                DirectoryLoadingPolicy::kRespondWithListing);

      net::RedirectInfo redirect_info;
      redirect_info.new_method = "GET";
      redirect_info.status_code = 301;
      redirect_info.new_url = path.EndsWithSeparator()
                                  ? request.url
                                  : AppendUrlSeparator(request.url);
      head.encoded_data_length = 0;

      redirect_data_ = std::make_unique<RedirectData>();
      redirect_data_->is_directory = true;
      redirect_data_->profile_path = std::move(profile_path);
      redirect_data_->request = request;
      redirect_data_->directory_loading_policy = directory_loading_policy;
      redirect_data_->file_access_policy = file_access_policy;
      redirect_data_->link_following_policy = link_following_policy;
      redirect_data_->request.url = redirect_info.new_url;
      redirect_data_->observer = std::move(observer);
      redirect_data_->extra_response_headers =
          std::move(extra_response_headers);

      client_->OnReceiveRedirect(redirect_info, head);
      return;
    }

#if defined(OS_WIN)
    base::FilePath shortcut_target;
    if (link_following_policy == LinkFollowingPolicy::kFollow &&
        base::LowerCaseEqualsASCII(path.Extension(), ".lnk") &&
        base::win::ResolveShortcut(path, &shortcut_target, nullptr)) {
      // Follow Windows shortcuts
      redirect_data_ = std::make_unique<RedirectData>();
      if (!base::GetFileInfo(shortcut_target, &info)) {
        OnClientComplete(net::ERR_FILE_NOT_FOUND, std::move(observer));
        return;
      }

      GURL new_url = net::FilePathToFileURL(shortcut_target);
      if (info.is_directory && !path.EndsWithSeparator())
        new_url = AppendUrlSeparator(new_url);

      net::RedirectInfo redirect_info;
      redirect_info.new_method = "GET";
      redirect_info.status_code = 301;
      redirect_info.new_url = new_url;
      head.encoded_data_length = 0;

      redirect_data_->is_directory = info.is_directory;
      redirect_data_->profile_path = std::move(profile_path);
      redirect_data_->request = request;
      redirect_data_->directory_loading_policy = directory_loading_policy;
      redirect_data_->file_access_policy = file_access_policy;
      redirect_data_->link_following_policy = link_following_policy;
      redirect_data_->request.url = redirect_info.new_url;
      redirect_data_->observer = std::move(observer);
      redirect_data_->extra_response_headers =
          std::move(extra_response_headers);

      client_->OnReceiveRedirect(redirect_info, head);
      return;
    }
#endif  // defined(OS_WIN)

    if (file_access_policy == FileAccessPolicy::kRestricted &&
        !GetContentClient()->browser()->IsFileAccessAllowed(
            path, base::MakeAbsoluteFilePath(path), profile_path)) {
      OnClientComplete(net::ERR_ACCESS_DENIED, std::move(observer));
      return;
    }

    mojo::DataPipe pipe(kDefaultFileUrlPipeSize);
    if (!pipe.consumer_handle.is_valid()) {
      OnClientComplete(net::ERR_FAILED, std::move(observer));
      return;
    }

    // Should never be possible for this to be a directory. If FileURLLoader
    // is used to respond to a directory request, it must be because the URL
    // path didn't have a trailing path separator. In that case we finish with
    // a redirect above which will in turn be handled by FileURLDirectoryLoader.
    DCHECK(!info.is_directory);
    if (observer)
      observer->OnStart();

    base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
    if (!file.IsValid()) {
      if (observer) {
        observer->OnBytesRead(nullptr, 0u, file.error_details());
        observer->OnDoneReading();
      }
      net::Error net_error = net::FileErrorToNetError(file.error_details());
      client_->OnComplete(network::URLLoaderCompletionStatus(net_error));
      client_.reset();
      MaybeDeleteSelf();
      return;
    }
    char initial_read_buffer[net::kMaxBytesToSniff];
    int initial_read_result =
        file.ReadAtCurrentPos(initial_read_buffer, net::kMaxBytesToSniff);
    if (initial_read_result < 0) {
      base::File::Error read_error = base::File::GetLastFileError();
      DCHECK_NE(base::File::FILE_OK, read_error);
      if (observer) {
        // This can happen when the file is unreadable (which can happen during
        // corruption). We need to be sure to inform
        // the observer that we've finished reading so that it can proceed.
        observer->OnBytesRead(nullptr, 0u, read_error);
        observer->OnDoneReading();
      }
      net::Error net_error = net::FileErrorToNetError(read_error);
      client_->OnComplete(network::URLLoaderCompletionStatus(net_error));
      client_.reset();
      MaybeDeleteSelf();
      return;
    } else if (observer) {
      observer->OnBytesRead(initial_read_buffer, initial_read_result,
                            base::File::FILE_OK);
    }
    size_t initial_read_size = static_cast<size_t>(initial_read_result);

    std::string range_header;
    net::HttpByteRange byte_range;
    if (request.headers.GetHeader(net::HttpRequestHeaders::kRange,
                                  &range_header)) {
      // Handle a simple Range header for a single range.
      std::vector<net::HttpByteRange> ranges;
      bool fail = false;
      if (net::HttpUtil::ParseRangeHeader(range_header, &ranges) &&
          ranges.size() == 1) {
        byte_range = ranges[0];
        if (!byte_range.ComputeBounds(info.size))
          fail = true;
      } else {
        fail = true;
      }

      if (fail) {
        OnClientComplete(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE,
                         std::move(observer));
        return;
      }
    }

    size_t first_byte_to_send = 0;
    size_t total_bytes_to_send = static_cast<size_t>(info.size);

    if (byte_range.IsValid()) {
      first_byte_to_send =
          static_cast<size_t>(byte_range.first_byte_position());
      total_bytes_to_send =
          static_cast<size_t>(byte_range.last_byte_position()) -
          first_byte_to_send + 1;
    }

    total_bytes_written_ = static_cast<size_t>(total_bytes_to_send);

    head.content_length = base::saturated_cast<int64_t>(total_bytes_to_send);

    if (first_byte_to_send < initial_read_size) {
      // Write any data we read for MIME sniffing, constraining by range where
      // applicable. This will always fit in the pipe (see assertion near
      // |kDefaultFileUrlPipeSize| definition).
      uint32_t write_size = std::min(
          static_cast<uint32_t>(initial_read_size - first_byte_to_send),
          static_cast<uint32_t>(total_bytes_to_send));
      const uint32_t expected_write_size = write_size;
      MojoResult result = pipe.producer_handle->WriteData(
          &initial_read_buffer[first_byte_to_send], &write_size,
          MOJO_WRITE_DATA_FLAG_NONE);
      if (result != MOJO_RESULT_OK || write_size != expected_write_size) {
        OnFileWritten(std::move(observer), result);
        return;
      }

      // Discount the bytes we just sent from the total range.
      first_byte_to_send = initial_read_size;
      total_bytes_to_send -= write_size;
    }

    if (!net::GetMimeTypeFromFile(path, &head.mime_type)) {
      net::SniffMimeType(
          initial_read_buffer, initial_read_result, request.url, head.mime_type,
          GetContentClient()->browser()->ForceSniffingFileUrlsForHtml()
              ? net::ForceSniffFileUrlsForHtml::kEnabled
              : net::ForceSniffFileUrlsForHtml::kDisabled,
          &head.mime_type);
      head.did_mime_sniff = true;
    }
    if (head.headers) {
      head.headers->AddHeader(
          base::StringPrintf("%s: %s", net::HttpRequestHeaders::kContentType,
                             head.mime_type.c_str()));
    }
    client_->OnReceiveResponse(head);
    client_->OnStartLoadingResponseBody(std::move(pipe.consumer_handle));

    if (total_bytes_to_send == 0) {
      // There's definitely no more data, so we're already done.
      OnFileWritten(std::move(observer), MOJO_RESULT_OK);
      return;
    }

    // In case of a range request, seek to the appropriate position before
    // sending the remaining bytes asynchronously. Under normal conditions
    // (i.e., no range request) this Seek is effectively a no-op.
    int64_t new_position = file.Seek(base::File::FROM_BEGIN,
                                     static_cast<int64_t>(first_byte_to_send));
    if (observer)
      observer->OnSeekComplete(new_position);

    data_producer_ = std::make_unique<mojo::FileDataPipeProducer>(
        std::move(pipe.producer_handle), std::move(observer));
    data_producer_->WriteFromFile(
        std::move(file), total_bytes_to_send,
        base::BindOnce(&FileURLLoader::OnFileWritten, base::Unretained(this),
                       nullptr));
  }

  void OnConnectionError() {
    binding_.Close();
    MaybeDeleteSelf();
  }

  void OnClientComplete(net::Error net_error,
                        std::unique_ptr<FileURLLoaderObserver> observer) {
    client_->OnComplete(network::URLLoaderCompletionStatus(net_error));
    client_.reset();
    if (observer)
      observer->OnDoneReading();
    MaybeDeleteSelf();
  }

  void MaybeDeleteSelf() {
    if (!binding_.is_bound() && !client_.is_bound())
      delete this;
  }

  void OnFileWritten(std::unique_ptr<FileURLLoaderObserver> observer,
                     MojoResult result) {
    // All the data has been written now. Close the data pipe. The consumer will
    // be notified that there will be no more data to read from now.
    data_producer_.reset();
    if (observer)
      observer->OnDoneReading();

    if (result == MOJO_RESULT_OK) {
      network::URLLoaderCompletionStatus status(net::OK);
      status.encoded_data_length = total_bytes_written_;
      status.encoded_body_length = total_bytes_written_;
      status.decoded_body_length = total_bytes_written_;
      client_->OnComplete(status);
    } else {
      client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
    }
    client_.reset();
    MaybeDeleteSelf();
  }

  std::unique_ptr<mojo::FileDataPipeProducer> data_producer_;
  mojo::Binding<network::mojom::URLLoader> binding_;
  network::mojom::URLLoaderClientPtr client_;
  std::unique_ptr<RedirectData> redirect_data_;

  // In case of successful loads, this holds the total number of bytes written
  // to the response (this may be smaller than the total size of the file when
  // a byte range was requested).
  // It is used to set some of the URLLoaderCompletionStatus data passed back
  // to the URLLoaderClients (eg SimpleURLLoader).
  size_t total_bytes_written_ = 0;

  DISALLOW_COPY_AND_ASSIGN(FileURLLoader);
};

}  // namespace

FileURLLoaderFactory::FileURLLoaderFactory(
    const base::FilePath& profile_path,
    scoped_refptr<const SharedCorsOriginAccessList>
        shared_cors_origin_access_list,
    scoped_refptr<base::SequencedTaskRunner> task_runner)
    : profile_path_(profile_path),
      shared_cors_origin_access_list_(
          std::move(shared_cors_origin_access_list)),
      task_runner_(std::move(task_runner)) {}

FileURLLoaderFactory::~FileURLLoaderFactory() = default;

void FileURLLoaderFactory::CreateLoaderAndStart(
    network::mojom::URLLoaderRequest loader,
    int32_t routing_id,
    int32_t request_id,
    uint32_t options,
    const network::ResourceRequest& request,
    network::mojom::URLLoaderClientPtr client,
    const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  bool cors_flag =
      request.fetch_request_mode !=
          network::mojom::FetchRequestMode::kNavigate &&
      request.fetch_request_mode != network::mojom::FetchRequestMode::kNoCors;

  // CORS mode requires a valid |request_inisiator|. Check this condition first
  // so that kDisableWebSecurity should not hide program errors in tests.
  if (cors_flag && !request.request_initiator) {
    client->OnComplete(
        network::URLLoaderCompletionStatus(net::ERR_INVALID_ARGUMENT));
    return;
  }

  // If kDisableWebSecurity flag is specified, make all requests pretend as
  // "no-cors" requests. Otherwise, call IsSameOriginWith to check if file
  // scheme match.
  cors_flag = cors_flag &&
              !base::CommandLine::ForCurrentProcess()->HasSwitch(
                  switches::kDisableWebSecurity) &&
              !request.request_initiator->IsSameOriginWith(
                  url::Origin::Create(request.url));

  // CORS is not available for the file scheme, but can be exceptionally
  // permitted by the access lists.
  if (cors_flag) {
    // Code in this clause assumes running on the UI thread.
    // GetOriginAccessList() is accessible only on the UI thread if
    // NetworkService is enabled, or on the IO thread if it is disabled.
    DCHECK_CURRENTLY_ON(BrowserThread::UI);

    if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
      // If NetworkService is enabled, |mode| should be kNoCors for the case of
      // |shared_cors_origin_access_list_| being nullptr, and the previous check
      // should not return kAskAccessList.
      // Only internal call sites, such as ExtensionDownloader, is permitted.
      DCHECK(shared_cors_origin_access_list_);
      cors_flag =
          shared_cors_origin_access_list_->GetOriginAccessList()
              .CheckAccessState(*request.request_initiator, request.url) !=
          network::cors::OriginAccessList::AccessState::kAllowed;
    } else {
      // TODO(toyoshim): Remove this thread-hop code once the NetworkService is
      // fully enabled, and if other IO thread users do not need cors enabled
      // requests. At this moment, ResourceDownloader is the only users on the
      // IO thread, and it always makes "no-cors" requests.
      base::PostTaskWithTraitsAndReplyWithResult(
          FROM_HERE, {BrowserThread::IO},
          base::BindOnce(&AskIfSharedCorsOriginAccessListNotAllowOnIO,
                         base::RetainedRef(shared_cors_origin_access_list_),
                         *request.request_initiator, request.url),
          base::BindOnce(&FileURLLoaderFactory::CreateLoaderAndStartInternal,
                         this->AsWeakPtr(), request, std::move(loader),
                         std::move(client)));
      return;
    }
  }

  CreateLoaderAndStartInternal(request, std::move(loader), std::move(client),
                               cors_flag);
}

void FileURLLoaderFactory::CreateLoaderAndStartInternal(
    const network::ResourceRequest request,
    network::mojom::URLLoaderRequest loader,
    network::mojom::URLLoaderClientPtr client,
    bool cors_flag) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  if (cors_flag) {
    // FileURLLoader doesn't support CORS and it's not covered by CorsURLLoader,
    // so we need to reject requests that need CORS manually.
    client->OnComplete(
        network::URLLoaderCompletionStatus(network::CorsErrorStatus(
            network::mojom::CorsError::kCorsDisabledScheme)));
    return;
  }

  // Check file path just after all CORS flag checks are handled.
  base::FilePath file_path;
  if (!net::FileURLToFilePath(request.url, &file_path)) {
    client->OnComplete(
        network::URLLoaderCompletionStatus(net::ERR_INVALID_URL));
    return;
  }

  if (file_path.EndsWithSeparator() && file_path.IsAbsolute()) {
    task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&FileURLDirectoryLoader::CreateAndStart, profile_path_,
                       request, std::move(loader), client.PassInterface(),
                       std::unique_ptr<FileURLLoaderObserver>(), nullptr));
  } else {
    task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&FileURLLoader::CreateAndStart, profile_path_, request,
                       std::move(loader), client.PassInterface(),
                       DirectoryLoadingPolicy::kRespondWithListing,
                       FileAccessPolicy::kRestricted,
                       LinkFollowingPolicy::kFollow,
                       std::unique_ptr<FileURLLoaderObserver>(),
                       nullptr /* extra_response_headers */));
  }
}

void FileURLLoaderFactory::Clone(
    network::mojom::URLLoaderFactoryRequest loader) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  bindings_.AddBinding(this, std::move(loader));
}

void CreateFileURLLoader(
    const network::ResourceRequest& request,
    network::mojom::URLLoaderRequest loader,
    network::mojom::URLLoaderClientPtr client,
    std::unique_ptr<FileURLLoaderObserver> observer,
    scoped_refptr<net::HttpResponseHeaders> extra_response_headers) {
  // TODO(crbug.com/924416): Re-evaluate how TaskPriority is set here and in
  // other file URL-loading-related code. Some callers require USER_VISIBLE
  // (i.e., BEST_EFFORT is not enough).
  auto task_runner = base::CreateSequencedTaskRunnerWithTraits(
      {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
  task_runner->PostTask(
      FROM_HERE,
      base::BindOnce(&FileURLLoader::CreateAndStart, base::FilePath(), request,
                     std::move(loader), client.PassInterface(),
                     DirectoryLoadingPolicy::kFail,
                     FileAccessPolicy::kUnrestricted,
                     LinkFollowingPolicy::kDoNotFollow, std::move(observer),
                     std::move(extra_response_headers)));
}

std::unique_ptr<network::mojom::URLLoaderFactory> CreateFileURLLoaderFactory(
    const base::FilePath& profile_path,
    scoped_refptr<const SharedCorsOriginAccessList>
        shared_cors_origin_access_list) {
  // TODO(crbug.com/924416): Re-evaluate TaskPriority: Should the caller provide
  // it?
  return std::make_unique<content::FileURLLoaderFactory>(
      profile_path, shared_cors_origin_access_list,
      base::CreateSequencedTaskRunnerWithTraits(
          {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
           base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}));
}

}  // namespace content
