#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(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(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(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(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; }