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

#include "extensions/browser/extension_protocols.h"

#include <stddef.h>

#include <memory>
#include <optional>
#include <string>
#include <utility>

#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/test/power_monitor_test.h"
#include "base/test/test_file_util.h"
#include "base/test/values_test_util.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/chrome_content_verifier_delegate.h"
#include "chrome/browser/extensions/chrome_extensions_browser_client.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/testing_profile.h"
#include "components/crx_file/id_util.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/web_contents_tester.h"
#include "extensions/browser/content_verifier/content_verifier.h"
#include "extensions/browser/content_verifier/test_utils.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/unloaded_extension_reason.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extension_paths.h"
#include "extensions/common/file_util.h"
#include "extensions/test/test_extension_dir.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/test/test_url_loader_client.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/loader/referrer_utils.h"

using extensions::ExtensionRegistry;
using network::mojom::URLLoader;
using testing::_;
using testing::StrictMock;

namespace extensions {
namespace {

constexpr char kValidTrialToken1[] = "valid_token_1";
constexpr char kValidTrialToken2[] = "valid_token_2";
constexpr char kTrialTokensHeaderValue[] = "valid_token_1, valid_token_2";

base::FilePath GetTestPath(const std::string& name) {
  base::FilePath path;
  EXPECT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &path));
  return path.AppendASCII("extensions").AppendASCII(name);
}

base::FilePath GetContentVerifierTestPath() {
  base::FilePath path;
  EXPECT_TRUE(base::PathService::Get(DIR_TEST_DATA, &path));
  return path.AppendASCII("content_hash_fetcher")
      .AppendASCII("different_sized_files");
}

scoped_refptr<const Extension> CreateTestExtension(const std::string& name,
                                                   bool incognito_split_mode,
                                                   int manifest_version) {
  return ExtensionBuilder(name)
      .SetManifestVersion(manifest_version)
      .SetManifestKey("incognito", incognito_split_mode ? "split" : "spanning")
      .SetPath(GetTestPath("response_headers"))
      .SetLocation(mojom::ManifestLocation::kInternal)
      .Build();
}

scoped_refptr<const Extension> CreateWebStoreExtension(int manifest_version) {
  base::FilePath path;
  EXPECT_TRUE(base::PathService::Get(chrome::DIR_RESOURCES, &path));
  path = path.AppendASCII("web_store");

  return ExtensionBuilder("WebStore")
      .SetManifestVersion(manifest_version)
      .SetManifestKey("icons",
                      base::Value::Dict().Set("16", "webstore_icon_16.png"))
      .SetManifestKey(
          "web_accessible_resources",
          manifest_version == 3
              ? base::Value::List().Append(
                    base::Value::Dict()
                        .Set("resources",
                             base::Value::List().Append("webstore_icon_16.png"))
                        .Set("matches", base::Value::List().Append("*://*/*")))
              : base::Value::List().Append("webstore_icon_16.png"))
      .SetPath(path)
      .SetLocation(mojom::ManifestLocation::kComponent)
      .Build();
}

scoped_refptr<const Extension> CreateTestResponseHeaderExtension(
    int manifest_version) {
  if (manifest_version == 3) {
    return ExtensionBuilder("An extension with web-accessible resources")
        .SetManifestVersion(3)
        .SetManifestKey(
            "web_accessible_resources",
            base::Value::List().Append(
                base::Value::Dict()
                    .Set("resources",
                         base::Value::List()
                             .Append("test.dat")
                             .Append("mime_type_sniffer_test.gif1"))
                    .Set("matches", base::Value::List().Append("*://*/*"))))
        .SetManifestKey("background", base::Value::Dict().Set("service_worker",
                                                              "background.js"))
        .SetManifestKey("trial_tokens", base::Value::List()
                                            .Append(kValidTrialToken1)
                                            .Append(kValidTrialToken2))
        .SetPath(GetTestPath("response_headers"))
        .Build();
  }
  return ExtensionBuilder("An extension with web-accessible resources")
      .SetManifestVersion(manifest_version)
      .SetManifestKey("web_accessible_resources",
                      base::Value::List()
                          .Append("test.dat")
                          .Append("mime_type_sniffer_test.gif1"))
      .SetManifestKey(
          "background",
          base::Value::Dict().Set("scripts",
                                  base::Value::List().Append("background.js")))
      .SetPath(GetTestPath("response_headers"))
      .Build();
}

scoped_refptr<const Extension> CreateTestModuleResponseHeaderExtension(
    int manifest_version) {
  return ExtensionBuilder("A module extension")
      .SetManifestVersion(manifest_version)
      .SetManifestKey("export", base::Value::Dict())
      .SetPath(GetTestPath("response_headers"))
      .Build();
}

scoped_refptr<const Extension> CreateTestModuleImporterResponseHeaderExtension(
    int manifest_version,
    const std::string& module_extension_id) {
  if (manifest_version == 3) {
    return ExtensionBuilder("A module importer extension")
        .SetManifestVersion(3)
        .SetManifestKey("import",
                        base::Value::List().Append(
                            base::Value::Dict().Set("id", module_extension_id)))
        .SetManifestKey("trial_tokens", base::Value::List()
                                            .Append(kValidTrialToken1)
                                            .Append(kValidTrialToken2))
        .SetPath(GetTestPath("response_headers"))
        .Build();
  }
  return ExtensionBuilder("A module importer extension")
      .SetManifestVersion(manifest_version)
      .SetManifestKey("import",
                      base::Value::List().Append(
                          base::Value::Dict().Set("id", module_extension_id)))
      .SetPath(GetTestPath("response_headers"))
      .Build();
}

