QNetworkAccessManager, adding proxy server support



  • Hello,
    I am subclassing QNetworkAccessManager to create a base class for all my webservice communictions.
    Everything works as expected, until i try to add proxy server support. It works great without authentication, but a major problem comes up when I try to add support for authentication. I've verified the proxy server with auth using FireFox.
    I'm using Qt 4.8.2. I'm targetting embedded linux, but i get the same result testing on linux desktop.

    Proxy support gets configured in NetworkAccessManager::configureProxy(), the the slot NetworkAccessManager::proxyAuthenticationRequired(...) gets called to provide authentication.

    the proxyAuthenticationRequired slot just gets called repeatedly.

    And i just the something like the following over and over.
    "
    NetworkAccessManager::proxyAuthenticationRequired -- called
    NetworkAccessManager::proxyAuthenticationRequired requesting realm: proxy
    QNetworkAccessCache::addEntry: overriding active cache entry 'auth:proxy-http://user@10.255.170.140:3128#proxy'
    QNetworkAccessCache::addEntry: overriding active cache entry 'auth:proxy-http://user@10.255.170.140:3128'
    QNetworkAccessCache::addEntry: overriding active cache entry 'auth:proxy-http://10.255.170.140:3128'
    "

    I've found the below related issue, but they did not lead helpful results.
    https://bugreports.qt-project.org/browse/QTBUG-16728
    https://bugreports.qt-project.org/browse/QTBUG-14850

    I've also tried applying patches from here:
    https://bugreports.qt-project.org/browse/QTBUG-15472
    recompiled everything, still see the same results.

    I was hoping someone would help shed some light on this issue. Perhaps i'm doing something wrong, or if this looks like a bug within Qt.

    I Appreciate and guidance.

    Edit:: it appears my post is too big including code. I'll post code in replies.



  • networkaccessmanager.h
    @
    #ifndef NETWORKACCESSMANAGER_H
    #define NETWORKACCESSMANAGER_H

    #include <QObject>
    #include <QNetworkAccessManager>
    #include <QtNetwork>
    #include <QUrl>

    class QNetworkReply;
    class QNetworkRequest;

    class NetworkAccessManager : public QNetworkAccessManager
    {
    Q_OBJECT
    public:
    //NetworkAccessManager(QObject *parent = 0);
    NetworkAccessManager();
    ~NetworkAccessManager();
    void setContent(const QString &content);
    void setUrl(const QString &url);
    void printResult() const;
    public slots:
    void configureProxy();
    private slots:
    void cancelRequest();
    void httpFinished();
    void httpReadyRead();
    void httpError(QNetworkReply::NetworkError error);
    void sslError(const QList<QSslError> &errorList);
    void authenticationRequired(QNetworkReply *reply, QAuthenticator *auth);
    virtual void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth);
    protected:
    void init();
    void startRequest();

    bool httpRequestAborted;
    bool error;
    QString result;
    

    private:
    QNetworkReply *reply;
    QNetworkRequest *request;
    QEventLoop *eventloop;

    QUrl url;
    QString result;
    QByteArray content;
    QString proxyHost;
    QString proxyPort;
    QString proxyUsername;
    QString proxyPassword;
    

    };

    #endif // NETWORKACCESSMANAGER_H
    @



  • networkaccessmanager.cpp
    @
    // qt
    #include <QDebug>

    // local
    #include "networkaccessmanager.h"
    #include "sysAdmin/databasemanager.h"

    //NetworkAccessManager::NetworkAccessManager(QObject parent)
    // : QNetworkAccessManager(parent)
    NetworkAccessManager::NetworkAccessManager()
    {
    error = false;
    httpRequestAborted = false;
    init();
    configureProxy();
    connect(this, SIGNAL(authenticationRequired(QNetworkReply
    ,QAuthenticator*)),this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*)));
    connect(this, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
    }

    NetworkAccessManager::~NetworkAccessManager()
    {
    }

    void NetworkAccessManager::setContent(const QString &content)
    {
    this->content.clear();
    this->content.append(content);
    }

    void NetworkAccessManager::setUrl(const QString &url)
    {
    this->url = url;
    }

    void NetworkAccessManager::printResult() const
    {
    qDebug() << "Results: " << result;
    }

    // public slots
    void NetworkAccessManager::configureProxy()
    {
    DatabaseManager db;
    QNetworkProxy proxy;
    //QNetworkProxy proxy(QNetworkProxy::HttpProxy);
    //QNetworkProxy *proxy = new QNetworkProxy();
    if(db.getProxyServerEnabled() ) {
    proxy.setType(QNetworkProxy::HttpProxy);
    //proxy.setType(QNetworkProxy::HttpCachingProxy);
    //proxy.setCapabilities(QNetworkProxy::CachingCapability | QNetworkProxy::HostNameLookupCapability);
    //proxy.setCapabilities(QNetworkProxy::HostNameLookupCapability);
    //proxy = QNetworkProxy::HttpProxy;
    //proxy.setType(QNetworkProxy::HttpProxy);
    //proxy.setType(QNetworkProxy::Socks5Proxy);
    //proxy.setType(QNetworkProxy::HttpCachingProxy);
    //proxy.setType(QNetworkProxy::DefaultProxy);

        proxyHost = db.getProxyServerHost();
        proxyPort = db.getProxyServerPort();
        proxyUsername = db.getProxyServerUser();
        proxyPassword = db.getProxyServerPassword();
    
        proxy.setHostName(proxyHost);
        proxy.setPort(proxyPort.toInt());
        proxy.setUser(proxyUsername);
        proxy.setPassword(proxyPassword);
    }
    else {
        proxy.setType(QNetworkProxy::NoProxy);
    }
    //QNetworkProxy::setApplicationProxy(proxy);
    setProxy(proxy);
    

    }

    // private slots
    void NetworkAccessManager::cancelRequest()
    {
    reply->abort();
    httpRequestAborted = true;
    }

    void NetworkAccessManager::httpFinished()
    {
    if(httpRequestAborted)
    error = true;

    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    
    if(statusCode.toString() != "200") 
        error = true;
    
    if(reply->error()) 
        error = true;
    
    eventloop->exit();
    reply->deleteLater();
    delete eventloop;
    delete request;
    

    }

    void NetworkAccessManager::httpReadyRead()
    {
    result += reply->readAll();
    }

    void NetworkAccessManager::httpError(QNetworkReply::NetworkError error )
    {
    this->error = true;
    }

    void NetworkAccessManager::sslError(const QList<QSslError> &errorList)
    {
    Q_UNUSED(errorList);
    reply->ignoreSslErrors();
    }

    void NetworkAccessManager::authenticationRequired(QNetworkReply *reply, QAuthenticator *auth)
    {
    Q_UNUSED(reply);
    Q_UNUSED(auth);
    }

    void NetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth)
    {
    //Q_UNUSED(proxy);
    //Q_UNUSED(auth);
    qDebug() << "NetworkAccessManager::proxyAuthenticationRequired -- called";
    qDebug() << "NetworkAccessManager::proxyAuthenticationRequired requesting realm:" << auth->realm();

    auth->setUser(proxyUsername);
    auth->setPassword(proxyPassword);
    
    //QNetworkProxy p(proxy);
    //p.setType(QNetworkProxy::HttpProxy);
    //p.setHostName(proxyHost);
    //p.setPort(proxyPort.toInt());
    //p.setUser(proxyUsername);
    //p.setPassword(proxyPassword);
    //QNetworkProxy::setApplicationProxy(p);
    

    }

    // private
    void NetworkAccessManager::init()
    {
    }

    void NetworkAccessManager::startRequest()
    {
    result.clear();
    error = false;
    httpRequestAborted = false;

    request = new QNetworkRequest();
    request->setUrl(url);
    request->setRawHeader("Content-Type", "text/xml");
    //request->setRawHeader(QString("Content-Length").toAscii(), QString::number(content.length()).toAscii());
    
    QSslConfiguration sslConfig = request->sslConfiguration();
    sslConfig.setPeerVerifyMode(QSslSocket::AutoVerifyPeer);
    sslConfig.setProtocol(QSsl::SslV3);
    
    request->setSslConfiguration(sslConfig);
    
    reply = this->post(*request, content);
    
    QTimer timer;
    timer.setSingleShot(true);
    eventloop = new QEventLoop();
    timer.start(30000);
    connect(reply, SIGNAL(finished()), this, SLOT(httpFinished()));
    connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(httpError(QNetworkReply::NetworkError)));
    connect(reply, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslError(const QList<QSslError> &)));
    connect(&timer, SIGNAL(timeout()), this, SLOT(cancelRequest()));
    eventloop->exec&#40;&#41;;
    

    }
    @



  • I am with almost same problem , the difference for me is before there are this msg too :

    QSslSocket: cannot resolve SSLv2_client_method
    QSslSocket: cannot resolve SSLv2_server_method
    ***frmBuyIt : isSSLSupported= true

    and after :
    QNetworkAccessCache::addEntry: overriding active cache entry 'auth:proxy-http://user@proxy:port
    and repet forever

    I search a lot but don't find solution



  • I am with almost same problem , the difference for me is before there are this msg too :

    QSslSocket: cannot resolve SSLv2_client_method
    QSslSocket: cannot resolve SSLv2_server_method
    ***frmBuyIt : isSSLSupported= true

    and after :
    QNetworkAccessCache::addEntry: overriding active cache entry 'auth:proxy-http://user@proxy:port
    and repet forever

    I search a lot but don't find solution


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.