0

Simple question: is it possible to whitelist an URL (or a domain) for proxy in Qt WebEngine?

When using other Qt modules that rely on Qt Network, it is possible to set a per URL proxy using QNetworkProxyFactory::queryProxy() like so:

QList<QNetworkProxy> MyProxyFactory::queryProxy(const QNetworkProxyQuery &query)
{
    if (whitelist.contains(query.url)) {
        return { QNetworkProxy::NoProxy };
    }
    ...
}

However, Qt WebEngine does not use Qt Network, but chromium network stack. Still Qt Web Engine does use Qt application level proxy, but only to a limited extent. Qt WebEngine basically just copies proxy host and port from Qt Network proxy to chromium network stack. Qt WebEngine does not call QNetworkProxyFactory::queryProxy() for each request.

Is there any other way to achieve the same result of having no proxy on some URLs and a proxy for all other URLs?

Benjamin T
  • 8,120
  • 20
  • 37

1 Answers1

0

In QtWebEngine you have to use QWebEngineUrlRequestInterceptor as I show in this answer, in your case it is:

#include <QApplication>
#include <QWebEngineProfile>
#include <QWebEngineUrlRequestInterceptor>
#include <QWebEngineView>

class WebEngineUrlRequestInterceptor: public QWebEngineUrlRequestInterceptor{
    Q_OBJECT
    Q_DISABLE_COPY(WebEngineUrlRequestInterceptor)
public:
    explicit WebEngineUrlRequestInterceptor(QObject* p = nullptr)
    : QWebEngineUrlRequestInterceptor(p)
    {
    }
    void interceptRequest(QWebEngineUrlRequestInfo &info){
        if(m_whitelist.contains(info.requestUrl()))
            info.block(true);
    }
    QList<QUrl> whitelist() const{
        return m_whitelist;
    }
    void setWhitelist(const QList<QUrl> &whitelist){
        m_whitelist = whitelist;
    }

private:
    QList<QUrl> m_whitelist;
};

int main(int argc, char *argv[]){
    QApplication a(argc, argv);
    WebEngineUrlRequestInterceptor *interceptor = new WebEngineUrlRequestInterceptor;
    interceptor->setWhitelist({QUrl("https://www.google.com/")});
    QWebEngineProfile::defaultProfile()->setRequestInterceptor(interceptor);
    QWebEngineView w;
    w.setUrl(QUrl("https://www.google.com/"));
    w.show();
    return a.exec();
}
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • `info.block()` will block the call. I want the call to be made but without proxy. I believe the interceptor could be used to redirect the call to another scheme and then I would need to use a scheme handler to make the call using my own QNetworkAccesManager, but it looks like more like a hack than a clean solution. – Benjamin T Mar 04 '20 at 18:29