Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Unsolved QNetworkAccessManager purges cookies if following redirect

    General and Desktop
    qtnetwork qnetworkaccessm redirect cookies
    2
    8
    2996
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      Jiloc last edited by

      Hello everyone, does someone know how to force QNetworkAccessManager to send back cookies even if it's following a redirect?
      Seems like if it receive a 301 or 302 response and the QNetworkRequest::FollowRedirectsAttribute is set to true in the request, it actually follow the redirect but ignores all the cookies received.
      Is it a bug or an exptected behaviour?

      raven-worx 1 Reply Last reply Reply Quote 0
      • raven-worx
        raven-worx Moderators @Jiloc last edited by

        @Jiloc
        depends how you use QNetworkAccessManager.
        If you reuse the same instance (or at least take over it's cookie-jar) it definitely works.
        If that is the case then it depends what the server sends.

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        J 1 Reply Last reply Reply Quote 0
        • J
          Jiloc @raven-worx last edited by

          @raven-worx I am not talking about multiple requestes. It's a problem with the single request.

          If i send a request like that:

          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);
          ...
          
          

          The server works like that

          1. 302 and redirects to /admin/login/
          2. 401 asking for basic auth
          3. 302 , sets cookie sessionid and redirects to /admin/
          4. reads sessionid and replies with 200

          If i follow this procedure with the browser or with python it works like a charm.
          If i try this with the code above the server does't receive any cookie, they are always empty, and the client enters in a redirect loop.

          I just tried to remove the QNetworkRequest::FollowRedirectsAttribute and manually handle the redirects. This way it stores the cookies, but I don't want to keep doing it manually.

          To me it seems a bug

          1 Reply Last reply Reply Quote 0
          • J
            Jiloc last edited by

            Taking a look at the source code of /network/access/qnetworkreplyhttpimpl.cpp in qtbase, 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;
            }
            
            raven-worx 1 Reply Last reply Reply Quote 0
            • raven-worx
              raven-worx Moderators @Jiloc last edited by

              @Jiloc
              this doesn't mean anything.
              Important is what happens before/after this method by the QNetworkAccessManager. If it stores the cookies from the reply or not.
              Means the reply isn't responsible for storing the cookies of course.
              I don't have time to check the sources right now.

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              J 1 Reply Last reply Reply Quote 0
              • J
                Jiloc @raven-worx last edited by

                @raven-worx
                You are right, I investigated further.

                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 "head, get, post, put, deleteResources and sendCustomRequest" which are not called to send the redirected requests.

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

                raven-worx 1 Reply Last reply Reply Quote 0
                • raven-worx
                  raven-worx Moderators @Jiloc last edited by

                  @Jiloc
                  then probably it's the best to open a new Qt bugreport

                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                  If you have a question please use the forum so others can benefit from the solution in the future

                  J 1 Reply Last reply Reply Quote 0
                  • J
                    Jiloc @raven-worx last edited by

                    @raven-worx
                    I did as you suggested https://bugreports.qt.io/browse/QTBUG-63313 . Hope the bug report is properly documented

                    1 Reply Last reply Reply Quote 1
                    • First post
                      Last post