123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- // Copyright 2019 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 "base/files/file_path.h"
- #include "base/strings/stringprintf.h"
- #include "base/strings/utf_string_conversions.h"
- #include "base/synchronization/lock.h"
- #include "base/test/bind.h"
- #include "base/thread_annotations.h"
- #include "build/build_config.h"
- #include "components/network_session_configurator/common/network_switches.h"
- #include "content/public/browser/web_contents.h"
- #include "content/public/test/browser_test_utils.h"
- #include "net/base/network_change_notifier.h"
- #include "net/dns/mock_host_resolver.h"
- #include "net/test/embedded_test_server/embedded_test_server.h"
- #include "net/test/embedded_test_server/http_request.h"
- #include "net/test/embedded_test_server/http_response.h"
- #include "weblayer/browser/tab_impl.h"
- #include "weblayer/shell/browser/shell.h"
- #include "weblayer/test/weblayer_browser_test.h"
- #include "weblayer/test/weblayer_browser_test_utils.h"
- namespace weblayer {
- namespace {
- const char kPrefetchPage[] = "/simple_prefetch.html";
- const char kRedirectPrefetchPage[] = "/redirect_prefetch.html";
- const char kRedirectPrefetchUrl[] = "/redirect";
- const char kRedirectedPrefetchUrl[] = "/redirected";
- const char kPrefetchTarget[] = "/prefetch_target.lnk";
- } // namespace
- class PrefetchBrowserTest : public WebLayerBrowserTest {
- public:
- void SetUpOnMainThread() override {
- // The test makes requests to google.com which we want to redirect to the
- // test server.
- host_resolver()->AddRule("*", "127.0.0.1");
- embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
- &PrefetchBrowserTest::MonitorRequest, base::Unretained(this)));
- ASSERT_TRUE(embedded_test_server()->Start());
- }
- void SetUpCommandLine(base::CommandLine* command_line) override {
- // Set a dummy variation ID to send X-Client-Data header to Google hosts
- // in RedirectedPrefetch test.
- command_line->AppendSwitchASCII("force-variation-ids", "42");
- // Need to ignore cert errors to use a HTTPS server for the test domains.
- command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
- }
- bool RunPrefetchExperiment(GURL url, const std::u16string expected_title) {
- content::TitleWatcher title_watcher(
- static_cast<TabImpl*>(shell()->tab())->web_contents(), expected_title);
- NavigateAndWaitForCompletion(url, shell());
- return expected_title == title_watcher.WaitAndGetTitle();
- }
- protected:
- bool prefetch_target_request_seen_ = false;
- base::Lock lock_;
- // |requests_| is accessed on the UI thread by the test body and on the IO
- // thread by the test server's request handler, so must be guarded by a lock
- // to avoid data races.
- std::vector<net::test_server::HttpRequest> requests_ GUARDED_BY(lock_);
- private:
- void MonitorRequest(const net::test_server::HttpRequest& request) {
- if (request.relative_url == std::string(kPrefetchTarget)) {
- prefetch_target_request_seen_ = true;
- }
- }
- };
- IN_PROC_BROWSER_TEST_F(PrefetchBrowserTest, PrefetchWorks) {
- // Set real NetworkChangeNotifier singleton aside.
- std::unique_ptr<net::NetworkChangeNotifier::DisableForTest> disable_for_test(
- new net::NetworkChangeNotifier::DisableForTest);
- ASSERT_FALSE(prefetch_target_request_seen_);
- EXPECT_TRUE(RunPrefetchExperiment(
- embedded_test_server()->GetURL(kPrefetchPage), u"link onload"));
- EXPECT_TRUE(prefetch_target_request_seen_);
- }
- // https://crbug.com/922362: When the prefetched request is redirected, DCHECKs
- // in PrefetchURLLoader::FollowRedirect() failed due to "X-Client-Data" in
- // removed_headers. Verify that it no longer does.
- IN_PROC_BROWSER_TEST_F(PrefetchBrowserTest, RedirectedPrefetch) {
- net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
- https_server.RegisterRequestHandler(base::BindLambdaForTesting(
- [this](const net::test_server::HttpRequest& request)
- -> std::unique_ptr<net::test_server::HttpResponse> {
- auto response = std::make_unique<net::test_server::BasicHttpResponse>();
- base::AutoLock auto_lock(lock_);
- if (request.relative_url == std::string(kRedirectPrefetchPage)) {
- requests_.push_back(request);
- response->set_content_type("text/html");
- response->set_content(
- base::StringPrintf("<link rel=\"prefetch\" href=\"%s\" "
- "onload=\"document.title='done'\">",
- kRedirectPrefetchUrl));
- return response;
- } else if (request.relative_url == std::string(kRedirectPrefetchUrl)) {
- requests_.push_back(request);
- response->set_code(net::HTTP_MOVED_PERMANENTLY);
- response->AddCustomHeader(
- "Location", base::StringPrintf("https://example.com:%s%s",
- request.GetURL().port().c_str(),
- kRedirectedPrefetchUrl));
- return response;
- } else if (request.relative_url ==
- std::string(kRedirectedPrefetchUrl)) {
- requests_.push_back(request);
- return response;
- }
- return nullptr;
- }));
- https_server.ServeFilesFromSourceDirectory(
- base::FilePath(FILE_PATH_LITERAL("weblayer/test/data")));
- {
- base::AutoLock auto_lock(lock_);
- requests_.clear();
- }
- ASSERT_TRUE(https_server.Start());
- GURL url = https_server.GetURL("www.google.com", kRedirectPrefetchPage);
- EXPECT_TRUE(RunPrefetchExperiment(url, u"done"));
- {
- base::AutoLock auto_lock(lock_);
- ASSERT_EQ(3U, requests_.size());
- EXPECT_EQ(base::StringPrintf("www.google.com:%u", https_server.port()),
- requests_[0].headers["Host"]);
- EXPECT_EQ(kRedirectPrefetchPage, requests_[0].relative_url);
- }
- }
- } // namespace weblayer
|