// Helper function to create a |ResourceRequest| for testing purposes.
network::ResourceRequest CreateResourceRequest(
    const std::string& method,
    network::mojom::RequestDestination destination,
    const GURL& url) {
  network::ResourceRequest request;
  request.method = method;
  request.url = url;
  request.site_for_cookies =
      net::SiteForCookies::FromUrl(url);  // bypass third-party cookie blocking.
  request.request_initiator =
      url::Origin::Create(url);  // ensure initiator set.
  request.referrer_policy = blink::ReferrerUtils::GetDefaultNetReferrerPolicy();
  request.destination = destination;
  request.is_outermost_main_frame =
      destination == network::mojom::RequestDestination::kDocument;
  return request;
}

// The result of either a URLRequest of a URLLoader response (but not both)
// depending on the on test type.
class GetResult {
 public:
  GetResult(network::mojom::URLResponseHeadPtr response, int result)
      : response_(std::move(response)), result_(result) {}
  GetResult(GetResult&& other) : result_(other.result_) {}

  GetResult(const GetResult&) = delete;
  GetResult& operator=(const GetResult&) = delete;

  ~GetResult() = default;

  std::string GetResponseHeaderByName(const std::string& name) const {
    if (!response_ || !response_->headers) {
      return std::string();
    }
    return response_->headers->GetNormalizedHeader(name).value_or(
        std::string());
  }

  bool HasContentLengthHeader() {
    std::string content_length =
        GetResponseHeaderByName(net::HttpRequestHeaders::kContentLength);

    int length_value = 0;
    return !content_length.empty() &&
           base::StringToInt(content_length, &length_value) && length_value > 0;
  }

  bool HeaderIsPresent(const std::string& name) {
    return !GetResponseHeaderByName(name).empty();
  }

  int result() const { return result_; }

 private:
  network::mojom::URLResponseHeadPtr response_;
  int result_;
};

}  // namespace

// This test lives in src/chrome instead of src/extensions because it tests
// functionality delegated back to Chrome via ChromeExtensionsBrowserClient.
// See chrome/browser/extensions/chrome_url_request_util.cc.
class ExtensionProtocolsTestBase : public testing::Test,
                                   public testing::WithParamInterface<int> {
 public:
  explicit ExtensionProtocolsTestBase(bool force_incognito)
      : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP),
        rvh_test_enabler_(new content::RenderViewHostTestEnabler()),
        force_incognito_(force_incognito) {}

  void SetUp() override {
    testing::Test::SetUp();
    testing_profile_ = TestingProfile::Builder().Build();
    contents_ = CreateTestWebContents();

    // Set up content verification.
    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
    command_line->AppendSwitchASCII(
        switches::kExtensionContentVerification,
        switches::kExtensionContentVerificationEnforce);
    content_verifier_ = new ContentVerifier(
        browser_context(),
        std::make_unique<ChromeContentVerifierDelegate>(browser_context()));
    content_verifier_->Start();
    static_cast<TestExtensionSystem*>(ExtensionSystem::Get(browser_context()))
        ->set_content_verifier(content_verifier_.get());
    loader_factory_.Bind(
        CreateExtensionNavigationURLLoaderFactory(browser_context(), false));
  }

  void TearDown() override {
    loader_factory_.reset();
    content_verifier_->Shutdown();
    // Shut down the PowerMonitor if initialized.
    base::PowerMonitor::GetInstance()->ShutdownForTesting();
  }

  GetResult RequestOrLoad(const GURL& url,
                          network::mojom::RequestDestination destination) {
    return LoadURL(url, destination);
  }

  void AddExtension(const scoped_refptr<const Extension>& extension,
                    bool incognito_enabled,
                    bool notifications_disabled) {
    EXPECT_TRUE(extension_registry()->AddEnabled(extension));
    extension_registry()->TriggerOnLoaded(extension.get());
    ExtensionPrefs::Get(browser_context())
        ->SetIsIncognitoEnabled(extension->id(), incognito_enabled);
  }

  void RemoveExtension(const scoped_refptr<const Extension>& extension,
                       const UnloadedExtensionReason reason) {
    EXPECT_TRUE(extension_registry()->RemoveEnabled(extension->id()));
    extension_registry()->TriggerOnUnloaded(extension.get(), reason);
    if (reason == UnloadedExtensionReason::DISABLE)
      EXPECT_TRUE(extension_registry()->AddDisabled(extension));
  }

  // Helper method to create a URL request/loader, call RequestOrLoad on it, and
  // return the result. If |extension| hasn't already been added to
  // extension_registry(), this will add it.
  GetResult DoRequestOrLoad(const scoped_refptr<Extension> extension,
                            const std::string& relative_path) {
    if (!extension_registry()->enabled_extensions().Contains(extension->id())) {
      AddExtension(extension.get(),
                   /*incognito_enabled=*/false,
                   /*notifications_disabled=*/false);
    }
    return RequestOrLoad(extension->GetResourceURL(relative_path),
                         network::mojom::RequestDestination::kDocument);
  }

  ExtensionRegistry* extension_registry() {
    return ExtensionRegistry::Get(browser_context());
  }

  content::BrowserContext* browser_context() {
    return force_incognito_ ? testing_profile_->GetPrimaryOTRProfile(
                                  /*create_if_needed=*/true)
                            : testing_profile_.get();
  }

  void EnableSimulationOfSystemSuspendForRequests() {
    power_monitor_source_.emplace();
  }

 protected:
  scoped_refptr<ContentVerifier> content_verifier_;

 private:
  GetResult LoadURL(const GURL& url,
                    network::mojom::RequestDestination destination) {
    constexpr int32_t kRequestId = 28;

    mojo::PendingRemote<network::mojom::URLLoader> loader;
    network::TestURLLoaderClient client;
    loader_factory_->CreateLoaderAndStart(
        loader.InitWithNewPipeAndPassReceiver(), kRequestId,
        network::mojom::kURLLoadOptionNone,
        CreateResourceRequest("GET", destination, url), client.CreateRemote(),
        net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));

    // If `power_monitor_source_` is set, simulates power suspend and resume
    // notifications. These notifications are posted tasks that will be executed
    // by `client.RunUntilComplete()`.
    if (power_monitor_source_) {
      power_monitor_source_->Suspend();
      power_monitor_source_->Resume();
    }

    client.RunUntilComplete();
    return GetResult(client.response_head().Clone(),
                     client.completion_status().error_code);
  }

  std::unique_ptr<content::WebContents> CreateTestWebContents() {
    auto site_instance = content::SiteInstance::Create(browser_context());
    return content::WebContentsTester::CreateTestWebContents(
        browser_context(), std::move(site_instance));
  }

  content::BrowserTaskEnvironment task_environment_;
  std::unique_ptr<content::RenderViewHostTestEnabler> rvh_test_enabler_;
  mojo::Remote<network::mojom::URLLoaderFactory> loader_factory_;
  std::unique_ptr<TestingProfile> testing_profile_;
  std::unique_ptr<content::WebContents> contents_;
  const bool force_incognito_;

  std::optional<base::test::ScopedPowerMonitorTestSource> power_monitor_source_;
};

