mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-01-29 18:49:52 +01:00
76642ccafa
The Chrome runtime requires that cookieable scheme information be available at Profile initialization time because it also triggers NetworkContext creation at the same time. To make this possible, and to avoid various race conditions when setting state, the cookieable scheme configuration has been added as |cookieable_schemes_list| and |cookieable_schemes_exclude_defaults| in CefSettings and CefBrowserContextSettings. The CefCookieManager:: SetSupportedSchemes and CefBrowserProcessHandler::GetCookieableSchemes methods are no longer required and have been removed. This change also modifies chrome to delay OffTheRecordProfileImpl initialization so that |ChromeBrowserContext::profile_| can be set before ChromeContentBrowserClientCef::ConfigureNetworkContextParams calls CefBrowserContext::FromBrowserContext to retrieve the ChromeBrowserContext and associated cookieable scheme information. Otherwise, the ChromeBrowserContext will not be matched and the NetworkContext will not be configured correctly. The CookieTest suite now passes with the Chrome runtime enabled.
2610 lines
86 KiB
C++
2610 lines
86 KiB
C++
// Copyright (c) 2011 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 <algorithm>
|
|
#include <vector>
|
|
|
|
#include "include/base/cef_bind.h"
|
|
#include "include/cef_callback.h"
|
|
#include "include/cef_origin_whitelist.h"
|
|
#include "include/cef_scheme.h"
|
|
#include "include/wrapper/cef_closure_task.h"
|
|
#include "tests/ceftests/test_handler.h"
|
|
#include "tests/ceftests/test_suite.h"
|
|
#include "tests/ceftests/test_util.h"
|
|
|
|
namespace {
|
|
|
|
class TestResults {
|
|
public:
|
|
TestResults() : status_code(200), sub_status_code(200), delay(0) {}
|
|
|
|
void reset() {
|
|
url.clear();
|
|
html.clear();
|
|
status_code = 200;
|
|
response_error_code = ERR_NONE;
|
|
expected_error_code = ERR_NONE;
|
|
redirect_url.clear();
|
|
sub_url.clear();
|
|
sub_html.clear();
|
|
sub_status_code = 200;
|
|
sub_allow_origin.clear();
|
|
exit_url.clear();
|
|
accept_language.clear();
|
|
console_messages.clear();
|
|
delay = 0;
|
|
got_request.reset();
|
|
got_read.reset();
|
|
got_output.reset();
|
|
got_sub_output.reset();
|
|
got_redirect.reset();
|
|
got_error.reset();
|
|
got_sub_error.reset();
|
|
got_sub_request.reset();
|
|
got_sub_read.reset();
|
|
got_sub_success.reset();
|
|
got_exit_request.reset();
|
|
}
|
|
|
|
std::string url;
|
|
std::string html;
|
|
int status_code;
|
|
|
|
// Error code set on the response.
|
|
cef_errorcode_t response_error_code;
|
|
// Error code expected in OnLoadError.
|
|
cef_errorcode_t expected_error_code;
|
|
|
|
// Used for testing redirects
|
|
std::string redirect_url;
|
|
|
|
// Used for testing XHR requests
|
|
std::string sub_url;
|
|
std::string sub_html;
|
|
int sub_status_code;
|
|
std::string sub_allow_origin;
|
|
std::string sub_redirect_url;
|
|
std::string exit_url;
|
|
|
|
// Used for testing per-browser Accept-Language.
|
|
std::string accept_language;
|
|
|
|
// Used for testing received console messages.
|
|
std::vector<std::string> console_messages;
|
|
|
|
// Delay for returning scheme handler results.
|
|
int delay;
|
|
|
|
TrackCallback got_request, got_read, got_output, got_sub_output, got_redirect,
|
|
got_error, got_sub_error, got_sub_redirect, got_sub_request, got_sub_read,
|
|
got_sub_success, got_exit_request;
|
|
};
|
|
|
|
// Current scheme handler object. Used when destroying the test from
|
|
// ClientSchemeHandler::ProcessRequest().
|
|
class TestSchemeHandler;
|
|
TestSchemeHandler* g_current_handler = nullptr;
|
|
|
|
class TestSchemeHandler : public TestHandler {
|
|
public:
|
|
explicit TestSchemeHandler(TestResults* tr) : test_results_(tr) {
|
|
g_current_handler = this;
|
|
}
|
|
|
|
void PopulateBrowserSettings(CefBrowserSettings* settings) override {
|
|
if (!test_results_->accept_language.empty()) {
|
|
CefString(&settings->accept_language_list) =
|
|
test_results_->accept_language;
|
|
}
|
|
}
|
|
|
|
void RunTest() override {
|
|
CreateBrowser(test_results_->url);
|
|
|
|
// Time out the test after a reasonable period of time.
|
|
SetTestTimeout();
|
|
}
|
|
|
|
// Necessary to make the method public in order to destroy the test from
|
|
// ClientSchemeHandler::ProcessRequest().
|
|
void DestroyTest() override {
|
|
EXPECT_TRUE(test_results_->console_messages.empty())
|
|
<< "Did not receive expected console message: "
|
|
<< test_results_->console_messages.front();
|
|
|
|
TestHandler::DestroyTest();
|
|
}
|
|
|
|
void DestroyTestIfDone() {
|
|
if (!test_results_->exit_url.empty() && !test_results_->got_exit_request) {
|
|
return;
|
|
}
|
|
|
|
if (!test_results_->sub_url.empty() &&
|
|
!(test_results_->got_sub_output || test_results_->got_sub_error ||
|
|
test_results_->got_exit_request)) {
|
|
return;
|
|
}
|
|
|
|
if (!(test_results_->got_output || test_results_->got_error)) {
|
|
return;
|
|
}
|
|
|
|
DestroyTest();
|
|
}
|
|
|
|
bool IsExitURL(const std::string& url) const {
|
|
return !test_results_->exit_url.empty() &&
|
|
url.find(test_results_->exit_url) != std::string::npos;
|
|
}
|
|
|
|
cef_return_value_t OnBeforeResourceLoad(
|
|
CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
CefRefPtr<CefRequest> request,
|
|
CefRefPtr<CefRequestCallback> callback) override {
|
|
if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) {
|
|
// Ignore favicon requests.
|
|
return RV_CANCEL;
|
|
}
|
|
|
|
const std::string& newUrl = request->GetURL();
|
|
if (IsExitURL(newUrl)) {
|
|
test_results_->got_exit_request.yes();
|
|
// XHR tests use an exit URL to destroy the test.
|
|
if (newUrl.find("SUCCESS") != std::string::npos)
|
|
test_results_->got_sub_success.yes();
|
|
DestroyTestIfDone();
|
|
return RV_CANCEL;
|
|
}
|
|
|
|
if (!test_results_->sub_redirect_url.empty() &&
|
|
newUrl == test_results_->sub_redirect_url) {
|
|
test_results_->got_sub_redirect.yes();
|
|
// Redirect to the sub URL.
|
|
request->SetURL(test_results_->sub_url);
|
|
} else if (newUrl == test_results_->redirect_url) {
|
|
test_results_->got_redirect.yes();
|
|
|
|
// No read should have occurred for the redirect.
|
|
EXPECT_TRUE(test_results_->got_request);
|
|
EXPECT_FALSE(test_results_->got_read);
|
|
|
|
// Now loading the redirect URL.
|
|
test_results_->url = test_results_->redirect_url;
|
|
test_results_->redirect_url.clear();
|
|
}
|
|
|
|
return RV_CONTINUE;
|
|
}
|
|
|
|
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
int httpStatusCode) override {
|
|
const std::string& url = frame->GetURL();
|
|
if (url == test_results_->url)
|
|
test_results_->got_output.yes();
|
|
else if (url == test_results_->sub_url)
|
|
test_results_->got_sub_output.yes();
|
|
else if (IsExitURL(url))
|
|
return;
|
|
|
|
if (url == test_results_->url || test_results_->status_code != 200) {
|
|
// Test that the status code is correct.
|
|
EXPECT_EQ(httpStatusCode, test_results_->status_code);
|
|
}
|
|
|
|
DestroyTestIfDone();
|
|
}
|
|
|
|
void OnLoadError(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
ErrorCode errorCode,
|
|
const CefString& errorText,
|
|
const CefString& failedUrl) override {
|
|
const std::string& url = failedUrl;
|
|
if (url == test_results_->url)
|
|
test_results_->got_error.yes();
|
|
else if (url == test_results_->sub_url)
|
|
test_results_->got_sub_error.yes();
|
|
else if (IsExitURL(url))
|
|
return;
|
|
|
|
// Tests sometimes also fail with ERR_ABORTED.
|
|
if (!(test_results_->expected_error_code == 0 &&
|
|
errorCode == ERR_ABORTED)) {
|
|
EXPECT_EQ(test_results_->expected_error_code, errorCode)
|
|
<< failedUrl.ToString();
|
|
}
|
|
|
|
DestroyTestIfDone();
|
|
}
|
|
|
|
bool OnConsoleMessage(CefRefPtr<CefBrowser> browser,
|
|
cef_log_severity_t level,
|
|
const CefString& message,
|
|
const CefString& source,
|
|
int line) override {
|
|
bool expected = false;
|
|
if (!test_results_->console_messages.empty()) {
|
|
std::vector<std::string>::iterator it =
|
|
test_results_->console_messages.begin();
|
|
for (; it != test_results_->console_messages.end(); ++it) {
|
|
const std::string& possible = *it;
|
|
const std::string& actual = message.ToString();
|
|
if (actual.find(possible) == 0U) {
|
|
expected = true;
|
|
test_results_->console_messages.erase(it);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
EXPECT_TRUE(expected) << "Unexpected console message: "
|
|
<< message.ToString();
|
|
return false;
|
|
}
|
|
|
|
protected:
|
|
TestResults* test_results_;
|
|
|
|
IMPLEMENT_REFCOUNTING(TestSchemeHandler);
|
|
};
|
|
|
|
class ClientSchemeHandlerOld : public CefResourceHandler {
|
|
public:
|
|
explicit ClientSchemeHandlerOld(TestResults* tr)
|
|
: test_results_(tr), offset_(0), is_sub_(false), has_delayed_(false) {}
|
|
|
|
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
|
CefRefPtr<CefCallback> callback) override {
|
|
EXPECT_TRUE(CefCurrentlyOn(TID_IO));
|
|
|
|
bool handled = false;
|
|
|
|
std::string url = request->GetURL();
|
|
is_sub_ =
|
|
(!test_results_->sub_url.empty() && test_results_->sub_url == url);
|
|
|
|
if (is_sub_) {
|
|
test_results_->got_sub_request.yes();
|
|
|
|
if (!test_results_->sub_html.empty())
|
|
handled = true;
|
|
} else {
|
|
EXPECT_EQ(url, test_results_->url);
|
|
|
|
test_results_->got_request.yes();
|
|
|
|
if (!test_results_->html.empty())
|
|
handled = true;
|
|
}
|
|
|
|
std::string accept_language;
|
|
CefRequest::HeaderMap headerMap;
|
|
CefRequest::HeaderMap::iterator headerIter;
|
|
request->GetHeaderMap(headerMap);
|
|
headerIter = headerMap.find("Accept-Language");
|
|
if (headerIter != headerMap.end())
|
|
accept_language = headerIter->second;
|
|
EXPECT_TRUE(!accept_language.empty());
|
|
|
|
if (!test_results_->accept_language.empty()) {
|
|
// Value from CefBrowserSettings.accept_language set in
|
|
// PopulateBrowserSettings().
|
|
EXPECT_STREQ(test_results_->accept_language.data(),
|
|
accept_language.data());
|
|
} else {
|
|
// CEF_SETTINGS_ACCEPT_LANGUAGE value from
|
|
// CefSettings.accept_language_list set in CefTestSuite::GetSettings()
|
|
// and expanded internally by ComputeAcceptLanguageFromPref.
|
|
EXPECT_STREQ("en-GB,en;q=0.9", accept_language.data());
|
|
}
|
|
|
|
if (handled) {
|
|
if (test_results_->delay > 0) {
|
|
// Continue after the delay.
|
|
CefPostDelayedTask(TID_IO,
|
|
base::Bind(&CefCallback::Continue, callback.get()),
|
|
test_results_->delay);
|
|
} else {
|
|
// Continue immediately.
|
|
callback->Continue();
|
|
}
|
|
return true;
|
|
} else if (test_results_->response_error_code != ERR_NONE) {
|
|
// Propagate the error code.
|
|
callback->Continue();
|
|
return true;
|
|
}
|
|
|
|
// Response was canceled.
|
|
if (g_current_handler)
|
|
g_current_handler->DestroyTest();
|
|
return false;
|
|
}
|
|
|
|
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
|
int64& response_length,
|
|
CefString& redirectUrl) override {
|
|
if (is_sub_) {
|
|
response->SetStatus(test_results_->sub_status_code);
|
|
|
|
if (!test_results_->sub_allow_origin.empty()) {
|
|
// Set the Access-Control-Allow-Origin header to allow cross-domain
|
|
// scripting.
|
|
CefResponse::HeaderMap headers;
|
|
headers.insert(std::make_pair("Access-Control-Allow-Origin",
|
|
test_results_->sub_allow_origin));
|
|
response->SetHeaderMap(headers);
|
|
}
|
|
|
|
if (!test_results_->sub_html.empty()) {
|
|
response->SetMimeType("text/html");
|
|
response_length = test_results_->sub_html.size();
|
|
}
|
|
} else if (!test_results_->redirect_url.empty()) {
|
|
redirectUrl = test_results_->redirect_url;
|
|
} else if (test_results_->response_error_code != ERR_NONE) {
|
|
response->SetError(test_results_->response_error_code);
|
|
} else {
|
|
response->SetStatus(test_results_->status_code);
|
|
|
|
if (!test_results_->html.empty()) {
|
|
response->SetMimeType("text/html");
|
|
response_length = test_results_->html.size();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Cancel() override { EXPECT_TRUE(CefCurrentlyOn(TID_IO)); }
|
|
|
|
bool ReadResponse(void* data_out,
|
|
int bytes_to_read,
|
|
int& bytes_read,
|
|
CefRefPtr<CefCallback> callback) override {
|
|
EXPECT_TRUE(CefCurrentlyOn(TID_IO));
|
|
|
|
if (test_results_->delay > 0) {
|
|
if (!has_delayed_) {
|
|
// Continue after a delay.
|
|
CefPostDelayedTask(
|
|
TID_IO,
|
|
base::Bind(&ClientSchemeHandlerOld::ContinueAfterDelay, this,
|
|
callback),
|
|
test_results_->delay);
|
|
bytes_read = 0;
|
|
return true;
|
|
}
|
|
|
|
has_delayed_ = false;
|
|
}
|
|
|
|
std::string* data;
|
|
|
|
if (is_sub_) {
|
|
test_results_->got_sub_read.yes();
|
|
data = &test_results_->sub_html;
|
|
} else {
|
|
test_results_->got_read.yes();
|
|
data = &test_results_->html;
|
|
}
|
|
|
|
bool has_data = false;
|
|
bytes_read = 0;
|
|
|
|
size_t size = data->size();
|
|
if (offset_ < size) {
|
|
int transfer_size =
|
|
std::min(bytes_to_read, static_cast<int>(size - offset_));
|
|
memcpy(data_out, data->c_str() + offset_, transfer_size);
|
|
offset_ += transfer_size;
|
|
|
|
bytes_read = transfer_size;
|
|
has_data = true;
|
|
}
|
|
|
|
return has_data;
|
|
}
|
|
|
|
private:
|
|
void ContinueAfterDelay(CefRefPtr<CefCallback> callback) {
|
|
has_delayed_ = true;
|
|
callback->Continue();
|
|
}
|
|
|
|
TestResults* test_results_;
|
|
size_t offset_;
|
|
bool is_sub_;
|
|
bool has_delayed_;
|
|
|
|
IMPLEMENT_REFCOUNTING(ClientSchemeHandlerOld);
|
|
DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandlerOld);
|
|
};
|
|
|
|
class ClientSchemeHandler : public CefResourceHandler {
|
|
public:
|
|
explicit ClientSchemeHandler(TestResults* tr)
|
|
: test_results_(tr), offset_(0), is_sub_(false), has_delayed_(false) {}
|
|
|
|
bool Open(CefRefPtr<CefRequest> request,
|
|
bool& handle_request,
|
|
CefRefPtr<CefCallback> callback) override {
|
|
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
|
|
|
if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) {
|
|
// Ignore favicon requests.
|
|
return false;
|
|
}
|
|
|
|
bool handled = false;
|
|
|
|
std::string url = request->GetURL();
|
|
is_sub_ =
|
|
(!test_results_->sub_url.empty() && test_results_->sub_url == url);
|
|
|
|
if (is_sub_) {
|
|
test_results_->got_sub_request.yes();
|
|
|
|
if (!test_results_->sub_html.empty())
|
|
handled = true;
|
|
} else {
|
|
EXPECT_EQ(url, test_results_->url);
|
|
|
|
test_results_->got_request.yes();
|
|
|
|
if (!test_results_->html.empty())
|
|
handled = true;
|
|
}
|
|
|
|
std::string accept_language;
|
|
CefRequest::HeaderMap headerMap;
|
|
CefRequest::HeaderMap::iterator headerIter;
|
|
request->GetHeaderMap(headerMap);
|
|
headerIter = headerMap.find("Accept-Language");
|
|
if (headerIter != headerMap.end())
|
|
accept_language = headerIter->second;
|
|
EXPECT_TRUE(!accept_language.empty());
|
|
|
|
if (!test_results_->accept_language.empty()) {
|
|
// Value from CefBrowserSettings.accept_language set in
|
|
// PopulateBrowserSettings().
|
|
EXPECT_STREQ(test_results_->accept_language.data(),
|
|
accept_language.data());
|
|
} else {
|
|
// CEF_SETTINGS_ACCEPT_LANGUAGE value from
|
|
// CefSettings.accept_language_list set in CefTestSuite::GetSettings()
|
|
// and expanded internally by ComputeAcceptLanguageFromPref.
|
|
EXPECT_STREQ("en-GB,en;q=0.9", accept_language.data());
|
|
}
|
|
|
|
// Continue or cancel the request immediately based on the return value.
|
|
handle_request = true;
|
|
|
|
if (handled) {
|
|
if (test_results_->delay > 0) {
|
|
// Continue after the delay.
|
|
handle_request = false;
|
|
CefPostDelayedTask(TID_FILE_USER_BLOCKING,
|
|
base::Bind(&CefCallback::Continue, callback.get()),
|
|
test_results_->delay);
|
|
}
|
|
return true;
|
|
} else if (test_results_->response_error_code != ERR_NONE) {
|
|
// Propagate the error code.
|
|
return true;
|
|
}
|
|
|
|
// Response was canceled.
|
|
if (g_current_handler)
|
|
g_current_handler->DestroyTest();
|
|
return false;
|
|
}
|
|
|
|
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
|
CefRefPtr<CefCallback> callback) override {
|
|
if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) {
|
|
// Ignore favicon requests.
|
|
return false;
|
|
}
|
|
|
|
EXPECT_TRUE(false); // Not reached.
|
|
return false;
|
|
}
|
|
|
|
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
|
int64& response_length,
|
|
CefString& redirectUrl) override {
|
|
if (is_sub_) {
|
|
response->SetStatus(test_results_->sub_status_code);
|
|
|
|
if (!test_results_->sub_allow_origin.empty()) {
|
|
// Set the Access-Control-Allow-Origin header to allow cross-domain
|
|
// scripting.
|
|
CefResponse::HeaderMap headers;
|
|
headers.insert(std::make_pair("Access-Control-Allow-Origin",
|
|
test_results_->sub_allow_origin));
|
|
response->SetHeaderMap(headers);
|
|
}
|
|
|
|
if (!test_results_->sub_html.empty()) {
|
|
response->SetMimeType("text/html");
|
|
response_length = test_results_->sub_html.size();
|
|
}
|
|
} else if (!test_results_->redirect_url.empty()) {
|
|
redirectUrl = test_results_->redirect_url;
|
|
} else if (test_results_->response_error_code != ERR_NONE) {
|
|
response->SetError(test_results_->response_error_code);
|
|
} else {
|
|
response->SetStatus(test_results_->status_code);
|
|
|
|
if (!test_results_->html.empty()) {
|
|
response->SetMimeType("text/html");
|
|
response_length = test_results_->html.size();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Cancel() override { EXPECT_TRUE(CefCurrentlyOn(TID_IO)); }
|
|
|
|
bool Read(void* data_out,
|
|
int bytes_to_read,
|
|
int& bytes_read,
|
|
CefRefPtr<CefResourceReadCallback> callback) override {
|
|
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
|
|
|
if (test_results_->delay > 0) {
|
|
if (!has_delayed_) {
|
|
// Continue after a delay.
|
|
CefPostDelayedTask(TID_FILE_USER_BLOCKING,
|
|
base::Bind(&ClientSchemeHandler::ContinueAfterDelay,
|
|
this, data_out, bytes_to_read, callback),
|
|
test_results_->delay);
|
|
bytes_read = 0;
|
|
return true;
|
|
}
|
|
|
|
has_delayed_ = false;
|
|
}
|
|
|
|
return GetData(data_out, bytes_to_read, bytes_read);
|
|
}
|
|
|
|
bool ReadResponse(void* data_out,
|
|
int bytes_to_read,
|
|
int& bytes_read,
|
|
CefRefPtr<CefCallback> callback) override {
|
|
EXPECT_TRUE(false); // Not reached.
|
|
bytes_read = -2;
|
|
return false;
|
|
}
|
|
|
|
private:
|
|
void ContinueAfterDelay(void* data_out,
|
|
int bytes_to_read,
|
|
CefRefPtr<CefResourceReadCallback> callback) {
|
|
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
|
|
|
has_delayed_ = true;
|
|
|
|
int bytes_read = 0;
|
|
GetData(data_out, bytes_to_read, bytes_read);
|
|
callback->Continue(bytes_read);
|
|
}
|
|
|
|
bool GetData(void* data_out, int bytes_to_read, int& bytes_read) {
|
|
std::string* data;
|
|
|
|
if (is_sub_) {
|
|
test_results_->got_sub_read.yes();
|
|
data = &test_results_->sub_html;
|
|
} else {
|
|
test_results_->got_read.yes();
|
|
data = &test_results_->html;
|
|
}
|
|
|
|
// Default to response complete.
|
|
bool has_data = false;
|
|
bytes_read = 0;
|
|
|
|
size_t size = data->size();
|
|
if (offset_ < size) {
|
|
int transfer_size =
|
|
std::min(bytes_to_read, static_cast<int>(size - offset_));
|
|
memcpy(data_out, data->c_str() + offset_, transfer_size);
|
|
offset_ += transfer_size;
|
|
|
|
bytes_read = transfer_size;
|
|
has_data = true;
|
|
}
|
|
|
|
return has_data;
|
|
}
|
|
|
|
TestResults* test_results_;
|
|
size_t offset_;
|
|
bool is_sub_;
|
|
bool has_delayed_;
|
|
|
|
IMPLEMENT_REFCOUNTING(ClientSchemeHandler);
|
|
DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandler);
|
|
};
|
|
|
|
class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory {
|
|
public:
|
|
explicit ClientSchemeHandlerFactory(TestResults* tr) : test_results_(tr) {}
|
|
|
|
CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
const CefString& scheme_name,
|
|
CefRefPtr<CefRequest> request) override {
|
|
EXPECT_TRUE(CefCurrentlyOn(TID_IO));
|
|
if (TestOldResourceAPI()) {
|
|
return new ClientSchemeHandlerOld(test_results_);
|
|
}
|
|
return new ClientSchemeHandler(test_results_);
|
|
}
|
|
|
|
TestResults* test_results_;
|
|
|
|
IMPLEMENT_REFCOUNTING(ClientSchemeHandlerFactory);
|
|
DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandlerFactory);
|
|
};
|
|
|
|
// Global test results object.
|
|
TestResults g_TestResults;
|
|
|
|
// If |domain| is empty the scheme will be registered as non-standard.
|
|
void RegisterTestScheme(const std::string& scheme, const std::string& domain) {
|
|
g_TestResults.reset();
|
|
|
|
EXPECT_TRUE(CefRegisterSchemeHandlerFactory(
|
|
scheme, domain, new ClientSchemeHandlerFactory(&g_TestResults)));
|
|
WaitForIOThread();
|
|
}
|
|
|
|
void ClearTestSchemes() {
|
|
EXPECT_TRUE(CefClearSchemeHandlerFactories());
|
|
WaitForIOThread();
|
|
}
|
|
|
|
struct XHRTestSettings {
|
|
XHRTestSettings() : synchronous(true) {}
|
|
|
|
std::string url;
|
|
std::string sub_url;
|
|
std::string sub_allow_origin;
|
|
std::string sub_redirect_url;
|
|
bool synchronous;
|
|
};
|
|
|
|
void SetUpXHR(const XHRTestSettings& settings) {
|
|
g_TestResults.sub_url = settings.sub_url;
|
|
g_TestResults.sub_html = "SUCCESS";
|
|
g_TestResults.sub_allow_origin = settings.sub_allow_origin;
|
|
g_TestResults.sub_redirect_url = settings.sub_redirect_url;
|
|
|
|
if (settings.synchronous) {
|
|
g_TestResults.console_messages.push_back(
|
|
"Synchronous XMLHttpRequest on the main thread is deprecated");
|
|
}
|
|
|
|
std::string request_url;
|
|
if (!settings.sub_redirect_url.empty())
|
|
request_url = settings.sub_redirect_url;
|
|
else
|
|
request_url = settings.sub_url;
|
|
|
|
g_TestResults.url = settings.url;
|
|
std::stringstream ss;
|
|
ss << "<html><head>"
|
|
"<script language=\"JavaScript\">"
|
|
"function onResult(val) {"
|
|
" document.location = \"http://tests/exit?result=\"+val;"
|
|
"}"
|
|
"function execXMLHttpRequest() {";
|
|
if (settings.synchronous) {
|
|
ss << "var result = 'FAILURE';"
|
|
"try {"
|
|
" xhr = new XMLHttpRequest();"
|
|
" xhr.open(\"GET\", \""
|
|
<< request_url.c_str()
|
|
<< "\", false);"
|
|
" xhr.send();"
|
|
" result = xhr.responseText;"
|
|
"} catch(e) {}"
|
|
"onResult(result)";
|
|
} else {
|
|
ss << "xhr = new XMLHttpRequest();"
|
|
"xhr.open(\"GET\", \""
|
|
<< request_url.c_str()
|
|
<< "\", true);"
|
|
"xhr.onload = function(e) {"
|
|
" if (xhr.readyState === 4) {"
|
|
" if (xhr.status === 200) {"
|
|
" onResult(xhr.responseText);"
|
|
" } else {"
|
|
" console.log('XMLHttpRequest failed with status ' + "
|
|
"xhr.status);"
|
|
" onResult('FAILURE');"
|
|
" }"
|
|
" }"
|
|
"};"
|
|
"xhr.onerror = function(e) {"
|
|
" onResult('FAILURE');"
|
|
"};"
|
|
"xhr.send()";
|
|
}
|
|
ss << "}"
|
|
"</script>"
|
|
"</head><body onload=\"execXMLHttpRequest();\">"
|
|
"Running execXMLHttpRequest..."
|
|
"</body></html>";
|
|
g_TestResults.html = ss.str();
|
|
|
|
g_TestResults.exit_url = "http://tests/exit";
|
|
}
|
|
|
|
struct FetchTestSettings {
|
|
FetchTestSettings() {}
|
|
|
|
std::string url;
|
|
std::string sub_url;
|
|
std::string sub_allow_origin;
|
|
std::string sub_redirect_url;
|
|
};
|
|
|
|
void SetUpFetch(const FetchTestSettings& settings) {
|
|
g_TestResults.sub_url = settings.sub_url;
|
|
g_TestResults.sub_html = "SUCCESS";
|
|
g_TestResults.sub_allow_origin = settings.sub_allow_origin;
|
|
g_TestResults.sub_redirect_url = settings.sub_redirect_url;
|
|
|
|
std::string request_url;
|
|
if (!settings.sub_redirect_url.empty())
|
|
request_url = settings.sub_redirect_url;
|
|
else
|
|
request_url = settings.sub_url;
|
|
|
|
g_TestResults.url = settings.url;
|
|
std::stringstream ss;
|
|
ss << "<html><head>"
|
|
"<script language=\"JavaScript\">"
|
|
"function onResult(val) {"
|
|
" document.location = \"http://tests/exit?result=\"+val;"
|
|
"}"
|
|
"function execFetchHttpRequest() {";
|
|
ss << "fetch('" << request_url.c_str()
|
|
<< "')"
|
|
".then(function(response) {"
|
|
" if (response.status === 200) {"
|
|
" response.text().then(function(text) {"
|
|
" onResult(text);"
|
|
" }).catch(function(e) {"
|
|
" onResult('FAILURE'); "
|
|
" });"
|
|
" } else {"
|
|
" onResult('FAILURE');"
|
|
" }"
|
|
"}).catch(function(e) {"
|
|
" onResult('FAILURE');"
|
|
"});"
|
|
<< "}"
|
|
"</script>"
|
|
"</head><body onload=\"execFetchHttpRequest();\">"
|
|
"Running execFetchHttpRequest..."
|
|
"</body></html>";
|
|
g_TestResults.html = ss.str();
|
|
|
|
g_TestResults.exit_url = "http://tests/exit";
|
|
} // namespace
|
|
|
|
void SetUpXSS(const std::string& url,
|
|
const std::string& sub_url,
|
|
const std::string& domain = std::string()) {
|
|
// 1. Load |url| which contains an iframe.
|
|
// 2. The iframe loads |sub_url|.
|
|
// 3. |sub_url| tries to call a JS function in |url|.
|
|
// 4. |url| tries to call a JS function in |sub_url|.
|
|
|
|
std::stringstream ss;
|
|
std::string domain_line;
|
|
if (!domain.empty())
|
|
domain_line = "document.domain = '" + domain + "';";
|
|
|
|
g_TestResults.sub_url = sub_url;
|
|
ss << "<html><head>"
|
|
"<script language=\"JavaScript\">"
|
|
<< domain_line
|
|
<< "function getResult() {"
|
|
" return 'SUCCESS';"
|
|
"}"
|
|
"function execXSSRequest() {"
|
|
" var result = 'FAILURE';"
|
|
" try {"
|
|
" result = parent.getResult();"
|
|
" } catch(e) { console.log(e.stack); }"
|
|
" document.location = \"http://tests/exit?result=\"+result;"
|
|
"}"
|
|
"</script>"
|
|
"</head><body onload=\"execXSSRequest();\">"
|
|
"Running execXSSRequest..."
|
|
"</body></html>";
|
|
g_TestResults.sub_html = ss.str();
|
|
|
|
g_TestResults.url = url;
|
|
ss.str("");
|
|
ss << "<html><head>"
|
|
"<script language=\"JavaScript\">"
|
|
<< domain_line
|
|
<< ""
|
|
"function getResult() {"
|
|
" try {"
|
|
" return document.getElementById('s').contentWindow.getResult();"
|
|
" } catch(e) { console.log(e.stack); }"
|
|
" return 'FAILURE';"
|
|
"}"
|
|
"</script>"
|
|
"</head><body>"
|
|
"<iframe src=\""
|
|
<< sub_url.c_str()
|
|
<< "\" id=\"s\">"
|
|
"</body></html>";
|
|
g_TestResults.html = ss.str();
|
|
|
|
g_TestResults.exit_url = "http://tests/exit";
|
|
}
|
|
|
|
} // namespace
|
|
|
|
// Test that scheme registration/unregistration works as expected.
|
|
TEST(SchemeHandlerTest, Registration) {
|
|
RegisterTestScheme("customstd", "test");
|
|
g_TestResults.url = "customstd://test/run.html";
|
|
g_TestResults.html =
|
|
"<html><head></head><body><h1>Success!</h1></body></html>";
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
|
|
// Unregister the handler.
|
|
EXPECT_TRUE(CefRegisterSchemeHandlerFactory("customstd", "test", nullptr));
|
|
WaitForIOThread();
|
|
|
|
g_TestResults.got_request.reset();
|
|
g_TestResults.got_read.reset();
|
|
g_TestResults.got_output.reset();
|
|
g_TestResults.expected_error_code = ERR_UNKNOWN_URL_SCHEME;
|
|
handler->ExecuteTest();
|
|
|
|
EXPECT_TRUE(g_TestResults.got_error);
|
|
EXPECT_FALSE(g_TestResults.got_request);
|
|
EXPECT_FALSE(g_TestResults.got_read);
|
|
EXPECT_FALSE(g_TestResults.got_output);
|
|
|
|
// Re-register the handler.
|
|
EXPECT_TRUE(CefRegisterSchemeHandlerFactory(
|
|
"customstd", "test", new ClientSchemeHandlerFactory(&g_TestResults)));
|
|
WaitForIOThread();
|
|
|
|
g_TestResults.got_error.reset();
|
|
g_TestResults.expected_error_code = ERR_NONE;
|
|
handler->ExecuteTest();
|
|
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_FALSE(g_TestResults.got_error);
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can return normal results.
|
|
TEST(SchemeHandlerTest, CustomStandardNormalResponse) {
|
|
RegisterTestScheme("customstd", "test");
|
|
g_TestResults.url = "customstd://test/run.html";
|
|
g_TestResults.html =
|
|
"<html><head></head><body><h1>Success!</h1></body></html>";
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can return normal results with delayed
|
|
// responses.
|
|
TEST(SchemeHandlerTest, CustomStandardNormalResponseDelayed) {
|
|
RegisterTestScheme("customstd", "test");
|
|
g_TestResults.url = "customstd://test/run.html";
|
|
g_TestResults.html =
|
|
"<html><head></head><body><h1>Success!</h1></body></html>";
|
|
g_TestResults.delay = 100;
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom nonstandard scheme can return normal results.
|
|
TEST(SchemeHandlerTest, CustomNonStandardNormalResponse) {
|
|
RegisterTestScheme("customnonstd", std::string());
|
|
g_TestResults.url = "customnonstd:some%20value";
|
|
g_TestResults.html =
|
|
"<html><head></head><body><h1>Success!</h1></body></html>";
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can return an error code.
|
|
TEST(SchemeHandlerTest, CustomStandardErrorResponse) {
|
|
RegisterTestScheme("customstd", "test");
|
|
g_TestResults.url = "customstd://test/run.html";
|
|
g_TestResults.html = "<html><head></head><body><h1>404</h1></body></html>";
|
|
g_TestResults.status_code = 404;
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can return a CEF error code in the
|
|
// response.
|
|
TEST(SchemeHandlerTest, CustomStandardErrorCodeResponse) {
|
|
RegisterTestScheme("customstd", "test");
|
|
g_TestResults.url = "customstd://test/run.html";
|
|
g_TestResults.response_error_code = ERR_FILE_TOO_BIG;
|
|
g_TestResults.expected_error_code = ERR_FILE_TOO_BIG;
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_FALSE(g_TestResults.got_read);
|
|
EXPECT_FALSE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_error);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom nonstandard scheme can return an error code.
|
|
TEST(SchemeHandlerTest, CustomNonStandardErrorResponse) {
|
|
RegisterTestScheme("customnonstd", std::string());
|
|
g_TestResults.url = "customnonstd:some%20value";
|
|
g_TestResults.html = "<html><head></head><body><h1>404</h1></body></html>";
|
|
g_TestResults.status_code = 404;
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that custom standard scheme handling fails when the scheme name is
|
|
// incorrect.
|
|
TEST(SchemeHandlerTest, CustomStandardNameNotHandled) {
|
|
RegisterTestScheme("customstd", "test");
|
|
g_TestResults.url = "customstd2://test/run.html";
|
|
g_TestResults.expected_error_code = ERR_UNKNOWN_URL_SCHEME;
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_FALSE(g_TestResults.got_request);
|
|
EXPECT_FALSE(g_TestResults.got_read);
|
|
EXPECT_FALSE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_error);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that custom nonstandard scheme handling fails when the scheme name is
|
|
// incorrect.
|
|
TEST(SchemeHandlerTest, CustomNonStandardNameNotHandled) {
|
|
RegisterTestScheme("customnonstd", std::string());
|
|
g_TestResults.url = "customnonstd2:some%20value";
|
|
g_TestResults.expected_error_code = ERR_UNKNOWN_URL_SCHEME;
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_FALSE(g_TestResults.got_request);
|
|
EXPECT_FALSE(g_TestResults.got_read);
|
|
EXPECT_FALSE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_error);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that custom standard scheme handling fails when the domain name is
|
|
// incorrect.
|
|
TEST(SchemeHandlerTest, CustomStandardDomainNotHandled) {
|
|
RegisterTestScheme("customstd", "test");
|
|
g_TestResults.url = "customstd://noexist/run.html";
|
|
g_TestResults.expected_error_code = ERR_UNKNOWN_URL_SCHEME;
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_FALSE(g_TestResults.got_request);
|
|
EXPECT_FALSE(g_TestResults.got_read);
|
|
EXPECT_FALSE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_error);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can return no response.
|
|
TEST(SchemeHandlerTest, CustomStandardNoResponse) {
|
|
RegisterTestScheme("customstd", "test");
|
|
g_TestResults.url = "customstd://test/run.html";
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_FALSE(g_TestResults.got_read);
|
|
EXPECT_FALSE(g_TestResults.got_output);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom nonstandard scheme can return no response.
|
|
TEST(SchemeHandlerTest, CustomNonStandardNoResponse) {
|
|
RegisterTestScheme("customnonstd", std::string());
|
|
g_TestResults.url = "customnonstd:some%20value";
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_FALSE(g_TestResults.got_read);
|
|
EXPECT_FALSE(g_TestResults.got_output);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate redirects.
|
|
TEST(SchemeHandlerTest, CustomStandardRedirect) {
|
|
RegisterTestScheme("customstd", "test");
|
|
g_TestResults.url = "customstd://test/run.html";
|
|
g_TestResults.redirect_url = "customstd://test/redirect.html";
|
|
g_TestResults.html =
|
|
"<html><head></head><body><h1>Redirected</h1></body></html>";
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_redirect);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom nonstandard scheme can generate redirects.
|
|
TEST(SchemeHandlerTest, CustomNonStandardRedirect) {
|
|
RegisterTestScheme("customnonstd", std::string());
|
|
g_TestResults.url = "customnonstd:some%20value";
|
|
g_TestResults.redirect_url = "customnonstd:some%20other%20value";
|
|
g_TestResults.html =
|
|
"<html><head></head><body><h1>Redirected</h1></body></html>";
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_redirect);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate same origin XHR requests.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRSameOriginSync) {
|
|
RegisterTestScheme("customstd", "test");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test/run.html";
|
|
settings.sub_url = "customstd://test/xhr.html";
|
|
SetUpXHR(settings);
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate same origin XHR requests.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRSameOriginAsync) {
|
|
RegisterTestScheme("customstd", "test");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test/run.html";
|
|
settings.sub_url = "customstd://test/xhr.html";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that custom nonstandard schemes are treated as unique origins that
|
|
// cannot generate XHR requests.
|
|
TEST(SchemeHandlerTest, CustomNonStandardXHRSameOriginSync) {
|
|
RegisterTestScheme("customnonstd", std::string());
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customnonstd:some%20value";
|
|
settings.sub_url = "customnonstd:xhr%20value";
|
|
SetUpXHR(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Access to XMLHttpRequest at 'customnonstd:xhr%20value' from origin "
|
|
"'null' has been blocked by CORS policy: Cross origin requests are only "
|
|
"supported for protocol schemes:");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_FALSE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that custom nonstandard schemes are treated as unique origins that
|
|
// cannot generate XHR requests.
|
|
TEST(SchemeHandlerTest, CustomNonStandardXHRSameOriginAsync) {
|
|
RegisterTestScheme("customnonstd", std::string());
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customnonstd:some%20value";
|
|
settings.sub_url = "customnonstd:xhr%20value";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Access to XMLHttpRequest at 'customnonstd:xhr%20value' from origin "
|
|
"'null' has been blocked by CORS policy: Cross origin requests are only "
|
|
"supported for protocol schemes:");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_FALSE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a non fetch enabled custom standard scheme can't generate same
|
|
// origin Fetch requests.
|
|
TEST(SchemeHandlerTest, CustomStandardFetchSameOrigin) {
|
|
RegisterTestScheme("customstd", "test");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "customstd://test/run.html";
|
|
settings.sub_url = "customstd://test/fetch.html";
|
|
SetUpFetch(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Fetch API cannot load customstd://test/fetch.html. URL scheme "
|
|
"\"customstd\" is not supported.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_FALSE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a fetch enabled custom standard scheme can generate same origin
|
|
// Fetch requests.
|
|
TEST(SchemeHandlerTest, FetchCustomStandardFetchSameOrigin) {
|
|
RegisterTestScheme("customstdfetch", "test");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "customstdfetch://test/run.html";
|
|
settings.sub_url = "customstdfetch://test/fetch.html";
|
|
SetUpFetch(settings);
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that custom nonstandard schemes are treated as unique origins that
|
|
// cannot generate Fetch requests.
|
|
TEST(SchemeHandlerTest, CustomNonStandardFetchSameOrigin) {
|
|
RegisterTestScheme("customnonstd", std::string());
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "customnonstd:some%20value";
|
|
settings.sub_url = "customnonstd:xhr%20value";
|
|
SetUpFetch(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Fetch API cannot load customnonstd:xhr%20value. URL scheme must be "
|
|
"\"http\" or \"https\" for CORS request.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_FALSE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate same origin XSS requests.
|
|
TEST(SchemeHandlerTest, CustomStandardXSSSameOrigin) {
|
|
RegisterTestScheme("customstd", "test");
|
|
SetUpXSS("customstd://test/run.html", "customstd://test/iframe.html");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that custom nonstandard schemes are treated as unique origins that
|
|
// cannot generate XSS requests.
|
|
TEST(SchemeHandlerTest, CustomNonStandardXSSSameOrigin) {
|
|
RegisterTestScheme("customnonstd", std::string());
|
|
SetUpXSS("customnonstd:some%20value", "customnonstd:xhr%20value");
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Error: Blocked a frame with origin \"null\" from accessing a "
|
|
"cross-origin frame.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme cannot generate cross-domain XHR requests
|
|
// by default. Behavior should be the same as with HTTP.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginSync) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
SetUpXHR(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Access to XMLHttpRequest at 'customstd://test2/xhr.html' from origin "
|
|
"'customstd://test1' has been blocked by CORS policy: No "
|
|
"'Access-Control-Allow-Origin' header is present on the requested "
|
|
"resource.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme cannot generate cross-domain XHR requests
|
|
// by default. Behavior should be the same as with HTTP.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginAsync) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Access to XMLHttpRequest at 'customstd://test2/xhr.html' from origin "
|
|
"'customstd://test1' has been blocked by CORS policy: No "
|
|
"'Access-Control-Allow-Origin' header is present on the requested "
|
|
"resource.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme cannot generate cross-domain Fetch
|
|
// requests by default. Behavior should be the same as with HTTP.
|
|
TEST(SchemeHandlerTest, CustomStandardFetchDifferentOrigin) {
|
|
RegisterTestScheme("customstdfetch", "test1");
|
|
RegisterTestScheme("customstdfetch", "test2");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "customstdfetch://test1/run.html";
|
|
settings.sub_url = "customstdfetch://test2/fetch.html";
|
|
SetUpFetch(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Access to fetch at 'customstdfetch://test2/fetch.html' from origin "
|
|
"'customstdfetch://test1' has been blocked by CORS policy: No "
|
|
"'Access-Control-Allow-Origin' header is present on the requested "
|
|
"resource. If an opaque response serves your needs, set the request's "
|
|
"mode to 'no-cors' to fetch the resource with CORS disabled.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme cannot generate cross-domain XSS requests
|
|
// by default.
|
|
TEST(SchemeHandlerTest, CustomStandardXSSDifferentOrigin) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
SetUpXSS("customstd://test1/run.html", "customstd://test2/iframe.html");
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Error: Blocked a frame with origin \"customstd://test2\" from accessing "
|
|
"a cross-origin frame.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a cross-protocol iframe load succeeds, and that the custom
|
|
// standard scheme cannot generate XSS requests to the HTTP protocol by default.
|
|
TEST(SchemeHandlerTest, CustomStandardXSSDifferentProtocolHttp) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("http", "test2");
|
|
SetUpXSS("customstd://test1/run.html", "http://test2/iframe.html");
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Error: Blocked a frame with origin \"http://test2\" from accessing a "
|
|
"cross-origin frame.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a cross-protocol iframe load succeeds, and that the custom
|
|
// standard scheme cannot generate XSS requests to a non-standard scheme by
|
|
// default.
|
|
TEST(SchemeHandlerTest, CustomStandardXSSDifferentProtocolCustomNonStandard) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customnonstd", std::string());
|
|
SetUpXSS("customstd://test1/run.html", "customnonstd:some%20value");
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Error: Blocked a frame with origin \"null\" from accessing a "
|
|
"cross-origin frame.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a cross-protocol iframe load succeeds, and that the HTTP protocol
|
|
// cannot generate XSS requests to the custom standard scheme by default.
|
|
TEST(SchemeHandlerTest, HttpXSSDifferentProtocolCustomStandard) {
|
|
RegisterTestScheme("http", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
SetUpXSS("http://test1/run.html", "customstd://test2/iframe.html");
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Error: Blocked a frame with origin \"customstd://test2\" from accessing "
|
|
"a cross-origin frame.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a cross-protocol iframe load succeeds, and that the HTTP protocol
|
|
// cannot generate XSS requests to the custom non-standard scheme by default.
|
|
TEST(SchemeHandlerTest, HttpXSSDifferentProtocolCustomNonStandard) {
|
|
RegisterTestScheme("http", "test1");
|
|
RegisterTestScheme("customnonstd", std::string());
|
|
SetUpXSS("http://test1/run.html", "customnonstd:some%20value");
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Error: Blocked a frame with origin \"null\" from accessing a "
|
|
"cross-origin frame.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that an HTTP scheme cannot generate cross-domain XHR requests by
|
|
// default.
|
|
TEST(SchemeHandlerTest, HttpXHRDifferentOriginSync) {
|
|
RegisterTestScheme("http", "test1");
|
|
RegisterTestScheme("http", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "http://test1/run.html";
|
|
settings.sub_url = "http://test2/xhr.html";
|
|
SetUpXHR(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Access to XMLHttpRequest at 'http://test2/xhr.html' from origin "
|
|
"'http://test1' has been blocked by CORS policy: No "
|
|
"'Access-Control-Allow-Origin' header is present on the requested "
|
|
"resource.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that an HTTP scheme cannot generate cross-domain XHR requests by
|
|
// default.
|
|
TEST(SchemeHandlerTest, HttpXHRDifferentOriginAsync) {
|
|
RegisterTestScheme("http", "test1");
|
|
RegisterTestScheme("http", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "http://test1/run.html";
|
|
settings.sub_url = "http://test2/xhr.html";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Access to XMLHttpRequest at 'http://test2/xhr.html' from origin "
|
|
"'http://test1' has been blocked by CORS policy: No "
|
|
"'Access-Control-Allow-Origin' header is present on the requested "
|
|
"resource.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that an HTTP scheme cannot generate cross-domain Fetch requests by
|
|
// default.
|
|
TEST(SchemeHandlerTest, HttpFetchDifferentOriginAsync) {
|
|
RegisterTestScheme("http", "test1");
|
|
RegisterTestScheme("http", "test2");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "http://test1/run.html";
|
|
settings.sub_url = "http://test2/fetch.html";
|
|
SetUpFetch(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Access to fetch at 'http://test2/fetch.html' from origin 'http://test1' "
|
|
"has been blocked by CORS policy: No 'Access-Control-Allow-Origin' "
|
|
"header is present on the requested resource. If an opaque response "
|
|
"serves your needs, set the request's mode to 'no-cors' to fetch the "
|
|
"resource with CORS disabled.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that an HTTP scheme cannot generate cross-domain XSS requests by
|
|
// default.
|
|
TEST(SchemeHandlerTest, HttpXSSDifferentOrigin) {
|
|
RegisterTestScheme("http", "test1");
|
|
RegisterTestScheme("http", "test2");
|
|
SetUpXSS("http://test1/run.html", "http://test2/xss.html");
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Error: Blocked a frame with origin \"http://test2\" from accessing a "
|
|
"cross-origin frame.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate cross-domain XHR requests
|
|
// when setting the Access-Control-Allow-Origin header. Should behave the same
|
|
// as HTTP.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithHeaderSync) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
settings.sub_allow_origin = "customstd://test1";
|
|
SetUpXHR(settings);
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate cross-domain XHR requests
|
|
// when setting the Access-Control-Allow-Origin header. Should behave the same
|
|
// as HTTP.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithHeaderAsync) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
settings.sub_allow_origin = "customstd://test1";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate cross-domain Fetch requests
|
|
// when setting the Access-Control-Allow-Origin header. Should behave the same
|
|
// as HTTP.
|
|
TEST(SchemeHandlerTest, CustomStandardFetchDifferentOriginWithHeader) {
|
|
RegisterTestScheme("customstdfetch", "test1");
|
|
RegisterTestScheme("customstdfetch", "test2");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "customstdfetch://test1/run.html";
|
|
settings.sub_url = "customstdfetch://test2/fetch.html";
|
|
settings.sub_allow_origin = "customstdfetch://test1";
|
|
SetUpFetch(settings);
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate cross-domain XHR requests
|
|
// when using the cross-origin whitelist.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelistSync1) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
SetUpXHR(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
|
|
"test2", false));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Same as above but origin whitelist matches any domain.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelistSync2) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
SetUpXHR(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
|
|
CefString(), true));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Same as above but origin whitelist matches sub-domains.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelistSync3) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "a.test2.foo");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://a.test2.foo/xhr.html";
|
|
SetUpXHR(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
|
|
"test2.foo", true));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate cross-domain XHR requests
|
|
// when using the cross-origin whitelist.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelistAsync1) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
|
|
"test2", false));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Same as above but origin whitelist matches any domain.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelistAsync2) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
|
|
CefString(), true));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Same as above but origin whitelist matches sub-domains.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelistAsync3) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "a.test2.foo");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://a.test2.foo/xhr.html";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
|
|
"test2.foo", true));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate cross-domain Fetch requests
|
|
// when using the cross-origin whitelist.
|
|
TEST(SchemeHandlerTest, CustomStandardFetchDifferentOriginWithWhitelist1) {
|
|
RegisterTestScheme("customstdfetch", "test1");
|
|
RegisterTestScheme("customstdfetch", "test2");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "customstdfetch://test1/run.html";
|
|
settings.sub_url = "customstdfetch://test2/fetch.html";
|
|
SetUpFetch(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry(
|
|
"customstdfetch://test1", "customstdfetch", "test2", false));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Same as above but origin whitelist matches any domain.
|
|
TEST(SchemeHandlerTest, CustomStandardFetchDifferentOriginWithWhitelist2) {
|
|
RegisterTestScheme("customstdfetch", "test1");
|
|
RegisterTestScheme("customstdfetch", "test2");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "customstdfetch://test1/run.html";
|
|
settings.sub_url = "customstdfetch://test2/fetch.html";
|
|
SetUpFetch(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry(
|
|
"customstdfetch://test1", "customstdfetch", CefString(), true));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Same as above but origin whitelist matches sub-domains.
|
|
TEST(SchemeHandlerTest, CustomStandardFetchDifferentOriginWithWhitelist3) {
|
|
RegisterTestScheme("customstdfetch", "test1");
|
|
RegisterTestScheme("customstdfetch", "a.test2.foo");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "customstdfetch://test1/run.html";
|
|
settings.sub_url = "customstdfetch://a.test2.foo/fetch.html";
|
|
SetUpFetch(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry(
|
|
"customstdfetch://test1", "customstdfetch", "test2.foo", true));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that an HTTP scheme can generate cross-domain XHR requests when setting
|
|
// the Access-Control-Allow-Origin header.
|
|
TEST(SchemeHandlerTest, HttpXHRDifferentOriginWithHeaderSync) {
|
|
RegisterTestScheme("http", "test1");
|
|
RegisterTestScheme("http", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "http://test1/run.html";
|
|
settings.sub_url = "http://test2/xhr.html";
|
|
settings.sub_allow_origin = "http://test1";
|
|
SetUpXHR(settings);
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that an HTTP scheme can generate cross-domain XHR requests when setting
|
|
// the Access-Control-Allow-Origin header.
|
|
TEST(SchemeHandlerTest, HttpXHRDifferentOriginWithHeaderAsync) {
|
|
RegisterTestScheme("http", "test1");
|
|
RegisterTestScheme("http", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "http://test1/run.html";
|
|
settings.sub_url = "http://test2/xhr.html";
|
|
settings.sub_allow_origin = "http://test1";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that an HTTP scheme can generate cross-domain XHR requests when setting
|
|
// the Access-Control-Allow-Origin header.
|
|
TEST(SchemeHandlerTest, HttpFetchDifferentOriginWithHeader) {
|
|
RegisterTestScheme("http", "test1");
|
|
RegisterTestScheme("http", "test2");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "http://test1/run.html";
|
|
settings.sub_url = "http://test2/fetch.html";
|
|
settings.sub_allow_origin = "http://test1";
|
|
SetUpFetch(settings);
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate cross-domain XSS requests
|
|
// when using document.domain.
|
|
TEST(SchemeHandlerTest, CustomStandardXSSDifferentOriginWithDomain) {
|
|
RegisterTestScheme("customstd", "a.test.com");
|
|
RegisterTestScheme("customstd", "b.test.com");
|
|
SetUpXSS("customstd://a.test.com/run.html",
|
|
"customstd://b.test.com/iframe.html", "test.com");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that an HTTP scheme can generate cross-domain XSS requests when using
|
|
// document.domain.
|
|
TEST(SchemeHandlerTest, HttpXSSDifferentOriginWithDomain) {
|
|
RegisterTestScheme("http", "a.test.com");
|
|
RegisterTestScheme("http", "b.test.com");
|
|
SetUpXSS("http://a.test.com/run.html", "http://b.test.com/iframe.html",
|
|
"test.com");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme cannot generate cross-domain XHR requests
|
|
// that perform redirects.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginRedirectSync) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
settings.sub_redirect_url = "customstd://test1/xhr.html";
|
|
SetUpXHR(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Access to XMLHttpRequest at 'customstd://test2/xhr.html' (redirected "
|
|
"from 'customstd://test1/xhr.html') from origin 'customstd://test1' has "
|
|
"been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is "
|
|
"present on the requested resource.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_redirect);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme cannot generate cross-domain XHR requests
|
|
// that perform redirects.
|
|
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginRedirectAsync) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
settings.sub_redirect_url = "customstd://test1/xhr.html";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Access to XMLHttpRequest at 'customstd://test2/xhr.html' (redirected "
|
|
"from 'customstd://test1/xhr.html') from origin 'customstd://test1' has "
|
|
"been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is "
|
|
"present on the requested resource.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_redirect);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme cannot generate cross-domain Fetch
|
|
// requests that perform redirects.
|
|
TEST(SchemeHandlerTest, CustomStandardFetchDifferentOriginRedirect) {
|
|
RegisterTestScheme("customstdfetch", "test1");
|
|
RegisterTestScheme("customstdfetch", "test2");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "customstdfetch://test1/run.html";
|
|
settings.sub_url = "customstdfetch://test2/fetch.html";
|
|
settings.sub_redirect_url = "customstdfetch://test1/fetch.html";
|
|
SetUpFetch(settings);
|
|
|
|
g_TestResults.console_messages.push_back(
|
|
"Access to fetch at 'customstdfetch://test2/fetch.html' (redirected from "
|
|
"'customstdfetch://test1/fetch.html') from origin "
|
|
"'customstdfetch://test1' has been blocked by CORS policy: No "
|
|
"'Access-Control-Allow-Origin' header is present on the requested "
|
|
"resource. If an opaque response serves your needs, set the request's "
|
|
"mode to 'no-cors' to fetch the resource with CORS disabled.");
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_redirect);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_FALSE(g_TestResults.got_sub_read);
|
|
EXPECT_FALSE(g_TestResults.got_sub_success);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate cross-domain XHR requests
|
|
// that perform redirects when using the cross-origin whitelist.
|
|
TEST(SchemeHandlerTest,
|
|
CustomStandardXHRDifferentOriginRedirectWithWhitelistSync) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
settings.sub_redirect_url = "customstd://test1/xhr.html";
|
|
SetUpXHR(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
|
|
"test2", false));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_redirect);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate cross-domain XHR requests
|
|
// that perform redirects when using the cross-origin whitelist.
|
|
TEST(SchemeHandlerTest,
|
|
CustomStandardXHRDifferentOriginRedirectWithWhitelistAsync1) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
settings.sub_redirect_url = "customstd://test1/xhr.html";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
|
|
"test2", false));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_redirect);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Same as above but origin whitelist matches any domain.
|
|
TEST(SchemeHandlerTest,
|
|
CustomStandardXHRDifferentOriginRedirectWithWhitelistAsync2) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "test2");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://test2/xhr.html";
|
|
settings.sub_redirect_url = "customstd://test1/xhr.html";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
|
|
CefString(), true));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_redirect);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Same as above but origin whitelist matches sub-domains.
|
|
TEST(SchemeHandlerTest,
|
|
CustomStandardXHRDifferentOriginRedirectWithWhitelistAsync3) {
|
|
RegisterTestScheme("customstd", "test1");
|
|
RegisterTestScheme("customstd", "a.test2.foo");
|
|
|
|
XHRTestSettings settings;
|
|
settings.url = "customstd://test1/run.html";
|
|
settings.sub_url = "customstd://a.test2.foo/xhr.html";
|
|
settings.sub_redirect_url = "customstd://test1/xhr.html";
|
|
settings.synchronous = false;
|
|
SetUpXHR(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
|
|
"test2.foo", true));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_redirect);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test that a custom standard scheme can generate cross-domain Fetch requests
|
|
// that perform redirects when using the cross-origin whitelist.
|
|
TEST(SchemeHandlerTest,
|
|
CustomStandardFetchDifferentOriginRedirectWithWhitelist1) {
|
|
RegisterTestScheme("customstdfetch", "test1");
|
|
RegisterTestScheme("customstdfetch", "test2");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "customstdfetch://test1/run.html";
|
|
settings.sub_url = "customstdfetch://test2/fetch.html";
|
|
settings.sub_redirect_url = "customstdfetch://test1/fetch.html";
|
|
SetUpFetch(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry(
|
|
"customstdfetch://test1", "customstdfetch", "test2", false));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_redirect);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Same as above but origin whitelist matches any domain.
|
|
TEST(SchemeHandlerTest,
|
|
CustomStandardFetchDifferentOriginRedirectWithWhitelist2) {
|
|
RegisterTestScheme("customstdfetch", "test1");
|
|
RegisterTestScheme("customstdfetch", "test2");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "customstdfetch://test1/run.html";
|
|
settings.sub_url = "customstdfetch://test2/fetch.html";
|
|
settings.sub_redirect_url = "customstdfetch://test1/fetch.html";
|
|
SetUpFetch(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry(
|
|
"customstdfetch://test1", "customstdfetch", CefString(), true));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_redirect);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Same as above but origin whitelist matches sub-domains.
|
|
TEST(SchemeHandlerTest,
|
|
CustomStandardFetchDifferentOriginRedirectWithWhitelist3) {
|
|
RegisterTestScheme("customstdfetch", "test1");
|
|
RegisterTestScheme("customstdfetch", "a.test2.foo");
|
|
|
|
FetchTestSettings settings;
|
|
settings.url = "customstdfetch://test1/run.html";
|
|
settings.sub_url = "customstdfetch://a.test2.foo/fetch.html";
|
|
settings.sub_redirect_url = "customstdfetch://test1/fetch.html";
|
|
SetUpFetch(settings);
|
|
|
|
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry(
|
|
"customstdfetch://test1", "customstdfetch", "test2.foo", true));
|
|
WaitForUIThread();
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
EXPECT_TRUE(g_TestResults.got_sub_redirect);
|
|
EXPECT_TRUE(g_TestResults.got_sub_request);
|
|
EXPECT_TRUE(g_TestResults.got_sub_read);
|
|
EXPECT_TRUE(g_TestResults.got_sub_success);
|
|
|
|
EXPECT_TRUE(CefClearCrossOriginWhitelist());
|
|
WaitForUIThread();
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Test per-browser setting of Accept-Language.
|
|
TEST(SchemeHandlerTest, AcceptLanguage) {
|
|
RegisterTestScheme("customstd", "test");
|
|
g_TestResults.url = "customstd://test/run.html";
|
|
g_TestResults.html =
|
|
"<html><head></head><body><h1>Success!</h1></body></html>";
|
|
|
|
// Value that will be set via CefBrowserSettings.accept_language in
|
|
// PopulateBrowserSettings().
|
|
g_TestResults.accept_language = "uk";
|
|
|
|
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
|
|
handler->ExecuteTest();
|
|
ReleaseAndWaitForDestructor(handler);
|
|
|
|
EXPECT_TRUE(g_TestResults.got_request);
|
|
EXPECT_TRUE(g_TestResults.got_read);
|
|
EXPECT_TRUE(g_TestResults.got_output);
|
|
|
|
ClearTestSchemes();
|
|
}
|
|
|
|
// Entry point for registering custom schemes.
|
|
// Called from client_app_delegates.cc.
|
|
void RegisterSchemeHandlerCustomSchemes(
|
|
CefRawPtr<CefSchemeRegistrar> registrar) {
|
|
// Registering the custom standard schemes as secure because requests from
|
|
// non-secure origins to the loopback address will be blocked by
|
|
// https://chromestatus.com/feature/5436853517811712.
|
|
|
|
// Add a custom standard scheme.
|
|
registrar->AddCustomScheme("customstd", CEF_SCHEME_OPTION_STANDARD |
|
|
CEF_SCHEME_OPTION_SECURE |
|
|
CEF_SCHEME_OPTION_CORS_ENABLED);
|
|
// Also used in cors_unittest.cc.
|
|
registrar->AddCustomScheme(
|
|
"customstdfetch", CEF_SCHEME_OPTION_STANDARD | CEF_SCHEME_OPTION_SECURE |
|
|
CEF_SCHEME_OPTION_CORS_ENABLED |
|
|
CEF_SCHEME_OPTION_FETCH_ENABLED);
|
|
// Add a custom non-standard scheme.
|
|
registrar->AddCustomScheme("customnonstd", CEF_SCHEME_OPTION_NONE);
|
|
registrar->AddCustomScheme("customnonstdfetch",
|
|
CEF_SCHEME_OPTION_FETCH_ENABLED);
|
|
}
|
|
|
|
// Entry point for registering cookieable schemes.
|
|
// Called from client_app_delegates.cc.
|
|
void RegisterSchemeHandlerCookieableSchemes(
|
|
std::vector<std::string>& cookieable_schemes) {
|
|
cookieable_schemes.push_back("customstd");
|
|
// Also used in cors_unittest.cc.
|
|
cookieable_schemes.push_back("customstdfetch");
|
|
}
|