PDA

View Full Version : [QNetworkAccessManager + QNetworkCookieJar] Cookies are not saved



Kempo
29th February 2012, 11:29
Hello!
Objective: To load different pages of one site, with the ability to use previously issued cookie

The simplest application loads the page from localhost.


#include <QtCore>
#include <QApplication>
#include <QDebug>
#include <QtNetwork>

class MyCookieJar : public QNetworkCookieJar
{
public:
QList<QNetworkCookie> getAllCookies() { return allCookies(); }
};


class CookiesTest : public QObject
{
Q_OBJECT
public:
CookiesTest(QWidget* parent = 0);

private slots:
void replyFinished(QNetworkReply*);

private:
QNetworkAccessManager* manager;
MyCookieJar *cookieJar;
};

CookiesTest::CookiesTest(QWidget* parent)
{
manager = new QNetworkAccessManager;
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));

cookieJar = new MyCookieJar;
manager->setCookieJar(cookieJar);

manager->get(QNetworkRequest(QUrl("http://test1.ru/test/cookie.php")));
manager->get(QNetworkRequest(QUrl("http://test1.ru/test/cookie.php")));
}

void CookiesTest::replyFinished(QNetworkReply* reply)
{
qDebug() << reply->readAll();
qDebug() << "getAllCookies: " << cookieJar->getAllCookies();
}


int main(int argc, char* argv[])
{
QApplication app(argc, argv);
CookiesTest cookiesTest;
return app.exec();
}

#include "main.moc"in the file .pro: QT += network

File cookie.php shows number of visits that page on the analysis of the cookie

<?php
if (isset($_COOKIE['Mortal'])) $cnt = $_COOKIE['Mortal'] + 1;
else $cnt = 1;

setcookie("Mortal",$cnt,0x6FFFFFFF);
echo "NUM: [".@$_COOKIE['Mortal']."]";
?>
Output:

"NUM: []"
getAllCookies: (QNetworkCookie("Mortal=1; expires=Wed, 18-Jul-2029 05:49:51 GMT; domain=test1.ru; path=/test/") )
"NUM: []"
getAllCookies: (QNetworkCookie("Mortal=1; expires=Wed, 18-Jul-2029 05:49:51 GMT; domain=test1.ru; path=/test/") )

Although to be the second time in brackets the number 1 and the second getAllCookies: Mortal = 2

Tell me please, where was the mistake, what's wrong? Why cookies are not stored on the 2nd request

ChrisW67
29th February 2012, 23:05
At the time you issue your two asynchronous network requests the cookie jar is empty. Both requests go to the server without a cookie and come back with the same Mortal=1 value. The PHP end is working correctly.

This version waits three seconds before issuing the second request:

#include <QtCore>
#include <QApplication>
#include <QDebug>
#include <QtNetwork>

class MyCookieJar : public QNetworkCookieJar
{
public:
QList<QNetworkCookie> getAllCookies() { return allCookies(); }
};


class CookiesTest : public QObject
{
Q_OBJECT
public:
CookiesTest(QWidget* parent = 0);

private slots:
void replyFinished(QNetworkReply*);
void doAnother();

private:
QNetworkAccessManager* manager;
MyCookieJar *cookieJar;
};

CookiesTest::CookiesTest(QWidget* parent)
{
manager = new QNetworkAccessManager;
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));

cookieJar = new MyCookieJar;
manager->setCookieJar(cookieJar);

manager->get(QNetworkRequest(QUrl("http://ptolemy/test.php")));
QTimer::singleShot(3000, this, SLOT(doAnother()));
}

void CookiesTest::replyFinished(QNetworkReply* reply)
{
qDebug() << reply->readAll();
qDebug() << "getAllCookies: " << cookieJar->getAllCookies();
}

void CookiesTest::doAnother() {
manager->get(QNetworkRequest(QUrl("http://ptolemy/test.php")));
}

int main(int argc, char* argv[])
{
QApplication app(argc, argv);
CookiesTest cookiesTest;
return app.exec();
}

#include "main.moc"

Kempo
1st March 2012, 10:59
Thank you very much ChrisW67! It works. :)

Perhaps I still misunderstand something, but that's an option for some reason just does not work, cookies Mortal = 1

#include <QtCore>
#include <QApplication>
#include <QDebug>
#include <QtNetwork>

class MyCookieJar : public QNetworkCookieJar
{
public:
QList<QNetworkCookie> getAllCookies() { return allCookies(); }
};


