I am using - for different reasons - a patched CEF, which overrides user agent on a per request/url basis.
Basically it's a new method in CefRequestHandler:
- Code: Select all
class CefRequestHandler : public virtual CefBaseRefCounted {
public:
typedef cef_return_value_t ReturnValue;
...
///
// Set user agent *before* CefRequest becomes readonly.
///
virtual bool GetOverrideUserAgent(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> request_info,
CefString& overrideUserAgent) { return false; }
};
#endif // CEF_INCLUDE_CEF_REQUEST_HANDLER_H_
(Can be used also directly CefString url instead of CefRefPtr<CefDictionaryValue> request_info - it's a dictionary for me in case I will need other values).
The implementation is basically:
1. in OnBeforeResourceLoad
- Code: Select all
CefRequestHandler::ReturnValue
ClientHandler::OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefRequestCallback> callback)
{
...
// spoof user agent if necessary
CefRefPtr<CefDictionaryValue> request_info =
CefDictionaryValue::Create();
if(request_info.get()) {
request_info->SetString(CefString("url"), request->GetURL());
}
CefRequest::HeaderMap headers;
request->GetHeaderMap(headers);
...
CefString overrideUserAgent;
if(GetOverrideUserAgent(browser, request_info, overrideUserAgent))
{
headers.erase("User-Agent");
headers.insert(std::make_pair("User-Agent", overrideUserAgent));
request->SetHeaderMap(headers);
}
...
and the implementation:
- Code: Select all
bool ClientHandler::GetOverrideUserAgent(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> request_info,
CefString& overrideUserAgent)
{
CEF_REQUIRE_IO_THREAD();
do {
if(request_info.get() == nullptr)
break;
if(!request_info->HasKey("url"))
break;
CefString url = request_info->GetString("url");
overrideUserAgent = CallYourInternalImplementationBasedOnUrl(url); // return empty string by default, Firefox user agent for others etc.
return !overrideUserAgent.empty();
#pragma warning(disable: 4127)
} while(0);
#pragma warning(default: 4127)
return false;
}
Then it's a matter of whatever CallYourInternalImplementationBasedOnUrl you need.
For example, if std::string(url).find("https://accounts.google.com/") == 0 ==> return Firefox UA etc.