How to cancel the QNetworkRequest in slot connected proxyAuthenticationRequired signal of QNetworkAccessManager
-
I am making my app proxy aware. On start up it first reads the proxy server and port using win http api and it set the application wide proxy setting.
To get authentication I have connected a slot to proxyAuthenticationRequired signal of QNetworkAccessManager. In this slot I show a modal dialog asking for user name and password.
After getting username and password I pass it to QAuthenticator and also update the application wide proxy setting.The problem is, if user cancels the modal dialog (which asks user name and password for proxy authentication) I want to cancel the network request. I am not able to find way to get the instance of QNetworkRequest or QNetworkAccessManager in slot connected to proxyAuthenticationRequired; so that I can cancel it.
Below is the code snippet:
@
QNetworkAccessManager * pnam = new QNetworkAccessManager(this);
connect(pnam, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)),
this, SLOT(askAndFillProxyAuthentication(const QNetworkProxy&, QAuthenticator*)));void HttpUtil::askAndFillProxyAuthentication( const QNetworkProxy & proxy, QAuthenticator * authenticator )
{
static QMutex waitForAuth;
static bool userCancelled = false;
waitForAuth.lock();QVariant isCredentialsSet = authenticator->option("CredentialsSet"); if(isCredentialsSet.isValid()) // if its asking credentials again, means the credentials are wrong. m_proxySet = false; if(!m_proxySet) { QString userid = "", password = ""; int ret = -1; QNetworkProxy::ProxyType type = QNetworkProxy::HttpProxy; if(!userCancelled) { ret = QTProxyLoginDialog::GetProxyCredentials(userid, password); m_proxyUserId = userid.toAscii(); m_proxyUserPwd = password.toAscii(); m_proxySet = (ret == QDialog::Accepted); userCancelled = (ret == QDialog::Rejected); } else { // tried to set invalid proxy if user cancels the QTProxyLoginDialog, to stop asking the username and password. // unfortunately its not working .... type = QNetworkProxy::NoProxy; m_proxyServer = ""; m_proxyPort = -1; } QNetworkProxy proxy; proxy.setType(type); proxy.setHostName(m_proxyServer.c_str()); proxy.setPort(m_proxyPort); proxy.setUser(m_proxyUserId.c_str()); proxy.setPassword(m_proxyUserPwd.c_str()); QNetworkProxy::setApplicationProxy(proxy); } waitForAuth.unlock(); authenticator->setUser(m_proxyUserId.c_str()); authenticator->setPassword(m_proxyUserPwd.c_str()); authenticator->setOption("CredentialsSet", true);
}
@ -
If you return from a slot connected to &QNetworkAccessManager::proxyAuthenticationRequired without calling any QAuthenticator method, the request will be aborted with real HTTP code (e.g. 401 or 407).
For instance you can call QAuthenticator::setUser and setPassword when the user clics OK and call nothing when he clics Cancel. That's all :-)
This is also true for slots connected to &QNetworkAccessManager::authenticationRequired (where you do not have to call QNetworkReply::abort(), you can simply call no QAuthenticator method at all, which preserve HTTP code too, whereas calling abort() alter it).