Russian Qt Forum

Qt => Работа с сетью => Тема начата: writerer от Декабрь 18, 2007, 23:59



Название: QHttp как проверить ответ ?
Отправлено: writerer от Декабрь 18, 2007, 23:59
Доббрый вечер!
Только начал разбираться и возника такой вопрос.
послада с помощью get запрос к скрипту и мне пришёл ответ, но как его взять ? к примеру вывести textedit ?
во всех примерах которые находил readAll только не пойму как у них получается ! помогите!


Название: Re: QHttp как проверить ответ ?
Отправлено: fox от Декабрь 19, 2007, 00:45
Доббрый вечер!
Только начал разбираться и возника такой вопрос.
послада с помощью get запрос к скрипту и мне пришёл ответ, но как его взять ? к примеру вывести textedit ?
во всех примерах которые находил readAll только не пойму как у них получается ! помогите!
стандартный пример examples/network/http вполне понятен


Название: Re: QHttp как проверить ответ ?
Отправлено: writerer от Декабрь 20, 2007, 00:39
и всё таки, попытаюсь ещё раз попросить помочь. но более конкретно:
в примерах " httpGetId = http->get(url.path(), file); "
это понятно, а как мне, к примеру, передать весь в ответ в строку ?

видел такое
QByteArray ba = m_pHttp->readAll();
QString str = QString( ba );
в слоте по httpDone

