Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-109718

QWebSocket cannot handle HTTP 407 response ("Proxy Authentication Required")

    XMLWordPrintable

Details

    • 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,

      1. The proxyAuthenticationRequired() is not emitted.
      2. 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

      1. Download the attached project
      2. Run the attached Python script, failingproxy.py
      3. 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"

      Attachments

        Activity

          People

            oyheskes Øystein Heskestad
            skoh-qt Sze Howe Koh
            Vladimir Minenko Vladimir Minenko
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated: