// 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_origin_whitelist.h" #include "include/cef_callback.h" #include "include/cef_runnable.h" #include "include/cef_scheme.h" #include "tests/unittests/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 sub_redirect_url; 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_redirect, 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: explicit 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 OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request) 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 (!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 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) { 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 void OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) OVERRIDE { test_results_->got_error.yes(); DestroyTest(); } protected: TestResults* test_results_; }; class ClientSchemeHandler : public CefResourceHandler { public: explicit ClientSchemeHandler(TestResults* tr) : test_results_(tr), offset_(0), is_sub_(false), has_delayed_(false) { } virtual 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; } if (handled) { if (test_results_->delay > 0) { // Continue after the delay. CefPostDelayedTask(TID_IO, NewCefRunnableMethod(callback.get(), &CefCallback::Continue), test_results_->delay); } else { // Continue immediately. callback->Continue(); } 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<CefCallback> 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<CefCallback> callback) { has_delayed_ = true; callback->Continue(); } TestResults* test_results_; size_t offset_; bool is_sub_; bool has_delayed_; IMPLEMENT_REFCOUNTING(ClientSchemeHandler); IMPLEMENT_LOCKING(ClientSchemeHandler); }; class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory { public: explicit ClientSchemeHandlerFactory(TestResults* tr) : test_results_(tr) { } virtual CefRefPtr<CefResourceHandler> Create( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, 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(); 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_status_code = 200; 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 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) {" " console.log('XMLHttpRequest failed with error ' + e);" " onResult('FAILURE');" "};" "xhr.send()"; } ss << "}" "</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"; } } // 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>"; 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, 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(); 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(); 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, CustomNonStandardXHRSameOriginSync) { RegisterTestScheme("customnonstd", std::string()); XHRTestSettings settings; settings.url = "customnonstd:some%20value"; settings.sub_url = "customnonstd:xhr%20value"; SetUpXHR(settings); 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, CustomNonStandardXHRSameOriginAsync) { RegisterTestScheme("customnonstd", std::string()); XHRTestSettings settings; settings.url = "customnonstd:some%20value"; settings.sub_url = "customnonstd:xhr%20value"; settings.synchronous = false; SetUpXHR(settings); 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. 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); 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 // 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); 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 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, HttpXHRDifferentOriginSync) { RegisterTestScheme("http", "test1"); RegisterTestScheme("http", "test2"); XHRTestSettings settings; settings.url = "http://test1/run.html"; settings.sub_url = "http://test2/xhr.html"; SetUpXHR(settings); 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, 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); 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"); SetUpXSS("http://test1/run.html", "http://test2/xss.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 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); } // 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); 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_redirect); 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 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); 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_redirect); 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 // that perform redirects when using the cross-origin whitelist. This is due to // an explicit check in SyncResourceHandler::OnRequestRedirected() and does not // represent ideal behavior. 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(); 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_FALSE(g_TestResults.got_sub_request); EXPECT_FALSE(g_TestResults.got_sub_read); EXPECT_FALSE(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. This is // because we add an "Access-Control-Allow-Origin" header internally in // CefResourceDispatcherHostDelegate::OnRequestRedirected() for the redirect // request. 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(); 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(); 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(); 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(); } // Entry point for registering custom schemes. // Called from client_app_delegates.cc. void RegisterSchemeHandlerCustomSchemes( CefRefPtr<CefSchemeRegistrar> registrar, std::vector<CefString>& cookiable_schemes) { // Add a custom standard scheme. registrar->AddCustomScheme("customstd", true, false, false); // Ad a custom non-standard scheme. registrar->AddCustomScheme("customnonstd", false, false, false); }