Russian Qt Forum

Qt => Работа с сетью => Тема начата: eldar85 от Декабрь 25, 2010, 17:50



Название: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 25, 2010, 17:50
Добрый день. Такая задачька, делаю класс для работы с сетью. Проблема в том что не знаю как отчистить QNetworkAccessManager. К примеру я логинюсь на каком нить сайте, а потом не убивая этого манеждера снова залогиниться другим аккаунтом, но само собой заходит опять на страничку первого аккаунта. QNetworkReply очищаю, QNetwprkRequest создается при каждом логине новый. А как очищать QNetworkAccessManager чтобы при логине другим акком все же открывалась страничка имено второго аккаунта. Сначала делал чтобы для каждого раза создавался новый QNetworkAccessManager а старый удалялся, но все же хочу сделать что бы работа продолжалась с тем же акком. Документацию понимаю плохо, но все же прочел всю по QNetworkAccessManager но так не разобрался что же очистит в нем и куки и прочее. В общем убить сессию созданную при первом логине.
Прошу совета у тех кто знает.


Название: Re: как чистить QNetworkAccessManager
Отправлено: serg_hd от Декабрь 25, 2010, 20:19
Слишком скромно описана ситуация. Перед тем как логинишься под вторым акком, нажимаешь там "выход" или что именно делаешь? Url сайта какой на тот момент? Возможно дело не в Qt, а в сервере. Передаёт по урл какие-нибудь идентификаторы сессии, по ним тебя и логинит. У себя на сайтах пробовал - всё ок, заходит под тем, под которым логинюсь.


Название: Re: как чистить QNetworkAccessManager
Отправлено: SimpleSunny от Декабрь 25, 2010, 21:23
Скорее всего поможет
manager->setCookieJar(new QNetworkCookieJar());

или
manager->setCookieJar(0);
но тогда надо будет вручную следить за куками


Название: Re: как чистить QNetworkAccessManager
Отправлено: serg_hd от Декабрь 25, 2010, 21:26
Скорее всего поможет
manager->setCookieJar(new QNetworkCookieJar());

или
manager->setCookieJar(0);
но тогда надо будет вручную следить за куками
А какой в этом смысл? При перелогине кукизы перезаписываются. Собственно поэтому и нет метода типа manager->clearCookies()


Название: Re: как чистить QNetworkAccessManager
Отправлено: SimpleSunny от Декабрь 25, 2010, 21:33
Насколько я понял, запрашивается страница логина с уже залогиненым пользователям и он автоматом перекидывается на свой профиль.


Название: Re: как чистить QNetworkAccessManager
Отправлено: serg_hd от Декабрь 25, 2010, 21:45
Насколько я понял, запрашивается страница логина с уже залогиненым пользователям и он автоматом перекидывается на свой профиль.
Имеешь ввиду, что скрипт сайта проверяет наличие нужных для авторизации кукизов и если они есть, то их и использует без перезаписи? Если это так, то вебдевелоперы пишущие такие скрипты имхо неадекватны. Кроме того, в таком случае перекидывалось бы на первый акк и в обычных браузерах о чём автор не упоминал. Хз вобщем, пусть ТС проверяет.


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 25, 2010, 21:56
куки записываются новые у второго аккаунта, я проверял. Куки точно очищаются. Делаю так, открывается главная страница логина, логинюсь и открываю страницу пользователя, посмотрел и хочу логиниться другим акком. Но открывается опять страница первого аккаунта. А если я новым менеджером логиняюсь то старая сессия сбрасывается, а я хотел с тем же менеджером продолжить, но хотелось бы полностью очищать менеджер содержащий информацию о предыдущей сессии


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 25, 2010, 21:58
и если не сложно помогите понять как получить куки и установить их в менееджер нормально. Если можно более понятный небольшой примерчик.


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 25, 2010, 22:02
в обычном браузере если не разлогинишься то так же не возможно вторым акком залогиниться. О одекватности сайта говорить сложно, они боряться со спамом (vkontakte.ru) поэтому там я думаю как вы и описали. Так вот интересно что еще кроме кукисов менеджер в себя сохраняет. Потому что кукисы новые получает а аккаунт тот же.


Название: Re: как чистить QNetworkAccessManager
Отправлено: serg_hd от Декабрь 25, 2010, 22:07
в обычном сайте если не разлогинишься
Ну естественно надо разлогиниться, т.к. файлы сессий могут храниться и на сервере, у них скорее всего так и есть. И файлы эти очищаются на момент разлогирования. А ты что хочешь, залогиниться новым предварительно не разлогиниваясь? Очень сомневаюсь что дело в кукизах. Но так, на всякий случай:

