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

Infinite blocking, while accessing a server

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P2: Important
    • None
    • 6.4.3
    • None
    • Windows

    Description

      Consider the following simple application. It initiates one POST request to a certain server and if it returns, it prints the error code and exits.

      #include <QCoreApplication>
      #include <QNetworkAccessManager>
      #include <QNetworkReply>
      #include <QNetworkRequest>
      #include <QUrl>

      auto main(int argc, char * argv[]) -> int {
          auto Application = QCoreApplication{argc, argv};
          auto NetworkAccessManager = QNetworkAccessManager{};
          auto NetworkRequest = QNetworkRequest{QUrl{"https://keycloak.limbachgruppe.com/"}};
          auto NetworkReply = NetworkAccessManager.post(NetworkRequest, "");

          QObject::connect(NetworkReply, &QNetworkReply::finished

              [NetworkReply]() {

                  qDebug() << NetworkReply->error();

                  QCoreApplication::exit(1);

          }{});

          return Application.exec();
      }

       

      This blocks indefinitely, because the finished signal is never emitted. The circumstances are kind of particular: The request has to be sent to this server and the application has to be run on Windows.
      Now, it would be easy to say, that this is the server's fault and its configuration should be fixed, but for three issues:

      1. When having a look at the communication via Wireshark, I can see a full TLSv1.2 communication has been performed and from what I can see, no major issues have arisen. (see attached image 1) Importantly, the TCP communication has been terminated correctly by mutual FINs and ACKs.
      2. When browsing to that same address with a browser on the same Windows system, I get the server's default error page (... because of missing parameters and such). (see attached image 2)
      3. When executing this little example application on Linux, I get the expected finished signal, QNetworkReply::ServiceUnavailableError is written to the console and the application exits. (see attached image 3 for the corresponding Wireshark)

      A few things worth mentioning

      • the application on Windows uses TLS1.2; the same application on Linux uses TLS1.3; the Qt version is identical (6.4.3), but Qt on WIndows is provided by the Qt Maintenance Tool, whereas Qt on Linux is provided by Ubuntu
      • when forcing TLS1.3 (through QSslConfiguration) on Windows, the request fails and finishes with QNetworkReply::UnknownNetworkError and the error string "Invalid protocol chosen".
      • when forcing TLS1.2 (through QSslConfiguration) on Linux, the request "succeeds" and finishes with QNetworkReply::ServiceUnavailableError, as expected
      • when interrupting the blocked application on Windows, inside of a (roughly) 30 second window, Qt writes a final message to the console: "QWaitCondition: Destroyed while threads are still waiting". After 30 seconds or more, no such message is printed.
      • extending the example application (see attached cpp file), I have connected to all signals that QNetworkReply exposes, which, on Windows, results in the following output; after which it blocks erroneously. 797 bytes is in fact the length of the full response as seen on Linux, indicating that the full answer from the server has in fact been received on both Windows and Linux.

      socketStartedConnecting
      encrypted
      metaDataChanged
      downloadProgress 797 / -1

      • When setting a timeout of any length, the request is aborted after that timeout and the finished signal is emitted. The error of the reply is QNetworkReply::OperationCanceledError instead of QNetworkReply::TimeoutError, probably because it wasn't the connection to the server that timed out.

      Expected behavior

      I want the request to finish. I realize that it may be impossible to get the correct reply from the server, due to a misconfiguration on the client side or missing support for some encryption on Windows, and that is not what I aim for. If the request fails for some reason, so be it, but it should not lock up the request and it should report a sensible and expressive error code and string! I can set a timeout and that is an okayish workaround, but the lockup is obviously something local and should be fixed.

      Attachments

        1. image1.png
          image1.png
          66 kB
        2. image2.png
          image2.png
          13 kB
        3. image3.png
          image3.png
          250 kB
        4. main.cpp
          2 kB
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            manordheim Mårten Nordheim
            hagen.moebius Hagen Möbius
            Votes:
            1 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes