problem with QNetworkAccessManager with VPN after migrating from Qt 5.2.12 to Qt 6.1.3
-
My colleagues and I have had a problem with
QNetworkAccessManager
after migrating fromQt 5.2.12
toQt 6.1.3
.Our Qt-based client application communicates with our server. The application creates a
QNetworkAccessManager
in order to retrieve data from the server. In a nutshell:QNetworkAccessManager* manager = new QNetworkAccessManager(<parent>); connect(manager, &QNetworkAccessManager::finished, this, &SomeClass::replyFinished); ///////////////////////////////// void SomeClass::replyFinished(QNetworkReply* reply) { if (reply->error() != QNetworkReply::NoError) { <error handling code> return; } const QString dataFromServer = QString(reply->readAll()); <code which uses dataFromServer> }
This works perfectly in
Qt 5.2.12
(Windows 10), even when the client uses a VPN.In
Qt 6.1.3
(Windows 10), however, we get an error when the client uses a VPN (but this works if the client does not uses a VPN). More precisely:- in the above code snippet,
reply->error()
returns:
QNetworkReply::ProtocolInvalidOperationError (302): "the requested operation is invalid for this protocol"
reply->errorString()
returns:
"Error transferring http://<our server's address> - server replied: <our server's error message>"
Some additional information:
The error message that we get (
"Error transferring ..."
) is generated inqtbase/src/network/access/qhttpthreaddelegate.cpp
, either by functionQHttpThreadDelegate::finishedSlot()
or by functionQHttpThreadDelegate::synchronousFinishedSlot()
. The implementations of these two functions are identical inQt 5.2.12
andQt 6.1.3
(except that, in the final statement of each function,0
replaced bynullptr
inQt 6.1.3
), so the problem is somewhere else.QNetworkAccessManager
defines six signals:
(1)void authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator)
(2)void encrypted(QNetworkReply *reply)
(3)void finished(QNetworkReply *reply)
(4)void preSharedKeyAuthenticationRequired(QNetworkReply *reply, QSslPreSharedKeyAuthenticator *authenticator)
(5)void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
(6)void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
By connecting signals (1), (2), (4), (5) and (6) to debugging slots, I have determined that none of these signals is emitted. Only signal (3) is emitted.If we use
https
instead ofhttp
, the problem disappears. We don't want to go in that direction, though, because that would require our customers to installOpenSSL
on their hosts, and all the hassle incurred.So, is this a bug in Qt 6.1.3? Or perhaps
QNetworkAccessManager
should be configured in some specific way in order to avoid this problem? - in the above code snippet,
-
Problem solved:
Instead of:
QNetworkAccessManager* manager = new QNetworkAccessManager(); manager->get(QNetworkRequest(<our URL>));
we use:
QNetworkAccessManager* manager = new QNetworkAccessManager(); QNetworkRequest request(<our URL>); request.setAttribute(QNetworkRequest::Http2AllowedAttribute, false); manager->get(request);
Http2AllowedAttribute
wasfalse
by default inQt 5
, and istrue
by default inQt 6
. -
My colleagues and I have had a problem with
QNetworkAccessManager
after migrating fromQt 5.2.12
toQt 6.1.3
.Our Qt-based client application communicates with our server. The application creates a
QNetworkAccessManager
in order to retrieve data from the server. In a nutshell:QNetworkAccessManager* manager = new QNetworkAccessManager(<parent>); connect(manager, &QNetworkAccessManager::finished, this, &SomeClass::replyFinished); ///////////////////////////////// void SomeClass::replyFinished(QNetworkReply* reply) { if (reply->error() != QNetworkReply::NoError) { <error handling code> return; } const QString dataFromServer = QString(reply->readAll()); <code which uses dataFromServer> }
This works perfectly in
Qt 5.2.12
(Windows 10), even when the client uses a VPN.In
Qt 6.1.3
(Windows 10), however, we get an error when the client uses a VPN (but this works if the client does not uses a VPN). More precisely:- in the above code snippet,
reply->error()
returns:
QNetworkReply::ProtocolInvalidOperationError (302): "the requested operation is invalid for this protocol"
reply->errorString()
returns:
"Error transferring http://<our server's address> - server replied: <our server's error message>"
Some additional information:
The error message that we get (
"Error transferring ..."
) is generated inqtbase/src/network/access/qhttpthreaddelegate.cpp
, either by functionQHttpThreadDelegate::finishedSlot()
or by functionQHttpThreadDelegate::synchronousFinishedSlot()
. The implementations of these two functions are identical inQt 5.2.12
andQt 6.1.3
(except that, in the final statement of each function,0
replaced bynullptr
inQt 6.1.3
), so the problem is somewhere else.QNetworkAccessManager
defines six signals:
(1)void authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator)
(2)void encrypted(QNetworkReply *reply)
(3)void finished(QNetworkReply *reply)
(4)void preSharedKeyAuthenticationRequired(QNetworkReply *reply, QSslPreSharedKeyAuthenticator *authenticator)
(5)void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
(6)void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
By connecting signals (1), (2), (4), (5) and (6) to debugging slots, I have determined that none of these signals is emitted. Only signal (3) is emitted.If we use
https
instead ofhttp
, the problem disappears. We don't want to go in that direction, though, because that would require our customers to installOpenSSL
on their hosts, and all the hassle incurred.So, is this a bug in Qt 6.1.3? Or perhaps
QNetworkAccessManager
should be configured in some specific way in order to avoid this problem? - in the above code snippet,
-
@Antonius
While you wait for a better answer. Are you tied to Qt 6.1.3? It is up to 6.5 now, there might have been a relevant bug fix. Are you able to test with a more recent version? -
My colleagues and I have had a problem with
QNetworkAccessManager
after migrating fromQt 5.2.12
toQt 6.1.3
.Our Qt-based client application communicates with our server. The application creates a
QNetworkAccessManager
in order to retrieve data from the server. In a nutshell:QNetworkAccessManager* manager = new QNetworkAccessManager(<parent>); connect(manager, &QNetworkAccessManager::finished, this, &SomeClass::replyFinished); ///////////////////////////////// void SomeClass::replyFinished(QNetworkReply* reply) { if (reply->error() != QNetworkReply::NoError) { <error handling code> return; } const QString dataFromServer = QString(reply->readAll()); <code which uses dataFromServer> }
This works perfectly in
Qt 5.2.12
(Windows 10), even when the client uses a VPN.In
Qt 6.1.3
(Windows 10), however, we get an error when the client uses a VPN (but this works if the client does not uses a VPN). More precisely:- in the above code snippet,
reply->error()
returns:
QNetworkReply::ProtocolInvalidOperationError (302): "the requested operation is invalid for this protocol"
reply->errorString()
returns:
"Error transferring http://<our server's address> - server replied: <our server's error message>"
Some additional information:
The error message that we get (
"Error transferring ..."
) is generated inqtbase/src/network/access/qhttpthreaddelegate.cpp
, either by functionQHttpThreadDelegate::finishedSlot()
or by functionQHttpThreadDelegate::synchronousFinishedSlot()
. The implementations of these two functions are identical inQt 5.2.12
andQt 6.1.3
(except that, in the final statement of each function,0
replaced bynullptr
inQt 6.1.3
), so the problem is somewhere else.QNetworkAccessManager
defines six signals:
(1)void authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator)
(2)void encrypted(QNetworkReply *reply)
(3)void finished(QNetworkReply *reply)
(4)void preSharedKeyAuthenticationRequired(QNetworkReply *reply, QSslPreSharedKeyAuthenticator *authenticator)
(5)void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
(6)void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
By connecting signals (1), (2), (4), (5) and (6) to debugging slots, I have determined that none of these signals is emitted. Only signal (3) is emitted.If we use
https
instead ofhttp
, the problem disappears. We don't want to go in that direction, though, because that would require our customers to installOpenSSL
on their hosts, and all the hassle incurred.So, is this a bug in Qt 6.1.3? Or perhaps
QNetworkAccessManager
should be configured in some specific way in order to avoid this problem? - in the above code snippet,
-
@Antonius What was the request? A GET, POST, something else?
Have you tried the same request outside of your application, e.g. withcurl
or the like?@ChrisW67 I should have mentioned in my original post that the request is a
GET
(throughQNetworkAccessManager::get()
).I tried the same request with Cygwin's
curl
, and it worked in both cases (with and without VPN). When the VPN was used, there was a very short delay (less than a second) beforecurl
started to print its output. -
Problem solved:
Instead of:
QNetworkAccessManager* manager = new QNetworkAccessManager(); manager->get(QNetworkRequest(<our URL>));
we use:
QNetworkAccessManager* manager = new QNetworkAccessManager(); QNetworkRequest request(<our URL>); request.setAttribute(QNetworkRequest::Http2AllowedAttribute, false); manager->get(request);
Http2AllowedAttribute
wasfalse
by default inQt 5
, and istrue
by default inQt 6
. -