cef/tests/unittests/scheme_handler_unittest.cc

1012 lines
30 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 "include/cef_runnable.h"
#include "test_handler.h"
namespace {
class TestResults
{
public:
TestResults()
: status_code(0),
sub_status_code(0),
delay(0)
{
}
void reset()
{
url.clear();
html.clear();
status_code = 0;
redirect_url.clear();
sub_url.clear();
sub_html.clear();
sub_status_code = 0;
sub_allow_origin.clear();
exit_url.clear();
delay = 0;
got_request.reset();
got_read.reset();
got_output.reset();
got_redirect.reset();
got_error.reset();
got_sub_request.reset();
got_sub_read.reset();
got_sub_success.reset();
}
std::string url;
std::string html;
int status_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 exit_url;
// Delay for returning scheme handler results.
int delay;
TrackCallback
got_request,
got_read,
got_output,
got_redirect,
got_error,
got_sub_request,
got_sub_read,
got_sub_success;
};
// Current scheme handler object. Used when destroying the test from
// ClientSchemeHandler::ProcessRequest().
class TestSchemeHandler;
TestSchemeHandler* g_current_handler = NULL;
class TestSchemeHandler : public TestHandler
{
public:
TestSchemeHandler(TestResults* tr)
: test_results_(tr)
{
g_current_handler = this;
}
virtual void RunTest() OVERRIDE
{
CreateBrowser(test_results_->url);
}
// Necessary to make the method public in order to destroy the test from
// ClientSchemeHandler::ProcessRequest().
void DestroyTest()
{
TestHandler::DestroyTest();
}
virtual bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
NavType navType,
bool isRedirect) OVERRIDE
{
std::string newUrl = request->GetURL();
if (!test_results_->exit_url.empty() &&
newUrl.find(test_results_->exit_url) != std::string::npos) {
// XHR tests use an exit URL to destroy the test.
if (newUrl.find("SUCCESS") != std::string::npos)
test_results_->got_sub_success.yes();
DestroyTest();
return true;
}
if (isRedirect) {
test_results_->got_redirect.yes();
EXPECT_EQ(newUrl, test_results_->redirect_url);
// 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 false;
}
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) OVERRIDE
{
std::string url = frame->GetURL();
if (url == test_results_->url || test_results_->status_code != 200) {
if (test_results_->sub_url.empty()) {
// Test that the output is correct.
std::string output = frame->GetSource();
if (output == test_results_->html)
test_results_->got_output.yes();
} else {
test_results_->got_output.yes();
}
// Test that the status code is correct.
EXPECT_EQ(httpStatusCode, test_results_->status_code);
if (test_results_->sub_url.empty())
DestroyTest();
}
}
virtual bool OnLoadError(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
ErrorCode errorCode,
const CefString& failedUrl,
CefString& errorText) OVERRIDE
{
test_results_->got_error.yes();
DestroyTest();
return false;
}
protected:
TestResults* test_results_;
};
class ClientSchemeHandler : public CefSchemeHandler
{
public:
ClientSchemeHandler(TestResults* tr)
: test_results_(tr), offset_(0), is_sub_(false), has_delayed_(false) {}
virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefSchemeHandlerCallback> 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;
}
if (handled) {
if (test_results_->delay > 0) {
// Continue after the delay.
CefPostDelayedTask(TID_IO, NewCefRunnableMethod(callback.get(),
&CefSchemeHandlerCallback::HeadersAvailable), test_results_->delay);
} else {
// Continue immediately.
callback->HeadersAvailable();
}
return true;
}
// Response was canceled.
if (g_current_handler)
g_current_handler->DestroyTest();
return false;
}
virtual 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 {
response->SetStatus(test_results_->status_code);
if (!test_results_->html.empty()) {
response->SetMimeType("text/html");
response_length = test_results_->html.size();
}
}
}
virtual void Cancel() OVERRIDE
{
EXPECT_TRUE(CefCurrentlyOn(TID_IO));
}
virtual bool ReadResponse(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefSchemeHandlerCallback> callback)
OVERRIDE
{
EXPECT_TRUE(CefCurrentlyOn(TID_IO));
if (test_results_->delay > 0) {
if (!has_delayed_) {
// Continue after a delay.
CefPostDelayedTask(TID_IO,
NewCefRunnableMethod(this,
&ClientSchemeHandler::ContinueAfterDelay, 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;
AutoLock lock_scope(this);
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<CefSchemeHandlerCallback> callback)
{
has_delayed_ = true;
callback->BytesAvailable();
}
TestResults* test_results_;
size_t offset_;
bool is_sub_;
bool has_delayed_;
IMPLEMENT_REFCOUNTING(ClientSchemeHandler);
IMPLEMENT_LOCKING(ClientSchemeHandler);
};
class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory
{
public:
ClientSchemeHandlerFactory(TestResults* tr)
: test_results_(tr){}
virtual CefRefPtr<CefSchemeHandler> Create(CefRefPtr<CefBrowser> browser,
const CefString& scheme_name,
CefRefPtr<CefRequest> request)
OVERRIDE
{
EXPECT_TRUE(CefCurrentlyOn(TID_IO));
return new ClientSchemeHandler(test_results_);
}
TestResults* test_results_;
IMPLEMENT_REFCOUNTING(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();
static std::set<std::string> schemes;
if (schemes.empty()) {
// Never register built-in schemes.
schemes.insert("http");
}
// Only register custom schemes one time.
if (schemes.find(scheme) == schemes.end()) {
EXPECT_TRUE(CefRegisterCustomScheme(scheme, domain.empty()?false:true,
false, false));
WaitForUIThread();
schemes.insert(scheme);
}
EXPECT_TRUE(CefRegisterSchemeHandlerFactory(scheme, domain,
new ClientSchemeHandlerFactory(&g_TestResults)));
WaitForIOThread();
}
void ClearTestSchemes()
{
EXPECT_TRUE(CefClearSchemeHandlerFactories());
WaitForIOThread();
}
void SetUpXHR(const std::string& url, const std::string& sub_url,
const std::string& sub_allow_origin = std::string())
{
g_TestResults.sub_url = sub_url;
g_TestResults.sub_html = "SUCCESS";
g_TestResults.sub_status_code = 200;
g_TestResults.sub_allow_origin = sub_allow_origin;
g_TestResults.url = url;
std::stringstream ss;
ss << "<html><head>\
<script language=\"JavaScript\">\
function execXMLHttpRequest() {\
var result = 'FAILURE';\
try {\
xhr = new XMLHttpRequest();\
xhr.open(\"GET\", \"" << sub_url.c_str() << "\", false);\
xhr.send();\
result = xhr.responseText;\
} catch(e) {}\
document.location = \"http://tests/exit?result=\"+result;\
}\
</script>\
</head><body onload=\"execXMLHttpRequest();\">\
Running execXMLHttpRequest...\
</body></html>";
g_TestResults.html = ss.str();
g_TestResults.status_code = 200;
g_TestResults.exit_url = "http://tests/exit";
}
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 |xss_url|.
// 3. |xss_url| tries to call a JS function in |url|.
// 4. |url| tries to call a JS function in |xss_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) {}\
document.location = \"http://tests/exit?result=\"+result;\
}\
</script>\
</head><body onload=\"execXSSRequest();\">\
Running execXSSRequest...\
</body></html>";
g_TestResults.sub_html = ss.str();
g_TestResults.sub_status_code = 200;
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) {}\
return 'FAILURE';\
}\
</script>\
</head><body>\
<iframe src=\"" << sub_url.c_str() << "\" id=\"s\">\
</body></html>";
g_TestResults.html = ss.str();
g_TestResults.status_code = 200;
g_TestResults.exit_url = "http://tests/exit";
}
} // anonymous
// 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>";
g_TestResults.status_code = 200;
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", NULL));
WaitForIOThread();
g_TestResults.got_request.reset();
g_TestResults.got_read.reset();
g_TestResults.got_output.reset();
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();
handler->ExecuteTest();
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>";
g_TestResults.status_code = 200;
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);
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.status_code = 200;
g_TestResults.delay = 100;
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);
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>";
g_TestResults.status_code = 200;
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);
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();
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 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();
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";
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
handler->ExecuteTest();
EXPECT_FALSE(g_TestResults.got_request);
EXPECT_FALSE(g_TestResults.got_read);
EXPECT_FALSE(g_TestResults.got_output);
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";
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
handler->ExecuteTest();
EXPECT_FALSE(g_TestResults.got_request);
EXPECT_FALSE(g_TestResults.got_read);
EXPECT_FALSE(g_TestResults.got_output);
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";
CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
handler->ExecuteTest();
EXPECT_FALSE(g_TestResults.got_request);
EXPECT_FALSE(g_TestResults.got_read);
EXPECT_FALSE(g_TestResults.got_output);
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();
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();
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();
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();
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, CustomStandardXHRSameOrigin)
{
RegisterTestScheme("customstd", "test");
SetUpXHR("customstd://test/run.html",
"customstd://test/xhr.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);
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 nonstandard scheme can generate same origin XHR requests.
TEST(SchemeHandlerTest, CustomNonStandardXHRSameOrigin)
{
RegisterTestScheme("customnonstd", std::string());
SetUpXHR("customnonstd:some%20value",
"customnonstd:xhr%20value");
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);
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 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();
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 nonstandard scheme can generate same origin XSS requests.
TEST(SchemeHandlerTest, CustomNonStandardXSSSameOrigin)
{
RegisterTestScheme("customnonstd", std::string());
SetUpXSS("customnonstd:some%20value",
"customnonstd:xhr%20value");
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);
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
// by default.
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOrigin)
{
RegisterTestScheme("customstd", "test1");
RegisterTestScheme("customstd", "test2");
SetUpXHR("customstd://test1/run.html",
"customstd://test2/xhr.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);
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 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");
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);
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, HttpXHRDifferentOrigin)
{
RegisterTestScheme("http", "test1");
RegisterTestScheme("http", "test2");
SetUpXHR("http://test1/run.html",
"http://test2/xhr.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);
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 XSS requests by
// default.
TEST(SchemeHandlerTest, HttpXSSDifferentOrigin)
{
RegisterTestScheme("http", "test1");
RegisterTestScheme("http", "test2");
SetUpXHR("http://test1/run.html",
"http://test2/xhr.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);
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
// even when setting the Access-Control-Allow-Origin header.
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithHeader)
{
RegisterTestScheme("customstd", "test1");
RegisterTestScheme("customstd", "test2");
SetUpXHR("customstd://test1/run.html",
"customstd://test2/xhr.html",
"customstd://test1");
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);
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 cross-domain XHR requests
// when using the cross-origin whitelist.
TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelist)
{
RegisterTestScheme("customstd", "test1");
RegisterTestScheme("customstd", "test2");
SetUpXHR("customstd://test1/run.html",
"customstd://test2/xhr.html");
EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
"test2", false));
WaitForUIThread();
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);
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, HttpXHRDifferentOriginWithHeader)
{
RegisterTestScheme("http", "test1");
RegisterTestScheme("http", "test2");
SetUpXHR("http://test1/run.html",
"http://test2/xhr.html",
"http://test1");
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);
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");
RegisterTestScheme("customstd", "b.test");
SetUpXSS("customstd://a.test/run.html",
"customstd://b.test/iframe.html",
"test");
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);
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");
RegisterTestScheme("http", "b.test");
SetUpXSS("http://a.test/run.html",
"http://b.test/iframe.html",
"test");
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);
EXPECT_TRUE(g_TestResults.got_sub_request);
EXPECT_TRUE(g_TestResults.got_sub_read);
EXPECT_TRUE(g_TestResults.got_sub_success);
ClearTestSchemes();
}