| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import <map> |
| #import <string> |
| |
| #import "ios/chrome/browser/https_upgrades/https_upgrade_test_helper.h" |
| |
| #import "base/functional/bind.h" |
| #import "base/strings/escape.h" |
| #import "base/strings/string_util.h" |
| #import "base/strings/stringprintf.h" |
| #import "base/strings/sys_string_conversions.h" |
| #import "base/test/ios/wait_util.h" |
| #import "base/test/metrics/histogram_tester.h" |
| #import "ios/chrome/browser/https_upgrades/https_upgrade_app_interface.h" |
| #import "ios/chrome/browser/metrics/metrics_app_interface.h" |
| #import "ios/testing/earl_grey/earl_grey_test.h" |
| #import "ios/testing/embedded_test_server_handlers.h" |
| #import "ios/web/common/features.h" |
| #import "net/test/embedded_test_server/default_handlers.h" |
| #import "net/test/embedded_test_server/http_request.h" |
| #import "net/test/embedded_test_server/http_response.h" |
| #import "net/test/embedded_test_server/request_handler_util.h" |
| #import "ui/base/l10n/l10n_util.h" |
| |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| #endif |
| |
| namespace { |
| |
| const long kVeryLongTimeout = 100 * 3600 * 1000; |
| |
| // net::EmbeddedTestServer handler that responds with simple text. |
| std::unique_ptr<net::test_server::HttpResponse> StandardResponse( |
| int* counter, |
| const net::test_server::HttpRequest& request) { |
| // Ignore favicon requests. |
| if (request.relative_url == "/favicon.ico") { |
| return nullptr; |
| } |
| std::unique_ptr<net::test_server::BasicHttpResponse> response( |
| new net::test_server::BasicHttpResponse); |
| response->set_content_type("text/html"); |
| response->set_content("HTTP_RESPONSE"); |
| if (counter) |
| (*counter)++; |
| return std::move(response); |
| } |
| |
| std::unique_ptr<net::test_server::HttpResponse> FakeHTTPSResponse( |
| const net::test_server::HttpRequest& request) { |
| std::unique_ptr<net::test_server::BasicHttpResponse> response( |
| new net::test_server::BasicHttpResponse); |
| |
| const GURL request_url = request.GetURL(); |
| const std::string destValue = |
| base::UnescapeBinaryURLComponent(request_url.query_piece()); |
| // If the URL is in the form http://example.com/?redirect=url, |
| // redirect the response to `url`. |
| if (base::StartsWith(destValue, "redirect=")) { |
| const std::string dest = destValue.substr(strlen("redirect=")); |
| response->set_code(net::HttpStatusCode::HTTP_MOVED_PERMANENTLY); |
| response->AddCustomHeader("Location", dest); |
| response->AddCustomHeader("Access-Control-Allow-Origin", "*"); |
| response->set_content_type("text/html"); |
| response->set_content(base::StringPrintf( |
| "<html><head></head><body>Redirecting to %s</body></html>", |
| dest.c_str())); |
| return response; |
| } |
| |
| response->set_content_type("text/html"); |
| response->set_content("HTTPS_RESPONSE"); |
| return std::move(response); |
| } |
| |
| std::unique_ptr<net::test_server::HttpResponse> FakeHungResponse( |
| const net::test_server::HttpRequest& request) { |
| return std::make_unique<net::test_server::HungResponse>(); |
| } |
| |
| } // namespace |
| |
| @implementation HttpsUpgradeTestCaseBase |
| |
| - (net::EmbeddedTestServer*)goodHTTPSServer { |
| if (!_goodHTTPSServer) { |
| _goodHTTPSServer = std::make_unique<net::EmbeddedTestServer>( |
| net::test_server::EmbeddedTestServer::TYPE_HTTP); |
| _goodHTTPSServer->RegisterRequestHandler( |
| base::BindRepeating(&FakeHTTPSResponse)); |
| } |
| return _goodHTTPSServer.get(); |
| } |
| |
| - (net::EmbeddedTestServer*)badHTTPSServer { |
| if (!_badHTTPSServer) { |
| _badHTTPSServer = std::make_unique<net::EmbeddedTestServer>( |
| net::test_server::EmbeddedTestServer::TYPE_HTTPS); |
| _badHTTPSServer->RegisterRequestHandler( |
| base::BindRepeating(&StandardResponse, nullptr)); |
| } |
| return _badHTTPSServer.get(); |
| } |
| |
| - (net::EmbeddedTestServer*)slowServer { |
| if (!_slowServer) { |
| _slowServer = std::make_unique<net::EmbeddedTestServer>( |
| net::test_server::EmbeddedTestServer::TYPE_HTTP); |
| _slowServer->RegisterRequestHandler(base::BindRepeating(&FakeHungResponse)); |
| } |
| return _slowServer.get(); |
| } |
| |
| - (void)setUp { |
| [super setUp]; |
| // Start test servers. |
| _HTTPResponseCounter = 0; |
| self.testServer->RegisterRequestHandler(base::BindRepeating( |
| base::BindRepeating(&StandardResponse, &_HTTPResponseCounter))); |
| |
| GREYAssertTrue(self.testServer->Start(), @"Test HTTP server failed to start"); |
| GREYAssertTrue(self.goodHTTPSServer->Start(), |
| @"Test good faux-HTTPS server failed to start."); |
| GREYAssertTrue(self.badHTTPSServer->Start(), |
| @"Test bad HTTPS server failed to start."); |
| GREYAssertTrue(self.slowServer->Start(), |
| @"Test slow server failed to start."); |
| |
| GREYAssertNil([MetricsAppInterface setupHistogramTester], |
| @"Cannot setup histogram tester."); |
| |
| [HttpsUpgradeAppInterface setHTTPSPortForTesting:self.goodHTTPSServer->port() |
| useFakeHTTPS:false]; |
| [HttpsUpgradeAppInterface setFallbackDelayForTesting:kVeryLongTimeout]; |
| } |
| |
| - (void)tearDown { |
| // Release the histogram tester. |
| GREYAssertNil([MetricsAppInterface releaseHistogramTester], |
| @"Cannot reset histogram tester."); |
| |
| [super tearDown]; |
| } |
| |
| @end |