PDA

View Full Version : QNetworkCookieJar



ttimt
26th February 2014, 10:43
So i set a QnetworkCookieJar for my QNetworkAccessManager


//Setup QNetwork
loginnam = new QNetworkAccessManager();

//Cookies
NetworkJar njarobj;
loginnam->setCookieJar(&njarobj);
njarobj.setParent(0);


and in Qt Documentation :

In order to implement your own security policy, override the QNetworkCookieJar::cookiesForUrl() and QNetworkCookieJar::setCookiesFromUrl() virtual functions. Those functions are called by QNetworkAccessManager when it detects a new cookie.
What if I don't want to implement my own security policy or whatever, do I need to implement my own setCookiesFromUrl ?
Don't I need to specify the location to store cookies? But I don't see that function, so I assume I'll need to reimplement SetCookiesFromUrl to store to disk and CookiesFromUrl to get from disk?

Using QFile?

Networkjar.h

#ifndef NETWORKJAR_H
#define NETWORKJAR_H

#include <QNetworkCookieJar>

class NetworkJar: public QNetworkCookieJar
{

public:
NetworkJar();
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const;
};

#endif // NETWORKJAR_H


Networkjar.cpp

#include "networkjar.h"
#include <QFile>
#include <QDateTime>
#include <QTextStream>

NetworkJar::NetworkJar()
{
}
bool NetworkJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
{
QList<QNetworkCookie> cookies = QNetworkCookieJar::allCookies();

QFile cookiesfile("Cookies");
QTextStream out(&cookiesfile);
if (!cookiesfile.open(QFile::WriteOnly | QFile::Text))
{
return false;
}
foreach (QNetworkCookie cookie, cookieList)
{
cookies += cookie;
out << "Name:" << cookie.name() << "Value:" << cookie.value() << "Path:" << cookie.path() << "Expire Date:" << cookie.expirationDate().toString();
}
return true;
}

QList<QNetworkCookie> NetworkJar::cookiesForUrl(const QUrl &url) const
{
//Later
}

anda_skoa
26th February 2014, 13:15
//Setup QNetwork
loginnam = new QNetworkAccessManager();

//Cookies
NetworkJar njarobj;
loginnam->setCookieJar(&njarobj);
njarobj.setParent(0);


That is unlikely to work properly, njarobj is on the stack and will go out of scope at then end of the block (probably a function body).



What if I don't want to implement my own security policy or whatever, do I need to implement my own setCookiesFromUrl ?

You don't need a derived class if you don't want to change anything that QNetworkCookieJar does



Don't I need to specify the location to store cookies?

QNetworkCookieJar does not persist cookies. Any derived class that implements persistence needs to address this depending on the persistence mechanism chosen for its implementation.




But I don't see that function, so I assume I'll need to reimplement SetCookiesFromUrl to store to disk and CookiesFromUrl to get from disk?

Or using explicit save/load methods that get called at the end/start of the program.


Using QFile?
Indeed a valid option.




Networkjar.cpp

#include "networkjar.h"
#include <QFile>
#include <QDateTime>
#include <QTextStream>

NetworkJar::NetworkJar()
{
}
bool NetworkJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
{
QList<QNetworkCookie> cookies = QNetworkCookieJar::allCookies();

QFile cookiesfile("Cookies");
QTextStream out(&cookiesfile);
if (!cookiesfile.open(QFile::WriteOnly | QFile::Text))
{
return false;
}
foreach (QNetworkCookie cookie, cookieList)
{
cookies += cookie;
out << "Name:" << cookie.name() << "Value:" << cookie.value() << "Path:" << cookie.path() << "Expire Date:" << cookie.expirationDate().toString();
}
return true;
}


That seems to ignore the "url" argument, which will likely make it difficult to then later retrieve the cookies for that URL.

Cheers,
_

ttimt
26th February 2014, 13:50
Or using explicit save/load methods that get called at the end/start of the program.

What's that




That seems to ignore the "url" argument, which will likely make it difficult to then later retrieve the cookies for that URL.

I haven't implement cookiesforURL. so I'll output the URL to my file too.