class ExtensionProtocolsTest : public ExtensionProtocolsTestBase {
 public:
  ExtensionProtocolsTest()
      : ExtensionProtocolsTestBase(false /*force_incognito*/) {}
};

class ExtensionProtocolsIncognitoTest : public ExtensionProtocolsTestBase {
 public:
  ExtensionProtocolsIncognitoTest()
      : ExtensionProtocolsTestBase(true /*force_incognito*/) {}
};

// A specialization that will only run on MV3 extensions.
using ExtensionProtocolsMV3Test = ExtensionProtocolsTest;

INSTANTIATE_TEST_SUITE_P(MV2, ExtensionProtocolsTest, ::testing::Values(2));
INSTANTIATE_TEST_SUITE_P(MV3, ExtensionProtocolsTest, ::testing::Values(3));
INSTANTIATE_TEST_SUITE_P(MV2,
                         ExtensionProtocolsIncognitoTest,
                         ::testing::Values(2));
INSTANTIATE_TEST_SUITE_P(MV3,
                         ExtensionProtocolsIncognitoTest,
                         ::testing::Values(3));
INSTANTIATE_TEST_SUITE_P(MV3, ExtensionProtocolsMV3Test, ::testing::Values(3));

// Tests that making a chrome-extension request in an incognito context is
// only allowed under the right circumstances (if the extension is allowed
// in incognito, and it's either a non-main-frame request or a split-mode
// extension).
TEST_P(ExtensionProtocolsIncognitoTest, IncognitoRequest) {
  struct TestCase {
    // Inputs.
    std::string name;
    bool incognito_split_mode;
    bool incognito_enabled;

    // Expected result.
    bool should_allow_main_frame_load;
  } test_cases[] = {
      {"spanning disabled", false, false, false},
      {"split disabled", true, false, false},
      {"spanning enabled", false, true, false},
      {"split enabled", true, true, true},
  };

  for (const auto& test_case : test_cases) {
    scoped_refptr<const Extension> extension = CreateTestExtension(
        test_case.name, test_case.incognito_split_mode, GetParam());
    AddExtension(extension, test_case.incognito_enabled, false);

    // First test a main frame request.
    // It doesn't matter that the resource doesn't exist. If the resource
    // is blocked, we should see BLOCKED_BY_CLIENT. Otherwise, the request
    // should just fail because the file doesn't exist.
    auto get_result =
        RequestOrLoad(extension->GetResourceURL("404.html"),
                      network::mojom::RequestDestination::kDocument);

    if (test_case.should_allow_main_frame_load) {
      EXPECT_EQ(net::ERR_FILE_NOT_FOUND, get_result.result()) << test_case.name;
    } else {
      EXPECT_EQ(net::ERR_BLOCKED_BY_CLIENT, get_result.result())
          << test_case.name;
    }
    // Subframe navigation requests are blocked in ExtensionNavigationThrottle
    // which isn't added in this unit test. This is tested in an integration
    // test in ExtensionResourceRequestPolicyTest.IframeNavigateToInaccessible.
    RemoveExtension(extension, UnloadedExtensionReason::UNINSTALL);
  }
}

// Tests getting a resource for a component extension works correctly, both when
// the extension is enabled and when it is disabled.
TEST_P(ExtensionProtocolsTest, ComponentResourceRequest) {
  scoped_refptr<const Extension> extension =
      CreateWebStoreExtension(GetParam());
  AddExtension(extension, false, false);

  // First test it with the extension enabled.
  {
    auto get_result =
        RequestOrLoad(extension->GetResourceURL("webstore_icon_16.png"),
                      network::mojom::RequestDestination::kVideo);
    EXPECT_EQ(net::OK, get_result.result());
    EXPECT_TRUE(get_result.HasContentLengthHeader());
    EXPECT_EQ("image/png", get_result.GetResponseHeaderByName(
                               net::HttpRequestHeaders::kContentType));
    // TODO(crbug.com/333078381): remove "Content-Security-Policy" header from
    // images.
    EXPECT_TRUE(get_result.HeaderIsPresent("Content-Security-Policy"));
  }

  // And then test it with the extension disabled.
  RemoveExtension(extension, UnloadedExtensionReason::DISABLE);
  {
    auto get_result =
        RequestOrLoad(extension->GetResourceURL("webstore_icon_16.png"),
                      network::mojom::RequestDestination::kVideo);
    EXPECT_EQ(net::OK, get_result.result());
    EXPECT_TRUE(get_result.HasContentLengthHeader());
    EXPECT_EQ("image/png", get_result.GetResponseHeaderByName(
                               net::HttpRequestHeaders::kContentType));
  }
}

