At long last! i decided to simply process reply in worker thread(Thanks @raven-worx ):
using Header = QMap<QString, QString>;
class HttpWorker : public QObject {
Q_OBJECT
public:
struct HttpData {
bool hasError = false;
NetworkError error = NetworkError::NoError;
QString errorString;
QByteArray data;
};
HttpWorker(QThread*, const QUrl&, const QUrlQuery&);
~HttpWorker();
void addHeaders(const Header&);
enum Method {
Post, Get
};
void setMethod(Method m) {
http_method = m;
}
Method method() const {
return http_method;
}
private Q_SLOTS:
void sendRequest();
private:
QNetworkAccessManager manager;
Header headers;
QUrlQuery params;
QUrl url;
Method http_method = Post;
private:
void check(QNetworkReply*);
void appendHeaders(QNetworkRequest*);
Q_SIGNALS:
void finished(HttpData);
};
HttpWorker::HttpWorker(QThread* thread, const QUrl& _url, const QUrlQuery& _params) :url{ _url }, params{ _params } {
qRegisterMetaType<HttpData>("HttpData");
moveToThread(thread);
manager.moveToThread(thread);
QObject::connect(thread, &QThread::started, this, &HttpWorker::sendRequest);
QObject::connect(this, &HttpWorker::finished, thread, &QThread::quit);
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
QObject::connect(thread, &QThread::finished, this, &HttpWorker::deleteLater);
QObject::connect(&manager, &QNetworkAccessManager::finished, this, &HttpWorker::check);
}
HttpWorker::~HttpWorker() {
}
void HttpWorker::addHeaders(const Header& _headers) {
headers = std::move(_headers);
}
void HttpWorker::appendHeaders(QNetworkRequest* req) {
if (!req)
return;
QMapIterator<QString, QString> iterator(headers);
while (iterator.hasNext()) {
iterator.next();
req->setRawHeader(QByteArray::fromStdString(iterator.key().toStdString()), QByteArray::fromStdString(iterator.value().toStdString()));
}
}
void HttpWorker::sendRequest() {
const auto content_h = QStringLiteral("application/x-www-form-urlencoded");
if (method() == Post) {
QNetworkRequest req(url);
req.setHeader(QNetworkRequest::ContentTypeHeader, content_h);
if (!headers.isEmpty())
appendHeaders(&req);
const auto data = params.isEmpty() ? url.toEncoded() : params.toString(QUrl::FullyEncoded).toUtf8();
manager.post(req, data);
} else {
url.setQuery(params);
QNetworkRequest req(url);
req.setHeader(QNetworkRequest::ContentTypeHeader, content_h);
manager.get(req);
}
}
void HttpWorker::check(QNetworkReply* reply) {
HttpData data;
if (reply->error()) {
data.hasError = true;
data.error = reply->error();
data.errorString = reply->errorString();
} else {
data.data = std::move(reply->readAll());
}
emit finished(std::move(data));
reply->deleteLater();
}