qNetworkAccessManager and cookies
I'm trying to download a website (youtube) that opens after user passes the consent page (accepting cookies). So i create QNetworkRequest request and set RawHeader to ("COOKIE" , "CONSENT=YES+42"). It works fine, but only with the first attempt to download. With every next attempt i bounce against the consent page. The problem is somehow bypassed when each time i use deleteLater() on QNetworkAccessManager object. But the documentation claims "One QNetworkAccessManager instance should be enough for the whole Qt application" (also creating new instance of QNetworkAccessManager for each use eventually results with not receiving a replay and rise of processor use). So my question is how to "reset" QNetworkAccessManager so with each next use, it acts as with the first request. My code looks like this:
Code:
{
manager = new QNetworkAccessManager(this);
}
void Youtube
::makeRequest(QString indexCore
){ QNetworkReply *reply;
QNetworkRequest request;
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slotReadyRead(QNetworkReply*)));
request.setRawHeader("COOKIE" , "CONSENT=YES+42" ); //works
request.
setUrl(QUrl("https://" + indexCore
));
reply = manager->get(request);
}
void Youtube::slotReadyRead(QNetworkReply *replay)
{
website = dataTemp.toStdString();
replay->deleteLater();
}
Re: qNetworkAccessManager and cookies
Quote:
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slotReadyRead(QNetworkReply*)));
You are making a new signal-slot connection every time makeRequest() is executed. This means the same slot will be executed extra times for each signal sent by the manager. Not only that, but on subsequent invocations of the same slot as a result of that one signal, you will be using a potentially invalid QNetworkReply (because you have asked it to delete itself).
Make the connection once, in the constructor where you create the QNetworkAccessManager instance.
In addition, in line 12 you have a memory leak because you do not delete the QNetworkReply instance that is created in the get() call.
Re: qNetworkAccessManager and cookies
Thanks. Though the problem remains, that with the first query i receive the correct answer from Youtube, but with the 2nd i return to the consent page, which demands correct cookie. In the code below i achieve right answers all the time but only when i delete QNetworkCookieJar each time, which is not the right practice according the documentation, and that also may lead to runtime error.
Code:
{
manager = new QNetworkAccessManager(this);
cookieJar = new QNetworkCookieJar(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slotReadyRead(QNetworkReply*)));
}
void Youtube
::makeRequest(QString indexCore
) {
QNetworkRequest request;
QNetworkCookie cookie;
cookie.setName("CONSENT=YES+42");
cookieJar->insertCookie(cookie);
manager->setCookieJar(cookieJar);
std::cout << termcolor::yellow << "YOUTUBE::makeRequest()" << termcolor::reset<< std::endl;
request.setRawHeader("COOKIE" , "CONSENT=YES+42" ); //works
request.
setUrl(QUrl("https://" + indexCore
));
manager->get(request);
}
void Youtube::slotReadyRead(QNetworkReply *replay)
{
website = dataTemp.toStdString();
manager->cookieJar()->deleteCookie(cookie);
std::cout << termcolor::yellow << "Youtube::slotReadyRead(QNetworkReply *replay)" << termcolor::reset<< std::endl;
replay->deleteLater();
manager->autoDeleteReplies();
manager->clearAccessCache();
manager->clearConnectionCache();
manager->setAutoDeleteReplies(true);
}
Re: qNetworkAccessManager and cookies
I do not see how line 28 of the new version can compile, or if it compiles, work. The variable "cookie" is either not defined in this scope, or it is defined but is not the "cookie" of line 13.
In any case, the point of a cookie is persistence so there seems little to be gained from constantly inserting and delete the same cookie. On your first request a cookie, or cookies, will come back and be placed in the cookie jar. If one of those is this "CONSENT" cookie then you are immediately removing any information the server may have placed in it.
Put your starting cookie in the jar once in the constructor and not in makeRequest(), then just leave the jar alone as you make requests.