// Tests that a URL request for resource from an extension returns a few
// expected response headers.
TEST_P(ExtensionProtocolsTest, ResourceRequestResponseHeaders) {
  scoped_refptr<const Extension> extension =
      CreateTestResponseHeaderExtension(GetParam());
  AddExtension(extension, false, false);

  {
    auto get_result = RequestOrLoad(extension->GetResourceURL("test.dat"),
                                    network::mojom::RequestDestination::kVideo);
    EXPECT_EQ(net::OK, get_result.result());

    // Check that cache-related headers are set.
    std::string etag = get_result.GetResponseHeaderByName("ETag");
    EXPECT_TRUE(base::StartsWith(etag, "\"", base::CompareCase::SENSITIVE));
    EXPECT_TRUE(base::EndsWith(etag, "\"", base::CompareCase::SENSITIVE));

    EXPECT_EQ("no-cache", get_result.GetResponseHeaderByName("Cache-Control"));

    // We set test.dat as web-accessible, so it should have CORS headers.
    EXPECT_EQ(
        "*", get_result.GetResponseHeaderByName("Access-Control-Allow-Origin"));
    EXPECT_EQ("cross-origin", get_result.GetResponseHeaderByName(
                                  "Cross-Origin-Resource-Policy"));

    // Only background service worker script should be allowed to load as a
    // service worker.
    EXPECT_FALSE(get_result.HeaderIsPresent("Service-Worker-Allowed"));

    // COEP header does not make sense in non-document responses.
    EXPECT_FALSE(get_result.HeaderIsPresent("Cross-Origin-Embedder-Policy"));

    // CSP header does not make sense in non-document responses
    // TODO(crbug.com/333078381): remove "Content-Security-Policy" header from
    // non-document responses and update this check.
    EXPECT_TRUE(get_result.HeaderIsPresent("Content-Security-Policy"));

    // COOP header does not make sense in non-document responses.
    EXPECT_FALSE(get_result.HeaderIsPresent("Cross-Origin-Opener-Policy"));

    // Origin Trials header does not make sense in video resource responses.
    EXPECT_FALSE(get_result.HeaderIsPresent("Origin-Trial"));
  }
}

// Tests that request for background script returns a few expected response
// headers.
TEST_P(ExtensionProtocolsTest, BackgroundScriptRequestResponseHeaders) {
  const int manifest_version = GetParam();
  scoped_refptr<const Extension> extension =
      CreateTestResponseHeaderExtension(manifest_version);
  AddExtension(extension, false, false);

  {
    auto get_result =
        RequestOrLoad(extension->GetResourceURL("background.js"),
                      network::mojom::RequestDestination::kServiceWorker);
    EXPECT_EQ(net::OK, get_result.result());

    // Check that cache-related headers are set.
    std::string etag = get_result.GetResponseHeaderByName("ETag");
    EXPECT_TRUE(base::StartsWith(etag, "\"", base::CompareCase::SENSITIVE));
    EXPECT_TRUE(base::EndsWith(etag, "\"", base::CompareCase::SENSITIVE));

    EXPECT_EQ("no-cache", get_result.GetResponseHeaderByName("Cache-Control"));

    // Background scripts are not web-accessible, so do not need CORS headers.
    EXPECT_FALSE(get_result.HeaderIsPresent("Access-Control-Allow-Origin"));
    EXPECT_FALSE(get_result.HeaderIsPresent("Cross-Origin-Resource-Policy"));

    // Only background service worker script should be allowed to load as a
    // service worker.
    if (manifest_version == 3) {
      EXPECT_EQ("/",
                get_result.GetResponseHeaderByName("Service-Worker-Allowed"));
    } else {
      EXPECT_FALSE(get_result.HeaderIsPresent("Service-Worker-Allowed"));
    }

    // COEP header does not make sense in non-document responses.
    EXPECT_FALSE(get_result.HeaderIsPresent("Cross-Origin-Embedder-Policy"));

    // Even though CSP is currently not respected for service workers, it
    // probably should be. We continue to send a CSP header for service worker
    // scripts for when this changes.
    // See also
    // https://github.com/w3c/webappsec-csp/issues/336#issuecomment-1274730655
    if (manifest_version == 3) {
      EXPECT_EQ("script-src 'self';",
                get_result.GetResponseHeaderByName("Content-Security-Policy"));
    } else {
      EXPECT_EQ(
          "script-src 'self' blob: filesystem:; object-src 'self' blob: "
          "filesystem:;",
          get_result.GetResponseHeaderByName("Content-Security-Policy"));
    }

    // COOP header does not make sense in non-document responses.
    EXPECT_FALSE(get_result.HeaderIsPresent("Cross-Origin-Opener-Policy"));
  }
}

// Tests that request for background service worker returns Origin-Trial
// response header.
TEST_P(ExtensionProtocolsMV3Test, BackgroundScriptRequestResponseHeaders) {
  EXPECT_EQ(3, GetParam());
  scoped_refptr<const Extension> extension =
      CreateTestResponseHeaderExtension(GetParam());
  AddExtension(extension, false, false);

  {
    auto get_result =
        RequestOrLoad(extension->GetResourceURL("background.js"),
                      network::mojom::RequestDestination::kServiceWorker);
    EXPECT_EQ(net::OK, get_result.result());

    // In MV3-style service workers origin trail tokens are served via service
    // worker Origin-Trial header.
    EXPECT_EQ(kTrialTokensHeaderValue,
              get_result.GetResponseHeaderByName("Origin-Trial"));
  }
}

// TODO(crbug.com/333078381): Add a test checking that:
// - when background.page or background.service_worker is specified requesting
//   generated background page fails
// - when no background is specified, requesting generated background page fails

