forked from jmccl/acme-lw
-
Notifications
You must be signed in to change notification settings - Fork 2
/
http.hpp
125 lines (105 loc) · 4.88 KB
/
http.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#ifndef VIRCADIA_LIBRARIES_NETWORKING_SRC_ACME_HTTP_HPP
#define VIRCADIA_LIBRARIES_NETWORKING_SRC_ACME_HTTP_HPP
#include "http.h"
#include "acme-exception.h"
#include "../NetworkAccessManager.h"
#include <cstring>
#include <functional>
#include <type_traits>
#include <QtNetwork/QNetworkReply>
namespace acme_lw_internal
{
using namespace acme_lw;
using namespace std::literals;
struct QDelayedDeleter {
void operator()(QObject* object) { object->deleteLater(); };
};
using QDelayedNetworkReply = std::unique_ptr<QNetworkReply, QDelayedDeleter>;
template <typename Callback>
void getHeader(Callback callback, const std::string& url, const char* headerKey) {
QNetworkRequest request(QString::fromStdString(url));
QNetworkReply* reply = NetworkAccessManager::getInstance().head(request);
QObject::connect(reply, &QNetworkReply::finished, [reply, callback = std::move(callback), headerKey]() mutable {
auto replyPtr = QDelayedNetworkReply(reply);
if(replyPtr->error() != QNetworkReply::NoError) {
callback(AcmeException(replyPtr->errorString().toStdString()));
} else {
if(replyPtr->hasRawHeader(headerKey)) {
callback(replyPtr->rawHeader(headerKey).toStdString());
} else {
callback(AcmeException("Reply missing header: "s + headerKey));
}
}
});
}
template <typename Callback>
void doPost(Callback callback, const std::string& url, const std::vector<std::pair<std::string, std::string>>& params) {
QNetworkRequest request(QString::fromStdString(url));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
std::string queryStr{};
if(!params.empty())
{
queryStr += params.front().first + "=" + params.front().second;
for(auto param = params.begin() + 1; param != params.end(); ++param) {
queryStr += "&" + param->first + "=" + QUrl::toPercentEncoding(param->second.c_str()).toStdString();
}
}
QNetworkReply* reply = NetworkAccessManager::getInstance().post(request, queryStr.c_str());
QObject::connect(reply, &QNetworkReply::finished, [reply, callback = std::move(callback)]() mutable {
auto replyPtr = QDelayedNetworkReply(reply);
if(replyPtr->error() != QNetworkReply::NoError) {
callback(AcmeException("Error: " + replyPtr->errorString().toStdString() + '\n'
+ "Response: " + replyPtr->readAll().toStdString()));
} else {
Response response{};
response.response_.resize(replyPtr->bytesAvailable());
replyPtr->read(response.response_.data(), response.response_.size());
callback(std::move(response));
}
});
}
template <typename Callback>
void doPost(Callback callback, const std::string& url, const std::string& postBody, const char * headerKey) {
QNetworkRequest request(QString::fromStdString(url));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/jose+json");
QNetworkReply* reply = NetworkAccessManager::getInstance().post(request, QByteArray::fromStdString(postBody));
QObject::connect(reply, &QNetworkReply::finished, [reply, callback = std::move(callback), headerKey]() mutable {
auto replyPtr = QDelayedNetworkReply(reply);
if(replyPtr->error() != QNetworkReply::NoError) {
callback(AcmeException("Error: " + replyPtr->errorString().toStdString() + '\n'
+ "Response: " + replyPtr->readAll().toStdString()));
} else {
Response response{};
if(headerKey)
{
if(replyPtr->hasRawHeader(headerKey)) {
response.headerValue_ = replyPtr->rawHeader(headerKey).toStdString();
} else {
callback(AcmeException("Reply missing header: "s + headerKey));
return;
}
};
response.response_.resize(replyPtr->bytesAvailable());
replyPtr->read(response.response_.data(), response.response_.size());
callback(std::move(response));
}
});
}
template <typename Callback>
void doGet(Callback callback, const std::string& url) {
QNetworkRequest request(QString::fromStdString(url));
QNetworkReply* reply = NetworkAccessManager::getInstance().get(request);
QObject::connect(reply, &QNetworkReply::finished, [reply, callback = std::move(callback)]() mutable {
auto replyPtr = QDelayedNetworkReply(reply);
if(replyPtr->error() != QNetworkReply::NoError) {
callback(AcmeException(replyPtr->errorString().toStdString()));
} else {
Response response{};
response.response_.resize(replyPtr->bytesAvailable());
replyPtr->read(response.response_.data(), response.response_.size());
callback(std::move(response));
}
});
}
}
#endif /* end of include guard */