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

QNetworkAccessManager doesn't immediately apply cookies received during redirect

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2: Important
    • Resolution: Done
    • Affects Version/s: 5.9.1, 5.9
    • Fix Version/s: 5.9
    • Component/s: Network: HTTP
    • Labels:
      None
    • Commits:
      8b64a1054ab5a428b7fcc4efad3ff31bc55dd7ed

      Description

      Problem

      If QNetworkRequest::FollowRedirectsAttribute is set to true in the request and/or QNetworkRequest::RedirectPolicy is set to a value different than QNetworkRequest::ManualRedirectPolicy, it actually follow the redirect but ignores all the cookies received in the redirection process.

      Example

      Example with a django application to which I tried to login using basic-auth:

      The workflow works like that:

      1. client requests /admin/ -> server replies 302 and redirects to /admin/login/
      2. clients follow redirects and requets /admin/login/ -> server replies 401 asking for basic auth
      3. clients requests /admin/login/ and sends credentials -> server sets cookie sessionid, replies 302 and redirects to /admin/
      4. clients requests /admin/ and sends sessionid cookie -> server reads sessionid and replies with 200

      If i follow this procedure with the browser or with the requests module in python it works like a charm.

      If I try with the code below the server does't receive any cookie, they are always empty, and the client enters in a redirect loop.

       

       

      SsoNetworkManager::SsoNetworkManager(QObject *parent) : QNetworkAccessManager(parent)
      {
          connect(this, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this, SLOT(onAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
          connect(this, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*)));
      }
      
      void SsoNetworkManager::onAuthenticationRequired(QNetworkReply *reply, QAuthenticator *auth) 
      {
          auth->setUser(QString("test"));
          auth->setPassword(QString("test"));
      }
      
      void SsoNetworkManager::onFinished(QNetworkReply *reply)
      {
          qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
      }
      
      ...
      SsoNetworkManager nam;
      QNetworkRequest request("http://127.0.0.1:8000/admin/");
      request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
      
      nam.get(request);
      ...
      

      I just tried to remove the QNetworkRequest::FollowRedirectsAttribute and manually handle the redirects. This way it stores the cookies.

       

      Hints (maybe)

      I investigated further and took a look at the source code.

      qnetworkaccessmanager.cpp

      to set cookies QNetworkAccessManager uses

      request.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue(cookies));

      Anyway the QNetworkAccessManager uses the CookieJar only inside this method:

      QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op, 
                                            const QNetworkRequest &originalReq,
                                            QIODevice *outgoingData) 
      { //... 
      }

      Which is only called by the public methods "headgetpostputdeleteResources and sendCustomRequest" which are not called to send the redirected requests.

      They are internally handled, the redirection process is completely transparent to the QNetworkAccessManager.

       

      qnetworkreplyhttpimpl.cpp

      It looks like that when a redirect request is created it just take care of copying the original request changing the url, it doesn't take into account any other information got from the response.

      QNetworkRequest QNetworkReplyHttpImplPrivate::createRedirectRequest(const QNetworkRequest &originalRequest, const QUrl &url, int maxRedirectsRemaining) 
      { 
          QNetworkRequest newRequest(originalRequest); 
          newRequest.setUrl(url);
          newRequest.setMaximumRedirectsAllowed(maxRedirectsRemaining); 
          return newRequest; 
      } 

      Hope it helps.

        Attachments

          Issue Links

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

            Activity

              People

              • Assignee:
                manordheim Mårten Nordheim
                Reporter:
                jiloc Francesco Leacche
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes