parent
952f2b0829
commit
46e1c4f177
|
@ -186,6 +186,8 @@
|
|||
'tests/shared/common/client_app_other.h',
|
||||
'tests/shared/common/client_switches.cc',
|
||||
'tests/shared/common/client_switches.h',
|
||||
'tests/shared/common/string_util.cc',
|
||||
'tests/shared/common/string_util.h',
|
||||
],
|
||||
'shared_sources_renderer': [
|
||||
'tests/shared/renderer/client_app_renderer.cc',
|
||||
|
@ -476,6 +478,7 @@
|
|||
'tests/ceftests/file_util_unittest.cc',
|
||||
'tests/ceftests/frame_handler_unittest.cc',
|
||||
'tests/ceftests/frame_unittest.cc',
|
||||
'tests/ceftests/hsts_redirect_unittest.cc',
|
||||
'tests/ceftests/image_unittest.cc',
|
||||
'tests/ceftests/image_util.cc',
|
||||
'tests/ceftests/image_util.h',
|
||||
|
|
|
@ -184,6 +184,13 @@ class CefTestServerImpl::Context {
|
|||
test_server_->RegisterRequestHandler(
|
||||
base::BindRepeating(&Context::HandleRequest, base::Unretained(this)));
|
||||
|
||||
if (https_server) {
|
||||
// Use a "localhost" domain certificate instead of IP address. This is
|
||||
// required for HSTS tests (see https://crbug.com/456712).
|
||||
test_server_->SetSSLConfig(
|
||||
EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
|
||||
}
|
||||
|
||||
test_server_handle_ =
|
||||
test_server_->StartAndReturnHandle(static_cast<int>(port));
|
||||
if (!test_server_handle_) {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "tests/shared/browser/resource_util.h"
|
||||
#include "tests/shared/common/binary_value_utils.h"
|
||||
#include "tests/shared/common/client_switches.h"
|
||||
#include "tests/shared/common/string_util.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
|
@ -1047,12 +1048,9 @@ void ClientHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
|
|||
if (url.empty())
|
||||
return;
|
||||
|
||||
std::string start_url = startup_url_;
|
||||
|
||||
// Convert URLs to lowercase for easier comparison.
|
||||
std::transform(url.begin(), url.end(), url.begin(), tolower);
|
||||
std::transform(start_url.begin(), start_url.end(), start_url.begin(),
|
||||
tolower);
|
||||
url = AsciiStrToLower(url);
|
||||
const std::string& start_url = AsciiStrToLower(startup_url_);
|
||||
|
||||
// Don't reload the URL that just resulted in termination.
|
||||
if (url.find(start_url) == 0)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "tests/shared/browser/file_util.h"
|
||||
#include "tests/shared/browser/resource_util.h"
|
||||
#include "tests/shared/common/string_util.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
|
@ -158,7 +159,7 @@ ImageCache::ImageType ImageCache::GetImageType(const std::string& path) {
|
|||
if (ext.empty())
|
||||
return TYPE_NONE;
|
||||
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
||||
ext = AsciiStrToLower(ext);
|
||||
if (ext == "png")
|
||||
return TYPE_PNG;
|
||||
if (ext == "jpg" || ext == "jpeg")
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "include/cef_parser.h"
|
||||
#include "tests/shared/browser/client_app_browser.h"
|
||||
#include "tests/shared/common/client_switches.h"
|
||||
#include "tests/shared/common/string_util.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
|
@ -19,10 +20,7 @@ const char kDefaultUrl[] = "http://www.google.com";
|
|||
|
||||
// Returns the ARGB value for |color|.
|
||||
cef_color_t ParseColor(const std::string& color) {
|
||||
std::string colorToLower;
|
||||
colorToLower.resize(color.size());
|
||||
std::transform(color.begin(), color.end(), colorToLower.begin(), ::tolower);
|
||||
|
||||
const std::string& colorToLower = AsciiStrToLower(color);
|
||||
if (colorToLower == "black")
|
||||
return CefColorSetARGB(255, 0, 0, 0);
|
||||
else if (colorToLower == "blue")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "tests/cefclient/browser/urlrequest_test.h"
|
||||
#include "tests/cefclient/browser/window_test.h"
|
||||
#include "tests/shared/browser/resource_util.h"
|
||||
#include "tests/shared/common/string_util.h"
|
||||
|
||||
namespace client {
|
||||
namespace test_runner {
|
||||
|
@ -54,31 +55,13 @@ void LoadStringResourcePage(CefRefPtr<CefBrowser> browser,
|
|||
browser->GetMainFrame()->LoadURL(kTestOrigin + page);
|
||||
}
|
||||
|
||||
// Replace all instances of |from| with |to| in |str|.
|
||||
std::string StringReplace(const std::string& str,
|
||||
const std::string& from,
|
||||
const std::string& to) {
|
||||
std::string result = str;
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type from_len = from.length();
|
||||
std::string::size_type to_len = to.length();
|
||||
do {
|
||||
pos = result.find(from, pos);
|
||||
if (pos != std::string::npos) {
|
||||
result.replace(pos, from_len, to);
|
||||
pos += to_len;
|
||||
}
|
||||
} while (pos != std::string::npos);
|
||||
return result;
|
||||
}
|
||||
|
||||
void RunGetSourceTest(CefRefPtr<CefBrowser> browser) {
|
||||
class Visitor : public CefStringVisitor {
|
||||
public:
|
||||
explicit Visitor(CefRefPtr<CefBrowser> browser) : browser_(browser) {}
|
||||
virtual void Visit(const CefString& string) override {
|
||||
std::string source = StringReplace(string, "<", "<");
|
||||
source = StringReplace(source, ">", ">");
|
||||
std::string source = AsciiStrReplace(string, "<", "<");
|
||||
source = AsciiStrReplace(source, ">", ">");
|
||||
std::stringstream ss;
|
||||
ss << "<html><body bgcolor=\"white\">Source:<pre>" << source
|
||||
<< "</pre></body></html>";
|
||||
|
@ -98,8 +81,8 @@ void RunGetTextTest(CefRefPtr<CefBrowser> browser) {
|
|||
public:
|
||||
explicit Visitor(CefRefPtr<CefBrowser> browser) : browser_(browser) {}
|
||||
virtual void Visit(const CefString& string) override {
|
||||
std::string text = StringReplace(string, "<", "<");
|
||||
text = StringReplace(text, ">", ">");
|
||||
std::string text = AsciiStrReplace(string, "<", "<");
|
||||
text = AsciiStrReplace(text, ">", ">");
|
||||
std::stringstream ss;
|
||||
ss << "<html><body bgcolor=\"white\">Text:<pre>" << text
|
||||
<< "</pre></body></html>";
|
||||
|
@ -649,8 +632,7 @@ CefRefPtr<CefStreamReader> GetDumpResponse(
|
|||
|
||||
CefRequest::HeaderMap::const_iterator it = requestMap.begin();
|
||||
for (; it != requestMap.end(); ++it) {
|
||||
std::string key = it->first;
|
||||
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
|
||||
const std::string& key = AsciiStrToLower(it->first);
|
||||
if (key == "origin") {
|
||||
origin = it->second;
|
||||
break;
|
||||
|
@ -801,8 +783,8 @@ void Alert(CefRefPtr<CefBrowser> browser, const std::string& message) {
|
|||
}
|
||||
|
||||
// Escape special characters in the message.
|
||||
std::string msg = StringReplace(message, "\\", "\\\\");
|
||||
msg = StringReplace(msg, "'", "\\'");
|
||||
std::string msg = AsciiStrReplace(message, "\\", "\\\\");
|
||||
msg = AsciiStrReplace(msg, "'", "\\'");
|
||||
|
||||
// Execute a JavaScript alert().
|
||||
CefRefPtr<CefFrame> frame = browser->GetMainFrame();
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "tests/ceftests/test_suite.h"
|
||||
#include "tests/ceftests/test_util.h"
|
||||
#include "tests/gtest/include/gtest/gtest.h"
|
||||
#include "tests/shared/common/string_util.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -1113,7 +1114,7 @@ class CookieAccessResponseHandler {
|
|||
std::string GetHeaderValue(const CefServer::HeaderMap& header_map,
|
||||
const std::string& header_name_lower) {
|
||||
for (const auto& [name, value] : header_map) {
|
||||
if (AsciiStrToLower(name) == header_name_lower) {
|
||||
if (client::AsciiStrToLower(name) == header_name_lower) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,312 @@
|
|||
// Copyright (c) 2022 The Chromium Embedded Framework 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 "include/base/cef_callback.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "tests/ceftests/test_handler.h"
|
||||
#include "tests/ceftests/test_server.h"
|
||||
#include "tests/ceftests/test_server_observer.h"
|
||||
#include "tests/gtest/include/gtest/gtest.h"
|
||||
#include "tests/shared/common/string_util.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Set the "Strict-Transport-Security" header on an HTTPS response to enable
|
||||
// HSTS redirects for follow-up HTTP requests to the same origin. See
|
||||
// https://www.chromium.org/hsts/.
|
||||
//
|
||||
// HSTS is implemented in the network service so real servers are required to
|
||||
// test the redirect behavior. It also requires a "localhost" domain certificate
|
||||
// instead of IP address (see https://crbug.com/456712). See additional comments
|
||||
// in OnResourceRedirect about redirect behavior with non-standard port numbers.
|
||||
//
|
||||
// The test works as follows:
|
||||
// 1. Start HTTP and HTTPS servers.
|
||||
// 2. Load an HTTP URL that redirects to an HTTPS URL.
|
||||
// 3. Set the "Strict-Transport-Security" header in response to the first HTTPS
|
||||
// request.
|
||||
// 4. Load the same HTTP URL additional times to trigger the internal HTTP to
|
||||
// HTTPS redirect.
|
||||
|
||||
// Number of times to load the same HTTP URL. Must be > 1.
|
||||
constexpr size_t kHSTSLoadCount = 3;
|
||||
|
||||
constexpr char kHSTSURLPath[] = "/index.html";
|
||||
|
||||
// Used to observe HTTP and HTTPS server requests.
|
||||
class HSTSTestServerObserver : public test_server::ObserverHelper {
|
||||
public:
|
||||
using ReadyCallback = base::OnceCallback<void(const std::string& url)>;
|
||||
|
||||
HSTSTestServerObserver(bool https_server,
|
||||
size_t& nav_ct,
|
||||
TrackCallback (&got_request)[kHSTSLoadCount],
|
||||
ReadyCallback ready_callback,
|
||||
base::OnceClosure done_callback)
|
||||
: https_server_(https_server),
|
||||
nav_ct_(nav_ct),
|
||||
got_request_(got_request),
|
||||
ready_callback_(std::move(ready_callback)),
|
||||
done_callback_(std::move(done_callback)) {
|
||||
Initialize(https_server);
|
||||
}
|
||||
|
||||
void OnInitialized(const std::string& server_origin) override {
|
||||
EXPECT_UI_THREAD();
|
||||
|
||||
origin_ = ToLocalhostOrigin(server_origin);
|
||||
url_ = origin_ + kHSTSURLPath;
|
||||
|
||||
std::move(ready_callback_).Run(url_);
|
||||
}
|
||||
|
||||
void OnShutdown() override {
|
||||
EXPECT_UI_THREAD();
|
||||
std::move(done_callback_).Run();
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool OnTestServerRequest(CefRefPtr<CefRequest> request,
|
||||
const ResponseCallback& response_callback) override {
|
||||
EXPECT_UI_THREAD();
|
||||
|
||||
// At most 1 request per load.
|
||||
EXPECT_FALSE(got_request_[nav_ct_]) << nav_ct_;
|
||||
got_request_[nav_ct_].yes();
|
||||
|
||||
const std::string& url = ToLocalhostOrigin(request->GetURL());
|
||||
|
||||
auto response = CefResponse::Create();
|
||||
response->SetMimeType("text/html");
|
||||
std::string response_body;
|
||||
|
||||
if (!https_server_) {
|
||||
// Redirect to the HTTPS URL.
|
||||
EXPECT_STREQ(url_.c_str(), url.c_str()) << nav_ct_;
|
||||
response->SetStatus(301); // Permanent Redirect
|
||||
response->SetHeaderByName("Location",
|
||||
GetLocalhostURL(/*https_server=*/true),
|
||||
/*overwrite=*/true);
|
||||
} else {
|
||||
// Normal response after an HTTP to HTTPS redirect.
|
||||
EXPECT_STREQ(url_.c_str(), url.c_str()) << nav_ct_;
|
||||
response->SetStatus(200);
|
||||
|
||||
if (nav_ct_ == 0) {
|
||||
// Set the "Strict-Transport-Security" header in response to the first
|
||||
// HTTPS request.
|
||||
response->SetHeaderByName("Strict-Transport-Security",
|
||||
"max-age=16070400",
|
||||
/*overwrite=*/true);
|
||||
}
|
||||
|
||||
// Don't cache the HTTPS response (so we see all the requests).
|
||||
response->SetHeaderByName("Cache-Control", "no-cache",
|
||||
/*overwrite=*/true);
|
||||
|
||||
response_body = "<html><body>Test1</body></html>";
|
||||
}
|
||||
|
||||
response_callback.Run(response, response_body);
|
||||
|
||||
// Stop propagating the callback.
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
static std::string ToLocalhostOrigin(const std::string& origin) {
|
||||
// Need to explicitly use the "localhost" domain instead of the IP address.
|
||||
// HTTPS URLs will already be using "localhost".
|
||||
return client::AsciiStrReplace(origin, "127.0.0.1", "localhost");
|
||||
}
|
||||
|
||||
static std::string GetLocalhostOrigin(bool https_server) {
|
||||
return ToLocalhostOrigin(test_server::GetOrigin(https_server));
|
||||
}
|
||||
|
||||
static std::string GetLocalhostURL(bool https_server) {
|
||||
return GetLocalhostOrigin(/*https_server=*/true) + kHSTSURLPath;
|
||||
}
|
||||
|
||||
const bool https_server_;
|
||||
|
||||
size_t& nav_ct_;
|
||||
TrackCallback (&got_request_)[kHSTSLoadCount];
|
||||
ReadyCallback ready_callback_;
|
||||
base::OnceClosure done_callback_;
|
||||
|
||||
std::string origin_;
|
||||
std::string url_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(HSTSTestServerObserver);
|
||||
};
|
||||
|
||||
class HSTSRedirectTest : public TestHandler {
|
||||
public:
|
||||
HSTSRedirectTest() = default;
|
||||
|
||||
void RunTest() override {
|
||||
SetTestTimeout();
|
||||
CefPostTask(TID_UI,
|
||||
base::BindOnce(&HSTSRedirectTest::StartHttpServer, this));
|
||||
}
|
||||
|
||||
void OnResourceRedirect(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefResponse> response,
|
||||
CefString& new_url) override {
|
||||
EXPECT_IO_THREAD();
|
||||
|
||||
EXPECT_FALSE(got_redirect_[nav_ct_]) << nav_ct_;
|
||||
got_redirect_[nav_ct_].yes();
|
||||
|
||||
EXPECT_STREQ(http_url_.c_str(), request->GetURL().ToString().c_str())
|
||||
<< nav_ct_;
|
||||
|
||||
if (nav_ct_ == 0) {
|
||||
// Initial HTTP to HTTPS redirect.
|
||||
EXPECT_STREQ(https_url_.c_str(), new_url.ToString().c_str()) << nav_ct_;
|
||||
} else {
|
||||
// HSTS HTTP to HTTPS redirect. This will use the wrong "localhost" port
|
||||
// number, per spec. From RFC 6797:
|
||||
// The UA MUST replace the URI scheme with "https" [RFC2818], and if the
|
||||
// URI contains an explicit port component of "80", then the UA MUST
|
||||
// convert the port component to be "443", or if the URI contains an
|
||||
// explicit port component that is not equal to "80", the port component
|
||||
// value MUST be preserved; otherwise, if the URI does not contain an
|
||||
// explicit port component, the UA MUST NOT add one.
|
||||
const std::string& expected_https_url =
|
||||
client::AsciiStrReplace(http_url_, "http:", "https:");
|
||||
EXPECT_STREQ(expected_https_url.c_str(), new_url.ToString().c_str())
|
||||
<< nav_ct_;
|
||||
|
||||
// Redirect to the correct HTTPS URL instead.
|
||||
new_url = https_url_;
|
||||
}
|
||||
}
|
||||
|
||||
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int httpStatusCode) override {
|
||||
EXPECT_UI_THREAD();
|
||||
|
||||
TestHandler::OnLoadEnd(browser, frame, httpStatusCode);
|
||||
|
||||
EXPECT_FALSE(got_load_end_[nav_ct_]) << nav_ct_;
|
||||
got_load_end_[nav_ct_].yes();
|
||||
|
||||
// Expect only the HTTPS URL to load.
|
||||
EXPECT_STREQ(https_url_.c_str(), frame->GetURL().ToString().c_str())
|
||||
<< nav_ct_;
|
||||
|
||||
if (++nav_ct_ == kHSTSLoadCount) {
|
||||
StopHttpServer();
|
||||
} else {
|
||||
// Load the same HTTP URL again.
|
||||
browser->GetMainFrame()->LoadURL(http_url_);
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyTest() override {
|
||||
EXPECT_FALSE(http_server_);
|
||||
EXPECT_FALSE(https_server_);
|
||||
|
||||
EXPECT_EQ(kHSTSLoadCount, nav_ct_);
|
||||
for (size_t i = 0; i < kHSTSLoadCount; ++i) {
|
||||
EXPECT_TRUE(got_redirect_[i]) << i;
|
||||
EXPECT_TRUE(got_load_end_[i]) << i;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < kHSTSLoadCount; ++i) {
|
||||
// Should only see the 1st HTTP request due to the internal HSTS redirect
|
||||
// for the 2nd+ requests.
|
||||
EXPECT_EQ(i == 0, got_http_request_[i]) << i;
|
||||
|
||||
// Should see all HTTPS requests.
|
||||
EXPECT_TRUE(got_https_request_[i]) << i;
|
||||
}
|
||||
|
||||
TestHandler::DestroyTest();
|
||||
}
|
||||
|
||||
private:
|
||||
void StartHttpServer() {
|
||||
EXPECT_UI_THREAD();
|
||||
|
||||
// Will delete itself after the server stops.
|
||||
http_server_ = new HSTSTestServerObserver(
|
||||
/*https_server=*/false, nav_ct_, got_http_request_,
|
||||
base::BindOnce(&HSTSRedirectTest::StartedHttpServer, this),
|
||||
base::BindOnce(&HSTSRedirectTest::StoppedHttpServer, this));
|
||||
}
|
||||
|
||||
void StartedHttpServer(const std::string& url) {
|
||||
EXPECT_UI_THREAD();
|
||||
|
||||
http_url_ = url;
|
||||
EXPECT_TRUE(http_url_.find("http://localhost:") == 0);
|
||||
|
||||
// Start the HTTPS server. Will delete itself after the server stops.
|
||||
https_server_ = new HSTSTestServerObserver(
|
||||
/*https_server=*/true, nav_ct_, got_https_request_,
|
||||
base::BindOnce(&HSTSRedirectTest::StartedHttpsServer, this),
|
||||
base::BindOnce(&HSTSRedirectTest::StoppedHttpsServer, this));
|
||||
}
|
||||
|
||||
void StartedHttpsServer(const std::string& url) {
|
||||
EXPECT_UI_THREAD();
|
||||
|
||||
https_url_ = url;
|
||||
EXPECT_TRUE(https_url_.find("https://localhost:") == 0);
|
||||
|
||||
CreateBrowser(http_url_);
|
||||
}
|
||||
|
||||
void StopHttpServer() {
|
||||
EXPECT_UI_THREAD();
|
||||
|
||||
// Results in a call to StoppedHttpServer().
|
||||
http_server_->Shutdown();
|
||||
}
|
||||
|
||||
void StoppedHttpServer() {
|
||||
EXPECT_UI_THREAD();
|
||||
|
||||
http_server_ = nullptr;
|
||||
|
||||
// Stop the HTTPS server. Results in a call to StoppedHttpsServer().
|
||||
https_server_->Shutdown();
|
||||
}
|
||||
|
||||
void StoppedHttpsServer() {
|
||||
EXPECT_UI_THREAD();
|
||||
|
||||
https_server_ = nullptr;
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
HSTSTestServerObserver* http_server_ = nullptr;
|
||||
std::string http_url_;
|
||||
|
||||
HSTSTestServerObserver* https_server_ = nullptr;
|
||||
std::string https_url_;
|
||||
|
||||
size_t nav_ct_ = 0U;
|
||||
TrackCallback got_http_request_[kHSTSLoadCount];
|
||||
TrackCallback got_https_request_[kHSTSLoadCount];
|
||||
TrackCallback got_load_end_[kHSTSLoadCount];
|
||||
TrackCallback got_redirect_[kHSTSLoadCount];
|
||||
|
||||
IMPLEMENT_REFCOUNTING(HSTSRedirectTest);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(HSTSRedirectTest, Redirect) {
|
||||
CefRefPtr<HSTSRedirectTest> handler = new HSTSRedirectTest();
|
||||
handler->ExecuteTest();
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
|
@ -10,12 +10,7 @@
|
|||
#include "include/cef_command_line.h"
|
||||
#include "include/cef_request_context_handler.h"
|
||||
#include "tests/gtest/include/gtest/gtest.h"
|
||||
|
||||
std::string AsciiStrToLower(const std::string& str) {
|
||||
std::string lowerStr = str;
|
||||
std::transform(lowerStr.begin(), lowerStr.end(), lowerStr.begin(), ::tolower);
|
||||
return lowerStr;
|
||||
}
|
||||
#include "tests/shared/common/string_util.h"
|
||||
|
||||
void TestMapEqual(const CefRequest::HeaderMap& map1,
|
||||
const CefRequest::HeaderMap& map2,
|
||||
|
@ -31,9 +26,9 @@ void TestMapEqual(const CefRequest::HeaderMap& map1,
|
|||
|
||||
for (it1 = map1.begin(); it1 != map1.end(); ++it1) {
|
||||
bool found = false;
|
||||
std::string name1 = AsciiStrToLower(it1->first);
|
||||
std::string name1 = client::AsciiStrToLower(it1->first);
|
||||
for (it2 = map2.begin(); it2 != map2.end(); ++it2) {
|
||||
std::string name2 = AsciiStrToLower(it2->first);
|
||||
std::string name2 = client::AsciiStrToLower(it2->first);
|
||||
if (name1 == name2 && it1->second == it2->second) {
|
||||
found = true;
|
||||
break;
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
CefTime CefTimeFrom(CefBaseTime value);
|
||||
CefBaseTime CefBaseTimeFrom(const CefTime& value);
|
||||
|
||||
std::string AsciiStrToLower(const std::string& str);
|
||||
|
||||
// Test that CefRequest::HeaderMap objects are equal. Multiple values with the
|
||||
// same key are allowed, but not duplicate entries with the same key/value. If
|
||||
// |allowExtras| is true then additional header fields will be allowed in
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "tests/gtest/include/gtest/gtest.h"
|
||||
#include "tests/shared/browser/client_app_browser.h"
|
||||
#include "tests/shared/browser/file_util.h"
|
||||
#include "tests/shared/common/string_util.h"
|
||||
#include "tests/shared/renderer/client_app_renderer.h"
|
||||
|
||||
using client::ClientAppRenderer;
|
||||
|
@ -453,7 +454,7 @@ std::string GetHeaderValue(const CefRequest::HeaderMap& header_map,
|
|||
const std::string& header_name_lower) {
|
||||
CefRequest::HeaderMap::const_iterator it = header_map.begin();
|
||||
for (; it != header_map.end(); ++it) {
|
||||
std::string name = AsciiStrToLower(it->first);
|
||||
std::string name = client::AsciiStrToLower(it->first);
|
||||
if (name == header_name_lower)
|
||||
return it->second;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "tests/shared/browser/file_util.h"
|
||||
#include "tests/shared/browser/resource_util.h"
|
||||
#include "tests/shared/common/string_util.h"
|
||||
|
||||
namespace client {
|
||||
namespace extension_util {
|
||||
|
@ -36,10 +37,8 @@ std::string GetInternalPath(const std::string& extension_path) {
|
|||
|
||||
#if defined(OS_WIN)
|
||||
// Convert to lower-case, since Windows paths are case-insensitive.
|
||||
std::transform(resources_path_lower.begin(), resources_path_lower.end(),
|
||||
resources_path_lower.begin(), ::tolower);
|
||||
std::transform(extension_path_lower.begin(), extension_path_lower.end(),
|
||||
extension_path_lower.begin(), ::tolower);
|
||||
resources_path_lower = AsciiStrToLower(resources_path_lower);
|
||||
extension_path_lower = AsciiStrToLower(extension_path_lower);
|
||||
#endif
|
||||
|
||||
std::string internal_path;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2022 The Chromium Embedded Framework 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 "tests/shared/common/string_util.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace client {
|
||||
|
||||
std::string AsciiStrToLower(const std::string& str) {
|
||||
std::string lowerStr = str;
|
||||
std::transform(lowerStr.begin(), lowerStr.end(), lowerStr.begin(), ::tolower);
|
||||
return lowerStr;
|
||||
}
|
||||
|
||||
std::string AsciiStrReplace(const std::string& str,
|
||||
const std::string& from,
|
||||
const std::string& to) {
|
||||
std::string result = str;
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type from_len = from.length();
|
||||
std::string::size_type to_len = to.length();
|
||||
do {
|
||||
pos = result.find(from, pos);
|
||||
if (pos != std::string::npos) {
|
||||
result.replace(pos, from_len, to);
|
||||
pos += to_len;
|
||||
}
|
||||
} while (pos != std::string::npos);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace client
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_SHARED_COMMON_STRING_UTIL_H_
|
||||
#define CEF_TESTS_SHARED_COMMON_STRING_UTIL_H_
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace client {
|
||||
|
||||
// Convert |str| to lowercase.
|
||||
std::string AsciiStrToLower(const std::string& str);
|
||||
|
||||
// Replace all instances of |from| with |to| in |str|.
|
||||
std::string AsciiStrReplace(const std::string& str,
|
||||
const std::string& from,
|
||||
const std::string& to);
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_SHARED_COMMON_STRING_UTIL_H_
|
Loading…
Reference in New Issue