From f67b6fecafc1886b3e4f65c431c34e7e32da6c59 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Wed, 18 Feb 2015 17:28:56 +0000 Subject: [PATCH] Support configuration of the "Accept-Language" HTTP header globally or on a per-browser basis using new CefSettings.accept_language_list and CefBrowserSettings.accept_language_list members (issue #318). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2033 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- AUTHORS.txt | 1 + include/internal/cef_types.h | 16 ++++++ include/internal/cef_types_wrappers.h | 12 +++- libcef/browser/url_network_delegate.cc | 9 +++ .../url_request_context_getter_impl.cc | 11 +++- tests/unittests/scheme_handler_unittest.cc | 56 +++++++++++++++++++ tests/unittests/test_handler.cc | 1 + tests/unittests/test_handler.h | 3 + tests/unittests/test_suite.cc | 3 + tests/unittests/test_suite.h | 2 + tests/unittests/urlrequest_unittest.cc | 6 ++ 11 files changed, 117 insertions(+), 3 deletions(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index 38c5d242c..aa45e3a95 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -27,3 +27,4 @@ Mihai Tica Czarek Tomczak Felix Bruns YuTeh Shen +Andrei Kurushin diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index 7d7dcdf81..dfc04e10b 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -381,6 +381,14 @@ typedef struct _cef_settings_t { // of the background color but will be otherwise ignored. /// cef_color_t background_color; + + /// + // Comma delimited ordered list of language codes without any whitespace that + // will be used in the "Accept-Language" HTTP header. May be overridden on a + // per-browser basis using the CefBrowserSettings.accept_language_list value. + // If both values are empty then "en-US,en" will be used. + /// + cef_string_t accept_language_list; } cef_settings_t; /// @@ -564,6 +572,14 @@ typedef struct _cef_browser_settings_t { // 0 to enable use of the background color but will be otherwise ignored. /// cef_color_t background_color; + + /// + // Comma delimited ordered list of language codes without any whitespace that + // will be used in the "Accept-Language" HTTP header. May be set globally + // using the CefBrowserSettings.accept_language_list value. If both values are + // empty then "en-US,en" will be used. + /// + cef_string_t accept_language_list; } cef_browser_settings_t; /// diff --git a/include/internal/cef_types_wrappers.h b/include/internal/cef_types_wrappers.h index 9a4036d9c..b28b76bac 100644 --- a/include/internal/cef_types_wrappers.h +++ b/include/internal/cef_types_wrappers.h @@ -276,8 +276,8 @@ struct CefScreenInfoTraits { }; /// -// Class representing the virtual screen information for use when window rendering -// is disabled. +// Class representing the virtual screen information for use when window +// rendering is disabled. /// class CefScreenInfo : public CefStructBase { public: @@ -425,6 +425,7 @@ struct CefSettingsTraits { cef_string_clear(&s->javascript_flags); cef_string_clear(&s->resources_dir_path); cef_string_clear(&s->locales_dir_path); + cef_string_clear(&s->accept_language_list); } static inline void set(const struct_type* src, struct_type* target, @@ -464,6 +465,9 @@ struct CefSettingsTraits { target->context_safety_implementation = src->context_safety_implementation; target->ignore_certificate_errors = src->ignore_certificate_errors; target->background_color = src->background_color; + + cef_string_set(src->accept_language_list.str, + src->accept_language_list.length, &target->accept_language_list, copy); } }; @@ -488,6 +492,7 @@ struct CefBrowserSettingsTraits { cef_string_clear(&s->cursive_font_family); cef_string_clear(&s->fantasy_font_family); cef_string_clear(&s->default_encoding); + cef_string_clear(&s->accept_language_list); } static inline void set(const struct_type* src, struct_type* target, @@ -540,6 +545,9 @@ struct CefBrowserSettingsTraits { target->webgl = src->webgl; target->background_color = src->background_color; + + cef_string_set(src->accept_language_list.str, + src->accept_language_list.length, &target->accept_language_list, copy); } }; diff --git a/libcef/browser/url_network_delegate.cc b/libcef/browser/url_network_delegate.cc index df7916a62..479442853 100644 --- a/libcef/browser/url_network_delegate.cc +++ b/libcef/browser/url_network_delegate.cc @@ -13,6 +13,7 @@ #include "libcef/common/request_impl.h" #include "net/base/net_errors.h" +#include "net/http/http_util.h" #include "net/url_request/url_request.h" namespace { @@ -92,6 +93,14 @@ int CefNetworkDelegate::OnBeforeURLRequest( CefRefPtr browser = CefBrowserHostImpl::GetBrowserForRequest(request); if (browser.get()) { + const CefBrowserSettings& browser_settings = browser->settings(); + if (browser_settings.accept_language_list.length > 0) { + const std::string& accept_language = + net::HttpUtil::GenerateAcceptLanguageHeader( + CefString(&browser_settings.accept_language_list)); + request->SetExtraRequestHeaderByName( + net::HttpRequestHeaders::kAcceptLanguage, accept_language, false); + } CefRefPtr client = browser->GetClient(); if (client.get()) { CefRefPtr handler = client->GetRequestHandler(); diff --git a/libcef/browser/url_request_context_getter_impl.cc b/libcef/browser/url_request_context_getter_impl.cc index 19b96e231..9c8603214 100644 --- a/libcef/browser/url_request_context_getter_impl.cc +++ b/libcef/browser/url_request_context_getter_impl.cc @@ -144,8 +144,17 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() { new net::ChannelIDService( new net::DefaultChannelIDStore(NULL), base::WorkerPool::GetTaskRunner(true)))); + + std::string accept_language; + if (settings.accept_language_list.length > 0) { + accept_language = + net::HttpUtil::GenerateAcceptLanguageHeader( + CefString(&settings.accept_language_list)); + } else { + accept_language = "en-US,en"; + } storage_->set_http_user_agent_settings( - new CefHttpUserAgentSettings("en-us,en")); + new CefHttpUserAgentSettings(accept_language)); storage_->set_host_resolver(net::HostResolver::CreateDefaultResolver(NULL)); storage_->set_cert_verifier(net::CertVerifier::CreateDefault()); diff --git a/tests/unittests/scheme_handler_unittest.cc b/tests/unittests/scheme_handler_unittest.cc index 800708f83..33fe01c06 100644 --- a/tests/unittests/scheme_handler_unittest.cc +++ b/tests/unittests/scheme_handler_unittest.cc @@ -13,6 +13,7 @@ #include "include/cef_scheme.h" #include "include/wrapper/cef_closure_task.h" #include "tests/unittests/test_handler.h" +#include "tests/unittests/test_suite.h" namespace { @@ -34,6 +35,7 @@ class TestResults { sub_status_code = 0; sub_allow_origin.clear(); exit_url.clear(); + accept_language.clear(); delay = 0; got_request.reset(); got_read.reset(); @@ -60,6 +62,9 @@ class TestResults { std::string sub_redirect_url; std::string exit_url; + // Used for testing per-browser Accept-Language. + std::string accept_language; + // Delay for returning scheme handler results. int delay; @@ -87,6 +92,13 @@ class TestSchemeHandler : public TestHandler { g_current_handler = this; } + void PopulateBrowserSettings(CefBrowserSettings* settings) override { + if (!test_results_->accept_language.empty()) { + CefString(&settings->accept_language_list) = + test_results_->accept_language; + } + } + void RunTest() override { CreateBrowser(test_results_->url); @@ -194,6 +206,27 @@ class ClientSchemeHandler : public CefResourceHandler { handled = true; } + std::string accept_language; + CefRequest::HeaderMap headerMap; + CefRequest::HeaderMap::iterator headerIter; + request->GetHeaderMap(headerMap); + headerIter = headerMap.find("Accept-Language"); + if (headerIter != headerMap.end()) + accept_language = headerIter->second; + EXPECT_TRUE(!accept_language.empty()); + + if (!test_results_->accept_language.empty()) { + // Value from CefBrowserSettings.accept_language set in + // PopulateBrowserSettings(). + EXPECT_STREQ(test_results_->accept_language.data(), + accept_language.data()); + } else { + // Value from CefSettings.accept_language set in + // CefTestSuite::GetSettings(). + EXPECT_STREQ(CEF_SETTINGS_ACCEPT_LANGUAGE, + accept_language.data()); + } + if (handled) { if (test_results_->delay > 0) { // Continue after the delay. @@ -1563,6 +1596,29 @@ TEST(SchemeHandlerTest, ClearTestSchemes(); } +// Test per-browser setting of Accept-Language. +TEST(SchemeHandlerTest, AcceptLanguage) { + RegisterTestScheme("customstd", "test"); + g_TestResults.url = "customstd://test/run.html"; + g_TestResults.html = + "

Success!

"; + g_TestResults.status_code = 200; + + // Value that will be set via CefBrowserSettings.accept_language in + // PopulateBrowserSettings(). + g_TestResults.accept_language = "uk"; + + CefRefPtr handler = new TestSchemeHandler(&g_TestResults); + handler->ExecuteTest(); + ReleaseAndWaitForDestructor(handler); + + EXPECT_TRUE(g_TestResults.got_request); + EXPECT_TRUE(g_TestResults.got_read); + EXPECT_TRUE(g_TestResults.got_output); + + ClearTestSchemes(); +} + // Entry point for registering custom schemes. // Called from client_app_delegates.cc. diff --git a/tests/unittests/test_handler.cc b/tests/unittests/test_handler.cc index 052e988d4..a94937cb4 100644 --- a/tests/unittests/test_handler.cc +++ b/tests/unittests/test_handler.cc @@ -287,6 +287,7 @@ void TestHandler::CreateBrowser( windowInfo.SetAsPopup(NULL, "CefUnitTest"); windowInfo.style |= WS_VISIBLE; #endif + PopulateBrowserSettings(&settings); CefBrowserHost::CreateBrowser(windowInfo, this, url, settings, request_context); } diff --git a/tests/unittests/test_handler.h b/tests/unittests/test_handler.h index 79e9dc11e..ddc452cc4 100644 --- a/tests/unittests/test_handler.h +++ b/tests/unittests/test_handler.h @@ -214,6 +214,9 @@ class TestHandler : public CefClient, // SetTestTimeout(). Calls DestroyTest() by default. virtual void OnTestTimeout(int timeout_ms); + // Called from CreateBrowser() to optionally set per-browser settings. + virtual void PopulateBrowserSettings(CefBrowserSettings* settings) {} + void CreateBrowser(const CefString& url, CefRefPtr request_context = NULL); diff --git a/tests/unittests/test_suite.cc b/tests/unittests/test_suite.cc index e6de22536..dee0cf50e 100644 --- a/tests/unittests/test_suite.cc +++ b/tests/unittests/test_suite.cc @@ -69,6 +69,9 @@ void CefTestSuite::GetSettings(CefSettings& settings) { // Necessary for the OSRTest tests. settings.windowless_rendering_enabled = true; + + // For Accept-Language test + CefString(&settings.accept_language_list) = CEF_SETTINGS_ACCEPT_LANGUAGE; } // static diff --git a/tests/unittests/test_suite.h b/tests/unittests/test_suite.h index 6ea3797a7..12b0d9d7d 100644 --- a/tests/unittests/test_suite.h +++ b/tests/unittests/test_suite.h @@ -36,4 +36,6 @@ class CefTestSuite : public TestSuite { static base::CommandLine* commandline_; }; +#define CEF_SETTINGS_ACCEPT_LANGUAGE "en-GB" + #endif // CEF_TESTS_UNITTESTS_TEST_SUITE_H_ diff --git a/tests/unittests/urlrequest_unittest.cc b/tests/unittests/urlrequest_unittest.cc index ca6bb3c77..cdebd142d 100644 --- a/tests/unittests/urlrequest_unittest.cc +++ b/tests/unittests/urlrequest_unittest.cc @@ -21,6 +21,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "tests/cefclient/renderer/client_app_renderer.h" #include "tests/unittests/test_handler.h" +#include "tests/unittests/test_suite.h" #include "tests/unittests/test_util.h" using client::ClientAppRenderer; @@ -212,6 +213,11 @@ class RequestSchemeHandler : public CefResourceHandler { headerIter = headerMap.find("Accept-Language"); EXPECT_TRUE(headerIter != headerMap.end() && !headerIter->second.empty()); + // Verify that we get the value that was set via + // CefSettings.accept_language_list in CefTestSuite::GetSettings(). + EXPECT_STREQ(CEF_SETTINGS_ACCEPT_LANGUAGE, + headerIter->second.ToString().data()); + // Check if the request cookie was sent. bool has_send_cookie = false; headerIter = headerMap.find("Cookie");