Russian Qt Forum

Qt => Работа с сетью => Тема начата: Paramon от Февраль 27, 2015, 14:25



Название: Обертка над QNetworkAccessManager
Отправлено: Paramon от Февраль 27, 2015, 14:25
Поделитесь ссылками, коль такие существуют.
Нужно удобно в одну строку отправлять запросы и файлы. Написал свою, но коряво и многое не нравится, опыта маловато.


Название: Re: Обертка над QNetworkAccessManager
Отправлено: ksk- от Февраль 27, 2015, 14:44
Да там, вроде, и так запросы одной строкой посылаются.


Название: Re: Обертка над QNetworkAccessManager
Отправлено: Paramon от Февраль 27, 2015, 16:54
Да там, вроде, и так запросы одной строкой посылаются.
У меня одной не получается.  :P

Тогда может подскажете, какие изъяны есть в моей миниобертке? Буду благодарен.
Забыл - ОСТОРОЖНО! Берегите нервы! Присутствует goto!  :)

Код:
    netManager *netVk=new netManager();
    netVk->networkRequest.setRawHeader("User-Agent","Mozilla/5.0");
    netVk->networkRequest.setRawHeader("Content-Type","application/x-www-form-urlencoded");

    netVk->setProxy(QNetworkProxy::HttpProxy,"127.0.0.1",9050);

    QByteArray retBodyGet;
    netVk->sendGet("http://dojki.com/",&retBodyGet);

    qDebug() << netVk->getHeader();
    qDebug() << retBodyGet;

    delete(netManager);

netManager.h
Код:
#ifndef NETMANAGER_H
#define NETMANAGER_H

#include <QObject>

#include <QNetworkAccessManager>
#include <QNetworkCookieJar>
#include <QNetworkProxy>
#include <QNetworkRequest>
#include <QNetworkReply>

#include <QEventLoop>
#include <QTimer>

#include <QDebug>

class netManager : public QObject
{
    Q_OBJECT
public:
    explicit netManager(QObject *parent = 0);
    ~netManager();

    QNetworkAccessManager *networkAccessManager;
    QNetworkCookieJar *networkCookieJar;
    QNetworkReply *networkReply;
    QNetworkRequest networkRequest;

    void setProxy(QNetworkProxy::ProxyType proxyType, QString strIP="", int iPort=0);

    bool sendGet(QString strURL, QByteArray *retBody, bool bAutoRedirect=true);
    bool sendPost(QString strURL, QByteArray *bytePost, QByteArray *retBody, bool bAutoRedirect=true);
    bool sendPost(QString strURL, QString bytePost, QByteArray *retBody, bool bAutoRedirect=true);

    void setTimeOut(int iTimeOut);

    QString getErrorString();
    int getErrorCode();

    int getStatusCode();
    QString getHeader();

    QString getProxyIP();
    quint16 getProxyPort();
    QNetworkProxy::ProxyType getProxyType();

private:
    void initRequest();
    bool sendRequest(QString strURL, QByteArray *bytePost, QByteArray *retBody, bool bAutoRedirect=true);

    int StatusCode;
    int TimeOut;
    int ErrorCode;
    QString ErrorString;
    QString Header;

    bool wait();
    void parseHeader();

};

#endif // NETMANAGER_H

netManager.cpp
Код:
#include "netManager.h"

netManager::netManager(QObject *parent) :
    QObject(parent)
{
    this->networkAccessManager=new QNetworkAccessManager(parent);
    this->networkCookieJar = new QNetworkCookieJar(parent);
    this->networkAccessManager->setCookieJar(this->networkCookieJar);

    this->TimeOut=15000;
}

netManager::~netManager()
{
    delete(this->networkCookieJar);
    delete(this->networkAccessManager);
}

void netManager::initRequest()
{
    this->StatusCode=0;
    this->ErrorCode=0;
    this->ErrorString="";
    this->Header="";
}

QString netManager::getErrorString()
{
    return this->ErrorString;
}

int netManager::getErrorCode()
{
    return this->ErrorCode;
}

void netManager::setTimeOut(int iTimeOut)
{
    this->TimeOut=iTimeOut;
}

int netManager::getStatusCode()
{
    return this->StatusCode;
}

QString netManager::getHeader()
{
    return this->Header;
}

QString netManager::getProxyIP()
{
    return this->networkAccessManager->proxy().hostName();
}