Those functions are called by QNetworkAccessManager when it detects a new cookie.
Tested. And I think it won't load, my cookies are saved in a file through setcookiesfromurl function. But when I create a new QNetworkAccessManager and access the same web, the Qnetworkaccessmanager just reset my files. Tried create a function in networkjar class and run cookiesforUrl then set it using this->setallcookies. still the same
*EDIT : Maybe I'll need to check the cookie existence before writing and append new data not rewrite :cool: Will do that soon



EDIT: Removed :rolleyes:

anda_skoa
26th February 2014, 19:44
What's that

A method?
This usually refers to a function declared as part of a class's interface.

Cheers,
_

ttimt
27th February 2014, 11:15
A method?
This usually refers to a function declared as part of a class's interface.

Cheers,
_

:rolleyes: The Save/Load



I tried to check for cookie name before writing to file but this is outputting nothing?


//Setup
QList<QNetworkCookie> cookies = QNetworkCookieJar::allCookies();
QFile cookiesfile("cookiefile");
QTextStream in(&cookiesfile);
QList<QString> savedcookies;

//Read
if (!cookiesfile.open(QFile::ReadOnly | QFile::Text))
{
emit networkreplyError("Failed to open file for reading!");
}
while (!cookiesfile.atEnd())
{
savedcookies << in.readLine();
}
in.flush();
cookiesfile.close();

//Append
QTextStream out(&cookiesfile);
if (cookiesfile.open(QFile::Append | QFile::Text))
{
emit networkreplyError("Failed to open file for reading");
}

foreach (QNetworkCookie cookie, cookieList)
{
for (int i = savedcookies.size()-1; i >= 0; i--)
{//will add check URL later
if (!savedcookies.at(i).contains(cookie.name()))
{
//Name, Value, Path, Domain, Expire Date, URL
out << "Name:" << cookie.name() << " spliter " << "Value:" << cookie.value() << " spliter " << "Path:" << cookie.path() << " spliter " << "Domain:" << cookie.domain() << " spliter " << "Expire Date:" << cookie.expirationDate().toString() << " spliter " << "URL:" << url.toString() << endl;
out.flush();
cookies += cookie;
}
}
}

//Close and Return
cookiesfile.close();
return true;

sasabeauty
27th February 2014, 11:56
Hello, everyone

anda_skoa
27th February 2014, 12:37
:rolleyes: The Save/Load

Oh, I thought that would be self explanatory :-)
A save method would write the cookies into a file and a load method would read them from a file.



I tried to check for cookie name before writing to file but this is outputting nothing?

I am not quite sure what you are trying to do here and where in the class you are doing it.
Trying to avoid duplicates in setCookiesForUrl()?

That would be another thing that is easier in an explicit save method, because there you can just overwrite the file with the current jar content.

Cheers,
_

ttimt
27th February 2014, 13:01
I mean what save/load is that, that get "called at the end/start" ?
Maybe I misinterpreted this.
You probably saying create functions that get called at the end/start, not some special qt save/load function that is not created by me


I'm in NetworkJar class, subclass QNetworkCookieJar.
That function is setCookiesforUrl, trying to check if cookies already exists before writing.

anda_skoa
27th February 2014, 14:50
I mean what save/load is that, that get "called at the end/start" ?
Maybe I misinterpreted this.
You probably saying create functions that get called at the end/start, not some special qt save/load function that is not created by me

Exactly. I was suggeting to use explicit methods for saving and loading instead of making the setter and getter do it on every invocation.

Cheers,
_

ttimt
1st March 2014, 18:12
Do I need to use setallcookies if I returned a Qlist<QNetworkCookie> in cookiesforurl ???

anda_skoa
1st March 2014, 20:09
I doubt it. setAllCookies() sounds more like the function you would call in a load method, i.e. to initially fill the cookie jar.

Cheers,
_

ChrisW67
1st March 2014, 20:36
The Qt browser demo (http://qt.gitorious.org/qt/qt/trees/4.8/demos/browser) implements cookie persistence. See cookiejar.h and cpp.