blob: 13d41b0a40adc625c741aa70d7018d92da605277 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/files/file_util.h"
#include "base/memory/raw_ptr.h"
#include "build/build_config.h"
#include "content/browser/web_package/web_bundle_browsertest_base.h"
#include "content/browser/web_package/web_bundle_utils.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
namespace content {
namespace {
// "%2F" is treated as an invalid character for file URLs.
constexpr char kInvalidFileUrl[] = "file:///tmp/test%2F/a.wbn";
} // namespace
class InvalidTrustableWebBundleFileUrlBrowserTest : public ContentBrowserTest {
public:
InvalidTrustableWebBundleFileUrlBrowserTest(
const InvalidTrustableWebBundleFileUrlBrowserTest&) = delete;
InvalidTrustableWebBundleFileUrlBrowserTest& operator=(
const InvalidTrustableWebBundleFileUrlBrowserTest&) = delete;
protected:
InvalidTrustableWebBundleFileUrlBrowserTest() = default;
~InvalidTrustableWebBundleFileUrlBrowserTest() override = default;
void SetUpOnMainThread() override {
ContentBrowserTest::SetUpOnMainThread();
original_client_ = SetBrowserClientForTesting(&browser_client_);
}
void TearDownOnMainThread() override {
ContentBrowserTest::TearDownOnMainThread();
SetBrowserClientForTesting(original_client_);
}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII(switches::kTrustableWebBundleFileUrl,
kInvalidFileUrl);
}
private:
raw_ptr<ContentBrowserClient> original_client_ = nullptr;
web_bundle_browsertest_utils::TestBrowserClient browser_client_;
};
IN_PROC_BROWSER_TEST_F(InvalidTrustableWebBundleFileUrlBrowserTest,
NoCrashOnNavigation) {
base::RunLoop run_loop;
web_bundle_browsertest_utils::FinishNavigationObserver
finish_navigation_observer(shell()->web_contents(),
run_loop.QuitClosure());
EXPECT_FALSE(NavigateToURL(shell()->web_contents(), GURL(kInvalidFileUrl)));
run_loop.Run();
ASSERT_TRUE(finish_navigation_observer.error_code());
EXPECT_EQ(net::ERR_INVALID_URL, *finish_navigation_observer.error_code());
}
class WebBundleTrustableFileBrowserTest
: public testing::WithParamInterface<
web_bundle_browsertest_utils::TestFilePathMode>,
public web_bundle_browsertest_utils::WebBundleBrowserTestBase {
public:
WebBundleTrustableFileBrowserTest(const WebBundleTrustableFileBrowserTest&) =
delete;
WebBundleTrustableFileBrowserTest& operator=(
const WebBundleTrustableFileBrowserTest&) = delete;
protected:
WebBundleTrustableFileBrowserTest() = default;
~WebBundleTrustableFileBrowserTest() override = default;
void SetUp() override {
InitializeTestDataUrl();
web_bundle_browsertest_utils::WebBundleBrowserTestBase::SetUp();
}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII(switches::kTrustableWebBundleFileUrl,
test_data_url().spec());
}
void WriteWebBundleFile(const std::string& contents) {
base::ScopedAllowBlockingForTesting allow_blocking;
ASSERT_FALSE(contents.empty());
ASSERT_TRUE(base::WriteFile(test_data_file_path_, contents.data(),
contents.size()) > 0);
}
void WriteCommonWebBundleFile() {
std::string contents;
{
base::ScopedAllowBlockingForTesting allow_blocking;
ASSERT_TRUE(
base::ReadFileToString(web_bundle_browsertest_utils::GetTestDataPath(
"web_bundle_browsertest_b2.wbn"),
&contents));
}
WriteWebBundleFile(contents);
}
const GURL& test_data_url() const { return test_data_url_; }
void RunSharedNavigationTest(
void (*setup_func)(net::EmbeddedTestServer*, GURL*, std::string*),
void (*run_test_func)(WebContents*,
const GURL&,
const GURL&,
base::RepeatingCallback<GURL(const GURL&)>)) {
GURL url_origin;
std::string web_bundle_content;
(*setup_func)(embedded_test_server(), &url_origin, &web_bundle_content);
WriteWebBundleFile(web_bundle_content);
(*run_test_func)(shell()->web_contents(), test_data_url(), url_origin,
base::BindRepeating([](const GURL& url) { return url; }));
}
private:
void InitializeTestDataUrl() {
base::FilePath file_path;
CreateTemporaryWebBundleFile("", &file_path);
if (GetParam() ==
web_bundle_browsertest_utils::TestFilePathMode::kNormalFilePath) {
test_data_file_path_ = file_path;
test_data_url_ = net::FilePathToFileURL(file_path);
return;
}
#if BUILDFLAG(IS_ANDROID)
DCHECK_EQ(web_bundle_browsertest_utils::TestFilePathMode::kContentURI,
GetParam());
web_bundle_browsertest_utils::CopyFileAndGetContentUri(
file_path, &test_data_url_, &test_data_file_path_);
#endif // BUILDFLAG(IS_ANDROID)
}
GURL test_data_url_;
base::FilePath test_data_file_path_;
};
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
TrustableWebBundleFile) {
WriteCommonWebBundleFile();
NavigateToBundleAndWaitForReady(
test_data_url(), GURL(web_bundle_browsertest_utils::kTestPageUrl));
}
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest, RangeRequest) {
WriteCommonWebBundleFile();
NavigateToBundleAndWaitForReady(
test_data_url(), GURL(web_bundle_browsertest_utils::kTestPageUrl));
RunTestScript("test-range-request.js");
}
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest, BasicNavigation) {
RunSharedNavigationTest(
&web_bundle_browsertest_utils::SetUpBasicNavigationTest,
&web_bundle_browsertest_utils::RunBasicNavigationTest);
}
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
BrowserInitiatedOutOfBundleNavigation) {
RunSharedNavigationTest(&web_bundle_browsertest_utils::
SetUpBrowserInitiatedOutOfBundleNavigationTest,
&web_bundle_browsertest_utils::
RunBrowserInitiatedOutOfBundleNavigationTest);
}
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
RendererInitiatedOutOfBundleNavigation) {
RunSharedNavigationTest(&web_bundle_browsertest_utils::
SetUpRendererInitiatedOutOfBundleNavigationTest,
&web_bundle_browsertest_utils::
RunRendererInitiatedOutOfBundleNavigationTest);
}
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
SameDocumentNavigation) {
RunSharedNavigationTest(
&web_bundle_browsertest_utils::SetUpSameDocumentNavigationTest,
&web_bundle_browsertest_utils::RunSameDocumentNavigationTest);
}
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_IframeNavigation DISABLED_IframeNavigation
#else
#define MAYBE_IframeNavigation IframeNavigation
#endif
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
MAYBE_IframeNavigation) {
RunSharedNavigationTest(
&web_bundle_browsertest_utils::SetUpIframeNavigationTest,
&web_bundle_browsertest_utils::RunIframeNavigationTest);
}
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
IframeOutOfBundleNavigation) {
RunSharedNavigationTest(
&web_bundle_browsertest_utils::SetUpIframeNavigationTest,
&web_bundle_browsertest_utils::RunIframeOutOfBundleNavigationTest);
}
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
IframeParentInitiatedOutOfBundleNavigation) {
RunSharedNavigationTest(
&web_bundle_browsertest_utils::SetUpIframeNavigationTest,
&web_bundle_browsertest_utils::
RunIframeParentInitiatedOutOfBundleNavigationTest);
}
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_IframeSameDocumentNavigation DISABLED_IframeSameDocumentNavigation
#else
#define MAYBE_IframeSameDocumentNavigation IframeSameDocumentNavigation
#endif
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
MAYBE_IframeSameDocumentNavigation) {
RunSharedNavigationTest(
&web_bundle_browsertest_utils::SetUpIframeNavigationTest,
&web_bundle_browsertest_utils::RunIframeSameDocumentNavigationTest);
}
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest, BaseURI) {
WriteCommonWebBundleFile();
NavigateToBundleAndWaitForReady(
test_data_url(), GURL(web_bundle_browsertest_utils::kTestPageUrl));
EXPECT_EQ(web_bundle_browsertest_utils::ExecuteAndGetString(
shell()->web_contents(), "(new Request('./foo/bar')).url"),
"https://test.example.org/foo/bar");
EXPECT_EQ(web_bundle_browsertest_utils::ExecuteAndGetString(
shell()->web_contents(), R"(
(() => {
const base_element = document.createElement('base');
base_element.href = 'https://example.org/piyo/';
document.body.appendChild(base_element);
return document.baseURI;
})()
)"),
"https://example.org/piyo/");
EXPECT_EQ(web_bundle_browsertest_utils::ExecuteAndGetString(
shell()->web_contents(), "(new Request('./foo/bar')).url"),
"https://example.org/piyo/foo/bar");
}
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest, Iframe) {
net::EmbeddedTestServer third_party_server;
GURL primary_url_origin;
GURL third_party_origin;
std::string web_bundle_content;
web_bundle_browsertest_utils::SetUpSubPageTest(
embedded_test_server(), &third_party_server, &primary_url_origin,
&third_party_origin, &web_bundle_content);
WriteWebBundleFile(web_bundle_content);
NavigateToBundleAndWaitForReady(test_data_url(),
primary_url_origin.Resolve("/top"));
web_bundle_browsertest_utils::RunSubPageTest(
shell()->web_contents(), primary_url_origin, third_party_origin,
&web_bundle_browsertest_utils::AddIframeAndWaitForMessage,
true /* support_third_party_wbn_page */);
}
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest, WindowOpen) {
net::EmbeddedTestServer third_party_server;
GURL primary_url_origin;
GURL third_party_origin;
std::string web_bundle_content;
web_bundle_browsertest_utils::SetUpSubPageTest(
embedded_test_server(), &third_party_server, &primary_url_origin,
&third_party_origin, &web_bundle_content);
WriteWebBundleFile(web_bundle_content);
NavigateToBundleAndWaitForReady(test_data_url(),
primary_url_origin.Resolve("/top"));
web_bundle_browsertest_utils::RunSubPageTest(
shell()->web_contents(), primary_url_origin, third_party_origin,
&web_bundle_browsertest_utils::WindowOpenAndWaitForMessage,
true /* support_third_party_wbn_page */);
}
// TODO(https://crbug.com/1225178): flaky
#if BUILDFLAG(IS_LINUX)
#define MAYBE_NoPrimaryURLFound DISABLED_NoPrimaryURLFound
#else
#define MAYBE_NoPrimaryURLFound NoPrimaryURLFound
#endif
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
MAYBE_NoPrimaryURLFound) {
std::string contents;
{
base::ScopedAllowBlockingForTesting allow_blocking;
ASSERT_TRUE(base::ReadFileToString(
web_bundle_browsertest_utils::GetTestDataPath("same_origin_b2.wbn"),
&contents));
}
WriteWebBundleFile(contents);
std::string console_message = web_bundle_browsertest_utils::
ExpectNavigationFailureAndReturnConsoleMessage(shell()->web_contents(),
test_data_url());
EXPECT_EQ(web_bundle_utils::kNoPrimaryUrlErrorMessage, console_message);
}
// TODO(https://crbug.com/1225178): flaky
#if BUILDFLAG(IS_LINUX)
#define MAYBE_InvalidExchangeUrl DISABLED_InvalidExchangeUrl
#else
#define MAYBE_InvalidExchangeUrl InvalidExchangeUrl
#endif
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
MAYBE_InvalidExchangeUrl) {
std::string contents;
{
base::ScopedAllowBlockingForTesting allow_blocking;
ASSERT_TRUE(
base::ReadFileToString(web_bundle_browsertest_utils::GetTestDataPath(
"foo_base_url_bundle_b2.wbn"),
&contents));
}
WriteWebBundleFile(contents);
std::string console_message = web_bundle_browsertest_utils::
ExpectNavigationFailureAndReturnConsoleMessage(shell()->web_contents(),
test_data_url());
EXPECT_EQ(web_bundle_utils::kInvalidExchangeUrlErrorMessage, console_message);
}
// TODO(https://crbug.com/1225178): flaky
#if BUILDFLAG(IS_LINUX)
#define MAYBE_InvalidPrimaryUrl DISABLED_InvalidPrimaryUrl
#else
#define MAYBE_InvalidPrimaryUrl InvalidPrimaryUrl
#endif
IN_PROC_BROWSER_TEST_P(WebBundleTrustableFileBrowserTest,
MAYBE_InvalidPrimaryUrl) {
std::string contents;
{
base::ScopedAllowBlockingForTesting allow_blocking;
ASSERT_TRUE(
base::ReadFileToString(web_bundle_browsertest_utils::GetTestDataPath(
"foo_primary_url_bundle_b2.wbn"),
&contents));
}
WriteWebBundleFile(contents);
std::string console_message = web_bundle_browsertest_utils::
ExpectNavigationFailureAndReturnConsoleMessage(shell()->web_contents(),
test_data_url());
EXPECT_EQ(web_bundle_utils::kInvalidPrimaryUrlErrorMessage, console_message);
}
INSTANTIATE_TEST_SUITE_P(WebBundleTrustableFileBrowserTest,
WebBundleTrustableFileBrowserTest,
TEST_FILE_PATH_MODE_PARAMS);
class WebBundleTrustableFileNotFoundBrowserTest
: public web_bundle_browsertest_utils::WebBundleBrowserTestBase {
public:
WebBundleTrustableFileNotFoundBrowserTest(
const WebBundleTrustableFileNotFoundBrowserTest&) = delete;
WebBundleTrustableFileNotFoundBrowserTest& operator=(
const WebBundleTrustableFileNotFoundBrowserTest&) = delete;
protected:
WebBundleTrustableFileNotFoundBrowserTest() = default;
~WebBundleTrustableFileNotFoundBrowserTest() override = default;
void SetUp() override {
test_data_url_ = net::FilePathToFileURL(
web_bundle_browsertest_utils::GetTestDataPath("not_found"));
web_bundle_browsertest_utils::WebBundleBrowserTestBase::SetUp();
}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII(switches::kTrustableWebBundleFileUrl,
test_data_url().spec());
}
const GURL& test_data_url() const { return test_data_url_; }
private:
GURL test_data_url_;
};
// TODO(https://crbug.com/1227439): flaky
#if BUILDFLAG(IS_LINUX)
#define MAYBE_NotFound DISABLED_NotFound
#else
#define MAYBE_NotFound NotFound
#endif
IN_PROC_BROWSER_TEST_F(WebBundleTrustableFileNotFoundBrowserTest,
MAYBE_NotFound) {
std::string console_message = web_bundle_browsertest_utils::
ExpectNavigationFailureAndReturnConsoleMessage(shell()->web_contents(),
test_data_url());
EXPECT_EQ("Failed to read metadata of Web Bundle file: FILE_ERROR_NOT_FOUND",
console_message);
}
} // namespace content