weblayer_variations_http_browsertest.cc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "weblayer/test/weblayer_browser_test.h"
  5. #include "base/command_line.h"
  6. #include "base/synchronization/lock.h"
  7. #include "base/thread_annotations.h"
  8. #include "components/variations/variations_ids_provider.h"
  9. #include "content/public/test/network_connection_change_simulator.h"
  10. #include "net/dns/mock_host_resolver.h"
  11. #include "net/test/embedded_test_server/embedded_test_server.h"
  12. #include "net/test/embedded_test_server/http_request.h"
  13. #include "net/test/embedded_test_server/http_response.h"
  14. #include "weblayer/public/navigation.h"
  15. #include "weblayer/public/navigation_controller.h"
  16. #include "weblayer/public/tab.h"
  17. #include "weblayer/shell/browser/shell.h"
  18. #include "weblayer/test/weblayer_browser_test_utils.h"
  19. namespace weblayer {
  20. // The purpose of this test is to verify Variations code is correctly wired up
  21. // for WebLayer. It's not intended to replicate VariationsHttpHeadersBrowserTest
  22. class WebLayerVariationsHttpBrowserTest : public WebLayerBrowserTest {
  23. public:
  24. WebLayerVariationsHttpBrowserTest()
  25. : https_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) {}
  26. ~WebLayerVariationsHttpBrowserTest() override = default;
  27. void SetUp() override {
  28. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  29. // HTTPS server only serves a valid cert for localhost, so this is needed to
  30. // load pages from "www.google.com" without an interstitial.
  31. command_line->AppendSwitch("ignore-certificate-errors");
  32. WebLayerBrowserTest::SetUp();
  33. }
  34. void SetUpOnMainThread() override {
  35. auto* variations_provider =
  36. variations::VariationsIdsProvider::GetInstance();
  37. variations_provider->ForceVariationIds({"12", "456", "t789"}, "");
  38. // The test makes requests to google.com which we want to redirect to the
  39. // test server.
  40. host_resolver()->AddRule("*", "127.0.0.1");
  41. https_server_.RegisterRequestHandler(
  42. base::BindRepeating(&WebLayerVariationsHttpBrowserTest::RequestHandler,
  43. base::Unretained(this)));
  44. ASSERT_TRUE(https_server_.Start());
  45. }
  46. GURL GetGoogleUrlWithPath(const std::string& path) const {
  47. return https_server_.GetURL("www.google.com", path);
  48. }
  49. GURL GetGoogleRedirectUrl1() const {
  50. return GetGoogleUrlWithPath("/redirect");
  51. }
  52. GURL GetGoogleRedirectUrl2() const {
  53. return GetGoogleUrlWithPath("/redirect2");
  54. }
  55. GURL GetExampleUrlWithPath(const std::string& path) const {
  56. return https_server_.GetURL("www.example.com", path);
  57. }
  58. GURL GetExampleUrl() const { return GetExampleUrlWithPath("/landing.html"); }
  59. // Returns whether a given |header| has been received for a |url|. If
  60. // |url| has not been observed, fails an EXPECT and returns false.
  61. bool HasReceivedHeader(const GURL& url, const std::string& header) {
  62. base::AutoLock lock(received_headers_lock_);
  63. auto it = received_headers_.find(url);
  64. EXPECT_TRUE(it != received_headers_.end());
  65. if (it == received_headers_.end())
  66. return false;
  67. return it->second.find(header) != it->second.end();
  68. }
  69. std::unique_ptr<net::test_server::HttpResponse> RequestHandler(
  70. const net::test_server::HttpRequest& request) {
  71. // Retrieve the host name (without port) from the request headers.
  72. std::string host = "";
  73. if (request.headers.find("Host") != request.headers.end())
  74. host = request.headers.find("Host")->second;
  75. if (host.find(':') != std::string::npos)
  76. host = host.substr(0, host.find(':'));
  77. // Recover the original URL of the request by replacing the host name in
  78. // request.GetURL() (which is 127.0.0.1) with the host name from the request
  79. // headers.
  80. GURL::Replacements replacements;
  81. replacements.SetHostStr(host);
  82. GURL original_url = request.GetURL().ReplaceComponents(replacements);
  83. {
  84. base::AutoLock lock(received_headers_lock_);
  85. // Memorize the request headers for this URL for later verification.
  86. received_headers_[original_url] = request.headers;
  87. }
  88. // Set up a test server that redirects according to the
  89. // following redirect chain:
  90. // https://www.google.com:<port>/redirect
  91. // --> https://www.google.com:<port>/redirect2
  92. // --> https://www.example.com:<port>/
  93. auto http_response =
  94. std::make_unique<net::test_server::BasicHttpResponse>();
  95. http_response->AddCustomHeader("Access-Control-Allow-Origin", "*");
  96. if (request.relative_url == GetGoogleRedirectUrl1().path()) {
  97. http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
  98. http_response->AddCustomHeader("Location",
  99. GetGoogleRedirectUrl2().spec());
  100. } else if (request.relative_url == GetGoogleRedirectUrl2().path()) {
  101. http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
  102. http_response->AddCustomHeader("Location", GetExampleUrl().spec());
  103. } else if (request.relative_url == GetExampleUrl().path()) {
  104. http_response->set_code(net::HTTP_OK);
  105. http_response->set_content("hello");
  106. http_response->set_content_type("text/plain");
  107. } else {
  108. return nullptr;
  109. }
  110. return http_response;
  111. }
  112. protected:
  113. net::EmbeddedTestServer https_server_;
  114. base::Lock received_headers_lock_;
  115. // Stores the observed HTTP Request headers.
  116. std::map<GURL, net::test_server::HttpRequest::HeaderMap> received_headers_
  117. GUARDED_BY(received_headers_lock_);
  118. };
  119. // Verify in an integration test that the variations header (X-Client-Data) is
  120. // attached to network requests to Google but stripped on redirects.
  121. IN_PROC_BROWSER_TEST_F(WebLayerVariationsHttpBrowserTest,
  122. TestStrippingHeadersFromResourceRequest) {
  123. OneShotNavigationObserver observer(shell());
  124. shell()->tab()->GetNavigationController()->Navigate(GetGoogleRedirectUrl1());
  125. observer.WaitForNavigation();
  126. EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl1(), "X-Client-Data"));
  127. EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl2(), "X-Client-Data"));
  128. EXPECT_TRUE(HasReceivedHeader(GetExampleUrl(), "Host"));
  129. EXPECT_FALSE(HasReceivedHeader(GetExampleUrl(), "X-Client-Data"));
  130. }
  131. } // namespace weblayer