PDA

View Full Version : QNetworkAccessManager can't handle multiple cookies?



krippy2k
7th June 2009, 19:53
Hi all,

I'm wondering if anybody else sees this problem.

When I use QNetworkAccessManager to handle HTTP connections, I have noticed that if the server issues several Set-Cookie headers that only the first one is added to the cookie jar.

If I dump the headers from the QNetworkReply I see that "Set-Cookie" shows all of the cookies that are received from the server, but if I do this immediately after:



QList<QNetworkCookie> cookieList = qvariant_cast<QList<QNetworkCookie> >(reply->header(QNetworkRequest::SetCookieHeader));
int count = cookieList.count();


"count" is always 1. And then if I access the cookie jar for the corresponding URL it only returns 1 cookie. I have a feeling that because it's several headers with the same name it's combining them all into one header and thus one cookie.

I'm going to see if I can track this down in the sources, but just wondering in the meantime if this works correctly for anybody else?

Thanks

krippy2k
7th June 2009, 21:29
Alright, I see what the problem is here. When multiple headers are added with the same name they are concatenated into a single header and separated with a new line '\n'. Then the static method QNetworkCookie::parseCookies is supposed to split the cookies up into separate cookies, but that method is broken.

From what I can tell that method thinks that cookies are separated by commas rather than newlines, because I see this case:



case ',':
// end of the cookie
endOfCookie = true;
break;


At first glance it would seem that just changing that ',' to '\n' would fix it, but no. What happens is everytime it encounters a ";" it thinks that a new field of the cookie is going to follow, and it jumps ahead to the next non-whitespace character after that, and starts the name of the next cookie as a new field in this cookie.

It would probably take a refactor of the parseCookies method to fix it correctly along the lines of what they're trying to do, but I found a temporary fix that works, and is probably a better solution anyway.

Near the beginning of this method is this:



int position = 0;
const int length = cookieString.length();
while (position < length) {


If we change that to this:


QList<QByteArray> cookieStrings = cookieString.split('\n');
foreach( QByteArray cookieString, cookieStrings )
{
int position = 0;
const int length = cookieString.length();


It will first break the set of cookies up into separate QByteArrays, and then process them individually so it doesn't have to worry about trying to find the separator character each time through.

I'm going to file a bug report after this, but figured I would post it in here in case anybody else runs into this problem.

Cheers

wysota
7th June 2009, 22:39
From what I know this is fixed in Qt 4.5.2

krippy2k
7th June 2009, 22:46
Ahh okay. Is there a 4.5.2 release or is that soon to come?

wysota
7th June 2009, 22:59
It's not yet released. But if you download the latest snapshot from the repository, the fix should already be there.

krippy2k
8th June 2009, 00:12
Okay, thanks a bunch. I did not even realize there were daily snapshots available. I'll be sure to test everything with the latest from now on.