summaryrefslogtreecommitdiffstats
path: root/app/src/httpclient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/httpclient.cpp')
-rw-r--r--app/src/httpclient.cpp281
1 files changed, 281 insertions, 0 deletions
diff --git a/app/src/httpclient.cpp b/app/src/httpclient.cpp
new file mode 100644
index 0000000..c9bad50
--- /dev/null
+++ b/app/src/httpclient.cpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2018-2019 TOYOTA MOTOR CORPORATION
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "httpclient.h"
+
+#include <QDebug>
+#include <QFile>
+#include <QHash>
+#include <QHttpMultiPart>
+#include <QHttpPart>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+#include <QUrlQuery>
+
+class HttpClientPrivate {
+ public:
+ HttpClientPrivate(const QString& url);
+
+ QString url;
+ QUrlQuery params;
+ QHash<QString, QString> 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<void(const QString&)> successHandler,
+ std::function<void(const QString&)> 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<void(const QString&)> successHandler,
+ std::function<void(const QString&)> 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<void(const QString&)> successHandler,
+ std::function<void(const QString&)> errorHandler,
+ const char* encoding) {
+ HttpClientPrivate::get(d, HttpClientPrivate::GET, successHandler,
+ errorHandler, encoding);
+}
+
+void HttpClient::download(
+ const QString& savePath,
+ std::function<void(const QString&)> successHandler,
+ std::function<void(const QString&)> errorHandler,
+ std::function<void(const qint64, const qint64)> 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<void(const QByteArray&)> readyRead,
+ std::function<void(const QString&)> successHandler,
+ std::function<void(const QString&)> errorHandler,
+ std::function<void(const qint64, const qint64)> 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<void(const QString&)> successHandler,
+ std::function<void(const QString&)> 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<QPair<QString, QString> > 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<QString, QString> 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<void(const QString&)> successHandler,
+ std::function<void(const QString&)> 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();
+ }
+}