TEST_P(ExtensionProtocolsTest, BackgroundPageRequestResponseHeaders) {
  const int manifest_version = GetParam();
  scoped_refptr<const Extension> extension =
      CreateTestResponseHeaderExtension(manifest_version);
  AddExtension(extension, false, false);

  {
    auto get_result = RequestOrLoad(
        extension->GetResourceURL(kGeneratedBackgroundPageFilename),
        network::mojom::RequestDestination::kDocument);
    EXPECT_EQ(net::OK, get_result.result());

    // Check that cache-related headers are omitted
    // TODO(crbug.com/333078381): consider adding these headers to generated
    // pages.
    EXPECT_FALSE(get_result.HeaderIsPresent("ETag"));
    EXPECT_FALSE(get_result.HeaderIsPresent("Cache-Control"));

    // Background pages are not web-accessible, so do not need CORS headers.
    EXPECT_FALSE(get_result.HeaderIsPresent("Access-Control-Allow-Origin"));
    EXPECT_FALSE(get_result.HeaderIsPresent("Cross-Origin-Resource-Policy"));

    // Background page does not need to be loaded as a service worker.
    EXPECT_FALSE(get_result.HeaderIsPresent("Service-Worker-Allowed"));

    // Background page does not load cross-origin content so does not need COEP
    // header.
    EXPECT_FALSE(get_result.HeaderIsPresent("Cross-Origin-Embedder-Policy"));

    if (manifest_version == 3) {
      EXPECT_EQ("script-src 'self';",
                get_result.GetResponseHeaderByName("Content-Security-Policy"));
    } else {
      EXPECT_EQ(
          "script-src 'self' blob: filesystem:; object-src 'self' blob: "
          "filesystem:;",
          get_result.GetResponseHeaderByName("Content-Security-Policy"));
    }

    // COOP header does not make sense in non-document responses.
    EXPECT_FALSE(get_result.HeaderIsPresent("Cross-Origin-Opener-Policy"));
  }
}

// Tests that resources from imported module extensions get appropriately
// loaded with proper headers or rejected
TEST_P(ExtensionProtocolsTest, ModuleRequestResponseHeaders) {
  const int manifest_version = GetParam();
  scoped_refptr<const Extension> module_extension =
      CreateTestModuleResponseHeaderExtension(manifest_version);
  scoped_refptr<const Extension> importer_extension =
      CreateTestModuleImporterResponseHeaderExtension(manifest_version,
                                                      module_extension->id());
  AddExtension(module_extension, false, false);
  AddExtension(importer_extension, false, false);

  // Not imported id will fail.
  {
    auto get_result =
        RequestOrLoad(importer_extension->GetResourceURL(
                          "_modules/modaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/test.dat"),
                      network::mojom::RequestDestination::kDocument);
    EXPECT_EQ(net::ERR_BLOCKED_BY_CLIENT, get_result.result());
  }
  {
    auto get_result =
        RequestOrLoad(importer_extension->GetResourceURL(
                          "_modules/modaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/test.dat"),
                      network::mojom::RequestDestination::kServiceWorker);
    EXPECT_EQ(net::ERR_BLOCKED_BY_CLIENT, get_result.result());
  }

  // Imported resources get loaded with proper headers (inherited from
  // importer).
  {
    auto get_result =
        RequestOrLoad(importer_extension->GetResourceURL(
                          "_modules/" + module_extension->id() + "/test.dat"),
                      network::mojom::RequestDestination::kDocument);
    EXPECT_EQ(net::OK, get_result.result());

    // Check that cache-related headers are set.
    std::string etag = get_result.GetResponseHeaderByName("ETag");
    EXPECT_TRUE(base::StartsWith(etag, "\"", base::CompareCase::SENSITIVE));
    EXPECT_TRUE(base::EndsWith(etag, "\"", base::CompareCase::SENSITIVE));

    // Background pages are not web-accessible, so do not need CORS headers.
    EXPECT_FALSE(get_result.HeaderIsPresent("Access-Control-Allow-Origin"));
    EXPECT_FALSE(get_result.HeaderIsPresent("Cross-Origin-Resource-Policy"));

    // Background page does not need to be loaded as a service worker.
    EXPECT_FALSE(get_result.HeaderIsPresent("Service-Worker-Allowed"));

    // Background page does not load cross-origin content so does not need COEP
    // header.
    EXPECT_FALSE(get_result.HeaderIsPresent("Cross-Origin-Embedder-Policy"));

    if (manifest_version == 3) {
      EXPECT_EQ("script-src 'self';",
                get_result.GetResponseHeaderByName("Content-Security-Policy"));
    } else {
      EXPECT_EQ(
          "script-src 'self' blob: filesystem:; object-src 'self' blob: "
          "filesystem:;",
          get_result.GetResponseHeaderByName("Content-Security-Policy"));
    }

    // COOP header does not make sense in non-document responses.
    EXPECT_FALSE(get_result.HeaderIsPresent("Cross-Origin-Opener-Policy"));
  }
}

// Tests that request for background service worker returns Origin-Trial
// response header.
TEST_P(ExtensionProtocolsMV3Test, ModuleRequestResponseHeaders) {
  EXPECT_EQ(3, GetParam());
  const int manifest_version = GetParam();
  scoped_refptr<const Extension> module_extension =
      CreateTestModuleResponseHeaderExtension(manifest_version);
  scoped_refptr<const Extension> importer_extension =
      CreateTestModuleImporterResponseHeaderExtension(manifest_version,
                                                      module_extension->id());
  AddExtension(module_extension, false, false);
  AddExtension(importer_extension, false, false);

  // Imported resources get loaded with proper headers (inherited from
  // importer).
  {
    auto get_result =
        RequestOrLoad(importer_extension->GetResourceURL(
                          "_modules/" + module_extension->id() + "/test.dat"),
                      network::mojom::RequestDestination::kDocument);
    EXPECT_EQ(net::OK, get_result.result());

    // Origin-Trial header should contain trials inherited from importer.
    EXPECT_EQ(kTrialTokensHeaderValue,
              get_result.GetResponseHeaderByName("Origin-Trial"));
  }
}

