Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
5.15.12, 6.2.6, 6.4.1
-
Windows 10 Pro 22H2, MSVC 2019 x64
-
8
-
Foundation Sprint 74, Foundation Sprint 75, Foundation Sprint 76, Foundation Sprint 77, Foundation Sprint 78, Foundations Sprint 79
Description
Problems
When QWebSocket makes tries to connect via a proxy that requires authentication,
- The proxyAuthenticationRequired() is not emitted.
- When the HTTP 407 response is received, QWebSocket attempts to re-connect immediately without sending authentication data.
As a result, the authentication requirement is not detectable from C++, and the proxy server is spammed with connection attempts that will never work.
Steps to reproduce
- Download the attached project
- Run the attached Python script, failingproxy.py
- Build and run the attached Qt project
# failingproxy.py from http.server import BaseHTTPRequestHandler, HTTPServer from http import HTTPStatus class FailingProxy(BaseHTTPRequestHandler): def do_CONNECT(self): print("New HTTP request: CONNECT") self.send_response(HTTPStatus.PROXY_AUTHENTICATION_REQUIRED) self.send_header("Server", "Proxy") self.send_header("Proxy-Authenticate", "NTLM") self.send_header("Proxy-Authenticate", "Basic realm=\"CCProxy Authorization\"") self.send_header("Proxy-Connection", "Close") self.end_headers() self.close_connection = True if __name__ == "__main__": HOST, PORT = "localhost", 8880 try: print(f"Starting HTTP server at {HOST}:{PORT}") with HTTPServer((HOST, PORT), FailingProxy) as server: server.serve_forever() except KeyboardInterrupt: pass print("Server stopped.")
// main.cpp #include <QCoreApplication> #include <QWebSocket> #include <QAuthenticator> class SampleClient : public QObject { Q_OBJECT public: SampleClient(const QUrl& wsUrl, QObject* parent = nullptr) : QObject(parent) { qDebug("Creating SampleClient"); QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::ProxyType::HttpProxy, "localhost", 8880)); auto socket = new QWebSocket(QString(), QWebSocketProtocol::Version::VersionLatest, this); socket->open(wsUrl); connect(socket, &QWebSocket::proxyAuthenticationRequired, this, [] { qDebug("proxyAuthenticationRequired() signal emitted"); }); } }; int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); SampleClient client(QUrl("ws://google.com")); return app.exec(); } #include "main.moc"
Actual outcome
Server prints:
Starting HTTP server at localhost:8880 New HTTP request: CONNECT 127.0.0.1 - - [30/Dec/2022 14:11:41] "CONNECT google.com:80 HTTP/1.1" 407 - New HTTP request: CONNECT 127.0.0.1 - - [30/Dec/2022 14:11:43] "CONNECT google.com:80 HTTP/1.1" 407 - New HTTP request: CONNECT 127.0.0.1 - - [30/Dec/2022 14:11:45] "CONNECT google.com:80 HTTP/1.1" 407 - New HTTP request: CONNECT 127.0.0.1 - - [30/Dec/2022 14:11:47] "CONNECT google.com:80 HTTP/1.1" 407 - New HTTP request: CONNECT ...
Client prints:
Creating SampleClient
Expected outcome
Client should also print "proxyAuthenticationRequired() signal emitted"