Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

CookieJar and setHeader woes



  • I have a PyQt5 application I'm developing that uses QNAM and different Cookie Jars depending on a few class specific variables that I check before making the request. I may make 5 different requests together in a loop. I originally was planning on using setCookieJar(cookieJar) just prior to making each request, however this does not seem to work as I'm getting the following error after the reply/s are finished:

    "RuntimeError: wrapped C/C++ object of type QNetworkCookieJar has been deleted"

    After inspection of the setCookieJar() source code in qnetworkaccessmanager.cpp (http://osxr.org:8080/qt/source/qtbase/src/network/access/qnetworkaccessmanager.cpp#0669), it seems everytime you call setCookieJar, Qt calls delete on whatever cookieJar you had set prior, hence why I would be getting the above error when QNAM tries to modify a cookie jar that no longer exists.

    So I scrapped the idea of using QNAM's Cookie Jar handling and implemented my own handling of cookies for every request by using:

    request.setAttribute(QNetworkRequest.CookieLoadControlAttribute, QNetworkRequest.Manual)
    request.setAttribute(QNetworkRequest.CookieSaveControlAttribute, QNetworkRequest.Manual)
    

    These prevent automatically loading and saving of cookies in QNAM's cookieJar instance.

    So to load the cookies before the request I tried doing something like the following:

    cookiesToSend = self.cookieJars[account].cookiesForUrl(url)
    if cookiesToSend:
        request.setHeader(QNetworkRequest.CookieHeader, cookiesToSend)
    

    However this doesn't seem to work! If I run the following line of code right after:

    request.header(QNetworkRequest.CookieHeader)
    

    Returns None. Why? According to the docs, you are supposed to give it a list of QNetworkCookies (http://doc.qt.io/qt-5/qnetworkrequest.html#KnownHeaders-enum):

    "Corresponds to the HTTP Cookie header and contains a QList<QNetworkCookie> representing the cookies to be sent back to the server."

    Even in the C++ source code of createRequest() it calls something very similar (http://osxr.org:8080/qt/source/qtbase/src/network/access/qnetworkaccessmanager.cpp#1162):

    QList<QNetworkCookie> cookies = d->cookieJar->cookiesForUrl(request.url());
    if (!cookies.isEmpty())
        request.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue(cookies));
    

    Is there some quirk with PyQt5 that is preventing this from working because PyQt5 doesn't have QVariant.fromValue()? I then did a test with the following line of code:

    cookiesToSend = self.cookieJars[account].cookiesForUrl(url)
    if cookiesToSend:
        for cookie in cookiesToSend:
            request.setHeader(QNetworkRequest.CookieHeader, cookie)
    

    This works, but only the last cookie in the loop gets set. The others are overridden each loop. So the setHeader call here does accept single QNetworkCookies. (Just not a list of QNetworkCookie objects in PyQt...hmm)

    At this point, I had to resort to the hacky way of using setRawHeader and currently do the following which does the job, but seems ugly:

    cookiesToSend = self.cookieJars[account].cookiesForUrl(url)
    if cookiesToSend:
        cookieString = str()
        for cookie in cookiesToSend:
            cookieString += str(cookie.name(), 'utf-8')+'='+str(cookie.value(), 'utf-8')+'; '
        cookieString = cookieString[:-2]  # remove '; ' from last cookie
        request.setRawHeader(bytes('Cookie', 'utf-8'), bytes(cookieString, 'utf-8'))
    

    In the docs of setRawHeader I also noticed the following:

    "Note: Setting the same header twice overrides the previous setting. To accomplish the behaviour of multiple HTTP headers of the same name, you should concatenate the two values, separating them with a comma (",") and set one single raw header."

    I'm guessing this is what they mean by what I did with setRawHeader()? Though I don't understand what they mean by using a comma.

    Any tips/suggestions/answers to any of my above questions would be appreciated,

    Thanks


Log in to reply