TEST_P(ExtensionProtocolsTest, InvalidBackgroundScriptRequest) {
  const int manifest_version = GetParam();
  scoped_refptr<const Extension> extension =
      CreateTestResponseHeaderExtension(manifest_version);
  AddExtension(extension, false, false);

  // Requesting script from background key with invalid destination is
  // forbidden.
  std::vector<network::mojom::RequestDestination> destinations = {
      // TODO(crbug.com/333078381): carefully consider which other
      // request destinations should be allowed or blocked and update
      // this test
      network::mojom::RequestDestination::kJson,
      network::mojom::RequestDestination::kStyle,
      network::mojom::RequestDestination::kVideo,
  };
  for (network::mojom::RequestDestination destination : destinations) {
    auto get_result =
        RequestOrLoad(extension->GetResourceURL("background.js"), destination);
    EXPECT_EQ(net::ERR_BLOCKED_BY_CLIENT, get_result.result()) << destination;
  }
}

// Tests that a URL request for main frame or subframe from an extension
// succeeds, but subresources fail. See http://crbug.com/312269.
TEST_P(ExtensionProtocolsTest, AllowFrameRequests) {
  scoped_refptr<const Extension> extension =
      CreateTestExtension("foo", false, GetParam());
  AddExtension(extension, false, false);

  // All MAIN_FRAME requests should succeed. SUB_FRAME requests that are not
  // explicitly listed in web_accessible_resources or same-origin to the parent
  // should not succeed.
  {
    auto get_result =
        RequestOrLoad(extension->GetResourceURL("test.dat"),
                      network::mojom::RequestDestination::kDocument);
    EXPECT_EQ(net::OK, get_result.result());
  }

  // Subframe navigation requests are blocked in ExtensionNavigationThrottle
  // which isn't added in this unit test. This is tested in an integration test
  // in ExtensionResourceRequestPolicyTest.IframeNavigateToInaccessible.

  // And subresource types, such as media, should fail.
  {
    auto get_result = RequestOrLoad(extension->GetResourceURL("test.dat"),
                                    network::mojom::RequestDestination::kVideo);
    EXPECT_EQ(net::ERR_BLOCKED_BY_CLIENT, get_result.result());
  }
}

// Make sure requests for paths ending with a separator aren't allowed. See
// https://crbug.com/356878412.
TEST_P(ExtensionProtocolsTest, PathsWithTrailingSeparatorsAreNotAllowed) {
  base::FilePath extension_dir = GetTestPath("simple_with_file");
  std::string error;
  scoped_refptr<Extension> extension = file_util::LoadExtension(
      extension_dir, mojom::ManifestLocation::kInternal, Extension::NO_FLAGS,
      &error);
  ASSERT_NE(extension.get(), nullptr) << "error: " << error;

  // Loading "/file.html" should succeed.
  EXPECT_EQ(net::OK, DoRequestOrLoad(extension, "file.html").result());

  // Loading "/file.html/" should fail.
  base::FilePath relative_path =
      base::FilePath(FILE_PATH_LITERAL("file.html")).AsEndingWithSeparator();
  EXPECT_EQ(net::ERR_FILE_NOT_FOUND,
            DoRequestOrLoad(extension, relative_path.AsUTF8Unsafe()).result());
}

// Make sure requests for paths ending with a dot or a space aren't resolved to
// the corresponding file without the ending dot or space, as it normally would
// on Windows. See https://crbug.com/400119351.
TEST_P(ExtensionProtocolsTest, PathsWithTrailingDotSpaceAreNotAllowed) {
  base::FilePath extension_dir = GetTestPath("simple_with_file");
  std::string error;
  scoped_refptr<Extension> extension = file_util::LoadExtension(
      extension_dir, mojom::ManifestLocation::kInternal, Extension::NO_FLAGS,
      &error);
  ASSERT_NE(extension.get(), nullptr) << "error: " << error;

  // Loading "/file.html" should succeed.
  EXPECT_EQ(net::OK, DoRequestOrLoad(extension, "file.html").result());

  // Loading "/file.html." and "/file.html " should fail.
  for (const std::string suffix : {".", "%20"}) {
    // Add the suffix manually, as `GetResourceURL` strips trailing spaces.
    GURL url = GURL(extension->GetResourceURL("file.html").spec() + suffix);
    EXPECT_EQ(net::ERR_FILE_NOT_FOUND,
              RequestOrLoad(url, network::mojom::RequestDestination::kDocument)
                  .result());
  }
}

// Make sure directories with an index.html file aren't serving the file, i.e.
// index.html doesn't get any special treatment.
TEST_P(ExtensionProtocolsTest, DirectoryWithIndexHtml) {
  base::FilePath extension_dir = GetTestPath("simple_with_index_html");
  std::string error;
  scoped_refptr<Extension> extension = file_util::LoadExtension(
      extension_dir, mojom::ManifestLocation::kInternal, Extension::NO_FLAGS,
      &error);
  ASSERT_NE(extension.get(), nullptr) << "error: " << error;

  // Loading "/test_dir" should fail.
  base::FilePath relative_path(FILE_PATH_LITERAL("test_dir"));
  EXPECT_EQ(net::ERR_FILE_NOT_FOUND,
            DoRequestOrLoad(extension, relative_path.AsUTF8Unsafe()).result());

  // Loading "/test_dir/" should fail.
  relative_path = relative_path.AsEndingWithSeparator();
  EXPECT_EQ(net::ERR_FILE_NOT_FOUND,
            DoRequestOrLoad(extension, relative_path.AsUTF8Unsafe()).result());

  // Loading "/test_dir/index.html" explicitly should succeed.
  relative_path = relative_path.AppendASCII("index.html");
  EXPECT_EQ(net::OK,
            DoRequestOrLoad(extension, relative_path.AsUTF8Unsafe()).result());
}

