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

QNetworkRequest with UserVerifiedRedirectPolicy ends with HTTP 100 when multiple redirects happen

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 5.15.2, 6.3.1
    • Network: HTTP
    • None
    • Windows

    Description

      QNetworkRequest with RedirectPolicyAttribute set to UserVerifiedRedirectPolicy does not handle multiple HTTP 302 redirects correctly.

      I have a server which responds to a specific GET request with a series of eight HTTP 302 redirects before serving the requested content. The QNetworkRequest finishes prematurely with a nonsensical HTTP status code of 100 after the second or third redirect (this behavior is random).

      The root cause of the bug seems to be that QNetworkReplyHttpImplPrivate::followRedirect() which is connected to redirectAllowed(), invokes QNetworkReplyHttpImplPrivate::start which invokes QNetworkReplyHttpImplPrivate::postRequest.
      postRequest agains connects (already connected) signal redirectAllowed to followRedirect. followRedirect is thus invoked multiple times on each subsequent emission of redirectAllowed, causing 1) multiple requests made to the server 2) some kind of race condition in parsing the reply headers, leading to the HTTP status code 100 which was never produced by the server.

      302 redirect seems to work fine when RedirectPolicy is set to NoLessSafeRedirectPolicy, due to more synchronous nature of evaluating the redirection. Unfortunately I can't use this, since my use case requires following an HTTPS->HTTP redirect.

      QNetworkRequest *req = new QNetworkRequest{ QUrl{"http://localhost:8080/multi_redirect"} };
      req->setAttribute(QNetworkRequest::Attribute::RedirectPolicyAttribute, QNetworkRequest::RedirectPolicy::UserVerifiedRedirectPolicy);
      auto reply = mgr->get(*req);
      connect(reply, &QNetworkReply::redirected, [this, reply] {
        emit reply->redirectAllowed(); 
      });
      connect(reply, &QNetworkReply::finished, [this, reply] { reply_finished(reply); });
      ...
      void reply_finished(QNetworkReply* reply)
      {
        auto code = qvariant_cast<int>(reply->attribute(QNetworkRequest::Attribute::HttpStatusCodeAttribute));
        printf("HTTP %d. %s\n", code, code == 100 ? "what?" : "");
        finished();
      }
      

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            manordheim Mårten Nordheim
            robert.skorpil Robert Skorpil
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes