Proxy and intranet websites

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Proxy and intranet websites

Postby Czarek » Wed Nov 07, 2018 10:37 am

When using proxy, is it possible to ignore certain hosts so that they do not load via proxy? For example I don't want for intranet websites to be loaded via proxy.
Maintainer of the CEF Python, PHP Desktop and CEF C API projects. My LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1927
Joined: Sun Nov 06, 2011 2:12 am

Re: Proxy and intranet websites

Postby ndesktop » Wed Nov 07, 2018 11:46 am

I don't know if what I did is ok, but I adapter the CefProxyHandler class (from CEF1...) into CEF3.
This way I can control proxy usage via
virtual void GetProxyForUrl(const CefString& url, CefProxyInfo& proxy_info) {}

So, in a little more detail (source excertps from custom modified 3440 branch derived):
- cef_app.h
CefApp new method GetProxyHandler
Code: Select all
  virtual CefRefPtr<CefProxyHandler> GetProxyHandler() {
    return NULL;
  }

- new file cef_proxy_handler.h
Code: Select all
class CefProxyHandler : public virtual CefBaseRefCounted {
 public:
  ///
  // Called to retrieve proxy information for the specified |url|.
  ///
  /*--cef()--*/
  virtual void GetProxyForUrl(const CefString& url,
                              CefProxyInfo& proxy_info) {}
};

- libcef/browser/net/url_request_context_getter_impl.cc
Code: Select all
#include "net/proxy_resolution/proxy_config_service_win.h"
#include "net/proxy_resolution/proxy_resolver_factory.h"
#include "net/proxy_resolution/proxy_resolver.h"

...
namespace {
class ProxyConfigServiceNull : public net::ProxyConfigService {
 public:
  ProxyConfigServiceNull() {}
  virtual void AddObserver(Observer* observer) override {}
  virtual void RemoveObserver(Observer* observer) override {}
  virtual ProxyConfigService::ConfigAvailability
      GetLatestProxyConfig(net::ProxyConfigWithAnnotation* config) override
      { return ProxyConfigService::CONFIG_VALID; }
  virtual void OnLazyPoll() override {}
};

// An implementation of |HttpUserAgentSettings| that provides a static
class CefProxyResolver
    : public net::ProxyResolver {
 public:
  explicit CefProxyResolver(CefRefPtr<CefProxyHandler> handler)
    : handler_(handler) {}
  virtual ~CefProxyResolver() {}
// HTTP Accept-Language header value and uses |content::GetUserAgent|
  virtual int GetProxyForURL(const GURL& url,
                             net::ProxyInfo* results,
                             const net::CompletionCallback& callback,
                             std::unique_ptr<Request>* request,
                             const net::NetLogWithSource& net_log) override {
    CefProxyInfo proxy_info;
    handler_->GetProxyForUrl(url.spec(), proxy_info);
    if (proxy_info.IsDirect())
      results->UseDirect();
    else if (proxy_info.IsNamedProxy())
      results->UseNamedProxy(proxy_info.ProxyList());
    else if (proxy_info.IsPacString())
      results->UsePacString(proxy_info.ProxyList());
// to provide the HTTP User-Agent header value.
    return net::OK;
  }
 protected:
  CefRefPtr<CefProxyHandler> handler_;
};

class CefProxyResolverFactory
    : public net::ProxyResolverFactory {
 public:
  explicit CefProxyResolverFactory(CefRefPtr<CefProxyHandler> handler)
      : net::ProxyResolverFactory(false)
      , handler_(handler) {
  }

  virtual ~CefProxyResolverFactory() {
  }

  // Creates a new ProxyResolver. The caller is responsible for freeing this
  // object.
  virtual int CreateProxyResolver(
      const scoped_refptr<net::PacFileData>& pac_script,
      std::unique_ptr<net::ProxyResolver>* resolver,
      const net::CompletionCallback& callback,
      std::unique_ptr<Request>* request) override {
      resolver->reset(new CefProxyResolver(handler_));
      return net::OK;
  }

 private:
  CefRefPtr<CefProxyHandler> handler_;
  DISALLOW_COPY_AND_ASSIGN(CefProxyResolverFactory);
};

};  //  namespace

- in the same file, tell to the url request context if you need proxy handler:
Code: Select all
net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
  CEF_REQUIRE_IOT();

  if (!io_state_->url_request_context_.get()) {
    const base::CommandLine* command_line =
        base::CommandLine::ForCurrentProcess();
...
    io_state_->storage_->set_ct_policy_enforcer(std::move(ct_policy_enforcer));

// and here:
    bool fCustomProxyHandler = false;
    if(app.get()) {
        CefRefPtr<CefProxyHandler> handler = app->GetProxyHandler();
        if(handler.get()) {
            // Force auto-detect so the client resolver will be called.
            net::ProxyConfigServiceWin::set_force_auto_detect(true);

            // The client will provide proxy resolution.
            std::unique_ptr<net::ProxyResolutionService> custom_proxy_service(
                new net::ProxyResolutionService(
                    net::ProxyResolutionService::CreateSystemProxyConfigService(
                        io_state_->io_task_runner_),
                    base::WrapUnique(
                        new CefProxyResolverFactory(handler)),
                nullptr));

            io_state_->storage_->set_proxy_resolution_service(
              std::move(custom_proxy_service));
            fCustomProxyHandler = true;
        }
    }
    if(!fCustomProxyHandler) {
        //  custom proxy resolution not provided
        std::unique_ptr<net::ProxyResolutionService> system_proxy_service =
            CreateProxyResolutionService(
                io_state_->net_log_,
                io_state_->url_request_context_.get(),
                io_state_->url_request_context_->network_delegate(),
                std::move(io_state_->proxy_resolver_factory_),
                std::move(io_state_->proxy_config_service_), *command_line,
                quick_check_enabled_.GetValue(),
                pac_https_url_stripping_enabled_.GetValue());
        io_state_->storage_->set_proxy_resolution_service(
            std::move(system_proxy_service));
    }
...
}


So if your CefApp returns a CefProxyHandler, it will use that one (else will default to the system proxy service).
Most of the code was in CEF1 and is adapted into CEF3.

It was a proposal some 2-3-4 years ago, but I think it was closed with WONTFIX because proxy info can be passed via command line arguments.
For me that was not an option since it dealt with secure credentials, NTLM auth etc.

This is my implementation since CEF3 (branch 1750, 1916, something like that). If you want me to send you a patch, PM me.
Or you can open an issue if Marshall gives us his blessing : )so I can submit the implementation.
ndesktop
Master
 
Posts: 750
Joined: Thu Dec 03, 2015 10:10 am

Re: Proxy and intranet websites

Postby Czarek » Wed Nov 07, 2018 12:21 pm

Thanks. Another option I think is to change proxy during runtime via preferences. When navigating to certain hosts I would disable it and then reenable.
Maintainer of the CEF Python, PHP Desktop and CEF C API projects. My LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1927
Joined: Sun Nov 06, 2011 2:12 am

Re: Proxy and intranet websites

Postby Czarek » Wed Nov 07, 2018 12:30 pm

Looks like there is a switch for ignoring hosts:

Code: Select all
--proxy-bypass-list

Specifies a list of hosts for whom we bypass proxy settings and use direct connections. Ignored unless --proxy-server is also specified. This is a comma-separated list of bypass rules. See: "net/proxy/proxy_bypass_rules.h" for the format of these rules. ↪


Btw. what is the default proxy mode? Auto detect or direct? Is it the same on all platforms? (I recall IE proxy settings are used by default on Windows)
Maintainer of the CEF Python, PHP Desktop and CEF C API projects. My LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1927
Joined: Sun Nov 06, 2011 2:12 am

Re: Proxy and intranet websites

Postby salvadordf » Wed Nov 07, 2018 1:05 pm

According to this old post it seems to be "auto_detect" :
https://magpcss.org/ceforum/viewtopic.p ... 458#p15798

This would fit with what some CEF4Delphi users found because we use "direct" by default and some of their clients needed to configure the proxy settings while cefclient could navigate without problems.
Maintainer of the CEF4Delphi, WebView4Delphi, WebUI4Delphi and WebUI4CSharp projects.
User avatar
salvadordf
Expert
 
Posts: 129
Joined: Sun Dec 18, 2016 8:39 am
Location: Spain

Re: Proxy and intranet websites

Postby ndesktop » Wed Nov 07, 2018 1:17 pm

I think the same old polling for IE implementation is in place today. Proxy autodetect I think is the default, but I'm not 100% sure.
ndesktop
Master
 
Posts: 750
Joined: Thu Dec 03, 2015 10:10 am


Return to Support Forum

Who is online

Users browsing this forum: No registered users and 32 guests