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

#include "net/url_request/url_request_file_dir_job.h"

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

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "net/base/filename_util.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/test/gtest_util.h"
#include "net/test/test_with_scoped_task_environment.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::StartsWith;
using net::test::IsError;
using net::test::IsOk;

namespace net {

namespace {

const int kBufferSize = 4096;

// Snippets of JS code from net/base/dir_header.html.
const char kHeaderStart[] = "<script>start(\"";
const char kEntryStart[] = "<script>addRow(\"";
const char kParentDirLink[] = "<script>onHasParentDirectory();";

bool HasHeader(const std::string& response_body, const base::FilePath& dir) {
  std::vector<std::string> lines = base::SplitString(
      response_body, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  for (const std::string& line : lines) {
    if (StartsWith(line, kHeaderStart, base::CompareCase::INSENSITIVE_ASCII))
      return line.find(dir.BaseName().MaybeAsASCII()) != std::string::npos;
  }
  return false;
}

bool HasParentDirLink(const std::string& response_body) {
  return response_body.find(kParentDirLink) != std::string::npos;
}

// There should not be any entries for the parent dir, so this should always
// return false.
bool HasParentDirEntry(const std::string& response_body) {
  std::string needle = kEntryStart;
  needle += "..\"";
  return response_body.find(needle) != std::string::npos;
}

bool HasEntry(const std::string& response_body, const base::FilePath& entry) {
  std::string needle = kEntryStart + entry.BaseName().MaybeAsASCII();
  return response_body.find(needle) != std::string::npos;
}

int GetEntryCount(const std::string& response_body) {
  int count = 0;
  std::vector<std::string> lines = base::SplitString(
      response_body, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  for (const std::string& line : lines) {
    if (StartsWith(line, kEntryStart, base::CompareCase::INSENSITIVE_ASCII))
      ++count;
  }
  return count;
}

class TestJobFactory : public URLRequestJobFactory {
 public:
  explicit TestJobFactory(const base::FilePath& path) : path_(path) {}
  ~TestJobFactory() override = default;

  URLRequestJob* MaybeCreateJobWithProtocolHandler(
      const std::string& scheme,
      URLRequest* request,
      NetworkDelegate* network_delegate) const override {
    URLRequestJob* job =
        new URLRequestFileDirJob(request, network_delegate, path_);

    return job;
  }

  URLRequestJob* MaybeInterceptRedirect(URLRequest* request,
                                        NetworkDelegate* network_delegate,
                                        const GURL& location) const override {
    return nullptr;
  }

  URLRequestJob* MaybeInterceptResponse(
      URLRequest* request,
      NetworkDelegate* network_delegate) const override {
    return nullptr;
  }

  bool IsHandledProtocol(const std::string& scheme) const override {
    return scheme == "file";
  }

  bool IsSafeRedirectTarget(const GURL& location) const override {
    return false;
  }

 private:
  const base::FilePath path_;

  DISALLOW_COPY_AND_ASSIGN(TestJobFactory);
};

class TestDirectoryURLRequestDelegate : public TestDelegate {
 public:
  TestDirectoryURLRequestDelegate() = default;

  ~TestDirectoryURLRequestDelegate() override = default;

  void OnResponseStarted(URLRequest* request, int net_error) override {
    got_response_started_ = true;
  }

  bool got_response_started() const { return got_response_started_; }

 private:
  bool got_response_started_ = false;

  DISALLOW_COPY_AND_ASSIGN(TestDirectoryURLRequestDelegate);
};

class URLRequestFileDirTest : public TestWithScopedTaskEnvironment {
 public:
  URLRequestFileDirTest()
      : buffer_(base::MakeRefCounted<IOBuffer>(kBufferSize)) {}

 protected:
  TestURLRequestContext context_;
  TestDirectoryURLRequestDelegate delegate_;
  scoped_refptr<IOBuffer> buffer_;
};

TEST_F(URLRequestFileDirTest, ListCompletionOnNoPending) {
  base::ScopedTempDir directory;
  // It is necessary to pass an existing directory to UrlRequest object,
  // but it will be deleted for testing purpose after request is started.
  ASSERT_TRUE(directory.CreateUniqueTempDir());
  TestJobFactory factory(directory.GetPath());
  context_.set_job_factory(&factory);
  std::unique_ptr<URLRequest> request(context_.CreateRequest(
      FilePathToFileURL(
          directory.GetPath().AppendASCII("this_path_does_not_exist")),
      DEFAULT_PRIORITY, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS));

  request->Start();
  ASSERT_TRUE(directory.Delete());

  // Since the DirectoryLister is running on the network thread, this
  // will spin the message loop until the read error is returned to the
  // URLRequestFileDirJob.
  RunUntilIdle();
  ASSERT_TRUE(delegate_.got_response_started());

  int bytes_read = request->Read(buffer_.get(), kBufferSize);

  // The URLRequestFileDirJobShould return the cached read error synchronously.
  // If it's not returned synchronously, the code path this is intended to test
  // was not executed.
  EXPECT_THAT(bytes_read, IsError(ERR_FILE_NOT_FOUND));
}

// Test the case where reading the response completes synchronously.
TEST_F(URLRequestFileDirTest, DirectoryWithASingleFileSync) {
  base::ScopedTempDir directory;
  ASSERT_TRUE(directory.CreateUniqueTempDir());
  base::FilePath path;
  base::CreateTemporaryFileInDir(directory.GetPath(), &path);

  TestJobFactory factory(directory.GetPath());
  context_.set_job_factory(&factory);

  std::unique_ptr<URLRequest> request(
      context_.CreateRequest(FilePathToFileURL(path), DEFAULT_PRIORITY,
                             &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS));
  request->Start();
  EXPECT_TRUE(request->is_pending());

  // Since the DirectoryLister is running on the network thread, this will spin
  // the message loop until the URLRequetsFileDirJob has received the
  // entire directory listing and cached it.
  RunUntilIdle();

  // This will complete synchronously, since the URLRequetsFileDirJob had
  // directory listing cached in memory.
  int bytes_read = request->Read(buffer_.get(), kBufferSize);

  ASSERT_GT(bytes_read, 0);
  ASSERT_LE(bytes_read, kBufferSize);
  std::string data(buffer_->data(), bytes_read);
  EXPECT_TRUE(HasHeader(data, directory.GetPath()));
  EXPECT_TRUE(HasParentDirLink(data));
  ASSERT_EQ(1, GetEntryCount(data));
  EXPECT_TRUE(HasEntry(data, path));
  EXPECT_FALSE(HasParentDirEntry(data));
}

// Test the case where reading the response completes asynchronously.
TEST_F(URLRequestFileDirTest, DirectoryWithASingleFileAsync) {
  base::ScopedTempDir directory;
  ASSERT_TRUE(directory.CreateUniqueTempDir());
  base::FilePath path;
  base::CreateTemporaryFileInDir(directory.GetPath(), &path);

  TestJobFactory factory(directory.GetPath());
  context_.set_job_factory(&factory);

  TestDelegate delegate;
  std::unique_ptr<URLRequest> request(
      context_.CreateRequest(FilePathToFileURL(path), DEFAULT_PRIORITY,
                             &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
  request->Start();
  EXPECT_TRUE(request->is_pending());

  base::RunLoop().Run();

  ASSERT_GT(delegate.bytes_received(), 0);
  ASSERT_LE(delegate.bytes_received(), kBufferSize);
  EXPECT_TRUE(HasHeader(delegate.data_received(), directory.GetPath()));
  EXPECT_TRUE(HasParentDirLink(delegate.data_received()));
  ASSERT_EQ(1, GetEntryCount(delegate.data_received()));
  EXPECT_TRUE(HasEntry(delegate.data_received(), path));
  EXPECT_FALSE(HasParentDirEntry(delegate.data_received()));
}

TEST_F(URLRequestFileDirTest, DirectoryWithAFileAndSubdirectory) {
  base::ScopedTempDir directory;
  ASSERT_TRUE(directory.CreateUniqueTempDir());

  base::FilePath sub_dir;
  CreateTemporaryDirInDir(directory.GetPath(),
                          FILE_PATH_LITERAL("CreateNewSubDirectoryInDirectory"),
                          &sub_dir);

  base::FilePath path;
  base::CreateTemporaryFileInDir(directory.GetPath(), &path);

  TestJobFactory factory(directory.GetPath());
  context_.set_job_factory(&factory);

  TestDelegate delegate;
  std::unique_ptr<URLRequest> request(
      context_.CreateRequest(FilePathToFileURL(path), DEFAULT_PRIORITY,
                             &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
  request->Start();
  EXPECT_TRUE(request->is_pending());

  base::RunLoop().Run();

  ASSERT_GT(delegate.bytes_received(), 0);
  ASSERT_LE(delegate.bytes_received(), kBufferSize);
  EXPECT_TRUE(HasHeader(delegate.data_received(), directory.GetPath()));
  EXPECT_TRUE(HasParentDirLink(delegate.data_received()));
  ASSERT_EQ(2, GetEntryCount(delegate.data_received()));
  EXPECT_TRUE(HasEntry(delegate.data_received(), sub_dir));
  EXPECT_TRUE(HasEntry(delegate.data_received(), path));
  EXPECT_FALSE(HasParentDirEntry(delegate.data_received()));
}

TEST_F(URLRequestFileDirTest, EmptyDirectory) {
  base::ScopedTempDir directory;
  ASSERT_TRUE(directory.CreateUniqueTempDir());

  TestJobFactory factory(directory.GetPath());
  context_.set_job_factory(&factory);

  TestDelegate delegate;
  std::unique_ptr<URLRequest> request(context_.CreateRequest(
      FilePathToFileURL(directory.GetPath()), DEFAULT_PRIORITY, &delegate,
      TRAFFIC_ANNOTATION_FOR_TESTS));
  request->Start();
  EXPECT_TRUE(request->is_pending());

  base::RunLoop().Run();

  ASSERT_GT(delegate.bytes_received(), 0);
  ASSERT_LE(delegate.bytes_received(), kBufferSize);
  EXPECT_TRUE(HasHeader(delegate.data_received(), directory.GetPath()));
  EXPECT_TRUE(HasParentDirLink(delegate.data_received()));
  ASSERT_EQ(0, GetEntryCount(delegate.data_received()));
  EXPECT_FALSE(HasParentDirEntry(delegate.data_received()));
}

// Android security policies prevent access to the root directory, so skip this
// test there.
#if !defined(OS_ANDROID)
TEST_F(URLRequestFileDirTest, RootDirectory) {
  for (int slashes_to_test = 1; slashes_to_test < 4; ++slashes_to_test) {
    base::FilePath::StringType root_dir_string;
#if defined(OS_WIN)
    root_dir_string = L"C:";
#endif
    root_dir_string.append(slashes_to_test, base::FilePath::kSeparators[0]);
    base::FilePath root_dir(root_dir_string);
    TestJobFactory factory(root_dir);
    context_.set_job_factory(&factory);

    TestDelegate delegate;
    std::unique_ptr<URLRequest> request(
        context_.CreateRequest(FilePathToFileURL(root_dir), DEFAULT_PRIORITY,
                               &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
    request->Start();
    EXPECT_TRUE(request->is_pending());

    base::RunLoop().Run();

    ASSERT_GT(delegate.bytes_received(), 0);
    ASSERT_LE(delegate.bytes_received(), kBufferSize);
    EXPECT_TRUE(HasHeader(delegate.data_received(), root_dir));
    EXPECT_FALSE(HasParentDirLink(delegate.data_received()));
    EXPECT_GT(GetEntryCount(delegate.data_received()), 0);
    EXPECT_FALSE(HasParentDirEntry(delegate.data_received()));
  }
}
#endif  // !defined(OS_ANDROID)

}  // namespace

}  // namespace net