и здесь тоже что-тоо никак ((

подскажите пожалуйста!


Название: Re: QHttp как проверить ответ ?
Отправлено: fox от Декабрь 20, 2007, 10:22
и всё таки, попытаюсь ещё раз попросить помочь. но более конкретно:
в примерах " httpGetId = http->get(url.path(), file); "
это понятно, а как мне, к примеру, передать весь в ответ в строку ?

видел такое
QByteArray ba = m_pHttp->readAll();
QString str = QString( ba );
в слоте по httpDone

и здесь тоже что-тоо никак ((

подскажите пожалуйста!
Попробуй почитать в сторону сигнала
Код:
void requestFinished ( int id, bool error )
ну и соотвественно
Код:
QByteArray QHttp::readAll ()


Название: Re: QHttp как проверить ответ ?
Отправлено: Mirael Karamir от Декабрь 21, 2007, 09:56
Доббрый вечер!
Только начал разбираться и возника такой вопрос.
послада с помощью get запрос к скрипту и мне пришёл ответ, но как его взять ? к примеру вывести textedit ?
во всех примерах которые находил readAll только не пойму как у них получается ! помогите!

Говоря простым языком, твоя ошибка в том, что чтение из буффера с помощью функции readAll() производится сразу же, не дожидаясь ответа сервера. Поэтому тебе нужно, как тебе рекомендовали выше дождатся ответа сервера. Когда ответ будет получен, QHttp сгенерирует сигнал void requestFinished ( int id, bool error ) (или же done() как в примере ниже). Именно в обработчике этого сигнала и нужно вызывать функцию readAll().
Это можно сделать и немного по другому, без readAll()

Код:

void getdata()
{
buffer = new QBuffer();
http=new QHttp("blablabla.ru");
http->get("/some.html",buffer);
connect(http,SIGNAL(done(bool)),this, SLOT(requestFinishedSlot(bool)));
}

void requestFinishedSlot(bool error)
{
if(!error)
 {
     QByteArray data;
     data=buffer->data();
      QString str(&data);
         textedit->setHtml(str);
 
 }
}


Главное понять, что общение с сервером происходит в асинхронном режиме, и нужно обязательно дожидатся ответа от него :)


Название: Re: QHttp как проверить ответ ?
Отправлено: vladymyr от Апрель 25, 2008, 21:54
Столкнулся с такой же проблемой. Программа работает, но не завершается. Файл остаётся нулевого размера. Функция-слот не выполняется
Код:
#include "httpsio.h"
#include <Qt/QtNetwork>

httpsio::httpsio(){
//httpsconnect();
QTextStream stream(stdout);
http = new QHttp(this);

    connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(httpRequestFinished(int, bool)));
//    connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
//            this, SLOT(readResponseHeader(const QHttpResponseHeader &)));

//downloadFile   
urlLine="http://www.opennet.ru/opennews/art.shtml?num=15492";
QUrl url(urlLine);
QFileInfo fileInfo(url.path());
QString fileName = fileInfo.fileName();
if (fileName.isEmpty())
fileName = "index.html";
stream<<"File name: "<<fileName<<endl;


if (QFile::exists(fileName)) {
stream<<"There already exists this file in the current directory \n"<<fileName<<endl;
if(QFile::remove(fileName))
stream<<"It is deleted"<<endl;
}

file = new QFile(fileName);
if (!file->open(QIODevice::WriteOnly)) {
stream<<"Unable to save the file "<<fileName<<" : "<<file->errorString()<<endl;
delete file;
file = 0;
return;
}

QHttp::ConnectionMode mode = url.scheme().toLower() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp;
stream<<url.host()<<" "<<url.port()<<endl;
http->setHost(url.host(), mode, url.port() == -1 ? 0 : url.port());


if (!url.userName().isEmpty())
http->setUser(url.userName(), url.password());

httpRequestAborted = false;
stream<<url.path()<<" "<<file<<endl;
httpGetId = http->get(url.path(), file);

}

httpsio::~httpsio(){
}


void httpsio::httpsconnect(){

}

void httpsio::httpRequestFinished(int requestId, bool error){
//RequestFinished
QTextStream stream(stdout);
stream<<"httpRequestFinished"<<endl;
stream<<http->readAll()<<endl;

if (requestId != httpGetId)
return;

    if (httpRequestAborted) {
        if (file) {
            file->close();
            file->remove();
            delete file;
            file = 0;
        }
        return;
    }

    if (requestId != httpGetId)
         return;
   
file->close();

if (error) {
file->remove();
stream<<"Download failed: "<<http->errorString()<<endl;
} else {
QString fileName = QFileInfo(QUrl(urlLine).path()).fileName();
stream<<"Downloaded "<<fileName<<" to current directory."<<endl;
}

delete file;
file = 0;
}

/*
void httpsio::readResponseHeader(const QHttpResponseHeader &responseHeader){
QTextStream stream(stdout);
stream<<"readResponseHeader"<<endl;
    if (responseHeader.statusCode() != 200) {
        stream<<"Download failed: "<<responseHeader.reasonPhrase()<<endl;
        httpRequestAborted = true;
        http->abort();
        return;
    }
}
*/


Код:
#ifndef HTTPSIO_H_
#define HTTPSIO_H_

#include <QTextStream>

class QFile;
class QHttp;
class QHttpResponseHeader;

class httpsio : public QObject{
Q_OBJECT
public:
httpsio();
virtual ~httpsio();
void httpsconnect();
private:
QHttp *http;
    QFile *file;
    int httpGetId;
    bool httpRequestAborted;
    QString urlLine;
   
private slots:
    void httpRequestFinished(int requestId, bool error);
//    void readResponseHeader(const QHttpResponseHeader &responseHeader);
};

#endif /*HTTPSIO_H_*/



Название: Re: QHttp как проверить ответ ?
Отправлено: ритт от Апрель 26, 2008, 00:47
уверен, что в httpRequestFinished не заходит? привяжись к stateChanged для посмотреть

урл, похоже, передаётся неверный (не учитывается часть encodedQuery)

попробуй убрать stream<<http->readAll()<<endl;

и советую учитывать возможность ответа 200

других мыслей пока нет


Название: Re: QHttp как проверить ответ ?
Отправлено: vladymyr от Апрель 26, 2008, 21:11
Я учитываю. использую слоты
void httpsio::readResponseHeader(const QHttpResponseHeader &responseHeader)
 - чтение ответа и
void httpsio::httpRequestFinished(int requestId, bool error)
 - обработка.
В начало каждого для проверки поставил вывод:
stream<<"httpRequestFinished"<<endl;
и
stream<<"readResponseHeader"<<endl;
Оба не выполняются. Делал по примеру в документации QtNetwork/Http, но в консоли. Почему-то не работает....


Название: Re: QHttp как проверить ответ ?
Отправлено: Вячеслав от Май 06, 2008, 09:52
QCoreApplication есть ? Слоты связаны ? чего connect вернул ? Версия qt ?


Название: Re: QHttp как проверить ответ ?
Отправлено: sendevent от Май 06, 2008, 13:23
Код:
urlLine = tr( "http://www.opennet.ru/opennews/art.shtml?num=15492" );
//-- QUrl url( urlLine ).host() - opennet.ru (или http://www.opennet.ru/ - не помню)
//-- QUrl url( urlLine ).path() - /opennews/art.shtml,
//-- поэтому когда есть параметры GET - передавать надо "оригинальный" path:
httpGetId = http->get( urlLine, file );
Помнится, тоже были косяки с сигналами/слотами при использловании http->get(...).
Т.к. такая форма запроса довольно куцая - не передается ни рефереров, ни юзер-агентов и пр., что часто проверяется при обращении за чужими документами, лучче обращаться полноценным запросом:
Код:
QHttpRequestHeader header( "GET", urlLine, 1, 1 );
header.setValue( "Host", QUrl( urlLine ).host() );
//header.setValue( "User-Agent", ... );
//header.setValue( "Accept", ... );
//header.setValue( "Accept-Language", ... );
//header.setValue( "Accept-Charset", ... );
//header.setValue( "Keep-Alive", ... );
//header.setValue( "Connection", ... );
//header.setValue( "Cookie", ... );
...
httpGetId = http->request( header, 0, file );
А вместо QFile удобней юзать QBuffer;)

Гы. Скомпиллил - всасывает art.shtml, вместо art.shtml?num=15492, в остальном все ок (4.4, VC8.0). Раз уж оба слота молчат - хотелось бы взглянуть на .pro, на всяк случай main и узнать платформу/версию.
Дома попробую под сусе, но, сдается мне, все будет так же и рыть надо в сторону настройки самой кути/проекта.


Название: Re: QHttp как проверить ответ ?
Отправлено: vladymyr от Май 06, 2008, 16:54
QCoreApplication есть ? Слоты связаны ? чего connect вернул ? Версия qt ?
Есть.

Да.
connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(httpRequestFinished(int, bool)));
connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)), this, SLOT(readResponseHeader(const QHttpResponseHeader &)));

