.pro
INCLUDEPATH += $$[QT_INSTALL_PREFIX]/src/3rdparty/zlib
.h
private:
enum answerType {
readAnswerToString,
readAnswerToByteArray,
readAnswerToOther,
noReadAnswer
};
enum headersShowType {
showHeaders,
noShowHeaders
};
enum redirectType {
autoRedirect,
noMakeRedirect
};
void GET(QNetworkAccessManager &qnam, int howReadAnswer = readAnswerToString, int headers = showHeaders, int redirect = autoRedirect, QByteArray contentType = QByteArray(), bool repeat = true);
void POST(QNetworkAccessManager &qnam, int howReadAnswer = readAnswerToString, int headers = showHeaders, int redirect = autoRedirect, QByteArray contentType = "application/x-www-form-urlencoded", bool repeat = true);
void REDIRECT(QNetworkAccessManager &qnam, int howReadAnswer = readAnswerToString, int headers = showHeaders);
void HTTPHEADERS(QNetworkReply *reply);
QByteArray uncompress(const QByteArray &data);
quint64 mRand(qint64, qint64, bool makeUSleep = false);
void writeOnFile(const QString &fileName, const QString &data) const;
void parseJson(QHash<QString, QString> &jsonElements, const QString &strIndexIn, const QString &prepend = QString());
QNetworkReply *reply;
QNetworkRequest request;
QString answer;
QByteArray answerBytes;
QString lastUrl;
QString location;
QString locationRedirect;
int redirectCount;
QHash<QByteArray, QByteArray> requestHeaders;
QHash<QByteArray, QByteArray> replyHeaders;
QByteArray postData;
bool SHOWHEADERS;
bool STOP;
QString parent;
.cpp
#include "zlib.h"
void Class::GET(QNetworkAccessManager &qnam, int howReadAnswer, int headers, int redirect, QByteArray contentType, bool repeat)
{
QEventLoop loopGet;
int badProxyCount=0;
request.setRawHeader("Content-Type", contentType);
REPEATGET:
reply = qnam.get(request);
reply->ignoreSslErrors();
//if (proxyType == "NoUseProxy")
QTimer::singleShot(60000, &loopGet, SLOT(quit()));
connect(reply, SIGNAL(finished()), &loopGet, SLOT(quit()));
loopGet.exec();
if (reply->error()) {
qDebug() << "REPLY ERROR:" << reply->errorString() << reply->error();
if (repeat && badProxyCount<3) {
badProxyCount++;
qDebug() << "badProxyCountGet: " << badProxyCount;
delete reply;
goto REPEATGET;
}
}
///////////////////////////////// ЗАПИСЬ ЗАГОЛОВКОВ НАЧАЛО ////////////////////////
requestHeaders.clear();
QList<QByteArray> listHeaders = reply->request().rawHeaderList();
foreach(QByteArray nameHeader, listHeaders) {
QByteArray valueHeader = reply->request().rawHeader(nameHeader);
requestHeaders.insert(nameHeader, valueHeader);
}
replyHeaders.clear();
listHeaders = reply->rawHeaderList();
foreach(QByteArray nameHeader, listHeaders) {
QByteArray valueHeader = reply->rawHeader(nameHeader);
replyHeaders.insert(nameHeader, valueHeader);
}
///////////////////////////////// ЗАПИСЬ ЗАГОЛОВКОВ КОНЕЦ ////////////////////////
if (headers == showHeaders) HTTPHEADERS(reply);
location = QByteArray::fromPercentEncoding(reply->rawHeader("Location"));
if (!reply->rawHeader("Ajax-Location").isEmpty()) {
location = QByteArray::fromPercentEncoding(reply->rawHeader("Ajax-Location"));
}
if (redirect == autoRedirect) {
if (!location.isEmpty()) {
lastUrl = reply->url().toString();
redirectCount = 0;
REDIRECT(qnam, howReadAnswer, showHeaders);
return;
}
}
answer.clear();
answerBytes.clear();
if (howReadAnswer == readAnswerToString) {
if (reply->rawHeader("Content-Encoding").contains("gzip")) {
answer = uncompress(reply->readAll());
} else {
answer = reply->readAll();
}
} else if (howReadAnswer == readAnswerToByteArray) {
answerBytes = reply->readAll();
} else if (howReadAnswer == readAnswerToOther) {
if (reply->rawHeader("Content-Type").contains("image/gif")) {
if (reply->rawHeader("Content-Encoding").contains("gzip")) { //if (gzip)
answerBytes = uncompress(reply->readAll());
} else {
answerBytes = reply->readAll();
}
} else {
if (reply->rawHeader("Content-Encoding").contains("gzip")) { //if (gzip)
answer = uncompress(reply->readAll());
} else {
answer = reply->readAll();
}
}
}
lastUrl = reply->url().toString();
delete reply;
}
void Class::POST(QNetworkAccessManager &qnam, int howReadAnswer, int headers, int redirect, QByteArray contentType, bool repeat)
{
QEventLoop loopPost;
int badProxyCount=0;
REPEATPOST:
request.setRawHeader("Content-Type", contentType);
reply = qnam.post(request, postData);
reply->ignoreSslErrors();
QTimer::singleShot(60000, &loopPost, SLOT(quit()));
connect(reply, SIGNAL(finished()), &loopPost, SLOT(quit()));
loopPost.exec();
if (reply->error()) {
qDebug() << "REPLY ERROR:" << reply->errorString() << reply->error();
if (repeat && badProxyCount<3) {
badProxyCount++;
qDebug() << "badProxyCountPost: " << badProxyCount;
delete reply;
goto REPEATPOST;
}
}
///////////////////////////////// ЗАПИСЬ ЗАГОЛОВКОВ НАЧАЛО ////////////////////////
requestHeaders.clear();
QList<QByteArray> listHeaders = reply->request().rawHeaderList();
foreach(QByteArray nameHeader, listHeaders) {
QByteArray valueHeader = reply->request().rawHeader(nameHeader);
requestHeaders.insert(nameHeader, valueHeader);
}
replyHeaders.clear();
listHeaders = reply->rawHeaderList();
foreach(QByteArray nameHeader, listHeaders) {
QByteArray valueHeader = reply->rawHeader(nameHeader);
replyHeaders.insert(nameHeader, valueHeader);
}
///////////////////////////////// ЗАПИСЬ ЗАГОЛОВКОВ КОНЕЦ ////////////////////////
if (headers == showHeaders) HTTPHEADERS(reply);
location = QByteArray::fromPercentEncoding(reply->rawHeader("Location"));
if (!reply->rawHeader("Ajax-Location").isEmpty()) {
location = QByteArray::fromPercentEncoding(reply->rawHeader("Ajax-Location"));
}
if (redirect == autoRedirect) {
if (!location.isEmpty()) {
lastUrl = reply->url().toString();
redirectCount = 0;
REDIRECT(qnam, howReadAnswer, showHeaders);
return;
}
}
if (howReadAnswer == readAnswerToString) {
if (reply->rawHeader("Content-Encoding").contains("gzip")) { //if (gzip)
answer = uncompress(reply->readAll());
} else {
answer = reply->readAll();
}
} else if (howReadAnswer == readAnswerToByteArray) {
answerBytes = reply->readAll();
}
lastUrl = reply->url().toString();
delete reply;
}
void Class::REDIRECT(QNetworkAccessManager &qnam, int howReadAnswer, int headers)
{
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
qDebug() << "redirect url do: " << redirectUrl;
if (!redirectUrl.isEmpty() && redirectUrl.isRelative()) {
redirectUrl = reply->url().resolved(redirectUrl);
qDebug() << "redirect url posle: " << redirectUrl;
} else if (!reply->rawHeader("Ajax-Location").isEmpty()) {
request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
request.setRawHeader("Wicket-Ajax", QByteArray());
redirectUrl = reply->url().resolved(QUrl::fromPercentEncoding(reply->rawHeader("Ajax-Location")));
qDebug() << "redirect url Ajax-Location posle: " << redirectUrl;
} else if (redirectUrl.isEmpty()) {
qDebug() << endl << this->objectName() << endl << endl << "NO REDIRECT!!!" << endl << endl << endl;
return;
}
request.setRawHeader("Content-Type", QByteArray());
request.setUrl(redirectUrl);
QEventLoop loopRedirect;
int badProxyCount=0;
delete reply;
REPEATREDIRECT:
reply = qnam.get(request);
reply->ignoreSslErrors();
QTimer::singleShot(60000, &loopRedirect, SLOT(quit()));
connect(reply, SIGNAL(finished()), &loopRedirect, SLOT(quit()));
loopRedirect.exec();
qDebug() << reply->url();
if (reply->error()) {
qDebug() << "REPLY ERROR:" << reply->errorString() << reply->error();
if (badProxyCount<3) {
badProxyCount++;
qDebug() << "badProxyCountRedirect: " << badProxyCount;
delete reply;
goto REPEATREDIRECT;
}
}
///////////////////////////////// ЗАПИСЬ ЗАГОЛОВКОВ НАЧАЛО ////////////////////////
requestHeaders.clear();
QList<QByteArray> listHeaders = reply->request().rawHeaderList();
foreach(QByteArray nameHeader, listHeaders) {
QByteArray valueHeader = reply->request().rawHeader(nameHeader);
requestHeaders.insert(nameHeader, valueHeader);
}
replyHeaders.clear();
listHeaders = reply->rawHeaderList();
foreach(QByteArray nameHeader, listHeaders) {
QByteArray valueHeader = reply->rawHeader(nameHeader);
replyHeaders.insert(nameHeader, valueHeader);
}
///////////////////////////////// ЗАПИСЬ ЗАГОЛОВКОВ КОНЕЦ ////////////////////////
if (headers == showHeaders) HTTPHEADERS(reply);
if ((!reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl().isEmpty() || !reply->rawHeader("Ajax-Location").isEmpty())
&& redirectCount < 33) {
redirectCount++;
REDIRECT(qnam, howReadAnswer, showHeaders);
} else {
if (howReadAnswer == readAnswerToString) {
if (reply->rawHeader("Content-Encoding").contains("gzip")) { //if (gzip)
answer = uncompress(reply->readAll());
} else {
answer = reply->readAll();
}
} else if (howReadAnswer == readAnswerToByteArray) {
answerBytes = reply->readAll();
}
locationRedirect = QByteArray::fromPercentEncoding(reply->rawHeader("Location"));
if (!reply->rawHeader("Ajax-Location").isEmpty()) {
locationRedirect = QByteArray::fromPercentEncoding(reply->rawHeader("Ajax-Location"));
}
lastUrl = reply->url().toString();
delete reply;
}
}
void Class::HTTPHEADERS(QNetworkReply *reply)
{
if (!SHOWHEADERS) return;
qDebug() << endl << this->objectName() << reply->url();
qDebug() << "Request headers: ";
QList<QByteArray> reqHeaders = reply->request().rawHeaderList();
foreach (QByteArray reqName, reqHeaders)
{
QByteArray reqValue = reply->request().rawHeader(reqName);
qDebug() << reqName << ":" << reqValue;
}
qDebug() << "Reply headers: ";
QList<QByteArray> reqHeadersReply = reply->rawHeaderList();
foreach( QByteArray reqName, reqHeadersReply )
{
QByteArray reqValue = reply->rawHeader( reqName );
qDebug() << reqName << ":" << reqValue;
}
}
QByteArray Class::uncompress(const QByteArray &data)
{
if (data.size() <= 4) {
qDebug("uncompress: Input data is truncated");
return QByteArray();
}
QByteArray result;
int ret;
z_stream strm;
static const int CHUNK_SIZE = 1024;
char out[CHUNK_SIZE];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = data.size();
strm.next_in = (Bytef*)(data.data());
ret = inflateInit2(&strm, 15 + 32); // gzip decoding
if (ret != Z_OK)
return QByteArray();
// run inflate()
do {
strm.avail_out = CHUNK_SIZE;
strm.next_out = (Bytef*)(out);
ret = inflate(&strm, Z_NO_FLUSH);
Q_ASSERT(ret != Z_STREAM_ERROR); // state not clobbered
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; // and fall through
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return QByteArray();
}
result.append(out, CHUNK_SIZE - strm.avail_out);
} while (strm.avail_out == 0);
// clean up and return
inflateEnd(&strm);
return result;
}
quint64 Class::mRand(qint64 a, qint64 b, bool makeUSleep)
{
if (makeUSleep) usleep(1);
qsrand(QDateTime::currentMSecsSinceEpoch() + reinterpret_cast<quint64>(this));
return (qrand() + qrand() * RAND_MAX)%(b-a+1)+a;
}
void Class::writeOnFile(const QString &fileName, const QString &data) const
{
QFile file(fileName);
file.open(QIODevice::WriteOnly);
QTextStream out(&file);
out << data;
file.close();
}
void Class::parseJson(QHash<QString, QString> &jsonElements, const QString &strIndexIn, const QString &prepend)
{
QRegExp rx; rx.setMinimal(true); rx.setCaseSensitivity(Qt::CaseInsensitive);
rx.setPattern("\"([^\"]+)\"
?
[^\\{][^,]*)(?:,|\\})|(\\{[^\\{]*\\})|(\\{.+\\}[^,]+))");
int pos = 0;
while ((pos = rx.indexIn(strIndexIn, pos)) != -1) {
//qDebug() << "rx.cap(1)" << rx.cap(1) << "rx.cap(2)" << rx.cap(2) << "rx.cap(3)" << rx.cap(3) << "rx.cap(4)" << rx.cap(4);
if (!rx.cap(2).isEmpty()) {
jsonElements.insert(prepend + rx.cap(1), rx.cap(2).replace(QRegExp("(?:\"|\\})"), ""));
} else if (!rx.cap(3).isEmpty()) {
parseJson(jsonElements, rx.cap(3), parent + rx.cap(1) + ".");
} else if (!rx.cap(4).isEmpty()) {
parent = rx.cap(1) + ".";
parseJson(jsonElements, rx.cap(4), parent);
parent.clear();
}
pos += rx.matchedLength();
}
// qDebug() << endl << "jsonElements" << "keys" << jsonElements.keys().count() << "values" << jsonElements.values().count();
// QHash<QString, QString>::const_iterator iteratorJsonElements = jsonElements.constBegin();
// while (iteratorJsonElements != jsonElements.constEnd()) {
// qDebug() << iteratorJsonElements.key() << "=" << iteratorJsonElements.value();
// ++iteratorJsonElements;
// }
}