TEST_P(ExtensionProtocolsTest, MetadataFolder) {
  base::FilePath extension_dir = GetTestPath("metadata_folder");
  std::string error;
  scoped_refptr<Extension> extension = file_util::LoadExtension(
      extension_dir, mojom::ManifestLocation::kInternal, Extension::NO_FLAGS,
      &error);
  ASSERT_NE(extension.get(), nullptr) << "error: " << error;

  // Loading "/test.html" should succeed.
  EXPECT_EQ(net::OK, DoRequestOrLoad(extension, "test.html").result());

  // Loading "/_metadata/verified_contents.json" should fail.
  base::FilePath relative_path =
      base::FilePath(kMetadataFolder).Append(kVerifiedContentsFilename);
  EXPECT_TRUE(base::PathExists(extension_dir.Append(relative_path)));
  EXPECT_NE(net::OK,
            DoRequestOrLoad(extension, relative_path.AsUTF8Unsafe()).result());

  // Loading "/_metadata/a.txt" should also fail.
  relative_path = base::FilePath(kMetadataFolder).AppendASCII("a.txt");
  EXPECT_TRUE(base::PathExists(extension_dir.Append(relative_path)));
  EXPECT_NE(net::OK,
            DoRequestOrLoad(extension, relative_path.AsUTF8Unsafe()).result());
}

// Tests that unreadable files and deleted files correctly go through
// ContentVerifyJob.
TEST_P(ExtensionProtocolsTest, VerificationSeenForFileAccessErrors) {
  // Unzip extension containing verification hashes to a temporary directory.
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath unzipped_path = temp_dir.GetPath();
  scoped_refptr<Extension> extension =
      content_verifier_test_utils::UnzipToDirAndLoadExtension(
          GetContentVerifierTestPath().AppendASCII("source.zip"),
          unzipped_path);
  ASSERT_TRUE(extension.get());
  ExtensionId extension_id = extension->id();

  const std::string kJs("1024.js");
  base::FilePath kRelativePath(FILE_PATH_LITERAL("1024.js"));

  // Valid and readable 1024.js.
  {
    TestContentVerifySingleJobObserver observer(extension_id, kRelativePath);
    EXPECT_EQ(net::OK, DoRequestOrLoad(extension, kJs).result());
    EXPECT_EQ(ContentVerifyJob::NONE, observer.WaitForJobFinished());
  }

  // chmod -r 1024.js.
  {
    TestContentVerifySingleJobObserver observer(extension_id, kRelativePath);
    base::FilePath file_path = unzipped_path.AppendASCII(kJs);
    ASSERT_TRUE(base::MakeFileUnreadable(file_path));
    EXPECT_EQ(net::ERR_ACCESS_DENIED, DoRequestOrLoad(extension, kJs).result());
    EXPECT_EQ(ContentVerifyJob::HASH_MISMATCH, observer.WaitForJobFinished());
    // NOTE: In production, hash mismatch would have disabled |extension|, but
    // since UnzipToDirAndLoadExtension() doesn't add the extension to
    // ExtensionRegistry, ChromeContentVerifierDelegate won't disable it.
    // TODO(lazyboy): We may want to update this to more closely reflect the
    // real flow.
  }

  // Delete 1024.js.
  {
    TestContentVerifySingleJobObserver observer(extension_id, kRelativePath);
    base::FilePath file_path = unzipped_path.AppendASCII(kJs);
    ASSERT_TRUE(base::DieFileDie(file_path, false));
    EXPECT_EQ(net::ERR_FILE_NOT_FOUND,
              DoRequestOrLoad(extension, kJs).result());
    EXPECT_EQ(ContentVerifyJob::HASH_MISMATCH, observer.WaitForJobFinished());
  }
}

// Tests that zero byte files correctly go through ContentVerifyJob.
TEST_P(ExtensionProtocolsTest, VerificationSeenForZeroByteFile) {
  const std::string kEmptyJs("empty.js");
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath unzipped_path = temp_dir.GetPath();

  scoped_refptr<Extension> extension =
      content_verifier_test_utils::UnzipToDirAndLoadExtension(
          GetContentVerifierTestPath().AppendASCII("source.zip"),
          unzipped_path);
  ASSERT_TRUE(extension.get());

  base::FilePath kRelativePath(FILE_PATH_LITERAL("empty.js"));
  ExtensionId extension_id = extension->id();

  // Sanity check empty.js.
  base::FilePath file_path = unzipped_path.AppendASCII(kEmptyJs);
  std::optional<int64_t> foo_file_size = base::GetFileSize(file_path);
  ASSERT_TRUE(foo_file_size.has_value());
  ASSERT_EQ(0, foo_file_size.value());

  // Request empty.js.
  {
    TestContentVerifySingleJobObserver observer(extension_id, kRelativePath);
    EXPECT_EQ(net::OK, DoRequestOrLoad(extension, kEmptyJs).result());
    EXPECT_EQ(ContentVerifyJob::NONE, observer.WaitForJobFinished());
  }

  // chmod -r empty.js.
  // Unreadable empty file results in hash mismatch.
  {
    TestContentVerifySingleJobObserver observer(extension_id, kRelativePath);
    ASSERT_TRUE(base::MakeFileUnreadable(file_path));
    EXPECT_EQ(net::ERR_ACCESS_DENIED,
              DoRequestOrLoad(extension, kEmptyJs).result());
    EXPECT_EQ(ContentVerifyJob::HASH_MISMATCH, observer.WaitForJobFinished());
  }

  // rm empty.js.
  // Deleted empty file results in hash mismatch.
  {
    TestContentVerifySingleJobObserver observer(extension_id, kRelativePath);
    ASSERT_TRUE(base::DieFileDie(file_path, false));
    EXPECT_EQ(net::ERR_FILE_NOT_FOUND,
              DoRequestOrLoad(extension, kEmptyJs).result());
    EXPECT_EQ(ContentVerifyJob::HASH_MISMATCH, observer.WaitForJobFinished());
  }
}