Ничего не вернул - функции void httpsio::readResponseHeader(const QHttpResponseHeader &responseHeader) и void httpsio::httpRequestFinished(int requestId, bool error) не выполнились.

4.3.3


Название: Re: QHttp как проверить ответ ?
Отправлено: vladymyr от Май 06, 2008, 17:05
Код:
urlLine = tr( "http://www.opennet.ru/opennews/art.shtml?num=15492" );
//-- QUrl url( urlLine ).host() - opennet.ru (или http://www.opennet.ru/ - не помню)
//-- QUrl url( urlLine ).path() - /opennews/art.shtml,
//-- поэтому когда есть параметры GET - передавать надо "оригинальный" path:
httpGetId = http->get( urlLine, file );
Помнится, тоже были косяки с сигналами/слотами при использловании http->get(...).
Т.к. такая форма запроса довольно куцая - не передается ни рефереров, ни юзер-агентов и пр., что часто проверяется при обращении за чужими документами, лучче обращаться полноценным запросом:
Код:
QHttpRequestHeader header( "GET", urlLine, 1, 1 );
header.setValue( "Host", QUrl( urlLine ).host() );
//header.setValue( "User-Agent", ... );
//header.setValue( "Accept", ... );
//header.setValue( "Accept-Language", ... );
//header.setValue( "Accept-Charset", ... );
//header.setValue( "Keep-Alive", ... );
//header.setValue( "Connection", ... );
//header.setValue( "Cookie", ... );
...
httpGetId = http->request( header, 0, file );
А вместо QFile удобней юзать QBuffer;)

Гы. Скомпиллил - всасывает art.shtml, вместо art.shtml?num=15492, в остальном все ок (4.4, VC8.0). Раз уж оба слота молчат - хотелось бы взглянуть на .pro, на всяк случай main и узнать платформу/версию.
Дома попробую под сусе, но, сдается мне, все будет так же и рыть надо в сторону настройки самой кути/проекта.

Спасибо, попробую расширить заголовок. QT4.3.3, AltLinux 4.
код:
Код:
// /usr/lib/qt4/bin/qmake && make && ./httpsinfo
#include <QtCore>
#include <QCoreApplication>