quint16 netManager::getProxyPort()
{
    return this->networkAccessManager->proxy().port();
}

QNetworkProxy::ProxyType netManager::getProxyType()
{
    return this->networkAccessManager->proxy().type();
}

void netManager::setProxy(QNetworkProxy::ProxyType proxyType, QString strIP, int iPort)
{
    QNetworkProxy proxy;
    proxy.setType(proxyType);
    if(proxyType!=QNetworkProxy::NoProxy)
    {
        proxy.setHostName(strIP);
        proxy.setPort(iPort);
    }
    this->networkAccessManager->setProxy(proxy);
}

bool netManager::wait() // private
{
    QTimer timer;
    timer.setSingleShot(true);

    QEventLoop loop;

    connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
    connect(this->networkAccessManager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit()));
    timer.start(this->TimeOut);
    loop.exec();
    if(timer.isActive())
        timer.stop();
    else
        return false;

    return true;
}

void netManager::parseHeader() // private
{
    QNetworkReply::RawHeaderPair header;
    QList<QNetworkReply::RawHeaderPair> m_listHeaders;

    this->Header  = QString::number(this->StatusCode);
    this->Header += " | ";
    this->Header += this->networkReply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
    this->Header += "\r\n";
    m_listHeaders = this->networkReply->rawHeaderPairs();
    int size = m_listHeaders.size();
    for(int i=0; i<size; ++i)
    {
        header = m_listHeaders.at(i);
        this->Header += header.first;
        this->Header += ": ";
        this->Header += header.second;
        this->Header += "\r\n";
    }
    m_listHeaders.clear();
}

bool netManager::sendGet(QString strURL, QByteArray *retBody, bool bAutoRedirect)
{
    return sendRequest(strURL,&QString("").toAscii(),retBody,bAutoRedirect);
}

bool netManager::sendPost(QString strURL, QByteArray *bytePost, QByteArray *retBody, bool bAutoRedirect)
{
    return sendRequest(strURL,bytePost,retBody,bAutoRedirect);
}

bool netManager::sendPost(QString strURL, QString bytePost, QByteArray *retBody, bool bAutoRedirect)
{
    return sendRequest(strURL,&bytePost.toAscii(),retBody,bAutoRedirect);
}

bool netManager::sendRequest(QString strURL, QByteArray *bytePost, QByteArray *retBody, bool bAutoRedirect)
{
    bool bPost=!bytePost->isEmpty();
    bool bRet=false;

    initRequest();

    this->networkRequest.setUrl(QUrl(strURL));

    sendreq:
    if(bPost)
        this->networkReply=this->networkAccessManager->post(this->networkRequest, *bytePost);
    else
        this->networkReply=this->networkAccessManager->get(this->networkRequest);

    if(wait()==false)
    {
        this->ErrorCode=-10;
        this->ErrorString="timeout";
        goto isfree;
    }

    this->ErrorCode=this->networkReply->error();
    this->ErrorString=this->networkReply->errorString();

    this->StatusCode=this->networkReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    if(this->ErrorCode!=QNetworkReply::NoError && this->StatusCode==0) goto isfree;
    parseHeader();

    if(bAutoRedirect)
    {
        if(this->StatusCode==301 || this->StatusCode==302)
        {
            QUrl redirectTo = this->networkReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
            if(redirectTo.scheme().isEmpty())
            {
                redirectTo.setScheme(this->networkRequest.url().scheme());
                redirectTo.setHost(this->networkRequest.url().host());
            }
            this->networkRequest.setUrl(redirectTo);
            bPost=false;
            goto sendreq;
        }
    }

    *retBody = this->networkReply->readAll();

    this->ErrorCode=this->networkReply->error();
    this->ErrorString=this->networkReply->errorString();

    if(this->ErrorCode==QNetworkReply::NoError || this->StatusCode>0) bRet=true;

    this->networkReply->close();

    isfree:
    this->networkReply->deleteLater();

    return bRet;
}


Название: Re: Обертка над QNetworkAccessManager
Отправлено: kambala от Февраль 27, 2015, 20:16
на отличном сайте тестируешь свой код


Название: Re: Обертка над QNetworkAccessManager
Отправлено: gil9red от Февраль 27, 2015, 22:30
на отличном сайте тестируешь свой код

Когда я тестил python + grab для парсинга сайтов тоже на каком-то порносайте экспериментировал ;D