X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=app%2Fsrc%2Fhttpclient.cpp;fp=app%2Fsrc%2Fhttpclient.cpp;h=490fd79523800c16dd5f2460d8d28c2a8c3efee2;hb=5a9d121e37b110a8dce34d2a2d506412cac6b2d7;hp=0000000000000000000000000000000000000000;hpb=de4e4f75c59b1da4de91a75b3ab7b94d0ab8335f;p=apps%2Fonscreenapp.git diff --git a/app/src/httpclient.cpp b/app/src/httpclient.cpp new file mode 100644 index 0000000..490fd79 --- /dev/null +++ b/app/src/httpclient.cpp @@ -0,0 +1,267 @@ + +#include "httpclient.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpClientPrivate { + public: + HttpClientPrivate(const QString& url); + + QString url; + QUrlQuery params; + QHash headers; + QNetworkAccessManager* manager; + + bool debug; + + enum HttpMethod { GET, POST, PUT, DELETE }; + + static QNetworkAccessManager* getManager(HttpClientPrivate* d, + bool* internal); + + static QNetworkRequest createRequest(HttpClientPrivate* d, HttpMethod method); + + static void get(HttpClientPrivate* d, + HttpMethod method, + std::function successHandler, + std::function errorHandler, + const char* encoding); + + static QString readReply(QNetworkReply* reply, + const char* encoding = "UTF-8"); + + static void handleFinish(bool debug, + const QString& successMessage, + const QString& errorMessage, + std::function successHandler, + std::function errorHandler, + QNetworkReply* reply, + QNetworkAccessManager* manager); +}; + +HttpClientPrivate::HttpClientPrivate(const QString& url) + : url(url), manager(NULL), debug(false) {} + +HttpClient::HttpClient(const QString& url) : d(new HttpClientPrivate(url)) {} + +HttpClient::~HttpClient() { + delete d; +} + +HttpClient& HttpClient::manager(QNetworkAccessManager* manager) { + d->manager = manager; + return *this; +} + +HttpClient& HttpClient::debug(bool debug) { + d->debug = debug; + return *this; +} + +HttpClient& HttpClient::param(const QString& name, const QString& value) { + d->params.addQueryItem(name, value); + return *this; +} + +HttpClient& HttpClient::header(const QString& header, const QString& value) { + d->headers[header] = value; + return *this; +} + +void HttpClient::get(std::function successHandler, + std::function errorHandler, + const char* encoding) { + HttpClientPrivate::get(d, HttpClientPrivate::GET, successHandler, + errorHandler, encoding); +} + +void HttpClient::download( + const QString& savePath, + std::function successHandler, + std::function errorHandler, + std::function progressHandler) { + bool debug = d->debug; + QFile* file = new QFile(savePath); + + if (file->open(QIODevice::WriteOnly)) { + download( + [=](const QByteArray& data) { file->write(data); }, + [=](const QString&) { + file->flush(); + file->close(); + file->deleteLater(); + + if (debug) { + qDebug().noquote() + << QString("download finished, save to: %1").arg(savePath); + } + + if (NULL != successHandler) { + successHandler( + QString("download finished, save to: %1").arg(savePath)); + } + }, + errorHandler, progressHandler); + } else { + if (debug) { + qDebug().noquote() << QString("open file error: %1").arg(savePath); + } + + if (NULL != errorHandler) { + errorHandler(QString("open file error: %1").arg(savePath)); + } + } +} + +void HttpClient::download( + std::function readyRead, + std::function successHandler, + std::function errorHandler, + std::function progressHandler) { + bool debug = d->debug; + bool internal; + + QNetworkAccessManager* manager = HttpClientPrivate::getManager(d, &internal); + QNetworkRequest request = + HttpClientPrivate::createRequest(d, HttpClientPrivate::GET); + QNetworkReply* reply = manager->get(request); + + QObject::connect(reply, &QNetworkReply::readyRead, + [=] { readyRead(reply->readAll()); }); + + QObject::connect(reply, &QNetworkReply::finished, [=] { + QString successMessage = "download finished"; + QString errorMessage = reply->errorString(); + HttpClientPrivate::handleFinish(debug, successMessage, errorMessage, + successHandler, errorHandler, reply, + internal ? manager : NULL); + }); + + QObject::connect(reply, &QNetworkReply::downloadProgress, + [=](qint64 bytesReceived, qint64 bytesTotal) { + if (NULL != progressHandler) { + progressHandler(bytesReceived, bytesTotal); + } + }); +} + +void HttpClientPrivate::get(HttpClientPrivate* d, + HttpMethod method, + std::function successHandler, + std::function errorHandler, + const char* encoding) { + bool internal; + + QNetworkAccessManager* manager = HttpClientPrivate::getManager(d, &internal); + QNetworkRequest request = + HttpClientPrivate::createRequest(d, HttpClientPrivate::GET); + QNetworkReply* reply = NULL; + + switch (method) { + case HttpClientPrivate::GET: + reply = manager->get(request); + break; + + default: + break; + } + + QObject::connect(reply, &QNetworkReply::finished, [=] { + QString successMessage = HttpClientPrivate::readReply(reply, encoding); + QString errorMessage = reply->errorString(); + HttpClientPrivate::handleFinish(d->debug, successMessage, errorMessage, + successHandler, errorHandler, reply, + internal ? manager : NULL); + }); +} + +QNetworkAccessManager* HttpClientPrivate::getManager(HttpClientPrivate* d, + bool* internal) { + *internal = d->manager == NULL; + return *internal ? new QNetworkAccessManager() : d->manager; +} + +QNetworkRequest HttpClientPrivate::createRequest(HttpClientPrivate* d, + HttpMethod method) { + if (!d->params.isEmpty()) { + d->url += "?" + d->params.toString(QUrl::FullyEncoded); + } + + if (d->debug) { + qDebug().noquote() << "url:" << d->url; + + QList > paramItems = d->params.queryItems(); + for (int i = 0; i < paramItems.size(); ++i) { + QString name = paramItems.at(i).first; + QString value = paramItems.at(i).second; + if (0 == i) { + qDebug().noquote() << QString("params: %1=%2").arg(name).arg(value); + } else { + qDebug().noquote() << QString(" %1=%2").arg(name).arg(value); + } + } + } + + QNetworkRequest request(QUrl(d->url)); + QHashIterator iter(d->headers); + while (iter.hasNext()) { + iter.next(); + request.setRawHeader(iter.key().toUtf8(), iter.value().toUtf8()); + } + + return request; +} + +QString HttpClientPrivate::readReply(QNetworkReply* reply, + const char* encoding) { + QTextStream in(reply); + QString result; + in.setCodec(encoding); + + while (!in.atEnd()) { + result += in.readLine(); + } + + return result; +} + +void HttpClientPrivate::handleFinish( + bool debug, + const QString& successMessage, + const QString& errorMessage, + std::function successHandler, + std::function errorHandler, + QNetworkReply* reply, + QNetworkAccessManager* manager) { + if (reply->error() == QNetworkReply::NoError) { + if (debug) { + qDebug().noquote() + << QString("request successed: %1").arg(successMessage); + } + + if (NULL != successHandler) { + successHandler(successMessage); + } + } else { + if (debug) { + qDebug().noquote() << QString("request failed: %1").arg(errorMessage); + } + + if (NULL != errorHandler) { + errorHandler(errorMessage); + } + } + + reply->deleteLater(); + if (NULL != manager) { + manager->deleteLater(); + } +}