class CookiesTest : public QObject
{
Q_OBJECT
public:
CookiesTest(QWidget* parent = 0);
void download(QString);

private slots:
void replyFinished(QNetworkReply*);
void doAnother();

private:
QNetworkAccessManager* manager;
MyCookieJar *cookieJar;
QUrl myUrl;
};

CookiesTest::CookiesTest(QWidget* parent)
{
manager = new QNetworkAccessManager;
cookieJar = new MyCookieJar;
manager->setCookieJar(cookieJar);

connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
}

void CookiesTest::replyFinished(QNetworkReply* reply)
{
qDebug() << reply->readAll();
qDebug() << "getAllCookies: " << cookieJar->getAllCookies();
}

void CookiesTest::doAnother() {
manager->get(QNetworkRequest(myUrl));
}

void CookiesTest::download(QString url)
{
myUrl = QUrl(url);
QTimer::singleShot(500, this, SLOT(doAnother()));
}

int main(int argc, char* argv[])
{
QApplication app(argc, argv);
CookiesTest cookiesTest;
cookiesTest.download("http://test1.ru/test/cookie.php");
cookiesTest.download("http://test1.ru/test/cookie.php");
return app.exec();
}

#include "main.moc"


Output:

"NUM: []"
getAllCookies: (QNetworkCookie("Mortal=1; expires=Wed, 18-Jul-2029 05:49:51 GMT; domain=test1.ru; path=/test/") )
"NUM: []"
getAllCookies: (QNetworkCookie("Mortal=1; expires=Wed, 18-Jul-2029 05:49:51 GMT; domain=test1.ru; path=/test/") )


But I found another solution to this


#include <QtCore>
#include <QApplication>
#include <QDebug>
#include <QtNetwork>


class MyCookieJar : public QNetworkCookieJar
{
public:
QList<QNetworkCookie> getAllCookies() { return allCookies(); }
};


class CookiesTest : public QObject
{
Q_OBJECT
public:
CookiesTest(QObject *parent = 0);
void download(QString);
void _download(QUrl);

private:
QNetworkAccessManager* manager;
MyCookieJar *cookieJar;
QList<QNetworkCookie> cookiesList;
};

CookiesTest::CookiesTest(QObject *parent) : QObject(parent)
{
manager = new QNetworkAccessManager;
cookieJar = new MyCookieJar();
manager->setCookieJar(cookieJar);
}

void CookiesTest::download(QString url)
{
_download(QUrl(url));
}

void CookiesTest::_download(QUrl url)
{
//enters event loop, simulate blocking io
QEventLoop q;
QTimer t;
t.setSingleShot(true);
connect(&t, SIGNAL(timeout()), &q, SLOT(quit()));

QNetworkReply *reply = manager->get(QNetworkRequest(url));
connect(reply, SIGNAL(finished()), &q, SLOT(quit()));

t.start(5000);
q.exec();

if (t.isActive()) {
t.stop();
QByteArray response = reply->readAll();
qDebug() << response;

QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttrib ute);
if (reply->error()) {
qDebug()<< "Download failed" << reply->errorString();
} else if (!redirectionTarget.isNull()) {
QUrl newUrl = url.resolved(redirectionTarget.toUrl());
qDebug()<< "Redirect to" << newUrl.toString();
url = newUrl;
// reply->deleteLater();
_download(url);
} else {
qDebug() << "Finish! ";
}

reply->deleteLater();

} else {
qDebug() << "Timeout";
}

cookiesList = cookieJar->getAllCookies();
qDebug() << "getAllCookies: " << cookiesList;
}

int main(int argc, char* argv[])
{
QApplication app(argc, argv);
CookiesTest cookiesTest;
cookiesTest.download("http://test1.ru/test/cookie.php");
cookiesTest.download("http://test1.ru/test/cookie.php");
cookiesTest.download("http://test1.ru/test/cookie.php");
return app.exec();
}

#include "main.moc"



Output:

"NUM: []"
Finish!
getAllCookies: (QNetworkCookie("Mortal=1; expires=Wed, 18-Jul-2029 05:49:51 GMT; domain=test1.ru; path=/test/") )
"NUM: [1]"
Finish!
getAllCookies: (QNetworkCookie("Mortal=2; expires=Wed, 18-Jul-2029 05:49:51 GMT; domain=test1.ru; path=/test/") )
"NUM: [2]"
Finish!
getAllCookies: (QNetworkCookie("Mortal=3; expires=Wed, 18-Jul-2029 05:49:51 GMT; domain=test1.ru; path=/test/") )