RemadedNetworkCookieJar.h:
Код
C++ (Qt)
#ifndef _MYNETWORKCOOKIEJAR_H
#define _MYNETWORKCOOKIEJAR_H
 
#include <QList>
#include <QNetworkCookie>
 
class RemadedNetworkCookieJar: public QNetworkCookieJar
{
public:
RemadedNetworkCookieJar();
virtual ~RemadedNetworkCookieJar();
QList<QNetworkCookie> getAllCookies();
void setAllSitesCookies(const QList<QNetworkCookie>& cookieList);
};
 
#endif
/* _MYNETWORKCOOKIEJAR_H */
 

RemadedNetworkCookieJar.cpp:
Код
C++ (Qt)
#include "RemadedNetworkCookieJar.h"
 
RemadedNetworkCookieJar::RemadedNetworkCookieJar() {}
 
QList<QNetworkCookie> RemadedNetworkCookieJar::getAllCookies()
{
return this->allCookies();
}
 
void RemadedNetworkCookieJar::setAllSitesCookies(const QList<QNetworkCookie>& cookieList)
{
this->setAllCookies(cookieList);
}
 
RemadedNetworkCookieJar::~RemadedNetworkCookieJar() { }
 

Пример установки новых кукизов:
Код
C++ (Qt)
this->jar = new RemadedNetworkCookieJar();
this->webView.page()->networkAccessManager()->setCookieJar(this->jar);
 

Т.е. всё предельно просто.
п.с. Скорее всего дело в SESSION_ID. Т.е. в момент авторизации под первым акком на сервере создаётся файл с парами типа "user=nickname; info1=1234" и т.п. и каждый раз твоему манагеру передаётся SESSION_ID, который он передаст назад серверу при следующем запросе, чтоб сервер знал из какого файла сессии читать данные. При разлогировании файл удалятся, при след. авторизации создаётся новый. Примерно так, но могу ошибаться.


Название: Re: как чистить QNetworkAccessManager
Отправлено: SimpleSunny от Декабрь 25, 2010, 22:42
А в какие этапы у вас проходит авторизация? У меня есть смутные сомнения, что вы не очистили lp куки на login.vk.com, поэтому когда вы запрашиваете эту страницу, вам выдаются сессионные куки как раз первого аккаунта (для которого были первоначально установлены эти куки), а вы ожидаете сессионные куки для второго аккаунта. Перед новой авторизацией, очистите все куки, как я показал выше, и все будет нормально.


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 26, 2010, 01:24
Скорее всего поможет
manager->setCookieJar(new QNetworkCookieJar());

или
manager->setCookieJar(0);
но тогда надо будет вручную следить за куками

Большое спасибо - этот метод помог и в правду открыв второй раз страницу логина со старыми куками тупо срабатывал переброс на главную страницу первого акка)
Код:
manager->setCookieJar(new QNetworkCookieJar());
помоглою


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 26, 2010, 01:27
в обычном сайте если не разлогинишься
Ну естественно надо разлогиниться, т.к. файлы сессий могут храниться и на сервере, у них скорее всего так и есть. И файлы эти очищаются на момент разлогирования. А ты что хочешь, залогиниться новым предварительно не разлогиниваясь? Очень сомневаюсь что дело в кукизах. Но так, на всякий случай:

RemadedNetworkCookieJar.h:
Код
C++ (Qt)
#ifndef _MYNETWORKCOOKIEJAR_H
#define _MYNETWORKCOOKIEJAR_H
 
#include <QList>
#include <QNetworkCookie>
 
class RemadedNetworkCookieJar: public QNetworkCookieJar
{
public:
RemadedNetworkCookieJar();
virtual ~RemadedNetworkCookieJar();
QList<QNetworkCookie> getAllCookies();
void setAllSitesCookies(const QList<QNetworkCookie>& cookieList);
};
 
#endif
/* _MYNETWORKCOOKIEJAR_H */
 

RemadedNetworkCookieJar.cpp:
Код
C++ (Qt)
#include "RemadedNetworkCookieJar.h"
 
RemadedNetworkCookieJar::RemadedNetworkCookieJar() {}
 
QList<QNetworkCookie> RemadedNetworkCookieJar::getAllCookies()
{
return this->allCookies();
}
 