#include "httpsio.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    httpsio *httpsi=new httpsio();

    delete httpsi;

    return a.exec();

}

Код:
TEMPLATE = app
TARGET = httpsinfo
QT += core \
    network
HEADERS += httpsio.h
SOURCES += httpsio.cpp \
    main.cpp
FORMS +=
RESOURCES +=

Код:
#include "httpsio.h"
#include <Qt/QtNetwork>

httpsio::httpsio(){
QTextStream stream(stdout);
http = new QHttp(this);

    connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(httpRequestFinished(int, bool)));
    connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
            this, SLOT(readResponseHeader(const QHttpResponseHeader &)));

//downloadFile   
urlLine="http://www.opennet.ru/opennews/art.shtml?num=15492";
QUrl url(urlLine);
QFileInfo fileInfo(url.path());
QString fileName = fileInfo.fileName();
if (fileName.isEmpty())
fileName = "index.html";
stream<<"File name: "<<fileName<<endl;


if (QFile::exists(fileName)) {
stream<<"There already exists this file in the current directory \n"<<fileName<<endl;
if(QFile::remove(fileName))
stream<<"It is deleted"<<endl;
}

file = new QFile(fileName);
if (!file->open(QIODevice::WriteOnly)) {
stream<<"Unable to save the file "<<fileName<<" : "<<file->errorString()<<endl;
delete file;
file = 0;
return;
}

QHttp::ConnectionMode mode = url.scheme().toLower() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp;
stream<<url.host()<<" "<<url.port()<<endl;
http->setHost(url.host(), mode, url.port() == -1 ? 0 : url.port());


if (!url.userName().isEmpty())
http->setUser(url.userName(), url.password());

httpRequestAborted = false;
stream<<url.path()<<" "<<file<<endl;
httpGetId = http->get(url.path(), file);

}

httpsio::~httpsio(){
}


void httpsio::httpsconnect(){

}

void httpsio::httpRequestFinished(int requestId, bool error){
//RequestFinished
QTextStream stream(stdout);
stream<<"httpRequestFinished"<<endl;
stream<<http->readAll()<<endl;

if (requestId != httpGetId)
return;

    if (httpRequestAborted) {
        if (file) {
            file->close();
            file->remove();
            delete file;
            file = 0;
        }
        return;
    }

    if (requestId != httpGetId)
         return;
   
file->close();

if (error) {
file->remove();
stream<<"Download failed: "<<http->errorString()<<endl;
} else {
QString fileName = QFileInfo(QUrl(urlLine).path()).fileName();
stream<<"Downloaded "<<fileName<<" to current directory."<<endl;
}

delete file;
file = 0;
}


void httpsio::readResponseHeader(const QHttpResponseHeader &responseHeader){
QTextStream stream(stdout);
stream<<"readResponseHeader"<<endl;
    if (responseHeader.statusCode() != 200) {
        stream<<"Download failed: "<<responseHeader.reasonPhrase()<<endl;
        httpRequestAborted = true;
        http->abort();
        return;
    }
}

Код:
#ifndef HTTPSIO_H_
#define HTTPSIO_H_

#include <QTextStream>

class QFile;
class QHttp;
class QHttpResponseHeader;

class httpsio : public QObject{
Q_OBJECT
public:
httpsio();
virtual ~httpsio();
void httpsconnect();
private:
QHttp *http;
    QFile *file;
    int httpGetId;
    bool httpRequestAborted;
    QString urlLine;
   
private slots:
    void httpRequestFinished(int requestId, bool error);
    void readResponseHeader(const QHttpResponseHeader &responseHeader);
};

#endif /*HTTPSIO_H_*/



Название: Re: QHttp как проверить ответ ?
Отправлено: Вячеслав от Май 06, 2008, 18:31
Цитировать
    QCoreApplication a(argc, argv);

    httpsio *httpsi=new httpsio();

    delete httpsi;

    return a.exec();
Хм ;) А слоты должны работать вне exec?


Название: Re: QHttp как проверить ответ ?
Отправлено: vladymyr от Май 06, 2008, 18:48
Цитировать
    QCoreApplication a(argc, argv);

    httpsio *httpsi=new httpsio();

    delete httpsi;

    return a.exec();
Хм ;) А слоты должны работать вне exec?

Большое спасибо. Работает!!!