/*========================================================================= medInria Copyright (c) INRIA 2013 - 2019. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ #include "RequestManager.h" RequestManager::RequestManager(QObject * parent):QObject(parent) { // initializing the network access manager that will be used by the plugin instance m_qnam = new QNetworkAccessManager(this); } RequestManager::~RequestManager() { } void RequestManager::httpGet(QUuid netReqId, QNetworkRequest req) { // sending the get request QNetworkReply *reply = m_qnam->get(req); handleReply(HTTP_GET_VERB, reply, netReqId); } void RequestManager::handleReply(int httpVerb, QNetworkReply * &reply, const QUuid &netReqId) { // storing the reply object in the reply map m_replyUuidMap[httpVerb][reply] = netReqId; // Connecting the request manager slots to the signals sent by the reply object QObject::connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(slotDownloadProgress(qint64, qint64))); QObject::connect(reply, SIGNAL(finished()), this, SLOT(slotFinished())); QObject::connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError(QNetworkReply::NetworkError))); } void RequestManager::slotDownloadProgress(qint64 bytesSent, qint64 bytesTotal) { // retrieving the reply object who sent a download signal QNetworkReply *reply = dynamic_cast(QObject::sender()); //handling the reply progression information if(reply) { if(m_replyUuidMap[HTTP_GET_VERB].contains(reply)) { currentResponse(reply, HTTP_GET_VERB, DOWNLOAD_CODE, bytesSent, bytesTotal); } else if(m_replyUuidMap[HTTP_POST_VERB].contains(reply)) { currentResponse(reply, HTTP_POST_VERB, DOWNLOAD_CODE, bytesSent, bytesTotal); } else if(m_replyUuidMap[HTTP_PUT_VERB].contains(reply)) { currentResponse(reply, HTTP_PUT_VERB, DOWNLOAD_CODE, bytesSent, bytesTotal); } } } void RequestManager::currentResponse(QNetworkReply *reply, int httpVerb, int status, qint64 bytesSent, qint64 bytesTotal) { // the response is in progress, therefore, the payload is empty. QByteArray payload = QByteArray(); // storing the bytes information of the reply in the header QList> headers; // sending the signal for the network classes to handle the reply information switch(httpVerb) { case HTTP_GET_VERB: emit responseHttpGet(m_replyUuidMap[httpVerb][reply], payload, headers, status); break; case HTTP_POST_VERB: emit responseHttpPost(m_replyUuidMap[httpVerb][reply], payload, headers, status); break; case HTTP_PUT_VERB: emit responseHttpPut(m_replyUuidMap[httpVerb][reply], payload, headers, status); break; default: break; } } void RequestManager::slotFinished() { // retrieving the reply object who sent a finish signal QNetworkReply *reply = dynamic_cast(QObject::sender()); //handling the reply finish information if(reply) { auto httpCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if(m_replyUuidMap[HTTP_GET_VERB].contains(reply)) { lastResponse(reply, HTTP_GET_VERB, httpCode); } else if(m_replyUuidMap[HTTP_POST_VERB].contains(reply)) { lastResponse(reply, HTTP_POST_VERB, httpCode); } else if(m_replyUuidMap[HTTP_PUT_VERB].contains(reply)) { lastResponse(reply, HTTP_PUT_VERB, httpCode); } } } void RequestManager::slotError(QNetworkReply::NetworkError err) { // retrieving the reply object who sent an error signal QNetworkReply *reply = dynamic_cast(QObject::sender()); //handling the reply error information if(reply) { int httpCode = static_cast(reply->error()); if(m_replyUuidMap[HTTP_GET_VERB].contains(reply)) { lastResponse(reply, HTTP_GET_VERB, httpCode); } else if(m_replyUuidMap[HTTP_POST_VERB].contains(reply)) { lastResponse(reply, HTTP_POST_VERB, httpCode); } else if(m_replyUuidMap[HTTP_PUT_VERB].contains(reply)) { lastResponse(reply, HTTP_PUT_VERB, httpCode); } } } void RequestManager::lastResponse(QNetworkReply * reply, int httpVerb, int statusOrHttpCode) { auto payload = reply->readAll(); auto headers = reply->rawHeaderPairs(); // sending the signal for the network classes to handle the reply information switch(httpVerb) { case HTTP_GET_VERB: emit responseHttpGet(m_replyUuidMap[httpVerb][reply], payload, headers, statusOrHttpCode); m_replyUuidMap[httpVerb].remove(reply); break; case HTTP_POST_VERB: emit responseHttpPost(m_replyUuidMap[httpVerb][reply], payload, headers, statusOrHttpCode); m_replyUuidMap[httpVerb].remove(reply); break; case HTTP_PUT_VERB: emit responseHttpPut(m_replyUuidMap[httpVerb][reply], payload, headers, statusOrHttpCode); m_replyUuidMap[httpVerb].remove(reply); break; default: break; } // Deletion of the reply object m_replyUuidMap->remove(reply); reply->deleteLater(); } void RequestManager::abort(QUuid idRequest) { // retrieving the reply object with the idRequest for(int i = 0; i < 3; ++i) { for(auto it = m_replyUuidMap[i].begin(); it != m_replyUuidMap[i].end(); ++it) { if(it.value() == idRequest) { QNetworkReply* reply = it.key(); reply->abort(); m_replyUuidMap[i].remove(reply); return; } } } }