blob: 6db7051cdefd43a9be0c4e04e9133771b2273d77 [file] [log] [blame]
// Copyright 2020 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 "weblayer/test/weblayer_browser_test.h"
#include "components/variations/variations_ids_provider.h"
#include "content/public/test/network_connection_change_simulator.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/public/navigation.h"
#include "weblayer/public/navigation_controller.h"
#include "weblayer/public/tab.h"
#include "weblayer/shell/browser/shell.h"
#include "weblayer/test/weblayer_browser_test_utils.h"
namespace weblayer {
// The purpose of this test is to verify Variations code is correctly wired up
// for WebLayer. It's not intended to replicate VariationsHttpHeadersBrowserTest
class WebLayerVariationsHttpBrowserTest : public WebLayerBrowserTest {
public:
WebLayerVariationsHttpBrowserTest()
: https_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) {}
~WebLayerVariationsHttpBrowserTest() override = default;
void SetUp() override {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
// HTTPS server only serves a valid cert for localhost, so this is needed to
// load pages from "www.google.com" without an interstitial.
command_line->AppendSwitch("ignore-certificate-errors");
WebLayerBrowserTest::SetUp();
}
void SetUpOnMainThread() override {
auto* variations_provider =
variations::VariationsIdsProvider::GetInstance();
variations_provider->ForceVariationIds({"12", "456", "t789"}, "");
// The test makes requests to google.com which we want to redirect to the
// test server.
host_resolver()->AddRule("*", "127.0.0.1");
https_server_.RegisterRequestHandler(
base::BindRepeating(&WebLayerVariationsHttpBrowserTest::RequestHandler,
base::Unretained(this)));
ASSERT_TRUE(https_server_.Start());
}
GURL GetGoogleUrlWithPath(const std::string& path) const {
return https_server_.GetURL("www.google.com", path);
}
GURL GetGoogleRedirectUrl1() const {
return GetGoogleUrlWithPath("/redirect");
}
GURL GetGoogleRedirectUrl2() const {
return GetGoogleUrlWithPath("/redirect2");
}
GURL GetExampleUrlWithPath(const std::string& path) const {
return https_server_.GetURL("www.example.com", path);
}
GURL GetExampleUrl() const { return GetExampleUrlWithPath("/landing.html"); }
// Returns whether a given |header| has been received for a |url|. If
// |url| has not been observed, fails an EXPECT and returns false.
bool HasReceivedHeader(const GURL& url, const std::string& header) const {
auto it = received_headers_.find(url);
EXPECT_TRUE(it != received_headers_.end());
if (it == received_headers_.end())
return false;
return it->second.find(header) != it->second.end();
}
std::unique_ptr<net::test_server::HttpResponse> RequestHandler(
const net::test_server::HttpRequest& request) {
// Retrieve the host name (without port) from the request headers.
std::string host = "";
if (request.headers.find("Host") != request.headers.end())
host = request.headers.find("Host")->second;
if (host.find(':') != std::string::npos)
host = host.substr(0, host.find(':'));
// Recover the original URL of the request by replacing the host name in
// request.GetURL() (which is 127.0.0.1) with the host name from the request
// headers.
url::Replacements<char> replacements;
replacements.SetHost(host.c_str(), url::Component(0, host.length()));
GURL original_url = request.GetURL().ReplaceComponents(replacements);
// Memorize the request headers for this URL for later verification.
received_headers_[original_url] = request.headers;
// Set up a test server that redirects according to the
// following redirect chain:
// https://www.google.com:<port>/redirect
// --> https://www.google.com:<port>/redirect2
// --> https://www.example.com:<port>/
auto http_response =
std::make_unique<net::test_server::BasicHttpResponse>();
http_response->AddCustomHeader("Access-Control-Allow-Origin", "*");
if (request.relative_url == GetGoogleRedirectUrl1().path()) {
http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
http_response->AddCustomHeader("Location",
GetGoogleRedirectUrl2().spec());
} else if (request.relative_url == GetGoogleRedirectUrl2().path()) {
http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
http_response->AddCustomHeader("Location", GetExampleUrl().spec());
} else if (request.relative_url == GetExampleUrl().path()) {
http_response->set_code(net::HTTP_OK);
http_response->set_content("hello");
http_response->set_content_type("text/plain");
} else {
return nullptr;
}
return http_response;
}
protected:
net::EmbeddedTestServer https_server_;
// Stores the observed HTTP Request headers.
std::map<GURL, net::test_server::HttpRequest::HeaderMap> received_headers_;
};
// Verify in an integration test that the variations header (X-Client-Data) is
// attached to network requests to Google but stripped on redirects.
IN_PROC_BROWSER_TEST_F(WebLayerVariationsHttpBrowserTest,
TestStrippingHeadersFromResourceRequest) {
OneShotNavigationObserver observer(shell());
shell()->tab()->GetNavigationController()->Navigate(GetGoogleRedirectUrl1());
observer.WaitForNavigation();
EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl1(), "X-Client-Data"));
EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl2(), "X-Client-Data"));
EXPECT_TRUE(HasReceivedHeader(GetExampleUrl(), "Host"));
EXPECT_FALSE(HasReceivedHeader(GetExampleUrl(), "X-Client-Data"));
}
} // namespace weblayer