void RemadedNetworkCookieJar::setAllSitesCookies(const QList<QNetworkCookie>& cookieList)
{
this->setAllCookies(cookieList);
}
 
RemadedNetworkCookieJar::~RemadedNetworkCookieJar() { }
 

Пример установки новых кукизов:
Код
C++ (Qt)
this->jar = new RemadedNetworkCookieJar();
this->webView.page()->networkAccessManager()->setCookieJar(this->jar);
 

Т.е. всё предельно просто.
п.с. Скорее всего дело в SESSION_ID. Т.е. в момент авторизации под первым акком на сервере создаётся файл с парами типа "user=nickname; info1=1234" и т.п. и каждый раз твоему манагеру передаётся SESSION_ID, который он передаст назад серверу при следующем запросе, чтоб сервер знал из какого файла сессии читать данные. При разлогировании файл удалятся, при след. авторизации создаётся новый. Примерно так, но могу ошибаться.

Большое спасибо за пример, давно хочу сделать подстановку куки руками а не с помощью кукиджар. ))


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 26, 2010, 01:29
проблема решена))) Не представляете как помогли вы мне SimpleSunny и serg_hd, я дня два ходил сам не свой, когда проблему не получается решить уснуть даже нормально не могу)) Еще раз большое спасибо)


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 26, 2010, 01:34
а вот этот метод
Код:
manger->clearCookies()
я так искал, все перечитал... Жаль что его нет, на мой взгляд очень нужная вещь) вот в моей задаче не было бы головняков если бы такой метод имел место быть)


Название: Re: как чистить QNetworkAccessManager
Отправлено: serg_hd от Декабрь 26, 2010, 01:47
Да я особо-то и не помог, разве что простой пример по кукизам привёл.
Только сейчас, честно говоря, понял что вопрос состоял в том, чтобы по сути "залогиниться не разлогиниваясь". Мдя(
Если сессия не хранится у них на сервере, тогда, конечно, дело намного упрощается, достаточно кукизы почистить.


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 26, 2010, 11:48
чет я вообще запутался в примере, он написан для QWebView же? я его вообще не использую, мне нужно выпарсить из страницы только часть информации и выдать на экран. поэтому я загружаю страницу менеджером в QByteArray и парсю его.
Вы не могли бы попдправить этот пример для работы имено с менеджером без QWebView? я сейчас начал и жесть полная, только начал с сетью работать с кьюти и путаюсь еще сильно очень.

мне нужно так, логиниться аккаунт, получает куки и потом если что то нужно (к примеру еще какую то страничку загрузить с этим аккаунтом то вставляет эти куки и заходит на страничку) то подставлять их по ходу работы проги.

к примеру при логине вызвал функцию getCookie() получил куки и потом там где нужно сделал setCookie(...) и подстваил куки там где нужно. Заранее благодарю)


Название: Re: как чистить QNetworkAccessManager
Отправлено: serg_hd от Декабрь 26, 2010, 20:32
...он написан для QWebView же?...
Нет, он написан для networkAccessManager, по коду же видно, что этот метод (setCookieJar()) используется именно им, а не qwebview. А взят манагер по указателю из qwebview или нет, это уже неважно.

мне нужно так, логиниться аккаунт, получает куки и потом если что то нужно (к примеру еще какую то страничку загрузить с этим аккаунтом то вставляет эти куки и заходит на страничку) то подставлять их по ходу работы проги.
да, и это должно делаться без проблем. Где именно непонятно? У меня похожий проект был, кукизы для удобства сохранял в локальную БД sqlite, оттуда и извлекал при надобности.


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 27, 2010, 14:17
я разобрался)) спасибо еще раз))


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 28, 2010, 12:33
такую вещь еще хотел спросить, допустим я первый раз залогинился с проксями установив

Код:
manager.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, "1111111", "8080"));

а во втором логине к примеру прокси издохлась или хочу другую поставить то мне так же вызвать эти же методы
Код:
manager.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, "2222222", "80"));
или до их вызова это тоже все как то почистить нужно?


Название: Re: как чистить QNetworkAccessManager
Отправлено: serg_hd от Декабрь 28, 2010, 16:48
если ты хочешь чтобы сайт думал, что новый ip это типа новый юзер, то лучше кукизы чистить. Только ты не забывай и про остальные заголовки, которые тоже надо менять, если уж делать)). Такие как user-agent, referrer и т.п.


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 29, 2010, 02:12
понятно, а вот такая очистка кукисов
Код:
manager->setCookieJar(new QNetworkCookieJar());
не засоряет память? очистку нужно как то делать после new QNetworkCookieJar() ???
А то у меня где то немного течет память, вот не могу пока найти где.


