2 #include "httpclient.h"
7 #include <QHttpMultiPart>
9 #include <QNetworkAccessManager>
10 #include <QNetworkReply>
11 #include <QNetworkRequest>
14 class HttpClientPrivate {
16 HttpClientPrivate(const QString& url);
20 QHash<QString, QString> headers;
21 QNetworkAccessManager* manager;
25 enum HttpMethod { GET, POST, PUT, DELETE };
27 static QNetworkAccessManager* getManager(HttpClientPrivate* d,
30 static QNetworkRequest createRequest(HttpClientPrivate* d, HttpMethod method);
32 static void get(HttpClientPrivate* d,
34 std::function<void(const QString&)> successHandler,
35 std::function<void(const QString&)> errorHandler,
36 const char* encoding);
38 static QString readReply(QNetworkReply* reply,
39 const char* encoding = "UTF-8");
41 static void handleFinish(bool debug,
42 const QString& successMessage,
43 const QString& errorMessage,
44 std::function<void(const QString&)> successHandler,
45 std::function<void(const QString&)> errorHandler,
47 QNetworkAccessManager* manager);
50 HttpClientPrivate::HttpClientPrivate(const QString& url)
51 : url(url), manager(NULL), debug(false) {}
53 HttpClient::HttpClient(const QString& url) : d(new HttpClientPrivate(url)) {}
55 HttpClient::~HttpClient() {
59 HttpClient& HttpClient::manager(QNetworkAccessManager* manager) {
64 HttpClient& HttpClient::debug(bool debug) {
69 HttpClient& HttpClient::param(const QString& name, const QString& value) {
70 d->params.addQueryItem(name, value);
74 HttpClient& HttpClient::header(const QString& header, const QString& value) {
75 d->headers[header] = value;
79 void HttpClient::get(std::function<void(const QString&)> successHandler,
80 std::function<void(const QString&)> errorHandler,
81 const char* encoding) {
82 HttpClientPrivate::get(d, HttpClientPrivate::GET, successHandler,
83 errorHandler, encoding);
86 void HttpClient::download(
87 const QString& savePath,
88 std::function<void(const QString&)> successHandler,
89 std::function<void(const QString&)> errorHandler,
90 std::function<void(const qint64, const qint64)> progressHandler) {
91 bool debug = d->debug;
92 QFile* file = new QFile(savePath);
94 if (file->open(QIODevice::WriteOnly)) {
96 [=](const QByteArray& data) { file->write(data); },
104 << QString("download finished, save to: %1").arg(savePath);
107 if (NULL != successHandler) {
109 QString("download finished, save to: %1").arg(savePath));
112 errorHandler, progressHandler);
115 qDebug().noquote() << QString("open file error: %1").arg(savePath);
118 if (NULL != errorHandler) {
119 errorHandler(QString("open file error: %1").arg(savePath));
124 void HttpClient::download(
125 std::function<void(const QByteArray&)> readyRead,
126 std::function<void(const QString&)> successHandler,
127 std::function<void(const QString&)> errorHandler,
128 std::function<void(const qint64, const qint64)> progressHandler) {
129 bool debug = d->debug;
132 QNetworkAccessManager* manager = HttpClientPrivate::getManager(d, &internal);
133 QNetworkRequest request =
134 HttpClientPrivate::createRequest(d, HttpClientPrivate::GET);
135 QNetworkReply* reply = manager->get(request);
137 QObject::connect(reply, &QNetworkReply::readyRead,
138 [=] { readyRead(reply->readAll()); });
140 QObject::connect(reply, &QNetworkReply::finished, [=] {
141 QString successMessage = "download finished";
142 QString errorMessage = reply->errorString();
143 HttpClientPrivate::handleFinish(debug, successMessage, errorMessage,
144 successHandler, errorHandler, reply,
145 internal ? manager : NULL);
148 QObject::connect(reply, &QNetworkReply::downloadProgress,
149 [=](qint64 bytesReceived, qint64 bytesTotal) {
150 if (NULL != progressHandler) {
151 progressHandler(bytesReceived, bytesTotal);
156 void HttpClientPrivate::get(HttpClientPrivate* d,
158 std::function<void(const QString&)> successHandler,
159 std::function<void(const QString&)> errorHandler,
160 const char* encoding) {
163 QNetworkAccessManager* manager = HttpClientPrivate::getManager(d, &internal);
164 QNetworkRequest request =
165 HttpClientPrivate::createRequest(d, HttpClientPrivate::GET);
166 QNetworkReply* reply = NULL;
169 case HttpClientPrivate::GET:
170 reply = manager->get(request);
177 QObject::connect(reply, &QNetworkReply::finished, [=] {
178 QString successMessage = HttpClientPrivate::readReply(reply, encoding);
179 QString errorMessage = reply->errorString();
180 HttpClientPrivate::handleFinish(d->debug, successMessage, errorMessage,
181 successHandler, errorHandler, reply,
182 internal ? manager : NULL);
186 QNetworkAccessManager* HttpClientPrivate::getManager(HttpClientPrivate* d,
188 *internal = d->manager == NULL;
189 return *internal ? new QNetworkAccessManager() : d->manager;
192 QNetworkRequest HttpClientPrivate::createRequest(HttpClientPrivate* d,
194 if (!d->params.isEmpty()) {
195 d->url += "?" + d->params.toString(QUrl::FullyEncoded);
199 qDebug().noquote() << "url:" << d->url;
201 QList<QPair<QString, QString> > paramItems = d->params.queryItems();
202 for (int i = 0; i < paramItems.size(); ++i) {
203 QString name = paramItems.at(i).first;
204 QString value = paramItems.at(i).second;
206 qDebug().noquote() << QString("params: %1=%2").arg(name).arg(value);
208 qDebug().noquote() << QString(" %1=%2").arg(name).arg(value);
213 QNetworkRequest request(QUrl(d->url));
214 QHashIterator<QString, QString> iter(d->headers);
215 while (iter.hasNext()) {
217 request.setRawHeader(iter.key().toUtf8(), iter.value().toUtf8());
223 QString HttpClientPrivate::readReply(QNetworkReply* reply,
224 const char* encoding) {
225 QTextStream in(reply);
227 in.setCodec(encoding);
229 while (!in.atEnd()) {
230 result += in.readLine();
236 void HttpClientPrivate::handleFinish(
238 const QString& successMessage,
239 const QString& errorMessage,
240 std::function<void(const QString&)> successHandler,
241 std::function<void(const QString&)> errorHandler,
242 QNetworkReply* reply,
243 QNetworkAccessManager* manager) {
244 if (reply->error() == QNetworkReply::NoError) {
247 << QString("request successed: %1").arg(successMessage);
250 if (NULL != successHandler) {
251 successHandler(successMessage);
255 qDebug().noquote() << QString("request failed: %1").arg(errorMessage);
258 if (NULL != errorHandler) {
259 errorHandler(errorMessage);
263 reply->deleteLater();
264 if (NULL != manager) {
265 manager->deleteLater();