qt/LedOK/communication/hpptclient.cpp
2022-01-04 18:11:48 +08:00

335 lines
8.6 KiB
C++

#include "hpptclient.h"
//HpptClient* HpptClient::gInstance = nullptr;
HpptClient::HpptClient(QObject *p):
QObject(p),
mNetAccessManager(new QNetworkAccessManager(this))
{
}
HpptClient::~HpptClient()
{
}
void HpptClient::clearRp(QNetworkReply *rp)
{
if(rp)
{
QString url = rp->request().url().toString();
QString postMD5 = rp->property("postMD5").toString();
QString postData = rp->property("data").toByteArray();
if(postMD5.isEmpty())
{
//清理对应缓存
mDownloadDataCache.remove(url);
//解除正在处理状态
mProcessingRq.remove(url);
}
else
{
//清理对应缓存
mDownloadDataCache.remove(postMD5);
//解除正在处理状态
mProcessingRq.remove(postMD5);
}
mRedirectMap.remove(url);
mRedirectMap.remove(postMD5);
//qDebug() << "delete cache, url:" << url << " postMOD5:" << postMD5;
rp->deleteLater();
}
}
void HpptClient::onHttpGetRspProgress(qint64 bytesReceived, qint64 bytesTotal)
{
Q_UNUSED(bytesReceived)
if(sender() == NULL)
{
return ;
}
QNetworkReply* rp = qobject_cast<QNetworkReply*>(sender());
if(rp == NULL)
{
return;
}
//qDebug() << "http get rsp progress:" << rp->url().toString() << bytesReceived << "/" << bytesTotal;
if(bytesTotal <= 0)
{
return;
}
QString url = rp->url().toString();
mDownloadDataCache[url].append(rp->readAll());
}
void HpptClient::onHttpGetRspFinished()
{
if(sender() == NULL)
{
return ;
}
QNetworkReply* rp = qobject_cast<QNetworkReply*>(sender());
if(rp == NULL)
{
return;
}
QByteArray rpData;
QString url = rp->url().toString();
int statusCode = rp->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString strUrl = rp->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
switch(statusCode)
{
case 200: // ok
{
rpData = mDownloadDataCache[rp->url().toString()];
QString redirectUrl = mRedirectMap[url];//重定向的url地址
if(redirectUrl.isEmpty())
{
// qDebug() << "http get rsp ok:" << url << "total size:" << rpData.count() << "bytes";
emit httpGetRspReady(url, rpData);
}
else
{
// qDebug() << "http get rsp ok:" << url << "total size:" << rpData.count() << "bytes" << "[redirect by]" << redirectUrl;
emit httpGetRspReady(redirectUrl, rpData);
}
}
break;
case 301:
case 302: // redirect
{
if(!strUrl.isEmpty())
{
QString turl = mRedirectMap[url];
if(turl.isEmpty())
mRedirectMap[strUrl] = url;
else
mRedirectMap[strUrl] = turl;
httpGet(strUrl);
}
}
break;
default: // error
{
qDebug() << url << "[get error:" << statusCode << "]";
QString redirectUrl = mRedirectMap[url];
if(redirectUrl.isEmpty())
{
emit httpGetRspReady(url, QByteArray());
}
else
{
emit httpGetRspReady(redirectUrl, QByteArray());
}
}
break;
}
clearRp(rp);
}
void HpptClient::onHttpPostRspProgress(qint64 bytesReceived, qint64 bytesTotal)
{
Q_UNUSED(bytesReceived);
if(sender() == NULL)
{
return ;
}
QNetworkReply* rp = qobject_cast<QNetworkReply*>(sender());
if(rp == NULL)
{
return;
}
// qDebug() << "http post rsp progress:" << rp->url().toString() << bytesReceived << "/" << bytesTotal;
if(bytesTotal <= 0)
{
return;
}
QString postMD5 = rp->property("postMD5").toString();
mDownloadDataCache[postMD5].append(rp->readAll());
}
void HpptClient::onHttpPostRspFinished()
{
if(sender() == NULL)
{
return ;
}
QNetworkReply* rp = qobject_cast<QNetworkReply*>(sender());
if(rp == NULL)
{
return;
}
QByteArray rpData;
QString url = rp->url().toString();
QString postMD5 = rp->property("postMD5").toString();
QByteArray postData = rp->property("data").toByteArray();
int statusCode = rp->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString strUrl = rp->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
switch(statusCode)
{
case 200:
{
rpData = mDownloadDataCache[postMD5];
QString redirectMD5 = mRedirectMap[postMD5];
QString redirectUrl = mRedirectMap[url];
if(redirectMD5.isEmpty() || redirectUrl.isEmpty())
{
// qDebug() << "http post rsp ok:" << url << "total size:" << rpData.count() << "bytes";
emit httpPostRspReady(url, postMD5, rpData);
}
else
{
// qDebug() << "http post rsp ok:" << url << "total size:" << rpData.count() << "bytes" << "[redirect by]" << redirectUrl << "[data]" << postData;
emit httpPostRspReady(redirectUrl, redirectMD5, rpData);
}
}
break;
case 301:
case 302:
{
if(!strUrl.isEmpty())
{
QString turl = mRedirectMap[url];//direct by
if(turl.isEmpty())
mRedirectMap[strUrl] = url;
else
mRedirectMap[strUrl] = turl;
QByteArray d;
d.append(strUrl);
d.append(postData);
QString md5 = QCryptographicHash::hash(d, QCryptographicHash::Md5);
QString tPostMD5 = mRedirectMap[md5];//direct by
if(tPostMD5.isEmpty())
{
mRedirectMap[md5] = postMD5;
}
else
{
mRedirectMap[md5] = tPostMD5;
}
httpPost(strUrl, postData);
}
}
break;
default:
qDebug() << url << "[post error:" << statusCode << "]";
QString redirectMD5 = mRedirectMap[postMD5];
QString redirectUrl = mRedirectMap[url];
if(redirectMD5.isEmpty() || redirectUrl.isEmpty())
{
emit httpPostRspReady(url, postMD5, QByteArray());
}
else
{
emit httpPostRspReady(redirectUrl, redirectMD5, QByteArray());
}
break;
}
clearRp(rp);
}
void HpptClient::httpGet(const QString &url)
{
if(mProcessingRq.value(url, false)) //ignore when rq processing
{
return;
}
for(int i = 0; i < mRedirectMap.values().count(); i++)
{
if(mRedirectMap.values()[i] == url) //ignore when redirect processing
{
return;
}
}
mProcessingRq.insert(url, true);
QNetworkRequest rq;
QSslConfiguration config = rq.sslConfiguration();
config.setPeerVerifyMode(QSslSocket::VerifyNone);
config.setProtocol(QSsl::TlsV1SslV3);
rq.setSslConfiguration(config);
rq.setUrl(QUrl(url));
QNetworkReply* rp = mNetAccessManager->get(rq);
connect(rp, &QNetworkReply::downloadProgress, this, &HpptClient::onHttpGetRspProgress);
connect(rp, &QNetworkReply::finished , this, &HpptClient::onHttpGetRspFinished);
}
QByteArray HpptClient::httpPost(const QString &url, const QByteArray &data)
{
QByteArray d;
d.append(url);
d.append(data);
QByteArray md5 = QCryptographicHash::hash(d, QCryptographicHash::Md5);
if(mProcessingRq.value(md5, false)) //ignore when rq processing
{
return md5;
}
for(int i = 0; i < mRedirectMap.values().count(); i++)
{
if(mRedirectMap.values()[i] == md5) //ignore when redirect processing
{
return md5;
}
}
mProcessingRq.insert(md5, true);
QNetworkRequest rq;
// QSslConfiguration config = rq.sslConfiguration();
// config.setPeerVerifyMode(QSslSocket::VerifyNone);
// config.setProtocol(QSsl::TlsV1SslV3);
// rq.setSslConfiguration(config);
rq.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));//add by alahover 20200304
rq.setUrl(QUrl(url));
QNetworkReply* rp = mNetAccessManager->post(rq, data);
rp->setProperty("postMD5", md5);
rp->setProperty("url", url);
rp->setProperty("data", data);
// qDebug() << "Request Payload" << url <<"\r\n"<< data;
connect(rp, &QNetworkReply::finished , this, &HpptClient::onHttpPostRspFinished);
connect(rp, &QNetworkReply::downloadProgress, this, &HpptClient::onHttpPostRspProgress);
return md5;
}