Changing the user agent in Chromium Embedded 3 (DCEF3) (CefVCL)
Asked Answered
R

7

2

I'm trying to modify the User Agent of TChromium and I found no procedure for this, in case it is using CefVCL. Already by ceflib looks like it has to yes, I saw a variable "settings" that receives a value "user_agent" but the VCL already has, will have or is not possible this way?

Rey answered 10/9, 2013 at 0:54 Comment(0)
E
1

There is no built in way to do this. In my experience, the user-agent setting does nothing.. so you have to edit ceflib.pas directly (line ~8532) to achieve this effect.

    settings.user_agent := cefstring(UserAgent);

becomes:

    settings.user_agent := cefstring('My USERAGENT v1.0');

With the above, you may want to include your own OS and Browser Info as this blocks off CEF's implementation of those variables. Or append it, like this:

    settings.user_agent := cefstring(UserAgent+'; My UserAgent v1.0');

This is how I do it.. I've been working with DCEF1 and DCEF3 for about a year.. and still learning!

Enchorial answered 12/11, 2013 at 17:14 Comment(2)
Unfortunately this is an outdated reference. Now it's line 11091.Vacillatory
Thank you for the update 4 years after the original post. Unfortunately that information is irrelevant now since DCEF is no longer being updated or maintained. Switching to CEF4Delphi is a prudent move if you don't want to be "outdated".Enchorial
C
1

ceflib.pas line 5549

Var

UA: integer;
UAescojido: Ustring;

...

settings.cache_path := CefString(Cache);
UA:= Random(2)+1; //NEW LINE
if UA=1 then UAescojido:= 'xxxxxxxxxx'; //NEW LINE
if UA=2 then UAescojido:= 'xxxxxxxxxx'; //NEW LINE
settings.user_agent := cefstring(UAescojido);  //ASSIGN VARIABLE
Christoper answered 11/6, 2014 at 4:34 Comment(1)
Unfortunately this is an outdated reference. Now it's line 11091.Vacillatory
B
1

View the demo guiclient's project source

begin
  //CefCache := 'cache';
  CefCache:='./ca1';
  CefUserAgent:='"Mozilla/5.0(Linux; U; Android 4.0.4; zh-cn; MI-ONE C1 Build/IMM76D) UC AppleWebKit/534.31 (KHTML, like Gecko) Mobile Safari/534.31"';

  CefOnRegisterCustomSchemes := RegisterSchemes;
  CefSingleProcess := False;
  if not CefLoadLibDefault then
    Exit;

  CefRegisterSchemeHandlerFactory('local', '', False, TFileScheme);


  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
end.
Bonnett answered 7/1, 2015 at 6:49 Comment(0)
N
1

Not full change, but it work for me.

procedure TForm1.Chromium1BeforeResourceLoad(Sender: TObject;
  const browser: ICefBrowser; const frame: ICefFrame;
  const request: ICefRequest; const callback: ICefRequestCallback; out
  Result: TCefReturnValue);

Var
  map: ICefStringMultimap;
begin
    map := TCefStringMultimapOwn.Create;
    request.GetHeaderMap(map);
    map.Append('User-Agent','Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16');
    request.SetHeaderMap(map);
    callback.Cont(true);
end;
Novellanovello answered 21/11, 2017 at 19:18 Comment(0)
F
0

Set the CefUserAgent variable in the initialization section of your main program unit.

initialization
  CefUserAgent := "Your Agent";

Alternative:

If you are using a version of CEF that does not have a CefUserAgent global varaible then you may try:

The user agent is stored in the

var
  settings: TCefSettings;

in the ceflib file which is declared in a local function, not a global variable. The settings record contains a variable settings.user_agent that can be modified.

function CefLoadLib

is where the variable is declared, and CefLoadLibDefault calls CefLoadLib.

Making settings a global at the top of the unit file instead of leaving it as a local function variable, could be a solution so that you could modify the user agent in the initialization section of another unit before the components are loaded on the form. However since globals are in many cases a bad thing and can cause unintended consequences.... One would have to check to see that it is not going to be unsafe to do such a modification.

If it hasn't been done so already, this should be a feature request that CEF for delphi contains a user agent setting modifiable in the vcl component. Has anyone requested this feature...yet.. If not it would definitely be useful.

Another temporary solution, is to make a global string variable instead of the entire settings record being global, and just use the global string variable when the user agent is set:

settings.user_agent := cefstring(YourGlobalVariableHere);

This again is not a permanent solution and this feature should really be implemented in the component itself.

Fungus answered 18/10, 2016 at 7:39 Comment(0)
H
0

My (C++) implementation forks CEF and add the following method to the CefRequestHandler:

  virtual bool GetOverrideUserAgent(CefRefPtr<CefBrowser> browser, 
                                    CefRefPtr<CefDictionaryValue> request_info, 
                                    CefString& overrideUserAgent) { return false; }

Then, in cef\libcef\common\request_impl.cc:

  void CefRequestImpl::Set(net::URLRequest* request) {
    base::AutoLock lock_scope(lock_);
    CHECK_READONLY_RETURN_VOID();
    ...
    const content::ResourceRequestInfo* info =
      content::ResourceRequestInfo::ForRequest(request);
    if (info) {
      ...
      CefRefPtr<CefBrowserHostImpl> browser = 
        CefBrowserHostImpl::GetBrowserForRequest(request);
      if(browser) {
        ...
        CefString overrideUserAgent;
        if(request_handler->**GetOverrideUserAgent**(browser.get(), 
          request_info, overrideUserAgent)) {
          headermap_.erase(
            net::HttpRequestHeaders::kUserAgent);
          headermap_.insert(
            std::make_pair(net::HttpRequestHeaders::kUserAgent, 
                           overrideUserAgent));
        }
        ...

So the (basic) steps are these: 1. fork CEF 2. add CefRequestHandler::GetOverrideUserAgent 3. in your application, client handler should be derived from CefRequestHandler and implement GetOverrideUserAgent 4. your application can set the UA as needed.

This is, however, how I did it. It might not be suitable for your needs.

Harm answered 21/10, 2016 at 11:38 Comment(0)
S
0

We've been using DCEF1 for several years, and we've have not upgrade to DCEF3 (as it is missing something we need). So this answer may be out of date, but for what it's worth:

In DCEF1 There is a global variable in the ciflib unit called CefUserAgent. We set that varible to our customer User Agent string in the initialization section of one of our project units. This is simple, and seems to work well for us.

CefUserAgent := OutCustomUserAgentString;

I dont remember the derivation of this method now (it was too long ago), but I expect we would only have done it in the initialization section of a unit if that is what was required to make it work properly.

Unfortunately I have no idea if this still works in DCEF3.

Succinctorium answered 30/10, 2016 at 1:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.