cef/tests/ceftests/urlrequest_unittest.cc

3126 lines
106 KiB
C++
Raw Normal View History

// Copyright (c) 2012 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 <map>
#include <memory>
#include <sstream>
#include "include/base/cef_callback.h"
#include "include/cef_parser.h"
Implement NetworkService request interception/handling (see issue #2622). Implementation notes: - Chromium change: CookieMonster::SetCookieableSchemes needs to be called immediately after the CookieMonster is created in NetworkContext:: ApplyContextParamsToBuilder. Add a Profile::GetCookieableSchemes method and NetworkContextParams.cookieable_schemes member (set from ProfileNetworkContextService::CreateNetworkContextParams) to support that. - Chromium change: Add a ContentBrowserClient::HandleExternalProtocol variant that exposes additional NetworkService request information. - GetResourceResponseFilter is not yet implemented. API changes: - Resource-related callbacks have been moved from CefRequestHandler to a new CefResourceRequestHandler interface which is returned via the GetResourceRequestHandler method. If the CefRequestHandler declines to handle a resource it can optionally be handled by the CefRequestContextHandler, if any, associated with the loading context. - The OnProtocolExecution callback has been moved from CefRequestHandler to CefResourceRequestHandler and will be called if a custom scheme request is unhandled. - Cookie send/save permission callbacks have been moved from CefRequestHandler and CefResourceHandler to CefResourceRequestHandler. - New methods added to CefResourceHandler that better match NetworkService execution sequence expectations. The old methods are now deprecated. - New methods added to CefRequest and CefResponse. Known behavior changes with the NetworkService implementation: - Modifying the |new_url| parameter in OnResourceRedirect will no longer result in the method being called an additional time (likely a bug in the old implementation). - Modifying the request URL in OnResourceResponse would previously cause a redirect. This behavior is now deprecated because the NetworkService does not support this functionality when using default network loaders. Temporary support has been added in combination with CefResourceHandler usage only. - Other changes to the request object in OnResourceResponse will now cause the request to be restarted. This means that OnBeforeResourceLoad, etc, will be called an additional time with the new request information. - CefResponse::GetMimeType will now be empty for non-200 responses. - Requests using custom schemes can now be handled via CefResourceRequestHandler with the same callback behavior as builtin schemes. - Redirects of custom scheme requests will now be followed as expected. - Default handling of builtin schemes can now be disabled by setting |disable_default_handling| to true in GetResourceRequestHandler. - Unhandled requests (custom scheme or builtin scheme with default handling disabled) will fail with an CefResponse::GetError value of ERR_UNKNOWN_URL_SCHEME. - The CefSchemeHandlerFactory::Create callback will now include cookie headers. To test: - Run `cefclient --enable-network-service`. All resources should load successfully (this tests the transparent proxy capability). - All tests pass with NetworkService disabled. - The following tests pass with NetworkService enabled: - CookieTest.* - FrameTest.* (excluding .*Nav) - NavigationTest.* (excluding .Redirect*) - RequestHandlerTest.* - RequestContextTest.Basic* - RequestContextTest.Popup* - RequestTest.* - ResourceManagerTest.* - ResourceRequestHandlerTest.* (excluding .Filter*) - SchemeHandlerTest.* - StreamResourceHandlerTest.*
2019-04-24 04:50:25 +02:00
#include "include/cef_request_context_handler.h"
Introduce the use of Chromium types (issue #1336). Changes to the CEF public API: - Add base::Bind, base::Callback, base::Lock, base::WeakPtr, scoped_refptr, scoped_ptr and supporting types. - Add include/wrapper/cef_closure_task.h helpers for converting a base::Closure to a CefTask. - Change CefRefPtr to extend scoped_refptr. -- Change CefBase method signatures to match RefCountedThreadSafeBase. - Change IMPLEMENT_REFCOUNTING to use base::AtomicRefCount*. -- Remove the CefAtomic* functions. -- IMPLEMENT_REFCOUNTING now enforces via a compile-time error that the correct class name was passed to the macro. - Change IMPLEMENT_LOCKING to use base::Lock. -- Remove the CefCriticalSection class. -- Deprecate the IMPLEMENT_LOCKING macro. -- base::Lock will DCHECK() in Debug builds if lock usage is reentrant. - Move include/internal/cef_tuple.h to include/base/cef_tuple.h. - Allow an empty |callback| parameter passed to CefBeginTracing. Changes to the CEF implementation: - Fix incorrect names passed to the IMPLEMENT_REFCOUNTING macro. - Fix instances of reentrant locking in the CefXmlObject and CefRequest implementations. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cef_unittests: - Add tests/unittests/chromium_includes.h and always include it first from unit test .cc files to avoid name conflicts with Chromium types. - Fix wrong header include ordering. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cefclient and cefsimple: - Use base::Bind and cef_closure_task.h instead of NewCefRunnable*. - Remove use of the IMPEMENT_LOCKING macro. - Fix incorrect/unnecessary locking. - Add additional runtime thread checks. - Windows: Perform actions on the UI thread instead of the main thread when running in multi-threaded-message-loop mode to avoid excessive locking. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1769 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2014-07-15 00:18:51 +02:00
#include "include/cef_scheme.h"
#include "include/cef_server.h"
Introduce the use of Chromium types (issue #1336). Changes to the CEF public API: - Add base::Bind, base::Callback, base::Lock, base::WeakPtr, scoped_refptr, scoped_ptr and supporting types. - Add include/wrapper/cef_closure_task.h helpers for converting a base::Closure to a CefTask. - Change CefRefPtr to extend scoped_refptr. -- Change CefBase method signatures to match RefCountedThreadSafeBase. - Change IMPLEMENT_REFCOUNTING to use base::AtomicRefCount*. -- Remove the CefAtomic* functions. -- IMPLEMENT_REFCOUNTING now enforces via a compile-time error that the correct class name was passed to the macro. - Change IMPLEMENT_LOCKING to use base::Lock. -- Remove the CefCriticalSection class. -- Deprecate the IMPLEMENT_LOCKING macro. -- base::Lock will DCHECK() in Debug builds if lock usage is reentrant. - Move include/internal/cef_tuple.h to include/base/cef_tuple.h. - Allow an empty |callback| parameter passed to CefBeginTracing. Changes to the CEF implementation: - Fix incorrect names passed to the IMPLEMENT_REFCOUNTING macro. - Fix instances of reentrant locking in the CefXmlObject and CefRequest implementations. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cef_unittests: - Add tests/unittests/chromium_includes.h and always include it first from unit test .cc files to avoid name conflicts with Chromium types. - Fix wrong header include ordering. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cefclient and cefsimple: - Use base::Bind and cef_closure_task.h instead of NewCefRunnable*. - Remove use of the IMPEMENT_LOCKING macro. - Fix incorrect/unnecessary locking. - Add additional runtime thread checks. - Windows: Perform actions on the UI thread instead of the main thread when running in multi-threaded-message-loop mode to avoid excessive locking. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1769 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2014-07-15 00:18:51 +02:00
#include "include/cef_task.h"
#include "include/cef_urlrequest.h"
#include "include/cef_waitable_event.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_scoped_temp_dir.h"
#include "tests/ceftests/test_handler.h"
#include "tests/ceftests/test_request.h"
#include "tests/ceftests/test_server_observer.h"
#include "tests/ceftests/test_suite.h"
#include "tests/ceftests/test_util.h"
#include "tests/gtest/include/gtest/gtest.h"
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
#include "tests/shared/browser/client_app_browser.h"
#include "tests/shared/browser/file_util.h"
#include "tests/shared/common/string_util.h"
// How to add a new test:
// 1. Add a new value to the RequestTestMode enumeration.
// 2. Add methods to set up and run the test in RequestTestRunner.
// 3. Add a line for the test in the RequestTestRunner constructor.
// 4. Add lines for the test in the "Define the tests" section at the bottom of
// the file.
namespace {
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
// Browser-side app delegate.
class URLRequestBrowserTest : public client::ClientAppBrowser::Delegate {
public:
URLRequestBrowserTest() = default;
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
void OnBeforeCommandLineProcessing(
CefRefPtr<client::ClientAppBrowser> app,
CefRefPtr<CefCommandLine> command_line) override {
// Delegate auth callbacks to GetAuthCredentials with the chrome runtime.
command_line->AppendSwitch("disable-chrome-login-prompt");
// Disable component extensions that require creation of a background
// WebContents because they slow down test runs.
command_line->AppendSwitch(
"disable-component-extensions-with-background-pages");
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
}
private:
IMPLEMENT_REFCOUNTING(URLRequestBrowserTest);
};
// TEST DATA
// Custom scheme handler backend.
const char kRequestSchemeCustom[] = "urcustom";
const char kRequestHostCustom[] = "test";
// Server backend.
const char* kRequestAddressServer = test_server::kHttpServerAddress;
const uint16_t kRequestPortServer = test_server::kHttpServerPort;
const char kRequestSchemeServer[] = "http";
const char kRequestSendCookieName[] = "urcookie_send";
const char kRequestSaveCookieName[] = "urcookie_save";
const char kCacheControlHeader[] = "cache-control";
enum RequestTestMode {
REQTEST_GET = 0,
REQTEST_GET_NODATA,
REQTEST_GET_PARTIAL_CONTENT,
REQTEST_GET_ALLOWCOOKIES,
REQTEST_GET_REDIRECT,
REQTEST_GET_REDIRECT_STOP,
REQTEST_GET_REDIRECT_LOCATION,
REQTEST_GET_REFERRER,
REQTEST_GET_AUTH,
REQTEST_POST,
REQTEST_POST_FILE,
REQTEST_POST_WITHPROGRESS,
REQTEST_POST_REDIRECT,
REQTEST_POST_REDIRECT_TOGET,
REQTEST_HEAD,
REQTEST_CACHE_WITH_CONTROL,
REQTEST_CACHE_WITHOUT_CONTROL,
REQTEST_CACHE_SKIP_FLAG,
REQTEST_CACHE_SKIP_HEADER,
REQTEST_CACHE_ONLY_FAILURE_FLAG,
REQTEST_CACHE_ONLY_FAILURE_HEADER,
REQTEST_CACHE_ONLY_SUCCESS_FLAG,
REQTEST_CACHE_ONLY_SUCCESS_HEADER,
REQTEST_CACHE_DISABLE_FLAG,
REQTEST_CACHE_DISABLE_HEADER,
REQTEST_INCOMPLETE_PROCESS_REQUEST,
REQTEST_INCOMPLETE_READ_RESPONSE,
};
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
enum ContextTestMode {
CONTEXT_GLOBAL,
CONTEXT_INMEMORY,
CONTEXT_ONDISK,
};
// Defines test expectations for a request.
struct RequestRunSettings {
RequestRunSettings() = default;
// Set expectations for request failure.
void SetRequestFailureExpected(cef_errorcode_t error_code) {
expect_upload_progress = false;
expect_download_progress = false;
expect_download_data = false;
expected_status = UR_FAILED;
expected_error_code = error_code;
response = nullptr;
response_data.clear();
}
// Request that will be sent.
CefRefPtr<CefRequest> request;
// Response that will be returned by the backend.
CefRefPtr<CefResponse> response;
// Optional response data that will be returned by the backend.
std::string response_data;
// Create an incomplete request to test shutdown behavior.
enum IncompleteType {
INCOMPLETE_NONE,
INCOMPLETE_PROCESS_REQUEST,
INCOMPLETE_READ_RESPONSE,
};
IncompleteType incomplete_type = INCOMPLETE_NONE;
// If true upload progress notification will be expected.
bool expect_upload_progress = false;
// If true download progress notification will be expected.
bool expect_download_progress = true;
// If true download data will be expected.
bool expect_download_data = true;
// The offset from what we passed that we expect to receive.
size_t expected_download_offset = 0;
// Expected status value.
CefURLRequest::Status expected_status = UR_SUCCESS;
// Expected error code value.
CefURLRequest::ErrorCode expected_error_code = ERR_NONE;
// If true the request cookie should be sent to the server.
bool expect_send_cookie = false;
// If true the response cookie should be saved.
bool expect_save_cookie = false;
// If true the test will begin by requiring Basic authentication and then
// continue with the actual request. The UR_FLAG_ALLOW_STORED_CREDENTIALS
// flag must be set on the request. When using the global request context
// CefRequestContext::ClearHttpAuthCredentials should be called to avoid
// leaking state across test runs. Authentication is only supported with
// browser-initiated requests and the server backend.
bool expect_authentication = false;
std::string username;
std::string password;
// If specified the test will begin with this redirect request and response.
CefRefPtr<CefRequest> redirect_request;
CefRefPtr<CefResponse> redirect_response;
// If true the redirect is expected to be followed.
bool expect_follow_redirect = true;
// If true the response is expected to be served from cache.
bool expect_response_was_cached = false;
// The expected number of requests to send, or -1 if unspecified.
// Used only with the server backend.
int expected_send_count = -1;
// The expected number of requests to receive, or -1 if unspecified.
// Used only with the server backend.
int expected_receive_count = -1;
using NextRequestCallback =
base::OnceCallback<void(int /* next_send_count */,
base::OnceClosure /* complete_callback */)>;
// If non-null this callback will be executed before subsequent requests are
// sent.
NextRequestCallback setup_next_request;
};
// Manages the map of request URL to test expectations.
class RequestDataMap {
public:
struct Entry {
enum Type {
TYPE_UNKNOWN,
TYPE_NORMAL,
TYPE_REDIRECT,
};
explicit Entry(Type entry_type) : type(entry_type) {}
Type type;
// Used with TYPE_NORMAL.
// |settings| is not owned by this object.
RequestRunSettings* settings = nullptr;
// Used with TYPE_REDIRECT.
CefRefPtr<CefRequest> redirect_request;
CefRefPtr<CefResponse> redirect_response;
};
RequestDataMap() : owner_task_runner_(CefTaskRunner::GetForCurrentThread()) {}
// Pass ownership to the specified |task_runner| thread.
// If |task_runner| is nullptr the test is considered destroyed.
void SetOwnerTaskRunner(CefRefPtr<CefTaskRunner> task_runner) {
EXPECT_TRUE(owner_task_runner_->BelongsToCurrentThread());
owner_task_runner_ = task_runner;
}
void AddSchemeHandler(RequestRunSettings* settings) {
EXPECT_TRUE(settings);
EXPECT_TRUE(owner_task_runner_->BelongsToCurrentThread());
const std::string& url = settings->request->GetURL();
data_map_.insert(std::make_pair(url, settings));
if (settings->redirect_request) {
const std::string& redirect_url = settings->redirect_request->GetURL();
redirect_data_map_.insert(std::make_pair(
redirect_url, std::make_pair(settings->redirect_request,
settings->redirect_response)));
}
}
Entry Find(const std::string& url) {
EXPECT_TRUE(owner_task_runner_->BelongsToCurrentThread());
Entry entry(Entry::TYPE_UNKNOWN);
// Try to find a test match.
{
DataMap::const_iterator it = data_map_.find(url);
if (it != data_map_.end()) {
entry.type = Entry::TYPE_NORMAL;
entry.settings = it->second;
return entry;
}
}
// Try to find a redirect match.
{
RedirectDataMap::const_iterator it = redirect_data_map_.find(url);
if (it != redirect_data_map_.end()) {
entry.type = Entry::TYPE_REDIRECT;
entry.redirect_request = it->second.first;
entry.redirect_response = it->second.second;
return entry;
}
}
// Unknown test.
ADD_FAILURE() << "url: " << url;
return entry;
}
size_t size() const { return data_map_.size() + redirect_data_map_.size(); }
private:
CefRefPtr<CefTaskRunner> owner_task_runner_;
// The below members are only accessed on the |owner_task_runner_| thread.
// RequestRunSettings pointer is not owned by this object.
typedef std::map<std::string, RequestRunSettings*> DataMap;
DataMap data_map_;
typedef std::map<std::string,
std::pair<CefRefPtr<CefRequest>, CefRefPtr<CefResponse>>>
RedirectDataMap;
RedirectDataMap redirect_data_map_;
};
class TestCompletionCallback : public CefCompletionCallback {
public:
explicit TestCompletionCallback(base::OnceClosure complete_callback)
: complete_callback_(std::move(complete_callback)) {
EXPECT_FALSE(complete_callback_.is_null());
}
void OnComplete() override { std::move(complete_callback_).Run(); }
private:
base::OnceClosure complete_callback_;
IMPLEMENT_REFCOUNTING(TestCompletionCallback);
};
std::string GetRequestScheme(bool server_backend) {
return server_backend ? kRequestSchemeServer : kRequestSchemeCustom;
}
std::string GetRequestHost(bool server_backend, bool with_port) {
if (server_backend) {
if (with_port) {
std::stringstream ss;
ss << kRequestAddressServer << ":" << kRequestPortServer;
return ss.str();
} else {
return kRequestAddressServer;
}
} else {
return kRequestHostCustom;
}
}
std::string GetRequestOrigin(bool server_backend) {
return GetRequestScheme(server_backend) + "://" +
GetRequestHost(server_backend, true);
}
void SetUploadData(CefRefPtr<CefRequest> request, const std::string& data) {
CefRefPtr<CefPostData> postData = CefPostData::Create();
CefRefPtr<CefPostDataElement> element = CefPostDataElement::Create();
element->SetToBytes(data.size(), data.c_str());
postData->AddElement(element);
request->SetPostData(postData);
}
void SetUploadFile(CefRefPtr<CefRequest> request, const std::string& file) {
CefRefPtr<CefPostData> postData = CefPostData::Create();
CefRefPtr<CefPostDataElement> element = CefPostDataElement::Create();
element->SetToFile(file);
postData->AddElement(element);
request->SetPostData(postData);
}
void GetUploadData(CefRefPtr<CefRequest> request, std::string& data) {
CefRefPtr<CefPostData> postData = request->GetPostData();
EXPECT_TRUE(postData.get());
CefPostData::ElementVector elements;
postData->GetElements(elements);
EXPECT_EQ((size_t)1, elements.size());
CefRefPtr<CefPostDataElement> element = elements[0];
EXPECT_TRUE(element.get());
size_t size = element->GetBytesCount();
data.resize(size);
EXPECT_EQ(size, data.size());
EXPECT_EQ(size, element->GetBytes(size, const_cast<char*>(data.c_str())));
}
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
// Set a cookie so that we can test if it's sent with the request.
void SetTestCookie(CefRefPtr<CefRequestContext> request_context,
bool server_backend,
base::OnceClosure callback) {
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
class Callback : public CefSetCookieCallback {
public:
explicit Callback(base::OnceClosure callback)
: callback_(std::move(callback)) {
EXPECT_FALSE(callback_.is_null());
}
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
void OnComplete(bool success) override {
EXPECT_TRUE(success);
std::move(callback_).Run();
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
}
private:
base::OnceClosure callback_;
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
IMPLEMENT_REFCOUNTING(Callback);
};
CefCookie cookie;
CefString(&cookie.name) = kRequestSendCookieName;
CefString(&cookie.value) = "send-cookie-value";
CefString(&cookie.domain) = GetRequestHost(server_backend, false);
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
CefString(&cookie.path) = "/";
cookie.has_expires = false;
EXPECT_TRUE(request_context->GetCookieManager(nullptr)->SetCookie(
GetRequestOrigin(server_backend), cookie,
new Callback(std::move(callback))));
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
}
using GetTestCookieCallback =
base::OnceCallback<void(bool /* cookie exists */)>;
// Tests if the save cookie has been set. If set, it will be deleted at the same
// time.
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
void GetTestCookie(CefRefPtr<CefRequestContext> request_context,
bool server_backend,
GetTestCookieCallback callback) {
class Visitor : public CefCookieVisitor {
public:
explicit Visitor(GetTestCookieCallback callback)
: callback_(std::move(callback)) {
EXPECT_FALSE(callback_.is_null());
}
~Visitor() override { std::move(callback_).Run(cookie_exists_); }
bool Visit(const CefCookie& cookie,
int count,
int total,
bool& deleteCookie) override {
std::string cookie_name = CefString(&cookie.name);
if (cookie_name == kRequestSaveCookieName) {
cookie_exists_ = true;
deleteCookie = true;
return false;
}
return true;
}
private:
GetTestCookieCallback callback_;
bool cookie_exists_ = false;
IMPLEMENT_REFCOUNTING(Visitor);
};
CefRefPtr<CefCookieManager> cookie_manager =
request_context->GetCookieManager(nullptr);
cookie_manager->VisitUrlCookies(GetRequestOrigin(server_backend), true,
new Visitor(std::move(callback)));
}
std::string GetHeaderValue(const CefRequest::HeaderMap& header_map,
const std::string& header_name_lower) {
CefRequest::HeaderMap::const_iterator it = header_map.begin();
for (; it != header_map.end(); ++it) {
std::string name = client::AsciiStrToLower(it->first);
2023-01-02 23:59:03 +01:00
if (name == header_name_lower) {
return it->second;
2023-01-02 23:59:03 +01:00
}
}
return std::string();
}
// Verify normal request expectations.
void VerifyNormalRequest(const RequestRunSettings* settings,
CefRefPtr<CefRequest> request,
bool server_backend) {
// Shouldn't get here if we're not following redirects.
EXPECT_TRUE(settings->expect_follow_redirect);
// Verify that the request was sent correctly.
TestRequestEqual(settings->request, request, true);
CefRequest::HeaderMap headerMap;
request->GetHeaderMap(headerMap);
// Check if the default headers were sent.
EXPECT_FALSE(GetHeaderValue(headerMap, "user-agent").empty());
// 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",
GetHeaderValue(headerMap, "accept-language").c_str());
if (server_backend) {
EXPECT_FALSE(GetHeaderValue(headerMap, "accept-encoding").empty());
EXPECT_STREQ(GetRequestHost(true, true).c_str(),
GetHeaderValue(headerMap, "host").c_str());
}
// Check if the request cookie was sent.
const std::string& cookie_value = GetHeaderValue(headerMap, "cookie");
bool has_send_cookie = false;
if (!cookie_value.empty() &&
cookie_value.find(kRequestSendCookieName) != std::string::npos) {
has_send_cookie = true;
}
EXPECT_EQ(settings->expect_send_cookie, has_send_cookie);
}
// Populate normal response contents.
void GetNormalResponse(const RequestRunSettings* settings,
CefRefPtr<CefResponse> response) {
EXPECT_TRUE(settings->response);
2023-01-02 23:59:03 +01:00
if (!settings->response) {
return;
2023-01-02 23:59:03 +01:00
}
response->SetStatus(settings->response->GetStatus());
response->SetStatusText(settings->response->GetStatusText());
response->SetMimeType(settings->response->GetMimeType());
CefResponse::HeaderMap headerMap;
settings->response->GetHeaderMap(headerMap);
if (settings->expect_save_cookie) {
std::stringstream ss;
ss << kRequestSaveCookieName << "=" << "save-cookie-value";
headerMap.insert(std::make_pair("Set-Cookie", ss.str()));
}
response->SetHeaderMap(headerMap);
}
// Based on https://en.wikipedia.org/wiki/Basic_access_authentication#Protocol
void GetAuthResponse(CefRefPtr<CefResponse> response) {
response->SetStatus(401);
response->SetStatusText("Unauthorized");
response->SetMimeType("text/html");
CefResponse::HeaderMap headerMap;
headerMap.insert(
std::make_pair("WWW-Authenticate", "Basic realm=\"Test Realm\""));
response->SetHeaderMap(headerMap);
}
bool IsAuthorized(CefRefPtr<CefRequest> request,
const std::string& username,
const std::string& password) {
const std::string& authHeader = request->GetHeaderByName("Authorization");
2023-01-02 23:59:03 +01:00
if (authHeader.empty()) {
return false;
2023-01-02 23:59:03 +01:00
}
if (authHeader.find("Basic ") == 0) {
const std::string& base64 = authHeader.substr(6);
CefRefPtr<CefBinaryValue> data = CefBase64Decode(base64);
EXPECT_TRUE(data);
if (!data) {
LOG(ERROR) << "Failed to decode Authorization value: " << base64;
return false;
}
std::string decoded;
decoded.resize(data->GetSize());
data->GetData(&decoded[0], data->GetSize(), 0);
const std::string& expected = username + ":" + password;
EXPECT_STREQ(expected.c_str(), decoded.c_str());
return decoded == expected;
}
LOG(ERROR) << "Unexpected Authorization value: " << authHeader;
return false;
}
// SCHEME HANDLER BACKEND
// Serves request responses.
class RequestSchemeHandlerOld : public CefResourceHandler {
public:
RequestSchemeHandlerOld(RequestRunSettings* settings,
base::OnceClosure destroy_callback)
: settings_(settings), destroy_callback_(std::move(destroy_callback)) {}
~RequestSchemeHandlerOld() override {
EXPECT_EQ(1, cancel_ct_);
std::move(destroy_callback_).Run();
}
bool ProcessRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback) override {
EXPECT_IO_THREAD();
VerifyNormalRequest(settings_, request, false);
// HEAD requests are identical to GET requests except no response data is
// sent.
2023-01-02 23:59:03 +01:00
if (request->GetMethod() != "HEAD") {
response_data_ = settings_->response_data;
2023-01-02 23:59:03 +01:00
}
// Continue immediately.
callback->Continue();
return true;
}
void GetResponseHeaders(CefRefPtr<CefResponse> response,
int64_t& response_length,
CefString& redirectUrl) override {
EXPECT_IO_THREAD();
GetNormalResponse(settings_, response);
response_length = response_data_.length();
}
bool ReadResponse(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefCallback> callback) override {
EXPECT_IO_THREAD();
bool has_data = false;
bytes_read = 0;
size_t size = response_data_.length();
if (offset_ < size) {
int transfer_size =
std::min(bytes_to_read, static_cast<int>(size - offset_));
memcpy(data_out, response_data_.c_str() + offset_, transfer_size);
offset_ += transfer_size;
bytes_read = transfer_size;
has_data = true;
}
return has_data;
}
void Cancel() override {
EXPECT_IO_THREAD();
cancel_ct_++;
}
private:
// |settings_| is not owned by this object.
RequestRunSettings* settings_;
base::OnceClosure destroy_callback_;
std::string response_data_;
size_t offset_ = 0;
int cancel_ct_ = 0;
IMPLEMENT_REFCOUNTING(RequestSchemeHandlerOld);
DISALLOW_COPY_AND_ASSIGN(RequestSchemeHandlerOld);
};
class RequestSchemeHandler : public CefResourceHandler {
public:
RequestSchemeHandler(RequestRunSettings* settings,
base::OnceClosure destroy_callback)
: settings_(settings), destroy_callback_(std::move(destroy_callback)) {}
~RequestSchemeHandler() override {
EXPECT_EQ(1, cancel_ct_);
std::move(destroy_callback_).Run();
}
bool Open(CefRefPtr<CefRequest> request,
bool& handle_request,
CefRefPtr<CefCallback> callback) override {
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
VerifyNormalRequest(settings_, request, false);
// HEAD requests are identical to GET requests except no response data is
// sent.
2023-01-02 23:59:03 +01:00
if (request->GetMethod() != "HEAD") {
response_data_ = settings_->response_data;
2023-01-02 23:59:03 +01:00
}
// Continue immediately.
handle_request = true;
return true;
}
bool ProcessRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback) override {
EXPECT_TRUE(false); // Not reached.
return false;
}
void GetResponseHeaders(CefRefPtr<CefResponse> response,
int64_t& response_length,
CefString& redirectUrl) override {
EXPECT_IO_THREAD();
GetNormalResponse(settings_, response);
response_length = response_data_.length() - offset_;
}
bool Skip(int64_t bytes_to_skip,
int64_t& bytes_skipped,
CefRefPtr<CefResourceSkipCallback> callback) override {
size_t size = response_data_.length();
if (offset_ < size) {
bytes_skipped =
std::min(bytes_to_skip, static_cast<int64_t>(size - offset_));
offset_ += bytes_skipped;
} else {
bytes_skipped = ERR_FAILED;
}
return bytes_skipped > 0;
}
bool Read(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefResourceReadCallback> callback) override {
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
// Default to response complete.
bool has_data = false;
bytes_read = 0;
size_t size = response_data_.length();
if (offset_ < size) {
int transfer_size =
std::min(bytes_to_read, static_cast<int>(size - offset_));
memcpy(data_out, response_data_.c_str() + offset_, transfer_size);
offset_ += transfer_size;
bytes_read = transfer_size;
has_data = true;
}
return has_data;
}
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;
}
void Cancel() override {
EXPECT_IO_THREAD();
cancel_ct_++;
}
private:
// |settings_| is not owned by this object.
RequestRunSettings* settings_;
base::OnceClosure destroy_callback_;
std::string response_data_;
size_t offset_ = 0;
int cancel_ct_ = 0;
Introduce the use of Chromium types (issue #1336). Changes to the CEF public API: - Add base::Bind, base::Callback, base::Lock, base::WeakPtr, scoped_refptr, scoped_ptr and supporting types. - Add include/wrapper/cef_closure_task.h helpers for converting a base::Closure to a CefTask. - Change CefRefPtr to extend scoped_refptr. -- Change CefBase method signatures to match RefCountedThreadSafeBase. - Change IMPLEMENT_REFCOUNTING to use base::AtomicRefCount*. -- Remove the CefAtomic* functions. -- IMPLEMENT_REFCOUNTING now enforces via a compile-time error that the correct class name was passed to the macro. - Change IMPLEMENT_LOCKING to use base::Lock. -- Remove the CefCriticalSection class. -- Deprecate the IMPLEMENT_LOCKING macro. -- base::Lock will DCHECK() in Debug builds if lock usage is reentrant. - Move include/internal/cef_tuple.h to include/base/cef_tuple.h. - Allow an empty |callback| parameter passed to CefBeginTracing. Changes to the CEF implementation: - Fix incorrect names passed to the IMPLEMENT_REFCOUNTING macro. - Fix instances of reentrant locking in the CefXmlObject and CefRequest implementations. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cef_unittests: - Add tests/unittests/chromium_includes.h and always include it first from unit test .cc files to avoid name conflicts with Chromium types. - Fix wrong header include ordering. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cefclient and cefsimple: - Use base::Bind and cef_closure_task.h instead of NewCefRunnable*. - Remove use of the IMPEMENT_LOCKING macro. - Fix incorrect/unnecessary locking. - Add additional runtime thread checks. - Windows: Perform actions on the UI thread instead of the main thread when running in multi-threaded-message-loop mode to avoid excessive locking. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1769 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2014-07-15 00:18:51 +02:00
IMPLEMENT_REFCOUNTING(RequestSchemeHandler);
DISALLOW_COPY_AND_ASSIGN(RequestSchemeHandler);
};
// Serves redirect request responses.
class RequestRedirectSchemeHandlerOld : public CefResourceHandler {
public:
RequestRedirectSchemeHandlerOld(CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response,
base::OnceClosure destroy_callback)
: request_(request),
response_(response),
destroy_callback_(std::move(destroy_callback)) {}
~RequestRedirectSchemeHandlerOld() override {
EXPECT_EQ(1, cancel_ct_);
std::move(destroy_callback_).Run();
}
bool ProcessRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback) override {
EXPECT_IO_THREAD();
// Verify that the request was sent correctly.
TestRequestEqual(request_, request, true);
// Continue immediately.
callback->Continue();
return true;
}
void GetResponseHeaders(CefRefPtr<CefResponse> response,
int64_t& response_length,
CefString& redirectUrl) override {
EXPECT_IO_THREAD();
response->SetStatus(response_->GetStatus());
response->SetStatusText(response_->GetStatusText());
response->SetMimeType(response_->GetMimeType());
CefResponse::HeaderMap headerMap;
response_->GetHeaderMap(headerMap);
response->SetHeaderMap(headerMap);
response_length = 0;
}
bool ReadResponse(void* response_data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefCallback> callback) override {
EXPECT_IO_THREAD();
NOTREACHED();
return false;
}
void Cancel() override {
EXPECT_IO_THREAD();
cancel_ct_++;
}
private:
CefRefPtr<CefRequest> request_;
CefRefPtr<CefResponse> response_;
base::OnceClosure destroy_callback_;
int cancel_ct_ = 0;
IMPLEMENT_REFCOUNTING(RequestRedirectSchemeHandlerOld);
DISALLOW_COPY_AND_ASSIGN(RequestRedirectSchemeHandlerOld);
};
class RequestRedirectSchemeHandler : public CefResourceHandler {
public:
RequestRedirectSchemeHandler(CefRefPtr<CefRequest> request,
CefRefPtr<CefResponse> response,
base::OnceClosure destroy_callback)
: request_(request),
response_(response),
destroy_callback_(std::move(destroy_callback)) {}
~RequestRedirectSchemeHandler() override {
EXPECT_EQ(1, cancel_ct_);
std::move(destroy_callback_).Run();
}
bool Open(CefRefPtr<CefRequest> request,
bool& handle_request,
CefRefPtr<CefCallback> callback) override {
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
// Verify that the request was sent correctly.
TestRequestEqual(request_, request, true);
// Continue immediately.
handle_request = true;
return true;
}
bool ProcessRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback) override {
EXPECT_TRUE(false); // Not reached.
return false;
}
void GetResponseHeaders(CefRefPtr<CefResponse> response,
int64_t& response_length,
CefString& redirectUrl) override {
EXPECT_IO_THREAD();
response->SetStatus(response_->GetStatus());
response->SetStatusText(response_->GetStatusText());
response->SetMimeType(response_->GetMimeType());
CefResponse::HeaderMap headerMap;
response_->GetHeaderMap(headerMap);
response->SetHeaderMap(headerMap);
response_length = 0;
}
bool Read(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefResourceReadCallback> callback) override {
EXPECT_TRUE(false); // Not reached.
bytes_read = -1;
return false;
}
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;
}
void Cancel() override {
EXPECT_IO_THREAD();
cancel_ct_++;
}
private:
CefRefPtr<CefRequest> request_;
CefRefPtr<CefResponse> response_;
base::OnceClosure destroy_callback_;
int cancel_ct_ = 0;
Introduce the use of Chromium types (issue #1336). Changes to the CEF public API: - Add base::Bind, base::Callback, base::Lock, base::WeakPtr, scoped_refptr, scoped_ptr and supporting types. - Add include/wrapper/cef_closure_task.h helpers for converting a base::Closure to a CefTask. - Change CefRefPtr to extend scoped_refptr. -- Change CefBase method signatures to match RefCountedThreadSafeBase. - Change IMPLEMENT_REFCOUNTING to use base::AtomicRefCount*. -- Remove the CefAtomic* functions. -- IMPLEMENT_REFCOUNTING now enforces via a compile-time error that the correct class name was passed to the macro. - Change IMPLEMENT_LOCKING to use base::Lock. -- Remove the CefCriticalSection class. -- Deprecate the IMPLEMENT_LOCKING macro. -- base::Lock will DCHECK() in Debug builds if lock usage is reentrant. - Move include/internal/cef_tuple.h to include/base/cef_tuple.h. - Allow an empty |callback| parameter passed to CefBeginTracing. Changes to the CEF implementation: - Fix incorrect names passed to the IMPLEMENT_REFCOUNTING macro. - Fix instances of reentrant locking in the CefXmlObject and CefRequest implementations. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cef_unittests: - Add tests/unittests/chromium_includes.h and always include it first from unit test .cc files to avoid name conflicts with Chromium types. - Fix wrong header include ordering. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cefclient and cefsimple: - Use base::Bind and cef_closure_task.h instead of NewCefRunnable*. - Remove use of the IMPEMENT_LOCKING macro. - Fix incorrect/unnecessary locking. - Add additional runtime thread checks. - Windows: Perform actions on the UI thread instead of the main thread when running in multi-threaded-message-loop mode to avoid excessive locking. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1769 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2014-07-15 00:18:51 +02:00
IMPLEMENT_REFCOUNTING(RequestRedirectSchemeHandler);
DISALLOW_COPY_AND_ASSIGN(RequestRedirectSchemeHandler);
};
// Resource handler implementation that never completes. Used to test
// destruction handling behavior for in-progress requests.
class IncompleteSchemeHandlerOld : public CefResourceHandler {
public:
IncompleteSchemeHandlerOld(RequestRunSettings* settings,
base::OnceClosure destroy_callback)
: settings_(settings), destroy_callback_(std::move(destroy_callback)) {
EXPECT_NE(settings_->incomplete_type, RequestRunSettings::INCOMPLETE_NONE);
}
~IncompleteSchemeHandlerOld() override {
EXPECT_EQ(1, process_request_ct_);
EXPECT_EQ(1, cancel_ct_);
if (settings_->incomplete_type ==
RequestRunSettings::INCOMPLETE_READ_RESPONSE) {
EXPECT_EQ(1, get_response_headers_ct_);
EXPECT_EQ(1, read_response_ct_);
} else {
EXPECT_EQ(0, get_response_headers_ct_);
EXPECT_EQ(0, read_response_ct_);
}
std::move(destroy_callback_).Run();
}
bool ProcessRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback) override {
EXPECT_IO_THREAD();
process_request_ct_++;
if (settings_->incomplete_type ==
RequestRunSettings::INCOMPLETE_PROCESS_REQUEST) {
// Never release or execute this callback.
incomplete_callback_ = callback;
} else {
callback->Continue();
}
return true;
}
void GetResponseHeaders(CefRefPtr<CefResponse> response,
int64_t& response_length,
CefString& redirectUrl) override {
EXPECT_IO_THREAD();
EXPECT_EQ(settings_->incomplete_type,
RequestRunSettings::INCOMPLETE_READ_RESPONSE);
get_response_headers_ct_++;
response->SetStatus(settings_->response->GetStatus());
response->SetStatusText(settings_->response->GetStatusText());
response->SetMimeType(settings_->response->GetMimeType());
CefResponse::HeaderMap headerMap;
settings_->response->GetHeaderMap(headerMap);
settings_->response->SetHeaderMap(headerMap);
response_length = static_cast<int64_t>(settings_->response_data.size());
}
bool ReadResponse(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefCallback> callback) override {
EXPECT_IO_THREAD();
EXPECT_EQ(settings_->incomplete_type,
RequestRunSettings::INCOMPLETE_READ_RESPONSE);
read_response_ct_++;
// Never release or execute this callback.
incomplete_callback_ = callback;
bytes_read = 0;
return true;
}
void Cancel() override {
EXPECT_IO_THREAD();
cancel_ct_++;
}
private:
RequestRunSettings* const settings_;
base::OnceClosure destroy_callback_;
int process_request_ct_ = 0;
int get_response_headers_ct_ = 0;
int read_response_ct_ = 0;
int cancel_ct_ = 0;
CefRefPtr<CefCallback> incomplete_callback_;
IMPLEMENT_REFCOUNTING(IncompleteSchemeHandlerOld);
DISALLOW_COPY_AND_ASSIGN(IncompleteSchemeHandlerOld);
};
class IncompleteSchemeHandler : public CefResourceHandler {
public:
IncompleteSchemeHandler(RequestRunSettings* settings,
base::OnceClosure destroy_callback)
: settings_(settings), destroy_callback_(std::move(destroy_callback)) {
EXPECT_NE(settings_->incomplete_type, RequestRunSettings::INCOMPLETE_NONE);
}
~IncompleteSchemeHandler() override {
EXPECT_EQ(1, open_ct_);
EXPECT_EQ(1, cancel_ct_);
if (settings_->incomplete_type ==
RequestRunSettings::INCOMPLETE_READ_RESPONSE) {
EXPECT_EQ(1, get_response_headers_ct_);
EXPECT_EQ(1, read_ct_);
} else {
EXPECT_EQ(0, get_response_headers_ct_);
EXPECT_EQ(0, read_ct_);
}
std::move(destroy_callback_).Run();
}
bool Open(CefRefPtr<CefRequest> request,
bool& handle_request,
CefRefPtr<CefCallback> callback) override {
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
open_ct_++;
if (settings_->incomplete_type ==
RequestRunSettings::INCOMPLETE_PROCESS_REQUEST) {
// Never release or execute this callback.
incomplete_open_callback_ = callback;
} else {
// Continue immediately.
handle_request = true;
}
return true;
}
bool ProcessRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback) override {
EXPECT_TRUE(false); // Not reached.
return false;
}
void GetResponseHeaders(CefRefPtr<CefResponse> response,
int64_t& response_length,
CefString& redirectUrl) override {
EXPECT_IO_THREAD();
EXPECT_EQ(settings_->incomplete_type,
RequestRunSettings::INCOMPLETE_READ_RESPONSE);
get_response_headers_ct_++;
response->SetStatus(settings_->response->GetStatus());
response->SetStatusText(settings_->response->GetStatusText());
response->SetMimeType(settings_->response->GetMimeType());
CefResponse::HeaderMap headerMap;
settings_->response->GetHeaderMap(headerMap);
settings_->response->SetHeaderMap(headerMap);
response_length = static_cast<int64_t>(settings_->response_data.size());
}
bool Read(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefResourceReadCallback> callback) override {
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
EXPECT_EQ(settings_->incomplete_type,
RequestRunSettings::INCOMPLETE_READ_RESPONSE);
read_ct_++;
// Never release or execute this callback.
incomplete_read_callback_ = callback;
bytes_read = 0;
return true;
}
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;
}
void Cancel() override {
EXPECT_IO_THREAD();
cancel_ct_++;
}
private:
RequestRunSettings* const settings_;
base::OnceClosure destroy_callback_;
int open_ct_ = 0;
int get_response_headers_ct_ = 0;
int read_ct_ = 0;
int cancel_ct_ = 0;
CefRefPtr<CefCallback> incomplete_open_callback_;
CefRefPtr<CefResourceReadCallback> incomplete_read_callback_;
IMPLEMENT_REFCOUNTING(IncompleteSchemeHandler);
DISALLOW_COPY_AND_ASSIGN(IncompleteSchemeHandler);
};
class RequestSchemeHandlerFactory : public CefSchemeHandlerFactory {
public:
RequestSchemeHandlerFactory() = default;
CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& scheme_name,
CefRefPtr<CefRequest> request) override {
EXPECT_IO_THREAD();
handler_create_ct_++;
auto destroy_callback =
base::BindOnce(&RequestSchemeHandlerFactory::OnHandlerDestroyed, this);
RequestDataMap::Entry entry = data_map_.Find(request->GetURL());
if (entry.type == RequestDataMap::Entry::TYPE_NORMAL) {
if (entry.settings->incomplete_type ==
RequestRunSettings::INCOMPLETE_NONE) {
if (TestOldResourceAPI()) {
return new RequestSchemeHandlerOld(entry.settings,
std::move(destroy_callback));
}
return new RequestSchemeHandler(entry.settings,
std::move(destroy_callback));
}
if (TestOldResourceAPI()) {
return new IncompleteSchemeHandlerOld(entry.settings,
std::move(destroy_callback));
}
return new IncompleteSchemeHandler(entry.settings,
std::move(destroy_callback));
} else if (entry.type == RequestDataMap::Entry::TYPE_REDIRECT) {
if (TestOldResourceAPI()) {
return new RequestRedirectSchemeHandlerOld(entry.redirect_request,
entry.redirect_response,
std::move(destroy_callback));
}
return new RequestRedirectSchemeHandler(entry.redirect_request,
entry.redirect_response,
std::move(destroy_callback));
}
// Unknown test.
ADD_FAILURE();
return nullptr;
}
void SetOwnerTaskRunner(CefRefPtr<CefTaskRunner> task_runner) {
data_map_.SetOwnerTaskRunner(task_runner);
}
void AddSchemeHandler(RequestRunSettings* settings) {
const std::string& scheme = GetRequestScheme(false);
// Verify that the scheme is correct.
const std::string& url = settings->request->GetURL();
EXPECT_EQ(0U, url.find(scheme));
if (settings->redirect_request) {
// Verify that the scheme is correct.
const std::string& redirect_url = settings->redirect_request->GetURL();
EXPECT_EQ(0U, redirect_url.find(scheme));
}
data_map_.AddSchemeHandler(settings);
}
void OnHandlerDestroyed() {
if (!CefCurrentlyOn(TID_IO)) {
CefPostTask(TID_IO,
base::BindOnce(
&RequestSchemeHandlerFactory::OnHandlerDestroyed, this));
return;
}
handler_destroy_ct_++;
MaybeShutdown();
}
void Shutdown(base::OnceClosure complete_callback) {
if (!CefCurrentlyOn(TID_IO)) {
CefPostTask(TID_IO, base::BindOnce(&RequestSchemeHandlerFactory::Shutdown,
this, std::move(complete_callback)));
return;
}
EXPECT_TRUE(shutdown_callback_.is_null());
shutdown_callback_ = std::move(complete_callback);
data_map_.SetOwnerTaskRunner(nullptr);
MaybeShutdown();
}
private:
void MaybeShutdown() {
if (!shutdown_callback_.is_null() &&
handler_create_ct_ == handler_destroy_ct_) {
std::move(shutdown_callback_).Run();
}
}
RequestDataMap data_map_;
int handler_create_ct_ = 0;
int handler_destroy_ct_ = 0;
base::OnceClosure shutdown_callback_;
Introduce the use of Chromium types (issue #1336). Changes to the CEF public API: - Add base::Bind, base::Callback, base::Lock, base::WeakPtr, scoped_refptr, scoped_ptr and supporting types. - Add include/wrapper/cef_closure_task.h helpers for converting a base::Closure to a CefTask. - Change CefRefPtr to extend scoped_refptr. -- Change CefBase method signatures to match RefCountedThreadSafeBase. - Change IMPLEMENT_REFCOUNTING to use base::AtomicRefCount*. -- Remove the CefAtomic* functions. -- IMPLEMENT_REFCOUNTING now enforces via a compile-time error that the correct class name was passed to the macro. - Change IMPLEMENT_LOCKING to use base::Lock. -- Remove the CefCriticalSection class. -- Deprecate the IMPLEMENT_LOCKING macro. -- base::Lock will DCHECK() in Debug builds if lock usage is reentrant. - Move include/internal/cef_tuple.h to include/base/cef_tuple.h. - Allow an empty |callback| parameter passed to CefBeginTracing. Changes to the CEF implementation: - Fix incorrect names passed to the IMPLEMENT_REFCOUNTING macro. - Fix instances of reentrant locking in the CefXmlObject and CefRequest implementations. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cef_unittests: - Add tests/unittests/chromium_includes.h and always include it first from unit test .cc files to avoid name conflicts with Chromium types. - Fix wrong header include ordering. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cefclient and cefsimple: - Use base::Bind and cef_closure_task.h instead of NewCefRunnable*. - Remove use of the IMPEMENT_LOCKING macro. - Fix incorrect/unnecessary locking. - Add additional runtime thread checks. - Windows: Perform actions on the UI thread instead of the main thread when running in multi-threaded-message-loop mode to avoid excessive locking. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1769 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2014-07-15 00:18:51 +02:00
IMPLEMENT_REFCOUNTING(RequestSchemeHandlerFactory);
DISALLOW_COPY_AND_ASSIGN(RequestSchemeHandlerFactory);
};
// SERVER BACKEND
// HTTP server handler.
class RequestServerHandler : public test_server::ObserverHelper {
public:
RequestServerHandler() = default;
~RequestServerHandler() override { RunCompleteCallback(false); }
// Must be called before CreateServer().
void AddSchemeHandler(RequestRunSettings* settings) {
EXPECT_FALSE(initialized_);
data_map_.AddSchemeHandler(settings);
}
// Must be called before CreateServer().
void SetExpectedRequestCount(int count) {
EXPECT_FALSE(initialized_);
expected_http_request_ct_ = count;
}
// |complete_callback| will be executed on the UI thread after the server is
// started.
void CreateServer(base::OnceClosure complete_callback) {
EXPECT_UI_THREAD();
if (expected_http_request_ct_ < 0) {
// Default to the assumption of one request per registered URL.
SetExpectedRequestCount(static_cast<int>(data_map_.size()));
}
EXPECT_FALSE(initialized_);
initialized_ = true;
EXPECT_TRUE(complete_callback_.is_null());
complete_callback_ = std::move(complete_callback);
Initialize(/*https_server=*/false);
}
// Results in a call to VerifyResults() and eventual execution of the
// |complete_callback| on the UI thread via RequestServerHandler destruction.
void ShutdownServer(base::OnceClosure complete_callback) {
EXPECT_UI_THREAD();
EXPECT_TRUE(complete_callback_.is_null());
complete_callback_ = std::move(complete_callback);
Shutdown();
}
void OnInitialized(const std::string& server_origin) override {
EXPECT_UI_THREAD();
EXPECT_STREQ(server_origin.c_str(), GetRequestOrigin(true).c_str());
EXPECT_FALSE(got_initialized_);
got_initialized_.yes();
RunCompleteCallback(true);
}
void OnShutdown() override {
EXPECT_UI_THREAD();
EXPECT_FALSE(got_shutdown_);
got_shutdown_.yes();
data_map_.SetOwnerTaskRunner(nullptr);
VerifyResults();
delete this;
}
bool OnTestServerRequest(CefRefPtr<CefRequest> request,
const ResponseCallback& response_callback) override {
EXPECT_UI_THREAD();
// Log the requests for better error reporting.
request_log_ += request->GetMethod().ToString() + " " +
request->GetURL().ToString() + "\n";
actual_http_request_ct_++;
return HandleRequest(request, response_callback);
}
private:
void VerifyResults() {
EXPECT_TRUE(got_initialized_);
EXPECT_TRUE(got_shutdown_);
EXPECT_EQ(expected_http_request_ct_, actual_http_request_ct_)
<< request_log_;
}
bool HandleRequest(CefRefPtr<CefRequest> request,
const ResponseCallback& response_callback) {
RequestDataMap::Entry entry = data_map_.Find(request->GetURL());
if (entry.type == RequestDataMap::Entry::TYPE_NORMAL) {
const bool needs_auth = entry.settings->expect_authentication &&
!IsAuthorized(request, entry.settings->username,
entry.settings->password);
if (needs_auth) {
return HandleAuthRequest(request, response_callback);
}
return HandleNormalRequest(request, response_callback, entry.settings);
} else if (entry.type == RequestDataMap::Entry::TYPE_REDIRECT) {
return HandleRedirectRequest(request, response_callback,
entry.redirect_request,
entry.redirect_response);
} else {
// Unknown test.
ADD_FAILURE() << "url: " << request->GetURL().ToString();
}
return false;
}
static bool HandleAuthRequest(CefRefPtr<CefRequest> request,
const ResponseCallback& response_callback) {
CefRefPtr<CefResponse> response = CefResponse::Create();
GetAuthResponse(response);
response_callback.Run(response, std::string());
return true;
}
static bool HandleNormalRequest(CefRefPtr<CefRequest> request,
const ResponseCallback& response_callback,
RequestRunSettings* settings) {
VerifyNormalRequest(settings, request, true);
CefRefPtr<CefResponse> response = CefResponse::Create();
GetNormalResponse(settings, response);
// HEAD requests are identical to GET requests except no response data is
// sent.
std::string response_data;
if (request->GetMethod() != "HEAD") {
size_t expected_offset = settings->expected_download_offset;
response_data = settings->response_data.substr(expected_offset);
}
response_callback.Run(response, response_data);
return true;
}
static bool HandleRedirectRequest(CefRefPtr<CefRequest> request,
const ResponseCallback& response_callback,
CefRefPtr<CefRequest> redirect_request,
CefRefPtr<CefResponse> redirect_response) {
if (redirect_response->GetStatus() == 302) {
// Simulate wrong copying of POST-specific headers Content-Type and
// Content-Length. A 302 redirect should end up in a GET request and
// these headers should not propagate from a 302 POST-to-GET redirect.
CefResponse::HeaderMap redirectHeaderMap;
redirect_response->GetHeaderMap(redirectHeaderMap);
redirectHeaderMap.insert(
std::make_pair("content-type", "application/x-www-form-urlencoded"));
redirectHeaderMap.insert(std::make_pair("content-length", "0"));
redirect_response->SetHeaderMap(redirectHeaderMap);
}
// Verify that the request was sent correctly.
TestRequestEqual(redirect_request, request, true);
response_callback.Run(redirect_response, std::string());
return true;
}
void RunCompleteCallback(bool startup) {
EXPECT_UI_THREAD();
if (startup) {
// Transfer DataMap ownership to the UI thread.
data_map_.SetOwnerTaskRunner(CefTaskRunner::GetForCurrentThread());
}
EXPECT_FALSE(complete_callback_.is_null());
std::move(complete_callback_).Run();
}
RequestDataMap data_map_;
bool initialized_ = false;
// Only accessed on the UI thread.
base::OnceClosure complete_callback_;
// After initialization the below members are only accessed on the server
// thread.
TrackCallback got_initialized_;
TrackCallback got_shutdown_;
int expected_http_request_ct_ = -1;
int actual_http_request_ct_ = 0;
std::string request_log_;
};
// SHARED TEST RUNNER
// Executes the tests.
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
public:
using TestCallback = base::RepeatingCallback<void(base::OnceClosure)>;
RequestTestRunner(bool is_server_backend,
bool use_frame_method,
base::OnceClosure incomplete_request_callback)
: is_server_backend_(is_server_backend),
use_frame_method_(use_frame_method),
incomplete_request_callback_(std::move(incomplete_request_callback)) {
owner_task_runner_ = CefTaskRunner::GetForCurrentThread();
EXPECT_TRUE(owner_task_runner_.get());
EXPECT_TRUE(owner_task_runner_->BelongsToCurrentThread());
}
void Initialize() {
// Helper macro for registering test callbacks.
#define REGISTER_TEST(test_mode, setup_method, run_method) \
RegisterTest(test_mode, \
base::BindRepeating(&RequestTestRunner::setup_method, this), \
base::BindRepeating(&RequestTestRunner::run_method, this));
// Register the test callbacks.
REGISTER_TEST(REQTEST_GET, SetupGetTest, SingleRunTest);
REGISTER_TEST(REQTEST_GET_NODATA, SetupGetNoDataTest, SingleRunTest);
REGISTER_TEST(REQTEST_GET_PARTIAL_CONTENT, SetupGetPartialContentTest,
SingleRunTest);
REGISTER_TEST(REQTEST_GET_ALLOWCOOKIES, SetupGetAllowCookiesTest,
SingleRunTest);
REGISTER_TEST(REQTEST_GET_REDIRECT, SetupGetRedirectTest, SingleRunTest);
REGISTER_TEST(REQTEST_GET_REDIRECT_STOP, SetupGetRedirectStopTest,
SingleRunTest);
REGISTER_TEST(REQTEST_GET_REDIRECT_LOCATION, SetupGetRedirectLocationTest,
SingleRunTest);
REGISTER_TEST(REQTEST_GET_REFERRER, SetupGetReferrerTest, SingleRunTest);
REGISTER_TEST(REQTEST_GET_AUTH, SetupGetAuthTest, SingleRunTest);
REGISTER_TEST(REQTEST_POST, SetupPostTest, SingleRunTest);
REGISTER_TEST(REQTEST_POST_FILE, SetupPostFileTest, SingleRunTest);
REGISTER_TEST(REQTEST_POST_WITHPROGRESS, SetupPostWithProgressTest,
SingleRunTest);
REGISTER_TEST(REQTEST_POST_REDIRECT, SetupPostRedirectTest, SingleRunTest);
REGISTER_TEST(REQTEST_POST_REDIRECT_TOGET, SetupPostRedirectToGetTest,
SingleRunTest);
REGISTER_TEST(REQTEST_HEAD, SetupHeadTest, SingleRunTest);
REGISTER_TEST(REQTEST_CACHE_WITH_CONTROL, SetupCacheWithControlTest,
MultipleRunTest);
REGISTER_TEST(REQTEST_CACHE_WITHOUT_CONTROL, SetupCacheWithoutControlTest,
MultipleRunTest);
REGISTER_TEST(REQTEST_CACHE_SKIP_FLAG, SetupCacheSkipFlagTest,
MultipleRunTest);
REGISTER_TEST(REQTEST_CACHE_SKIP_HEADER, SetupCacheSkipHeaderTest,
MultipleRunTest);
REGISTER_TEST(REQTEST_CACHE_ONLY_FAILURE_FLAG,
SetupCacheOnlyFailureFlagTest, MultipleRunTest);
REGISTER_TEST(REQTEST_CACHE_ONLY_FAILURE_HEADER,
SetupCacheOnlyFailureHeaderTest, MultipleRunTest);
REGISTER_TEST(REQTEST_CACHE_ONLY_SUCCESS_FLAG,
SetupCacheOnlySuccessFlagTest, MultipleRunTest);
REGISTER_TEST(REQTEST_CACHE_ONLY_SUCCESS_HEADER,
SetupCacheOnlySuccessHeaderTest, MultipleRunTest);
REGISTER_TEST(REQTEST_CACHE_DISABLE_FLAG, SetupCacheDisableFlagTest,
MultipleRunTest);
REGISTER_TEST(REQTEST_CACHE_DISABLE_HEADER, SetupCacheDisableHeaderTest,
MultipleRunTest);
REGISTER_TEST(REQTEST_INCOMPLETE_PROCESS_REQUEST,
SetupIncompleteProcessRequestTest, SingleRunTest);
REGISTER_TEST(REQTEST_INCOMPLETE_READ_RESPONSE,
SetupIncompleteReadResponseTest, SingleRunTest);
}
void Destroy() {
owner_task_runner_ = nullptr;
request_context_ = nullptr;
incomplete_request_callback_.Reset();
}
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
// Called in the browser process to set the request context that will be used
// when creating the URL request.
void SetRequestContext(CefRefPtr<CefRequestContext> request_context) {
request_context_ = request_context;
}
CefRefPtr<CefRequestContext> GetRequestContext() const {
return request_context_;
}
// Called to setup the test.
void SetupTest(RequestTestMode test_mode,
base::OnceClosure complete_callback) {
EXPECT_TRUE(owner_task_runner_->BelongsToCurrentThread());
TestMap::const_iterator it = test_map_.find(test_mode);
if (it != test_map_.end()) {
auto safe_complete_callback =
base::BindOnce(&RequestTestRunner::CompleteOnCorrectThread, this,
std::move(complete_callback));
it->second.setup.Run(base::BindOnce(&RequestTestRunner::SetupContinue,
this,
std::move(safe_complete_callback)));
} else {
// Unknown test.
ADD_FAILURE();
std::move(complete_callback).Run();
}
}
// Called to run the test.
void RunTest(RequestTestMode test_mode,
CefRefPtr<CefFrame> frame,
base::OnceClosure complete_callback) {
EXPECT_TRUE(owner_task_runner_->BelongsToCurrentThread());
frame_ = frame;
TestMap::const_iterator it = test_map_.find(test_mode);
if (it != test_map_.end()) {
auto safe_complete_callback =
base::BindOnce(&RequestTestRunner::CompleteOnCorrectThread, this,
std::move(complete_callback));
it->second.run.Run(std::move(safe_complete_callback));
} else {
// Unknown test.
ADD_FAILURE();
std::move(complete_callback).Run();
}
}
// Called to shut down the test.
void ShutdownTest(base::OnceClosure complete_callback) {
EXPECT_TRUE(owner_task_runner_->BelongsToCurrentThread());
auto safe_complete_callback =
base::BindOnce(&RequestTestRunner::CompleteOnCorrectThread, this,
std::move(complete_callback));
if (!post_file_tmpdir_.IsEmpty()) {
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
CefPostTask(TID_FILE_USER_VISIBLE,
base::BindOnce(&RequestTestRunner::RunDeleteTempDirectory,
this, std::move(safe_complete_callback)));
return;
}
// Continue with test shutdown.
RunShutdown(std::move(safe_complete_callback));
}
private:
// Continued after |settings_| is populated for the test.
void SetupContinue(base::OnceClosure complete_callback) {
if (!owner_task_runner_->BelongsToCurrentThread()) {
owner_task_runner_->PostTask(CefCreateClosureTask(
base::BindOnce(&RequestTestRunner::SetupContinue, this,
std::move(complete_callback))));
return;
}
SetupTestBackend(std::move(complete_callback));
}
std::string GetTestPath(const std::string& name) {
return std::string("/Browser") + name;
}
std::string GetTestURL(const std::string& name) {
// Avoid name duplication between tests running in different processes.
// Otherwise we'll get unexpected state leakage (cache hits) when running
// multiple tests.
return GetRequestOrigin(is_server_backend_) + GetTestPath(name);
}
void SetupGetTestShared() {
settings_.request = CefRequest::Create();
settings_.request->SetURL(GetTestURL("GetTest.html"));
settings_.request->SetMethod("GET");
settings_.response = CefResponse::Create();
settings_.response->SetMimeType("text/html");
settings_.response->SetStatus(200);
settings_.response->SetStatusText("OK");
settings_.response_data = "GET TEST SUCCESS";
}
void SetupGetTest(base::OnceClosure complete_callback) {
SetupGetTestShared();
std::move(complete_callback).Run();
}
void SetupGetNoDataTest(base::OnceClosure complete_callback) {
// Start with the normal get test.
SetupGetTestShared();
// Disable download data notifications.
settings_.request->SetFlags(UR_FLAG_NO_DOWNLOAD_DATA);
settings_.expect_download_data = false;
std::move(complete_callback).Run();
}
void SetupGetPartialContentTest(base::OnceClosure complete_callback) {
// Start with the normal get test.
SetupGetTestShared();
// Skip first 4 bytes of content and expect to receive the rest
settings_.request->SetHeaderByName("Range", "bytes=4-", true);
settings_.response->SetHeaderByName("Content-Range", "bytes 4-8/8", true);
settings_.response->SetStatus(206);
settings_.response->SetStatusText("Partial Content");
settings_.expected_download_offset = 4;
std::move(complete_callback).Run();
}
void SetupGetAllowCookiesTest(base::OnceClosure complete_callback) {
// Start with the normal get test.
SetupGetTestShared();
// Send cookies.
settings_.request->SetFlags(UR_FLAG_ALLOW_STORED_CREDENTIALS);
settings_.expect_save_cookie = true;
settings_.expect_send_cookie = true;
std::move(complete_callback).Run();
}
void SetupGetRedirectTest(base::OnceClosure complete_callback) {
// Start with the normal get test.
SetupGetTestShared();
// Add a redirect request.
settings_.redirect_request = CefRequest::Create();
settings_.redirect_request->SetURL(GetTestURL("redirect.html"));
settings_.redirect_request->SetMethod("GET");
settings_.redirect_response = CefResponse::Create();
settings_.redirect_response->SetMimeType("text/html");
settings_.redirect_response->SetStatus(302);
settings_.redirect_response->SetStatusText("Found");
CefResponse::HeaderMap headerMap;
headerMap.insert(std::make_pair("Location", settings_.request->GetURL()));
settings_.redirect_response->SetHeaderMap(headerMap);
std::move(complete_callback).Run();
}
void SetupGetRedirectStopTest(base::OnceClosure complete_callback) {
settings_.request = CefRequest::Create();
settings_.request->SetURL(GetTestURL("GetTest.html"));
settings_.request->SetMethod("GET");
// With the test server only the status is expected
// on stop redirects.
settings_.response = CefResponse::Create();
settings_.response->SetStatus(302);
settings_.response->SetStatusText("Found");
// Add a redirect request.
settings_.redirect_request = CefRequest::Create();
settings_.redirect_request->SetURL(GetTestURL("redirect.html"));
settings_.redirect_request->SetMethod("GET");
settings_.redirect_request->SetFlags(UR_FLAG_STOP_ON_REDIRECT);
settings_.redirect_response = CefResponse::Create();
settings_.redirect_response->SetMimeType("text/html");
settings_.redirect_response->SetStatus(302);
settings_.redirect_response->SetStatusText("Found");
CefResponse::HeaderMap headerMap;
headerMap.insert(std::make_pair("Location", settings_.request->GetURL()));
settings_.redirect_response->SetHeaderMap(headerMap);
settings_.expected_status = UR_CANCELED;
settings_.expected_error_code = ERR_ABORTED;
settings_.expect_download_data = false;
settings_.expect_download_progress = false;
settings_.expected_send_count = 1;
settings_.expected_receive_count = 1;
std::move(complete_callback).Run();
}
void SetupGetRedirectLocationTest(base::OnceClosure complete_callback) {
// Start with the normal get test.
SetupGetTestShared();
// Add a redirect request.
settings_.redirect_request = CefRequest::Create();
settings_.redirect_request->SetURL(GetTestURL("redirect.html"));
settings_.redirect_request->SetMethod("GET");
settings_.redirect_response = CefResponse::Create();
settings_.redirect_response->SetMimeType("text/html");
settings_.redirect_response->SetStatus(302);
settings_.redirect_response->SetStatusText("Found");
CefResponse::HeaderMap headerMap;
headerMap.insert(std::make_pair("LoCaTioN", GetTestPath("GetTest.html")));
settings_.redirect_response->SetHeaderMap(headerMap);
std::move(complete_callback).Run();
}
void SetupGetReferrerTest(base::OnceClosure complete_callback) {
settings_.request = CefRequest::Create();
settings_.request->SetURL(GetTestURL("GetTest.html"));
settings_.request->SetMethod("GET");
// The referrer URL must be HTTP or HTTPS. This is enforced by
// GURL::GetAsReferrer() called from URLRequest::SetReferrer().
settings_.request->SetReferrer("https://tests.com/referrer.html",
REFERRER_POLICY_DEFAULT);
settings_.response = CefResponse::Create();
settings_.response->SetMimeType("text/html");
settings_.response->SetStatus(200);
settings_.response->SetStatusText("OK");
settings_.response_data = "GET TEST SUCCESS";
std::move(complete_callback).Run();
}
void SetupGetAuthTest(base::OnceClosure complete_callback) {
// Start with the normal get test.
SetupGetTestShared();
// Require Basic authentication.
settings_.expect_authentication = true;
settings_.username = "user";
settings_.password = "pass";
// This flag is required to support credentials, which means we'll also get
// the cookies.
settings_.request->SetFlags(UR_FLAG_ALLOW_STORED_CREDENTIALS);
settings_.expect_save_cookie = true;
settings_.expect_send_cookie = true;
// The authentication request will come first, then the actual request.
settings_.expected_receive_count = 2;
settings_.expected_send_count = 2;
std::move(complete_callback).Run();
}
void SetupPostTestShared() {
settings_.request = CefRequest::Create();
settings_.request->SetURL(GetTestURL("PostTest.html"));
settings_.request->SetMethod("POST");
SetUploadData(settings_.request, "the_post_data");
settings_.response = CefResponse::Create();
settings_.response->SetMimeType("text/html");
settings_.response->SetStatus(200);
settings_.response->SetStatusText("OK");
settings_.response_data = "POST TEST SUCCESS";
}
void SetupPostTest(base::OnceClosure complete_callback) {
SetupPostTestShared();
std::move(complete_callback).Run();
}
void SetupPostFileTest(base::OnceClosure complete_callback) {
settings_.request = CefRequest::Create();
settings_.request->SetURL(GetTestURL("PostFileTest.html"));
settings_.request->SetMethod("POST");
settings_.response = CefResponse::Create();
settings_.response->SetMimeType("text/html");
settings_.response->SetStatus(200);
settings_.response->SetStatusText("OK");
settings_.response_data = "POST TEST SUCCESS";
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
CefPostTask(TID_FILE_USER_VISIBLE,
base::BindOnce(&RequestTestRunner::SetupPostFileTestContinue,
this, std::move(complete_callback)));
}
void SetupPostFileTestContinue(base::OnceClosure complete_callback) {
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
EXPECT_TRUE(CefCurrentlyOn(TID_FILE_USER_VISIBLE));
EXPECT_TRUE(post_file_tmpdir_.CreateUniqueTempDir());
const std::string& path =
client::file_util::JoinPath(post_file_tmpdir_.GetPath(), "example.txt");
const char content[] = "HELLO FRIEND!";
int write_ct =
client::file_util::WriteFile(path, content, sizeof(content) - 1);
EXPECT_EQ(static_cast<int>(sizeof(content) - 1), write_ct);
SetUploadFile(settings_.request, path);
std::move(complete_callback).Run();
}
void SetupPostWithProgressTest(base::OnceClosure complete_callback) {
// Start with the normal post test.
SetupPostTestShared();
// Enable upload progress notifications.
settings_.request->SetFlags(UR_FLAG_REPORT_UPLOAD_PROGRESS);
settings_.expect_upload_progress = true;
std::move(complete_callback).Run();
}
void SetupPostRedirectTest(base::OnceClosure complete_callback) {
// Start with the normal post test.
SetupPostTestShared();
// Add a redirect request.
settings_.redirect_request = CefRequest::Create();
settings_.redirect_request->SetURL(GetTestURL("redirect.html"));
settings_.redirect_request->SetMethod("POST");
SetUploadData(settings_.redirect_request, "the_post_data");
settings_.redirect_response = CefResponse::Create();
settings_.redirect_response->SetMimeType("text/html");
// Only 307 is supported for redirecting the same method and post data.
settings_.redirect_response->SetStatus(307);
settings_.redirect_response->SetStatusText("Found");
CefResponse::HeaderMap headerMap;
headerMap.insert(std::make_pair("Location", settings_.request->GetURL()));
settings_.redirect_response->SetHeaderMap(headerMap);
std::move(complete_callback).Run();
}
void SetupPostRedirectToGetTest(base::OnceClosure complete_callback) {
// Start with the normal post test.
SetupPostTestShared();
// The expected result after redirect is a GET request without POST data.
settings_.request = CefRequest::Create();
settings_.request->SetURL(GetTestURL("PostTest.html"));
settings_.request->SetMethod("GET");
// Add a redirect request.
settings_.redirect_request = CefRequest::Create();
settings_.redirect_request->SetURL(GetTestURL("redirect.html"));
settings_.redirect_request->SetMethod("POST");
SetUploadData(settings_.redirect_request, "the_post_data");
settings_.redirect_response = CefResponse::Create();
settings_.redirect_response->SetMimeType("text/html");
// Redirect codes other than 307 will cause conversion to GET and removal
// of POST data.
settings_.redirect_response->SetStatus(302);
settings_.redirect_response->SetStatusText("Found");
CefResponse::HeaderMap headerMap;
headerMap.insert(std::make_pair("Location", settings_.request->GetURL()));
settings_.redirect_response->SetHeaderMap(headerMap);
std::move(complete_callback).Run();
}
void SetupHeadTest(base::OnceClosure complete_callback) {
settings_.request = CefRequest::Create();
settings_.request->SetURL(GetTestURL("HeadTest.html"));
settings_.request->SetMethod("HEAD");
settings_.response = CefResponse::Create();
settings_.response->SetMimeType("text/html");
settings_.response->SetStatus(200);
settings_.response->SetStatusText("OK");
// The backend will disregard this value when it returns the result.
settings_.response_data = "HEAD TEST SUCCESS";
settings_.expect_download_progress = false;
settings_.expect_download_data = false;
std::move(complete_callback).Run();
}
void SetupCacheShared(const std::string& name, bool with_cache_control) {
// Start with the normal get test.
SetupGetTestShared();
// Specify a unique URL.
settings_.request->SetURL(GetTestURL(name));
if (with_cache_control) {
// Allow the page to be cached for 10 seconds.
CefResponse::HeaderMap headerMap;
headerMap.insert(std::make_pair(kCacheControlHeader, "max-age=10"));
settings_.response->SetHeaderMap(headerMap);
}
}
void SetupCacheWithControlTest(base::OnceClosure complete_callback) {
SetupCacheShared("CacheWithControlTest.html", true);
// Send multiple requests. With the Cache-Control response header the 2nd+
// should receive cached data.
settings_.expected_send_count = 3;
settings_.expected_receive_count = 1;
settings_.setup_next_request =
base::BindOnce(&RequestTestRunner::SetupCacheWithControlTestNext, this);
std::move(complete_callback).Run();
}
void SetupCacheWithControlTestNext(int next_send_count,
base::OnceClosure complete_callback) {
// Only handle from the cache.
settings_.expect_response_was_cached = true;
// The following requests will use the same setup, so no more callbacks
// are required.
EXPECT_TRUE(settings_.setup_next_request.is_null());
std::move(complete_callback).Run();
}
void SetupCacheWithoutControlTest(base::OnceClosure complete_callback) {
SetupCacheShared("CacheWithoutControlTest.html", false);
// Send multiple requests. Without the Cache-Control response header all
// should be received.
settings_.expected_send_count = 3;
settings_.expected_receive_count = 3;
std::move(complete_callback).Run();
}
void SetupCacheSkipFlagTest(base::OnceClosure complete_callback) {
SetupCacheShared("CacheSkipFlagTest.html", true);
// Skip the cache despite the the Cache-Control response header.
// This will not read from the cache, but still write to the cache.
settings_.request->SetFlags(UR_FLAG_SKIP_CACHE);
// Send multiple requests. The 1st request will be handled normally,
// but not result in any reads from the cache. The 2nd request will
// expect a cached response and the 3nd request will skip the cache
// again.
settings_.expected_send_count = 3;
settings_.expected_receive_count = 2;
settings_.setup_next_request =
base::BindOnce(&RequestTestRunner::SetupCacheSkipFlagTestNext, this);
std::move(complete_callback).Run();
}
void SetupCacheSkipFlagTestNext(int next_send_count,
base::OnceClosure complete_callback) {
// Recreate the request object because the existing object will now be
// read-only.
EXPECT_TRUE(settings_.request->IsReadOnly());
SetupCacheShared("CacheSkipFlagTest.html", true);
// Expect a cached response.
settings_.expect_response_was_cached = true;
settings_.setup_next_request =
base::BindOnce(&RequestTestRunner::SetupCacheSkipFlagTestLast, this);
std::move(complete_callback).Run();
}
void SetupCacheSkipFlagTestLast(int next_send_count,
base::OnceClosure complete_callback) {
// Recreate the request object because the existing object will now be
// read-only.
EXPECT_TRUE(settings_.request->IsReadOnly());
SetupCacheShared("CacheSkipFlagTest.html", true);
// Skip the cache despite the the Cache-Control response header.
settings_.request->SetFlags(UR_FLAG_SKIP_CACHE);
// Expect the cache to be skipped.
settings_.expect_response_was_cached = false;
EXPECT_TRUE(settings_.setup_next_request.is_null());
std::move(complete_callback).Run();
}
void SetupCacheSkipHeaderTest(base::OnceClosure complete_callback) {
SetupCacheShared("CacheSkipHeaderTest.html", true);
// Skip the cache despite the the Cache-Control response header.
// This will not read from the cache, but still write to the cache.
CefRequest::HeaderMap headerMap;
headerMap.insert(std::make_pair(kCacheControlHeader, "no-cache"));
settings_.request->SetHeaderMap(headerMap);
// Send multiple requests. The 1st request will be handled normally,
// but not result in any reads from the cache. The 2nd request will
// expect a cached response and the 3nd request will skip the cache
// again.
settings_.expected_send_count = 3;
settings_.expected_receive_count = 2;
settings_.setup_next_request =
base::BindOnce(&RequestTestRunner::SetupCacheSkipHeaderTestNext, this);
std::move(complete_callback).Run();
}
void SetupCacheSkipHeaderTestNext(int next_send_count,
base::OnceClosure complete_callback) {
// Recreate the request object because the existing object will now be
// read-only.
EXPECT_TRUE(settings_.request->IsReadOnly());
SetupCacheShared("CacheSkipHeaderTest.html", true);
// Expect a cached response.
settings_.expect_response_was_cached = true;
settings_.setup_next_request =
base::BindOnce(&RequestTestRunner::SetupCacheSkipHeaderTestLast, this);
std::move(complete_callback).Run();
}
void SetupCacheSkipHeaderTestLast(int next_send_count,
base::OnceClosure complete_callback) {
// Recreate the request object because the existing object will now be
// read-only.
EXPECT_TRUE(settings_.request->IsReadOnly());
SetupCacheShared("CacheSkipHeaderTest.html", true);
// Skip the cache despite the the Cache-Control response header.
settings_.request->SetFlags(UR_FLAG_SKIP_CACHE);
// Expect the cache to be skipped.
settings_.expect_response_was_cached = false;
EXPECT_TRUE(settings_.setup_next_request.is_null());
std::move(complete_callback).Run();
}
void SetupCacheOnlyFailureFlagTest(base::OnceClosure complete_callback) {
SetupCacheShared("CacheOnlyFailureFlagTest.html", true);
// Only handle from the cache.
settings_.request->SetFlags(UR_FLAG_ONLY_FROM_CACHE);
// Send multiple requests. All should fail because there's no entry in the
// cache currently.
settings_.expected_send_count = 3;
settings_.expected_receive_count = 0;
// The request is expected to fail.
settings_.SetRequestFailureExpected(ERR_CACHE_MISS);
std::move(complete_callback).Run();
}
void SetupCacheOnlyFailureHeaderTest(base::OnceClosure complete_callback) {
SetupCacheShared("CacheOnlyFailureFlagTest.html", true);
// Only handle from the cache.
CefRequest::HeaderMap headerMap;
headerMap.insert(std::make_pair(kCacheControlHeader, "only-if-cached"));
settings_.request->SetHeaderMap(headerMap);
// Send multiple requests. All should fail because there's no entry in the
// cache currently.
settings_.expected_send_count = 3;
settings_.expected_receive_count = 0;
// The request is expected to fail.
settings_.SetRequestFailureExpected(ERR_CACHE_MISS);
std::move(complete_callback).Run();
}
void SetupCacheOnlySuccessFlagTest(base::OnceClosure complete_callback) {
SetupCacheShared("CacheOnlySuccessFlagTest.html", false);
// Send multiple requests. The 1st request will be handled normally. The
// 2nd+ requests will be configured by SetupCacheOnlySuccessFlagNext to
// require cached data.
settings_.expected_send_count = 3;
settings_.expected_receive_count = 1;
settings_.setup_next_request =
base::BindOnce(&RequestTestRunner::SetupCacheOnlySuccessFlagNext, this);
std::move(complete_callback).Run();
}
void SetupCacheOnlySuccessFlagNext(int next_send_count,
base::OnceClosure complete_callback) {
// Recreate the request object because the existing object will now be
// read-only.
EXPECT_TRUE(settings_.request->IsReadOnly());
SetupCacheShared("CacheOnlySuccessFlagTest.html", false);
// Only handle from the cache.
settings_.request->SetFlags(UR_FLAG_ONLY_FROM_CACHE);
settings_.expect_response_was_cached = true;
// The following requests will use the same setup, so no more callbacks
// are required.
EXPECT_TRUE(settings_.setup_next_request.is_null());
std::move(complete_callback).Run();
}
void SetupCacheOnlySuccessHeaderTest(base::OnceClosure complete_callback) {
SetupCacheShared("CacheOnlySuccessHeaderTest.html", false);
// Send multiple requests. The 1st request will be handled normally. The
// 2nd+ requests will be configured by SetupCacheOnlySuccessHeaderNext to
// require cached data.
settings_.expected_send_count = 3;
settings_.expected_receive_count = 1;
settings_.setup_next_request = base::BindOnce(
&RequestTestRunner::SetupCacheOnlySuccessHeaderNext, this);
std::move(complete_callback).Run();
}
void SetupCacheOnlySuccessHeaderNext(int next_send_count,
base::OnceClosure complete_callback) {
// Recreate the request object because the existing object will now be
// read-only.
EXPECT_TRUE(settings_.request->IsReadOnly());
SetupCacheShared("CacheOnlySuccessHeaderTest.html", false);
// Only handle from the cache.
CefRequest::HeaderMap headerMap;
headerMap.insert(std::make_pair(kCacheControlHeader, "only-if-cached"));
settings_.request->SetHeaderMap(headerMap);
settings_.expect_response_was_cached = true;
// The following requests will use the same setup, so no more callbacks
// are required.
EXPECT_TRUE(settings_.setup_next_request.is_null());
std::move(complete_callback).Run();
}
void SetupCacheDisableFlagTest(base::OnceClosure complete_callback) {
SetupCacheShared("CacheDisableFlagTest.html", true);
// Disable the cache despite the the Cache-Control response header.
settings_.request->SetFlags(UR_FLAG_DISABLE_CACHE);
// Send multiple requests. The 1st request will be handled normally,
// but not result in any reads from or writes to the cache.
// Therefore all following requests that are set to be only handled
// from the cache should fail.
settings_.expected_send_count = 3;
settings_.expected_receive_count = 1;
settings_.setup_next_request =
base::BindOnce(&RequestTestRunner::SetupCacheDisableFlagTestNext, this);
std::move(complete_callback).Run();
}
void SetupCacheDisableFlagTestNext(int next_send_count,
base::OnceClosure complete_callback) {
// Recreate the request object because the existing object will now be
// read-only.
EXPECT_TRUE(settings_.request->IsReadOnly());
SetupCacheShared("CacheDisableFlagTest.html", true);
// Only handle from the cache.
settings_.request->SetFlags(UR_FLAG_ONLY_FROM_CACHE);
// The request is expected to fail.
settings_.SetRequestFailureExpected(ERR_CACHE_MISS);
// The following requests will use the same setup, so no more callbacks
// are required.
EXPECT_TRUE(settings_.setup_next_request.is_null());
std::move(complete_callback).Run();
}
void SetupCacheDisableHeaderTest(base::OnceClosure complete_callback) {
SetupCacheShared("CacheDisableHeaderTest.html", true);
// Disable the cache despite the the Cache-Control response header.
CefRequest::HeaderMap headerMap;
headerMap.insert(std::make_pair(kCacheControlHeader, "no-store"));
settings_.request->SetHeaderMap(headerMap);
// Send multiple requests. The 1st request will be handled normally,
// but not result in any reads from or writes to the cache.
// Therefore all following requests that are set to be only handled
// from the cache should fail.
settings_.expected_send_count = 3;
settings_.expected_receive_count = 1;
settings_.setup_next_request = base::BindOnce(
&RequestTestRunner::SetupCacheDisableHeaderTestNext, this);
std::move(complete_callback).Run();
}
void SetupCacheDisableHeaderTestNext(int next_send_count,
base::OnceClosure complete_callback) {
// Recreate the request object because the existing object will now be
// read-only.
EXPECT_TRUE(settings_.request->IsReadOnly());
SetupCacheShared("CacheDisableHeaderTest.html", true);
// Only handle from the cache.
CefRequest::HeaderMap headerMap;
headerMap.insert(std::make_pair(kCacheControlHeader, "only-if-cached"));
settings_.request->SetHeaderMap(headerMap);
// The request is expected to fail.
settings_.SetRequestFailureExpected(ERR_CACHE_MISS);
// The following requests will use the same setup, so no more callbacks
// are required.
EXPECT_TRUE(settings_.setup_next_request.is_null());
std::move(complete_callback).Run();
}
void SetupIncompleteProcessRequestTest(base::OnceClosure complete_callback) {
// Start with the normal get test.
SetupGetTestShared();
settings_.incomplete_type = RequestRunSettings::INCOMPLETE_PROCESS_REQUEST;
// There will be no response and the request will be aborted.
settings_.response = CefResponse::Create();
settings_.response_data.clear();
settings_.expected_error_code = ERR_ABORTED;
settings_.expected_status = UR_FAILED;
settings_.expect_download_progress = false;
settings_.expect_download_data = false;
std::move(complete_callback).Run();
}
void SetupIncompleteReadResponseTest(base::OnceClosure complete_callback) {
// Start with the normal get test.
SetupGetTestShared();
settings_.incomplete_type = RequestRunSettings::INCOMPLETE_READ_RESPONSE;
// There will be a response but the request will be aborted without
// receiving any data.
settings_.response_data = test_server::kIncompleteDoNotSendData;
settings_.expected_error_code = ERR_ABORTED;
settings_.expected_status = UR_FAILED;
settings_.expect_download_progress = true;
settings_.expect_download_data = false;
std::move(complete_callback).Run();
}
// Send a request. |complete_callback| will be executed on request completion.
void SendRequest(test_request::RequestDoneCallback done_callback) {
test_request::SendConfig config;
2023-01-02 23:59:03 +01:00
if (settings_.redirect_request) {
config.request_ = settings_.redirect_request;
2023-01-02 23:59:03 +01:00
} else {
config.request_ = settings_.request;
2023-01-02 23:59:03 +01:00
}
EXPECT_TRUE(config.request_.get());
// Not delegating to CefRequestHandler::GetAuthCredentials.
if (!use_frame_method_ && settings_.expect_authentication) {
config.has_credentials_ = true;
config.username_ = settings_.username;
config.password_ = settings_.password;
}
if (use_frame_method_) {
EXPECT_TRUE(frame_);
config.frame_ = frame_;
} else {
config.request_context_ = request_context_;
}
test_request::Send(config, std::move(done_callback));
if (settings_.incomplete_type != RequestRunSettings::INCOMPLETE_NONE) {
std::move(incomplete_request_callback_).Run();
}
}
// Verify a response.
void VerifyResponse(const test_request::State* const client) {
CefRefPtr<CefRequest> expected_request;
CefRefPtr<CefResponse> expected_response;
2023-01-02 23:59:03 +01:00
if (settings_.redirect_request) {
expected_request = settings_.redirect_request;
2023-01-02 23:59:03 +01:00
} else {
expected_request = settings_.request;
2023-01-02 23:59:03 +01:00
}
if (settings_.redirect_response && !settings_.expect_follow_redirect) {
// A redirect response was sent but the redirect is not expected to be
// followed.
expected_response = settings_.redirect_response;
} else {
expected_response = settings_.response;
}
TestRequestEqual(expected_request, client->request_, false);
EXPECT_EQ(settings_.expected_status, client->status_);
EXPECT_EQ(settings_.expected_error_code, client->error_code_);
2023-01-02 23:59:03 +01:00
if (expected_response && client->response_) {
TestResponseEqual(expected_response, client->response_, true);
2023-01-02 23:59:03 +01:00
}
EXPECT_EQ(settings_.expect_response_was_cached,
client->response_was_cached_);
EXPECT_EQ(1, client->request_complete_ct_);
if (settings_.expect_upload_progress) {
EXPECT_LE(1, client->upload_progress_ct_);
std::string upload_data;
GetUploadData(expected_request, upload_data);
EXPECT_EQ((int64_t)upload_data.size(), client->upload_total_);
} else {
EXPECT_EQ(0, client->upload_progress_ct_);
EXPECT_EQ(0, client->upload_total_);
}
if (settings_.expect_download_progress) {
EXPECT_LE(1, client->download_progress_ct_);
EXPECT_EQ((int64_t)(settings_.response_data.size() -
settings_.expected_download_offset),
client->download_total_);
} else {
EXPECT_EQ(0, client->download_progress_ct_);
EXPECT_EQ(0, client->download_total_);
}
if (settings_.expect_download_data) {
size_t expected_offset = settings_.expected_download_offset;
EXPECT_LE(1, client->download_data_ct_);
EXPECT_STREQ(settings_.response_data.substr(expected_offset).c_str(),
client->download_data_.c_str());
} else {
EXPECT_EQ(0, client->download_data_ct_);
EXPECT_TRUE(client->download_data_.empty());
}
if (settings_.expect_authentication) {
EXPECT_EQ(1, client->auth_credentials_ct_);
} else {
EXPECT_EQ(0, client->auth_credentials_ct_);
}
}
// Run a test with a single request.
void SingleRunTest(base::OnceClosure complete_callback) {
SendRequest(base::BindOnce(&RequestTestRunner::SingleRunTestComplete, this,
std::move(complete_callback)));
}
void SingleRunTestComplete(base::OnceClosure complete_callback,
const test_request::State& completed_client) {
VerifyResponse(&completed_client);
std::move(complete_callback).Run();
}
// Run a test with multiple requests.
void MultipleRunTest(base::OnceClosure complete_callback) {
EXPECT_GT(settings_.expected_send_count, 0);
EXPECT_GE(settings_.expected_receive_count, 0);
MultipleRunTestContinue(std::move(complete_callback), 1);
}
void MultipleRunTestContinue(base::OnceClosure complete_callback,
int send_count) {
// Send the next request.
SendRequest(base::BindOnce(&RequestTestRunner::MultipleRunTestNext, this,
std::move(complete_callback), send_count));
}
void MultipleRunTestNext(base::OnceClosure complete_callback,
int send_count,
const test_request::State& completed_client) {
// Verify the completed request.
VerifyResponse(&completed_client);
if (send_count == settings_.expected_send_count) {
// All requests complete.
std::move(complete_callback).Run();
return;
}
const int next_send_count = send_count + 1;
auto continue_callback =
base::BindOnce(&RequestTestRunner::MultipleRunTestContinue, this,
std::move(complete_callback), next_send_count);
if (!settings_.setup_next_request.is_null()) {
// Provide an opportunity to modify expectations before the next request.
std::move(settings_.setup_next_request)
.Run(next_send_count, std::move(continue_callback));
} else {
std::move(continue_callback).Run();
}
}
// Register a test. Called in the constructor.
void RegisterTest(RequestTestMode test_mode,
TestCallback setup,
TestCallback run) {
TestEntry entry = {setup, run};
test_map_.insert(std::make_pair(test_mode, entry));
}
void CompleteOnCorrectThread(base::OnceClosure complete_callback) {
if (!owner_task_runner_->BelongsToCurrentThread()) {
owner_task_runner_->PostTask(CefCreateClosureTask(
base::BindOnce(&RequestTestRunner::CompleteOnCorrectThread, this,
std::move(complete_callback))));
return;
}
std::move(complete_callback).Run();
}
void RunDeleteTempDirectory(base::OnceClosure complete_callback) {
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
EXPECT_TRUE(CefCurrentlyOn(TID_FILE_USER_VISIBLE));
EXPECT_TRUE(post_file_tmpdir_.Delete());
EXPECT_TRUE(post_file_tmpdir_.IsEmpty());
// Continue with test shutdown.
RunShutdown(std::move(complete_callback));
}
void RunShutdown(base::OnceClosure complete_callback) {
if (!owner_task_runner_->BelongsToCurrentThread()) {
owner_task_runner_->PostTask(CefCreateClosureTask(
base::BindOnce(&RequestTestRunner::RunShutdown, this,
std::move(complete_callback))));
return;
}
ShutdownTestBackend(std::move(complete_callback));
}
// Create the backend for the current test. Called during test setup.
void SetupTestBackend(base::OnceClosure complete_callback) {
EXPECT_TRUE(settings_.request.get());
EXPECT_TRUE(settings_.response.get() ||
settings_.expected_status == UR_FAILED);
if (is_server_backend_) {
StartServer(std::move(complete_callback));
} else {
AddSchemeHandler(std::move(complete_callback));
}
}
void StartServer(base::OnceClosure complete_callback) {
EXPECT_FALSE(server_handler_);
server_handler_ = new RequestServerHandler();
server_handler_->AddSchemeHandler(&settings_);
if (settings_.expected_receive_count >= 0) {
server_handler_->SetExpectedRequestCount(
settings_.expected_receive_count);
}
server_handler_->CreateServer(std::move(complete_callback));
}
void AddSchemeHandler(base::OnceClosure complete_callback) {
EXPECT_FALSE(scheme_factory_);
// Add the factory registration.
scheme_factory_ = new RequestSchemeHandlerFactory();
request_context_->RegisterSchemeHandlerFactory(GetRequestScheme(false),
GetRequestHost(false, false),
scheme_factory_.get());
scheme_factory_->AddSchemeHandler(&settings_);
// Any further calls will come from the IO thread.
scheme_factory_->SetOwnerTaskRunner(CefTaskRunner::GetForThread(TID_IO));
std::move(complete_callback).Run();
}
// Shutdown the backend for the current test. Called during test shutdown.
void ShutdownTestBackend(base::OnceClosure complete_callback) {
if (is_server_backend_) {
ShutdownServer(std::move(complete_callback));
} else {
RemoveSchemeHandler(std::move(complete_callback));
}
}
void ShutdownServer(base::OnceClosure complete_callback) {
EXPECT_TRUE(server_handler_);
// |server_handler_| will delete itself after shutdown.
server_handler_->ShutdownServer(std::move(complete_callback));
server_handler_ = nullptr;
}
void RemoveSchemeHandler(base::OnceClosure complete_callback) {
EXPECT_TRUE(scheme_factory_);
// Remove the factory registration.
request_context_->RegisterSchemeHandlerFactory(
GetRequestScheme(false), GetRequestHost(false, false), nullptr);
scheme_factory_->Shutdown(std::move(complete_callback));
scheme_factory_ = nullptr;
}
const bool is_server_backend_;
const bool use_frame_method_;
// Used with incomplete request tests.
base::OnceClosure incomplete_request_callback_;
// Primary thread runner (UI thread) for the object that owns us.
CefRefPtr<CefTaskRunner> owner_task_runner_;
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
CefRefPtr<CefRequestContext> request_context_;
// Frame that originates the request. May be nullptr.
CefRefPtr<CefFrame> frame_;
struct TestEntry {
TestCallback setup;
TestCallback run;
};
typedef std::map<RequestTestMode, TestEntry> TestMap;
TestMap test_map_;
// Server backend.
RequestServerHandler* server_handler_ = nullptr;
// Scheme handler backend.
std::string scheme_name_;
CefRefPtr<RequestSchemeHandlerFactory> scheme_factory_;
CefScopedTempDir post_file_tmpdir_;
public:
RequestRunSettings settings_;
};
class RequestTestHandler : public TestHandler {
public:
RequestTestHandler(RequestTestMode test_mode,
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
ContextTestMode context_mode,
bool test_server_backend,
bool test_frame_method)
: test_mode_(test_mode),
context_mode_(context_mode),
test_server_backend_(test_server_backend),
test_frame_method_(test_frame_method),
test_url_(GetRequestOrigin(test_server_backend) +
"/URLRequestTest.Test") {}
void RunTest() override {
// Time out the test after a reasonable period of time.
SetTestTimeout(5000);
// Start pre-setup actions.
PreSetupStart();
}
void PreSetupStart() {
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
CefPostTask(TID_FILE_USER_VISIBLE,
base::BindOnce(&RequestTestHandler::PreSetupFileTasks, this));
}
void PreSetupFileTasks() {
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
EXPECT_TRUE(CefCurrentlyOn(TID_FILE_USER_VISIBLE));
if (context_mode_ == CONTEXT_ONDISK) {
EXPECT_TRUE(context_tmpdir_.CreateUniqueTempDirUnderPath(
CefTestSuite::GetInstance()->root_cache_path()));
context_tmpdir_path_ = context_tmpdir_.GetPath();
EXPECT_FALSE(context_tmpdir_path_.empty());
}
CefPostTask(TID_UI,
base::BindOnce(&RequestTestHandler::PreSetupContinue, this));
}
void PreSetupContinue() {
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
test_runner_ = new RequestTestRunner(
test_server_backend_, test_frame_method_,
base::BindOnce(&RequestTestHandler::OnIncompleteRequest, this));
test_runner_->Initialize();
// Configure the number of times that SignalTestCompletion() will be called.
// We need to call it at least 1 time if we don't create a browser.
size_t completion_count = test_frame_method_ ? 0U : 1U;
if (context_mode_ != CONTEXT_GLOBAL) {
// Don't end the test until the temporary request context has been
// destroyed.
completion_count++;
}
if (completion_count > 0U) {
SetSignalTestCompletionCount(completion_count);
}
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
// Get or create the request context.
if (context_mode_ == CONTEXT_GLOBAL) {
CefRefPtr<CefRequestContext> request_context =
CefRequestContext::GetGlobalContext();
EXPECT_TRUE(request_context.get());
test_runner_->SetRequestContext(request_context);
PreSetupComplete();
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
} else {
CefRequestContextSettings settings;
if (context_mode_ == CONTEXT_ONDISK) {
EXPECT_FALSE(context_tmpdir_.IsEmpty());
CefString(&settings.cache_path) = context_tmpdir_path_;
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
}
if (!test_server_backend_) {
// Set the schemes that are allowed to store cookies.
CefString(&settings.cookieable_schemes_list) = GetRequestScheme(false);
}
// Create a new temporary request context. Calls OnContextInitialized.
CefRequestContext::CreateContext(settings,
new RequestContextHandler(this));
}
}
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
void OnContextInitialized(CefRefPtr<CefRequestContext> request_context) {
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
EXPECT_TRUE(request_context.get());
test_runner_->SetRequestContext(request_context);
PreSetupComplete();
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
}
void PreSetupComplete() {
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
if (!CefCurrentlyOn(TID_UI)) {
CefPostTask(TID_UI,
base::BindOnce(&RequestTestHandler::PreSetupComplete, this));
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
return;
}
// Setup the test. This will create the objects that we test against and
// register the backend.
test_runner_->SetupTest(
test_mode_, base::BindOnce(&RequestTestHandler::OnSetupComplete, this));
}
// Browser process setup is complete.
void OnSetupComplete() {
// Start post-setup actions.
SetTestCookie(test_runner_->GetRequestContext(), test_server_backend_,
base::BindOnce(&RequestTestHandler::PostSetupComplete, this));
}
void PostSetupComplete() {
if (!CefCurrentlyOn(TID_UI)) {
CefPostTask(TID_UI,
base::BindOnce(&RequestTestHandler::PostSetupComplete, this));
return;
}
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
if (test_frame_method_) {
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
AddResource(test_url_, "<html><body>TEST</body></html>", "text/html");
// Create the browser who's main frame will be the initiator for the
// request.
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
CreateBrowser(test_url_, test_runner_->GetRequestContext());
} else {
// Run the test now.
test_running_ = true;
test_runner_->RunTest(
test_mode_, nullptr /* frame */,
base::BindOnce(&RequestTestHandler::OnRunComplete, this));
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
}
}
ReturnValue OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback) override {
if (test_running_ && test_frame_method_) {
EXPECT_TRUE(frame);
EXPECT_STREQ(test_frame_->GetIdentifier().ToString().c_str(),
frame->GetIdentifier().ToString().c_str());
test_frame_resource_load_ct_++;
}
return TestHandler::OnBeforeResourceLoad(browser, frame, request, callback);
}
bool GetAuthCredentials(CefRefPtr<CefBrowser> browser,
const CefString& origin_url,
bool isProxy,
const CefString& host,
int port,
const CefString& realm,
const CefString& scheme,
CefRefPtr<CefAuthCallback> callback) override {
EXPECT_TRUE(test_frame_method_);
auth_credentials_ct_++;
if (test_runner_->settings_.expect_authentication) {
callback->Continue(test_runner_->settings_.username,
test_runner_->settings_.password);
return true;
}
return false;
}
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) override {
if (test_frame_method_) {
// Run the test now.
test_frame_ = frame;
test_running_ = true;
test_runner_->RunTest(
test_mode_, frame,
base::BindOnce(&RequestTestHandler::OnRunComplete, this));
return;
}
}
// Incomplete tests will not complete normally. Instead, we trigger a browser
// close to abort in-progress requests.
void OnIncompleteRequest() {
if (!CefCurrentlyOn(TID_UI)) {
CefPostTask(TID_UI, base::BindOnce(
&RequestTestHandler::OnIncompleteRequest, this));
return;
}
EXPECT_TRUE(test_frame_method_);
EXPECT_NE(RequestRunSettings::INCOMPLETE_NONE,
test_runner_->settings_.incomplete_type);
// TestComplete will eventually be called from DestroyTest instead of being
// triggered by browser destruction.
CefPostDelayedTask(
TID_UI, base::BindOnce(&TestHandler::CloseBrowser, GetBrowser(), false),
1000);
}
// Test run is complete.
void OnRunComplete() {
GetTestCookie(test_runner_->GetRequestContext(), test_server_backend_,
base::BindOnce(&RequestTestHandler::PostRunComplete, this));
}
void PostRunComplete(bool has_save_cookie) {
if (!CefCurrentlyOn(TID_UI)) {
CefPostTask(TID_UI, base::BindOnce(&RequestTestHandler::PostRunComplete,
this, has_save_cookie));
return;
}
EXPECT_EQ(test_runner_->settings_.expect_save_cookie, has_save_cookie);
// Shut down the browser side of the test.
test_runner_->ShutdownTest(
base::BindOnce(&RequestTestHandler::MaybeClearAuthCredentials, this));
}
void MaybeClearAuthCredentials() {
if (test_runner_->settings_.expect_authentication &&
context_mode_ == CONTEXT_GLOBAL) {
// Clear the HTTP authentication cache to avoid leaking state between
// test runs when using the global request context.
test_runner_->GetRequestContext()->ClearHttpAuthCredentials(
new TestCompletionCallback(
base::BindOnce(&RequestTestHandler::DestroyTest, this)));
return;
}
DestroyTest();
}
void DestroyTest() override {
if (test_frame_method_) {
// Expect at least 1 call to OnBeforeResourceLoad for every test.
// Redirect tests may get multiple calls.
EXPECT_LE(1, test_frame_resource_load_ct_);
}
// CefRequestHandler::GetAuthCredentials should be called after
// CefURLRequestClient::GetAuthCredentials when the request has an
// associated frame.
if (test_frame_method_ && test_runner_->settings_.expect_authentication) {
EXPECT_EQ(1, auth_credentials_ct_);
} else {
EXPECT_EQ(0, auth_credentials_ct_);
}
TestHandler::DestroyTest();
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
// Release references to the context and handler.
test_runner_->Destroy();
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
// These tests don't create a browser that would signal implicitly.
if (!test_frame_method_) {
OnTestComplete();
2023-01-02 23:59:03 +01:00
}
}
void OnTestComplete() {
if (!CefCurrentlyOn(TID_UI)) {
CefPostTask(TID_UI,
base::BindOnce(&RequestTestHandler::OnTestComplete, this));
return;
}
if (!context_tmpdir_.IsEmpty()) {
// Temp directory will be deleted on application shutdown.
context_tmpdir_.Take();
}
SignalTestCompletion();
}
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
private:
// Used with temporary request contexts to signal test completion once the
// temporary context has been destroyed.
class RequestContextHandler : public CefRequestContextHandler {
public:
explicit RequestContextHandler(CefRefPtr<RequestTestHandler> test_handler)
: test_handler_(test_handler) {}
~RequestContextHandler() override { test_handler_->OnTestComplete(); }
void OnRequestContextInitialized(
CefRefPtr<CefRequestContext> request_context) override {
test_handler_->OnContextInitialized(request_context);
}
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
private:
CefRefPtr<RequestTestHandler> test_handler_;
IMPLEMENT_REFCOUNTING(RequestContextHandler);
};
const RequestTestMode test_mode_;
const ContextTestMode context_mode_;
const bool test_server_backend_;
const bool test_frame_method_;
const std::string test_url_;
Add support for complete isolation of storage and permissions (cache, cookies, localStorage, access grants, etc) on a per-request-context basis (issue #1044). - CefRequestContext instances can be configured using a new CefRequestContextSettings structure passed to CefRequestContext::CreateContext. - Scheme registration is now per-request-context using new CefRequestContext::RegisterSchemeHandlerFactory and ClearSchemeHandlerFactories methods. - Cookie managers are now per-request-context by default and can be retrieved using a new CefRequestContext::GetDefaultCookieManager method. - CefURLRequest::Create now accepts an optional CefRequestContext argument for associating a URL request with a context (browser process only). - The CefRequestContextHandler associated with a CefRequestContext will not be released until all objects related to that context have been destroyed. - When the cache path is empty an in-memory cache ("incognito mode") will be used for storage and no data will be persisted to disk. - Add CefSettings.user_data_path which specifies the location where user data such as spell checking dictionary files will be stored on disk. - Add asynchronous callbacks for all CefCookieManager methods. - Add PK_LOCAL_APP_DATA and PK_USER_DATA path keys for retrieving user directories via CefGetPath. - cefclient: Add "New Window" test that creates a new window unrelated to existing windows. When used in combination with `--request-context-per-browser` the new window will be given a new and isolated request context. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2040 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2015-03-02 21:25:14 +01:00
scoped_refptr<RequestTestRunner> test_runner_;
bool test_running_ = false;
CefRefPtr<CefFrame> test_frame_;
int test_frame_resource_load_ct_ = 0;
CefScopedTempDir context_tmpdir_;
CefString context_tmpdir_path_;
public:
int auth_credentials_ct_ = 0;
IMPLEMENT_REFCOUNTING(RequestTestHandler);
};
} // namespace
// Entry point for registering custom schemes.
// Called from client_app_delegates.cc.
void RegisterURLRequestCustomSchemes(CefRawPtr<CefSchemeRegistrar> registrar) {
const std::string& scheme = GetRequestScheme(false);
registrar->AddCustomScheme(
scheme, CEF_SCHEME_OPTION_STANDARD | CEF_SCHEME_OPTION_CORS_ENABLED);
}
// Entry point for registering cookieable schemes.
// Called from client_app_delegates.cc.
void RegisterURLRequestCookieableSchemes(
std::vector<std::string>& cookieable_schemes) {
const std::string& scheme = GetRequestScheme(false);
cookieable_schemes.push_back(scheme);
}
// Helpers for defining URLRequest tests.
#define REQ_TEST(name, test_mode, context_mode, test_server_backend, \
test_frame_method) \
TEST(URLRequestTest, name) { \
CefRefPtr<RequestTestHandler> handler = new RequestTestHandler( \
test_mode, context_mode, test_server_backend, test_frame_method); \
handler->ExecuteTest(); \
ReleaseAndWaitForDestructor(handler); \
}
// Define the tests.
#define REQ_TEST_SET_EX(suffix, context_mode, test_server_backend, \
test_frame_method) \
REQ_TEST(BrowserGET##suffix, REQTEST_GET, context_mode, test_server_backend, \
test_frame_method) \
REQ_TEST(BrowserGETNoData##suffix, REQTEST_GET_NODATA, context_mode, \
test_server_backend, test_frame_method) \
REQ_TEST(BrowserGETPartialContent##suffix, REQTEST_GET_PARTIAL_CONTENT, \
context_mode, test_server_backend, test_frame_method) \
REQ_TEST(BrowserGETAllowCookies##suffix, REQTEST_GET_ALLOWCOOKIES, \
context_mode, test_server_backend, test_frame_method) \
REQ_TEST(BrowserGETRedirect##suffix, REQTEST_GET_REDIRECT, context_mode, \
test_server_backend, test_frame_method) \
REQ_TEST(BrowserGETRedirectStop##suffix, REQTEST_GET_REDIRECT_STOP, \
context_mode, test_server_backend, test_frame_method) \
REQ_TEST(BrowserGETRedirectLocation##suffix, REQTEST_GET_REDIRECT_LOCATION, \
context_mode, test_server_backend, test_frame_method) \
REQ_TEST(BrowserGETReferrer##suffix, REQTEST_GET_REFERRER, context_mode, \
test_server_backend, test_frame_method) \
REQ_TEST(BrowserPOST##suffix, REQTEST_POST, context_mode, \
test_server_backend, test_frame_method) \
REQ_TEST(BrowserPOSTFile##suffix, REQTEST_POST_FILE, context_mode, \
test_server_backend, test_frame_method) \
REQ_TEST(BrowserPOSTWithProgress##suffix, REQTEST_POST_WITHPROGRESS, \
context_mode, test_server_backend, test_frame_method) \
REQ_TEST(BrowserPOSTRedirect##suffix, REQTEST_POST_REDIRECT, context_mode, \
test_server_backend, test_frame_method) \
REQ_TEST(BrowserPOSTRedirectToGET##suffix, REQTEST_POST_REDIRECT_TOGET, \
context_mode, test_server_backend, test_frame_method) \
REQ_TEST(BrowserHEAD##suffix, REQTEST_HEAD, context_mode, \
test_server_backend, test_frame_method)
#define REQ_TEST_SET(suffix, test_frame_method) \
REQ_TEST_SET_EX(ContextGlobalCustom##suffix, CONTEXT_GLOBAL, false, \
test_frame_method) \
REQ_TEST_SET_EX(ContextInMemoryCustom##suffix, CONTEXT_INMEMORY, false, \
test_frame_method) \
REQ_TEST_SET_EX(ContextOnDiskCustom##suffix, CONTEXT_ONDISK, false, \
test_frame_method) \
REQ_TEST_SET_EX(ContextGlobalServer##suffix, CONTEXT_GLOBAL, true, \
test_frame_method) \
REQ_TEST_SET_EX(ContextInMemoryServer##suffix, CONTEXT_INMEMORY, true, \
test_frame_method) \
REQ_TEST_SET_EX(ContextOnDiskServer##suffix, CONTEXT_ONDISK, true, \
test_frame_method)
REQ_TEST_SET(WithoutFrame, false)
REQ_TEST_SET(WithFrame, true)
// Define tests that can only run with a frame.
#define REQ_TEST_FRAME_SET_EX(suffix, context_mode, test_server_backend) \
REQ_TEST(BrowserIncompleteProcessRequest##suffix, \
REQTEST_INCOMPLETE_PROCESS_REQUEST, context_mode, \
test_server_backend, true) \
REQ_TEST(BrowserIncompleteReadResponse##suffix, \
REQTEST_INCOMPLETE_READ_RESPONSE, context_mode, \
test_server_backend, true)
#define REQ_TEST_FRAME_SET() \
REQ_TEST_FRAME_SET_EX(ContextGlobalCustomWithFrame, CONTEXT_GLOBAL, false) \
REQ_TEST_FRAME_SET_EX(ContextInMemoryCustomWithFrame, CONTEXT_INMEMORY, \
false) \
REQ_TEST_FRAME_SET_EX(ContextOnDiskCustomWithFrame, CONTEXT_ONDISK, false) \
REQ_TEST_FRAME_SET_EX(ContextGlobalServerWithFrame, CONTEXT_GLOBAL, true) \
REQ_TEST_FRAME_SET_EX(ContextInMemoryServerWithFrame, CONTEXT_INMEMORY, \
true) \
REQ_TEST_FRAME_SET_EX(ContextOnDiskServerWithFrame, CONTEXT_ONDISK, true)
REQ_TEST_FRAME_SET()
// Cache and authentication tests can only be run with the server backend.
#define REQ_TEST_CACHE_SET_EX(suffix, context_mode, test_frame_method) \
REQ_TEST(BrowserGETCacheWithControl##suffix, REQTEST_CACHE_WITH_CONTROL, \
context_mode, true, test_frame_method) \
REQ_TEST(BrowserGETCacheWithoutControl##suffix, \
REQTEST_CACHE_WITHOUT_CONTROL, context_mode, true, \
test_frame_method) \
REQ_TEST(BrowserGETCacheSkipFlag##suffix, REQTEST_CACHE_SKIP_FLAG, \
context_mode, true, test_frame_method) \
REQ_TEST(BrowserGETCacheSkipHeader##suffix, REQTEST_CACHE_SKIP_HEADER, \
context_mode, true, test_frame_method) \
REQ_TEST(BrowserGETCacheOnlyFailureFlag##suffix, \
REQTEST_CACHE_ONLY_FAILURE_FLAG, context_mode, true, \
test_frame_method) \
REQ_TEST(BrowserGETCacheOnlyFailureHeader##suffix, \
REQTEST_CACHE_ONLY_FAILURE_HEADER, context_mode, true, \
test_frame_method) \
REQ_TEST(BrowserGETCacheOnlySuccessFlag##suffix, \
REQTEST_CACHE_ONLY_SUCCESS_FLAG, context_mode, true, \
test_frame_method) \
REQ_TEST(BrowserGETCacheOnlySuccessHeader##suffix, \
REQTEST_CACHE_ONLY_SUCCESS_HEADER, context_mode, true, \
test_frame_method) \
REQ_TEST(BrowserGETCacheDisableFlag##suffix, REQTEST_CACHE_DISABLE_FLAG, \
context_mode, true, test_frame_method) \
REQ_TEST(BrowserGETCacheDisableHeader##suffix, REQTEST_CACHE_DISABLE_HEADER, \
context_mode, true, test_frame_method) \
REQ_TEST(BrowserGETAuth##suffix, REQTEST_GET_AUTH, context_mode, true, \
test_frame_method)
#define REQ_TEST_CACHE_SET(suffix, test_frame_method) \
REQ_TEST_CACHE_SET_EX(ContextGlobalServer##suffix, CONTEXT_GLOBAL, \
test_frame_method) \
REQ_TEST_CACHE_SET_EX(ContextInMemoryServer##suffix, CONTEXT_INMEMORY, \
test_frame_method) \
REQ_TEST_CACHE_SET_EX(ContextOnDiskServer##suffix, CONTEXT_ONDISK, \
test_frame_method)
REQ_TEST_CACHE_SET(WithoutFrame, false)
REQ_TEST_CACHE_SET(WithFrame, true)
namespace {
class InvalidURLTestClient : public CefURLRequestClient {
public:
InvalidURLTestClient() {
event_ = CefWaitableEvent::CreateWaitableEvent(true, false);
}
void RunTest() {
CefPostTask(TID_UI,
base::BindOnce(&InvalidURLTestClient::RunOnUIThread, this));
// Wait for the test to complete.
event_->Wait();
}
void OnRequestComplete(CefRefPtr<CefURLRequest> client) override {
EXPECT_EQ(UR_FAILED, client->GetRequestStatus());
EXPECT_EQ(ERR_UNKNOWN_URL_SCHEME, client->GetRequestError());
// Let the call stack unwind before signaling completion.
CefPostTask(TID_UI, base::BindOnce(
&InvalidURLTestClient::CompleteOnUIThread, this));
}
void OnUploadProgress(CefRefPtr<CefURLRequest> request,
int64_t current,
int64_t total) override {
EXPECT_TRUE(false); // Not reached.
}
void OnDownloadProgress(CefRefPtr<CefURLRequest> request,
int64_t current,
int64_t total) override {
EXPECT_TRUE(false); // Not reached.
}
void OnDownloadData(CefRefPtr<CefURLRequest> request,
const void* data,
size_t data_length) override {
EXPECT_TRUE(false); // Not reached.
}
bool GetAuthCredentials(bool isProxy,
const CefString& host,
int port,
const CefString& realm,
const CefString& scheme,
CefRefPtr<CefAuthCallback> callback) override {
EXPECT_TRUE(false); // Not reached.
return false;
}
private:
void RunOnUIThread() {
EXPECT_UI_THREAD();
CefRefPtr<CefRequest> request = CefRequest::Create();
request->SetMethod("GET");
request->SetURL("foo://invalidurl");
CefURLRequest::Create(request, this, nullptr);
}
void CompleteOnUIThread() {
EXPECT_UI_THREAD();
// Signal that the test is complete.
event_->Signal();
}
CefRefPtr<CefWaitableEvent> event_;
IMPLEMENT_REFCOUNTING(InvalidURLTestClient);
};
} // namespace
// Verify that failed requests do not leak references.
TEST(URLRequestTest, BrowserInvalidURL) {
CefRefPtr<InvalidURLTestClient> client = new InvalidURLTestClient();
client->RunTest();
}
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
// Entry point for creating URLRequest browser test objects.
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
// Called from client_app_delegates.cc.
void CreateURLRequestBrowserTests(
client::ClientAppBrowser::DelegateSet& delegates) {
delegates.insert(new URLRequestBrowserTest);
}