TEST_P(ExtensionProtocolsTest, VerifyScriptListedAsIcon) {
  const std::string kBackgroundJs("background.js");
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath unzipped_path = temp_dir.GetPath();

  base::FilePath path;
  EXPECT_TRUE(base::PathService::Get(DIR_TEST_DATA, &path));

  scoped_refptr<Extension> extension =
      content_verifier_test_utils::UnzipToDirAndLoadExtension(
          path.AppendASCII("content_hash_fetcher")
              .AppendASCII("manifest_mislabeled_script")
              .AppendASCII("source.zip"),
          unzipped_path);
  ASSERT_TRUE(extension.get());

  base::FilePath kRelativePath(FILE_PATH_LITERAL("background.js"));
  ExtensionId extension_id = extension->id();

  // Request background.js.
  {
    TestContentVerifySingleJobObserver observer(extension_id, kRelativePath);
    EXPECT_EQ(net::OK, DoRequestOrLoad(extension, kBackgroundJs).result());
    EXPECT_EQ(ContentVerifyJob::NONE, observer.WaitForJobFinished());
  }

  // Modify background.js and request it.
  {
    base::FilePath file_path = unzipped_path.AppendASCII("background.js");
    const std::string content = "new content";
    EXPECT_TRUE(base::WriteFile(file_path, content));

    TestContentVerifySingleJobObserver observer(extension_id, kRelativePath);
    EXPECT_EQ(net::OK, DoRequestOrLoad(extension, kBackgroundJs).result());
    EXPECT_EQ(ContentVerifyJob::HASH_MISMATCH, observer.WaitForJobFinished());
  }
}

// Tests that mime types are properly set for returned extension resources.
TEST_P(ExtensionProtocolsTest, MimeTypesForKnownFiles) {
  TestExtensionDir test_dir;
  const int manifest_version = GetParam();
  constexpr char kManifestV2[] = R"(
      {
        "name": "Test Ext",
        "manifest_version": 2,
        "version": "1",
        "web_accessible_resources": ["*"]
      })";
  constexpr char kManifestV3[] = R"(
      {
        "name": "Test Ext",
        "manifest_version": 3,
        "version": "1",
        "web_accessible_resources": [{
          "resources": [ "*" ],
          "matches": [ "*://*/*" ]
        }]
      })";
  const char* kManifest = manifest_version == 3 ? kManifestV3 : kManifestV2;
  test_dir.WriteManifest(kManifest);
  base::Value::Dict manifest = base::test::ParseJsonDict(kManifest);
  ASSERT_FALSE(manifest.empty());

  test_dir.WriteFile(FILE_PATH_LITERAL("json_file.json"), "{}");
  test_dir.WriteFile(FILE_PATH_LITERAL("js_file.js"), "function() {}");

  base::FilePath unpacked_path = test_dir.UnpackedPath();
  ASSERT_TRUE(base::PathExists(unpacked_path.AppendASCII("json_file.json")));
  std::string error;
  scoped_refptr<const Extension> extension =
      ExtensionBuilder()
          .SetManifest(std::move(manifest))
          .SetPath(unpacked_path)
          .SetLocation(mojom::ManifestLocation::kInternal)
          .Build();
  ASSERT_TRUE(extension);

  AddExtension(extension.get(), false, false);

  struct {
    const char* file_name;
    const char* expected_mime_type;
  } test_cases[] = {
      {"json_file.json", "application/json"},
      {"js_file.js", "text/javascript"},
      {"mem_file.mem", ""},
  };

  for (const auto& test_case : test_cases) {
    SCOPED_TRACE(test_case.file_name);
    EXPECT_EQ(
        test_case.expected_mime_type,
        RequestOrLoad(extension->GetResourceURL(test_case.file_name),
                      network::mojom::RequestDestination::kEmpty)
            .GetResponseHeaderByName(net::HttpRequestHeaders::kContentType));
  }
}

// Tests that requests for extension resources (including the generated
// background page) are not aborted on system suspend.
TEST_P(ExtensionProtocolsTest, ExtensionRequestsNotAborted) {
  base::FilePath extension_dir =
      GetTestPath("common").AppendASCII("background_script");
  std::string error;
  scoped_refptr<Extension> extension = file_util::LoadExtension(
      extension_dir, mojom::ManifestLocation::kInternal, Extension::NO_FLAGS,
      &error);
  ASSERT_TRUE(extension.get()) << error;

  EnableSimulationOfSystemSuspendForRequests();

  // Request the generated background page. Ensure the request completes
  // successfully.
  EXPECT_EQ(net::OK,
            DoRequestOrLoad(extension.get(), kGeneratedBackgroundPageFilename)
                .result());

  // Request the background.js file. Ensure the request completes successfully.
  EXPECT_EQ(net::OK,
            DoRequestOrLoad(extension.get(), "background.js").result());
}

// Tests that mime type sniffing is not performed for extension resources.
TEST_P(ExtensionProtocolsTest, MimeTypeSniffingNotPerformed) {
  scoped_refptr<const Extension> extension =
      CreateTestResponseHeaderExtension(GetParam());
  AddExtension(extension, false, false);

  auto get_result =
      RequestOrLoad(extension->GetResourceURL("mime_type_sniffer_test.gif1"),
                    network::mojom::RequestDestination::kDocument);
  EXPECT_EQ(net::OK, get_result.result());

  // With mime sniffing, the content type would be image/gif.
  EXPECT_EQ("application/octet-stream",
            get_result.GetResponseHeaderByName("Content-Type"));
}

}  // namespace extensions