Название: Re: как чистить QNetworkAccessManager
Отправлено: serg_hd от Декабрь 29, 2010, 15:22
Естесстно надо чистить, ты же создаёшь каждый раз новый объект. И скорей всего при зачистке манагера cookiejar по указателю не чистится, раз лики есть. Делай типа так:
Код
C++ (Qt)
QNetworkCookieJar p_cookiejar = new QNetworkCookieJar();
manager->setCookieJar(p_cookiejar);
 
//после юзания манагера
delete p_cookiejar;
p_cookiejar = new QNetworkCookieJar();
manager->setCookieJar(p_cookiejar);
//и т.п.
 
Это основы уже С++, а не Qt


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Декабрь 29, 2010, 16:23
да я знаю, потому и спрашиваю... спасибо)


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Январь 18, 2011, 23:31
сделал функцию у класса работы с сетью resetCookie();

Код:
void as_network::resetCookie()
{
    delete jar;
    jar = new QNetworkCookieJar;
    manager.setCookieJar(jar); //вот на этой строке вылетает, причем не сразу, работает примерно несколько минут и бах

}

получаю вот эту ошибку
ASSERT: "d" in file ..\..\include/QtCore/../../src/corelib/tools/qscopedpointer.h, line 112


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Январь 19, 2011, 16:00
а вот исходник QNetworkAccessManager.cpp
Код:
void QNetworkAccessManager::setCookieJar(QNetworkCookieJar *cookieJar)
{
    Q_D(QNetworkAccessManager);
    d->cookieJarCreated = true;
    if (d->cookieJar != cookieJar) {
        if (d->cookieJar && d->cookieJar->parent() == this)
            delete d->cookieJar;
        d->cookieJar = cookieJar;
        if (thread() == cookieJar->thread())
            d->cookieJar->setParent(this);
    }
}

получается в каких то случаях он удаляет сам куки... похоже в этом и проблема, когда я удаляю выделеную память, а он в некоторых случаях ее повторно пытается удалить - от этого наверное и вылетает, хотя вохможно я ошибаюсь, но судя по контексту так. Как же решить такую проблему???


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Январь 20, 2011, 01:19
вот в таком варианте не вылетает, хотя не знаю коректно ли я сделал, в принципи работает, конечно можно было и поровнее придумать)) вот мой вариант последний, тестю сейчас на утечку, вылетать точно не вылетает.
Похоже deleteLater() как то обрабатывает, когда нужно удалить, а когда нет.

Код:
void as_network::deleteMyCookieJar()
{
    this->myJar->deleteLater();
    qApp->processEvents();
}

void as_network::resetCookie()
{
    deleteMyCookieJar();

    this->myJar = new QNetworkCookieJar();

    manager.setCookieJar(this->myJar);
}


Название: Re: как чистить QNetworkAccessManager
Отправлено: SimpleSunny от Январь 20, 2011, 03:36
А зачем ві сами удаляет, если Qt сама єто делает?

Код
C++ (Qt)
if (d->cookieJar != cookieJar) {
       if (d->cookieJar && d->cookieJar->parent() == this)
           delete d->cookieJar;
       d->cookieJar = cookieJar;
       if (thread() == cookieJar->thread())
           d->cookieJar->setParent(this);
   }


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Январь 20, 2011, 13:01
Да что то я ночью тоже об этом подумал что это глупостью было)))просто у меня течь в программе сильная была и я винил в этом как раз эту фунцию, но оказалась что QNetworkReply при редиректе не очищалась.
 Если я правильно понимаю контекст то
тут
Код:
if (d->cookieJar != cookieJar)
проверяется равен ли d->cookieJar тому адресу памяти на который указывает cookieJar и если не равен идет дальше проверка
Код:
if (d->cookieJar && d->cookieJar->parent() == this)
на то - принадлежат ли эти адреса этому классу(то есть было ли это выделение памяти произведено именно этим классом), я правильно понял?


Название: Re: как чистить QNetworkAccessManager
Отправлено: eldar85 от Январь 20, 2011, 14:00
такой вариант вполне отлично работает
Код:
void as_network::resetCookie()
{
    manager.setCookieJar(new QNetworkCookieJar());
}

Вы случайно не знаете чем лучше в Qt ослеживать выделенную и удаленную память?