I am using - for different reasons - a patched CEF, which overrides user agent on a per request/url basis.
Hmm thanks for the workaround!
I am using - for different reasons - a patched CEF, which overrides user agent on a per request/url basis.
class MyCefResourceRequestHandler : public CefResourceRequestHandler {
public:
CefResourceRequestHandler::ReturnValue OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefRequestCallback> callback) OVERRIDE;
bool GetOverrideUserAgent(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> request_info,
CefString& overrideUserAgent);
};
CefResourceRequestHandler::ReturnValue MyCefResourceRequestHandler::OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefRequestCallback> callback) {
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);
}
return RV_CONTINUE;
}
bool MyCefResourceRequestHandler::GetOverrideUserAgent(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> request_info,
CefString& overrideUserAgent) {
// spoof user-agent to Firefox for proof of concept
overrideUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0";
return true;
}
virtual bool GetOverrideUserAgent(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> request_info,
CefString& overrideUserAgent) { return false; }
std::string GetUserAgentFromBrowser(CefRefPtr<CefBrowserHostImpl> browser,
const GURL& url) {
std::string browser_user_agent = "";
if(browser) {
CefRefPtr<CefClient> client = browser->GetClient();
if(client) {
CefRefPtr<CefRequestHandler> request_handler =
client->GetRequestHandler();
if(request_handler) {
// build dictionary (for now just URL)
// to avoid modifying prototypes later
CefRefPtr<CefDictionaryValue> request_info =
CefDictionaryValue::Create();
if(request_info.get()) {
request_info->SetString(CefString("url"), url.spec());
}
CefString overrideUserAgent;
if(request_handler->GetOverrideUserAgent(browser.get(),
request_info, overrideUserAgent)) {
browser_user_agent = overrideUserAgent.ToString();
}
}
}
}
return browser_user_agent;
}
// InterceptedRequestHandler methods:
void OnBeforeRequest(const RequestId& id,
network::ResourceRequest* request,
bool request_was_redirected,
OnBeforeRequestResultCallback callback,
CancelRequestCallback cancel_callback) override {
CEF_REQUIRE_IOT();
if (shutting_down_) {
// Abort immediately.
std::move(cancel_callback).Run(net::ERR_ABORTED);
return;
}
if (!init_state_) {
// Queue requests until we're initialized.
pending_requests_.push_back(std::make_unique<PendingRequest>(
id, request, request_was_redirected, std::move(callback),
std::move(cancel_callback)));
return;
}
// State may already exist for restarted requests.
RequestState* state = GetOrCreateState(id);
// Add standard headers, if currently unspecified.
request->headers.SetHeaderIfMissing(
net::HttpRequestHeaders::kAcceptLanguage,
init_state_->accept_language_);
request->headers.SetHeaderIfMissing(net::HttpRequestHeaders::kUserAgent,
init_state_->user_agent_);
// if browser says otherwise, override with it
std::string browser_user_agent =
GetUserAgentFromBrowser(init_state_->browser_, request->url);
if(!browser_user_agent.empty()) {
request->headers.SetHeader(net::HttpRequestHeaders::kUserAgent,
browser_user_agent);
}
const bool is_external = IsExternalRequest(request);
// External requests will not have a default handler.
bool intercept_only = is_external;
CefRefPtr<CefRequestImpl> requestPtr;
CefRefPtr<CefResourceRequestHandler> handler =
GetHandler(id, request, &intercept_only, requestPtr);
CefRefPtr<CefSchemeHandlerFactory> scheme_factory =
init_state_->resource_context_->GetSchemeHandlerFactory(request->url);
if (scheme_factory && !requestPtr) {
requestPtr = MakeRequest(request, id.hash(), true);
}
// True if there's a possibility that the client might handle the request.
const bool maybe_intercept_request = handler || scheme_factory;
if (!maybe_intercept_request && requestPtr)
requestPtr = nullptr;
// May have a handler and/or scheme factory.
state->Reset(handler, scheme_factory, requestPtr, request_was_redirected,
std::move(cancel_callback));
if (handler) {
state->cookie_filter_ = handler->GetCookieAccessFilter(
init_state_->browser_, init_state_->frame_, requestPtr.get());
}
auto exec_callback =
base::BindOnce(std::move(callback), maybe_intercept_request,
is_external ? true : intercept_only);
if (!maybe_intercept_request) {
// Cookies will be handled by the NetworkService.
std::move(exec_callback).Run();
return;
}
MaybeLoadCookies(id, state, request, std::move(exec_callback));
}
bool GetOverrideUserAgent(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> request_info,
CefString& overrideUserAgent) OVERRIDE;
bool ClientHandler::GetOverrideUserAgent(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> request_info,
CefString& overrideUserAgent) {
do {
if(!request_info.get()) {
LOG(INFO) << "[cefclient] request_info is nullptr";
break;
}
if(!request_info->HasKey("url")) {
LOG(INFO) << "[cefclient] request_info does not have the key 'url'";
break;
}
CefString url = request_info->GetString("url");
if(url.empty()) {
LOG(INFO) << "[cefclient] request_info 'url' key value is empty";
break;
}
std::wstring sUrl = url.ToWString();
std::wstring sDomain;
bool fGetDomain = GetDomainOfUrl(sDomain, url.c_str());
if(fGetDomain) {
if(sDomain == L"get.adobe.com") {
if(wcsstr(GetCommandLineW(), L"--getflash-as-firefox") != NULL) {
overrideUserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0";
std::wstring str = L"Posing as Firefox on get.adobe.com: UA=";
str += overrideUserAgent.ToWString(); // temp object, but
str += L"\r\n";
::OutputDebugStringW(str.c_str());
return true;
}
}
}
#pragma warning(disable: 4127)
} while(0);
#pragma warning(default: 4127)
return false;
}
class MyCefResourceRequestHandler : public CefResourceRequestHandler {
public:
//CefResourceRequestHandler methods
CefResourceRequestHandler::ReturnValue OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefRequestCallback> callback) OVERRIDE;
bool GetOverrideUserAgent(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> request_info,
CefString& overrideUserAgent);
IMPLEMENT_REFCOUNTING(MyCefResourceRequestHandler);
};
class MyCefRequestHandler : public CefRequestHandler {
public:
MyCefRequestHandler() {
resourceRequesthandler = new MyCefResourceRequestHandler();
}
CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool is_navigation,
bool is_download,
const CefString& request_initiator,
bool& disable_default_handling) OVERRIDE {
return resourceRequesthandler;
}
private:
CefRefPtr<MyCefResourceRequestHandler> resourceRequesthandler;
IMPLEMENT_REFCOUNTING(MyCefRequestHandler);
};
CefRefPtr <MyCefRequestHandler> requestHandler_;
requestHandler_ = new MyCefRequestHandler();
CefRefPtr<CefRequestHandler> GetRequestHandler() {
return requestHandler_;
}
"Mozilla/5.0 (X11; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0"
Users browsing this forum: No registered users and 154 guests