I've been trying to load a(ny) https:// webpage using QNetworkAccessManager, but can't get past the: preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *) signal. When I load the same pages with http:// they come in fine, but some servers require https:// so I'm stuck with them.
Edit to add: this is on Ubuntu 18.04 with Qt 5.9.5
I've connected most of the error signals, those aren't being emitted - I just get the encrypted() and preSharedKeyAuthenticationRequired() signals, which are pretty self explanatory as to what is happening, but the documentation for how to move forward is... lacking.
All these https:// pages load easily/simply in Chrome - no passwords required.
How can I make QNetworkAccessManager pull the pages the way that Chrome does, or similarly?
PageHandler::PageHandler( QObject *parent ) : QObject(parent)
{ connect(&networkManager, SIGNAL(finished(QNetworkReply*)) , SLOT(pageRequestFinished(QNetworkReply*)) );
connect(&networkManager, SIGNAL(encrypted(QNetworkReply*)), SLOT(pageRequestEncrypted(QNetworkReply*)) );
connect(&networkManager, SIGNAL(sslErrors(QNetworkReply *, const QList<QSslError> &)), SLOT(sslErrors(QNetworkReply *, const QList<QSslError> &)) );
getPage( QUrl( "https://google.com/" ) );
}
void PageHandler::getPage( const QUrl &url )
{ QNetworkRequest *request = new QNetworkRequest();
// request.setSslConfiguration( QSslConfiguration::defaultConfiguration() ); this seems to do nothing
request->setHeader( QNetworkRequest::UserAgentHeader, APP_NAME );
request->setUrl( url );
QNetworkReply *r = networkManager.get( *request );
connect( r, SIGNAL(finished()), SLOT(replyFinished()) );
connect( r, SIGNAL(encrypted()), SLOT(replyEncrypted()) );
connect( r, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *)), SLOT(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *)) );
// connect( r, SIGNAL(errorOccurred(QNetworkReply::NetworkError)), SLOT(errorOccurred(QNetworkReply::NetworkError)) ); Qt 5.15+ only
qDebug( QString( "getting page %1" ).arg( url.toString() ) );
}
// Get this for http://
void PageHandler::replyFinished()
{ qDebug( "replyFinished()" );
}
// Get this for https://
void PageHandler::replyEncrypted()
{ qDebug( "replyEncrypted()" );
}
// Never see this
void PageHandler::errorOccurred(QNetworkReply::NetworkError code)
{ qDebug( QString( "wrror occurred %1" ).arg(code) )
}
// Get this for https://
void PageHandler::preSharedKeyAuthenticationRequired( QSslPreSharedKeyAuthenticator *authenticator )
{ qDebug( QString( "preSharedKeyAuthenticationRequired hint '%1'" ).arg( QString::fromUtf8( authenticator->identityHint() ) ) ) // This is empty
authenticator->setIdentity( QByteArray() ); // What to do here, if anything?
authenticator->setPreSharedKey( QByteArray() );
}
// Get this for http://
void PageHandler::pageRequestFinished( QNetworkReply *r )
{ qDebug( "got page" );
QList<QByteArray> hl = r->rawHeaderList();
foreach ( QByteArray ba, hl )
qDebug( QString( "header '%1'").arg( QString::fromUtf8( ba ) ) )
qDebug( QString( "Reply '%1'").arg( QString::fromUtf8( r->readAll() ) ) )
r->deleteLater();
}
// Get this for https:// not for http:// (as expected)
void PageHandler::encrypted( QNetworkReply *r )
{ qDebug( "encrypted" );
if ( r->error() )
qDebug( QString( "encrypted signal error %1 %2" ).arg( r->error() ).arg( r->errorString() ) ); // Never see this
// Nothing shown for the header or body
QList<QByteArray> hl = r->rawHeaderList();
foreach ( QByteArray ba, hl )
qDebug( QString( "Encrypted header '%1'").arg( QString::fromUtf8( ba ) ) );
qDebug( QString( "Encrypted reply '%1'").arg( QString::fromUtf8( r->readAll() ) ) );
// r->ignoreSslErrors(); Makes no difference if this is commented or not
r->deleteLater();
}
void PageHandler::sslErrors(QNetworkReply *r, const QList<QSslError> &e)
{ qDebug( "sslErrors" ); // Never see this
}