#include "requestmanager.h" #include "request.h" #ifdef CORESDK_ZLIB #include "compression.h" #endif #include namespace serversdk { /** * @brief Wrapper around QNetworkAccessManger to handle soap protocol * @param parent */ RequestManager::RequestManager(QObject *parent) : QObject(parent) { connect(&mNetworkAccessManager, &QNetworkAccessManager::authenticationRequired, [](){ qCWarning(sdknetwork) << "server need authentication"; }); connect(&mNetworkAccessManager, &QNetworkAccessManager::sslErrors, this, &RequestManager::sslErrors); } /** * @brief Process request using QNetworkAccessManger * * @param Request */ void RequestManager::processRequest(const std::shared_ptr& request) { QNetworkReply *reply = nullptr; request->logStartTime(); if (request->type() == "POST") { if ( request->requestData().isEmpty()) { qCWarning(sdknetwork) << "Request data is empty -> nothing to send"; } reply = mNetworkAccessManager.post(request->networkRequest(), request->requestData()); } else if (request->type() == "GET") { if ( ! request->requestData().isEmpty()) { qCWarning(sdknetwork) << "Request data is not empty, and you are trying to use get ( not sending any data)"; } reply = mNetworkAccessManager.get(request->networkRequest()); } else if (request->type() == "PUT") { reply = mNetworkAccessManager.put(request->networkRequest(), request->requestData()); } else { qCritical(sdknetwork) << "Using request type:" << request->type() << "is not implemented"; return; } // Adding reply to final request reply->setParent(nullptr); // ensure QNetworkreply wont be deleted by QNetworkAccessManager ( it is parent of reply ) request->setNetworkReply(reply); // Add to map to get correct request when reply is used in signal mRequestMap.insert(reply, request); connect(reply, QOverload::of(&QNetworkReply::error), this, &RequestManager::replyError); connect(reply, &QNetworkReply::downloadProgress, this, &RequestManager::downloadProgress); connect(reply, &QNetworkReply::finished, this, [=]() { std::shared_ptr request = mRequestMap.value(reply); request->logFinishTime(); mRequestMap.remove(reply); emit request->finished(); emit downloadFinished(request); }); } /** * @brief Handle sslErrors -> only debug output * @param sslErrors ( from QNetworkReply::sslErrors ) */ void RequestManager::sslErrors(QNetworkReply *reply, const QList &sslErrors) { for (const QSslError &error : sslErrors) { qCDebug(sdknetwork) << QStringLiteral("SSL error:") << error.errorString(); } if (ignoreSsl()) { reply->ignoreSslErrors(sslErrors); } } /** * @brief called upon download progess -> adding data into QByteArray * @param bytesReceived ( can be different from actual data -> compression ) * @param bytesTotal ( can be different from actual data -> compression ) */ void RequestManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) { // Get Reply ( now only one ) //Q_ASSERT(mCurrentReply); auto *reply = qobject_cast(sender()); Q_ASSERT(mRequestMap.contains(reply)); std::shared_ptr request = mRequestMap.value(reply); //Q_ASSERT(reply == mCurrentReply); QString encoding; // Check encoding for (const auto & pair : reply->rawHeaderPairs()) { if (pair.first == QStringLiteral("Content-Encoding")) { encoding = pair.second; } } QByteArray data = reply->readAll(); // Decompress gzip data #ifdef CORESDK_ZLIB if (encoding.toLower() == "gzip" && !data.isEmpty() ) { data = Compression::decompress(data); } #endif // Append data to request request->appendResponseData(data); emit progresss(bytesReceived, bytesTotal); } void RequestManager::replyError(QNetworkReply::NetworkError code) { auto *reply = qobject_cast(sender()); Q_ASSERT(mRequestMap.contains(reply)); std::shared_ptr request = mRequestMap.value(reply); qCWarning(sdknetwork) << request.get() << "reply error: " << code; } bool RequestManager::ignoreSsl() const { return mIgnoreSsl; } void RequestManager::setIgnoreSsl(bool ignoreSsl) { mIgnoreSsl = ignoreSsl; } } // core