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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.