TaskUzonline: Download and parse addresses.

This commit is contained in:
Nodir Temirkhodjaev 2017-10-25 17:39:01 +05:00
parent cb36342136
commit 0e4d41c92e
9 changed files with 217 additions and 182 deletions

View File

@ -28,8 +28,8 @@ SOURCES += \
util/device.cpp \
util/fileutil.cpp \
util/hostinfo.cpp \
util/httpdownloader.cpp \
util/ip4range.cpp \
util/netdownloader.cpp \
util/netutil.cpp \
util/processinfo.cpp \
util/osutil.cpp \
@ -57,8 +57,8 @@ HEADERS += \
util/device.h \
util/fileutil.h \
util/hostinfo.h \
util/httpdownloader.h \
util/ip4range.h \
util/netdownloader.h \
util/netutil.h \
util/processinfo.h \
util/osutil.h \

View File

@ -9,8 +9,8 @@
#ifndef TASK_TEST
#include "../fortmanager.h"
#endif
#include "../util/httpdownloader.h"
#include "../util/ip4range.h"
#include "../util/netdownloader.h"
TaskTasix::TaskTasix(QObject *parent) :
TaskWorker(parent),
@ -20,26 +20,30 @@ TaskTasix::TaskTasix(QObject *parent) :
void TaskTasix::run()
{
m_downloader = new HttpDownloader(this);
m_downloader = new NetDownloader(this);
connect(m_downloader, &HttpDownloader::finished,
connect(m_downloader, &NetDownloader::finished,
this, &TaskTasix::downloadFinished);
m_rangeText = QString();
startDownloader();
setupDownloader();
downloader()->start();
}
void TaskTasix::startDownloader() const
void TaskTasix::setupDownloader() const
{
downloader()->post(QUrl("http://mrlg.tas-ix.uz/index.cgi"),
"router=cisco&pass1=&query=1&arg=");
downloader()->setUrl("http://mrlg.tas-ix.uz/index.cgi");
downloader()->setData("router=cisco&pass1=&query=1&arg=");
}
void TaskTasix::cancel(bool success)
{
if (!m_downloader) return;
m_downloader->disconnect(this); // to avoid recursive call on cancel()
m_downloader->cancel();
m_downloader->deleteLater();
m_downloader = nullptr;
@ -68,7 +72,7 @@ bool TaskTasix::processResult(FortManager *fortManager)
ipExclude->setText(m_rangeText);
return fortManager->saveOriginConf(tr("TAS-IX addresses updated!"));
return fortManager->saveOriginConf(successMessage());
#else
Q_UNUSED(fortManager)
@ -76,13 +80,30 @@ bool TaskTasix::processResult(FortManager *fortManager)
#endif
}
QString TaskTasix::parseTasixBuffer(const QByteArray &buffer)
QString TaskTasix::parseBuffer(const QByteArray &buffer) const
{
const QStringList list = parseCustomBuffer(buffer);
if (list.isEmpty())
return QString();
// Merge lines
Ip4Range ip4Range;
if (!ip4Range.fromText(list.join('\n')))
return QString();
return ip4Range.toText();
}
QStringList TaskTasix::parseTasixBuffer(const QByteArray &buffer)
{
QStringList list;
// Parse lines
const QString text = QString::fromLatin1(buffer);
foreach (const QStringRef &line, text.splitRef('\n')) {
foreach (const QStringRef &line, text.splitRef(
'\n', QString::SkipEmptyParts)) {
if (!line.startsWith('*'))
continue;
@ -99,20 +120,14 @@ QString TaskTasix::parseTasixBuffer(const QByteArray &buffer)
list.append(addrStr.toString());
}
if (list.isEmpty())
return QString();
// Include local networks
list.append("10.0.0.0/8");
list.append("127.0.0.0/8");
list.append("169.254.0.0/16");
list.append("172.16.0.0/12");
list.append("192.168.0.0/16");
if (!list.isEmpty()) {
list.append("10.0.0.0/8");
list.append("127.0.0.0/8");
list.append("169.254.0.0/16");
list.append("172.16.0.0/12");
list.append("192.168.0.0/16");
}
// Merge lines
Ip4Range ip4Range;
if (!ip4Range.fromText(list.join('\n')))
return QString();
return ip4Range.toText();
return list;
}

View File

@ -3,7 +3,7 @@
#include "taskworker.h"
class HttpDownloader;
class NetDownloader;
class TaskTasix : public TaskWorker
{
@ -12,17 +12,23 @@ class TaskTasix : public TaskWorker
public:
explicit TaskTasix(QObject *parent = nullptr);
HttpDownloader *downloader() const { return m_downloader; }
NetDownloader *downloader() const { return m_downloader; }
static QString parseTasixBuffer(const QByteArray &buffer);
static QStringList parseTasixBuffer(const QByteArray &buffer);
protected:
virtual void startDownloader() const;
virtual void setupDownloader() const;
virtual QString parseBuffer(const QByteArray &buffer) const {
QString parseBuffer(const QByteArray &buffer) const;
virtual QStringList parseCustomBuffer(const QByteArray &buffer) const {
return parseTasixBuffer(buffer);
}
virtual QString successMessage() const {
return tr("TAS-IX addresses updated!");
}
signals:
public slots:
@ -35,7 +41,7 @@ private slots:
void downloadFinished(bool success);
private:
HttpDownloader *m_downloader;
NetDownloader *m_downloader;
QString m_rangeText;
};

View File

@ -1,20 +1,46 @@
#include "taskuzonline.h"
#include "../util/httpdownloader.h"
#include <QRegularExpression>
#include <QVector>
#include "../util/netdownloader.h"
TaskUzonline::TaskUzonline(QObject *parent) :
TaskTasix(parent)
{
}
#include <QDebug>
QString TaskUzonline::parseUzonlineBuffer(const QByteArray &buffer)
void TaskUzonline::setupDownloader() const
{
qDebug() << buffer.length() << buffer;
return QString();
downloader()->setUrl("https://alltor.me/viewtopic.php?p=1345405");
}
void TaskUzonline::startDownloader() const
QStringList TaskUzonline::parseUzonlineBuffer(const QByteArray &buffer)
{
downloader()->get(QUrl("https://alltor.me/viewtopic.php?p=1345405"));
const int startPos = buffer.indexOf("=START=");
const int endPos = buffer.indexOf("=END=", startPos + 1);
if (startPos < 0 || endPos < 0)
return QStringList();
const QRegularExpression re("([\\d.]+)[^\\d.]*-[^\\d.]*([\\d.]+)");
QStringList list;
// Parse lines
const QString text = QString::fromLatin1(buffer.constData() + startPos,
endPos - startPos);
foreach (const QStringRef &line, text.splitRef(
"<br", QString::SkipEmptyParts)) {
const QRegularExpressionMatch match = re.match(line);
if (!match.hasMatch())
continue;
const QString ip1 = match.captured(1);
const QString ip2 = match.captured(2);
list.append(ip1 + '-' + ip2);
}
return list;
}

View File

@ -10,14 +10,18 @@ class TaskUzonline : public TaskTasix
public:
explicit TaskUzonline(QObject *parent = nullptr);
static QString parseUzonlineBuffer(const QByteArray &buffer);
static QStringList parseUzonlineBuffer(const QByteArray &buffer);
protected:
void startDownloader() const override;
void setupDownloader() const override;
QString parseBuffer(const QByteArray &buffer) const override {
virtual QStringList parseCustomBuffer(const QByteArray &buffer) const override {
return parseUzonlineBuffer(buffer);
}
QString successMessage() const override {
return tr("UzOnline addresses updated!");
}
};
#endif // TASKUZONLINE_H

View File

@ -1,94 +0,0 @@
#include "httpdownloader.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#define DOWNLOAD_TIMEOUT 30000 // 30 seconds timeout
#define DOWNLOAD_MAXSIZE (64 * 1024)
HttpDownloader::HttpDownloader(QObject *parent) :
QObject(parent),
m_networkManager(new QNetworkAccessManager(this)),
m_reply(nullptr)
{
connect(&m_timer, &QTimer::timeout, [this]() { cancel(); });
m_timer.setSingleShot(true);
}
void HttpDownloader::get(const QUrl &url)
{
QNetworkRequest request(url);
m_reply = m_networkManager->get(request);
prepareReply();
}
void HttpDownloader::post(const QUrl &url, const QByteArray &data)
{
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/x-www-form-urlencoded");
m_reply = m_networkManager->post(request, data);
prepareReply();
}
void HttpDownloader::prepareReply()
{
Q_ASSERT(m_reply);
connect(m_reply, &QIODevice::readyRead,
this, &HttpDownloader::requestReadyRead);
connect(m_reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
this, &HttpDownloader::requestError);
connect(m_reply, &QNetworkReply::finished,
this, &HttpDownloader::requestFinished);
m_timer.start(DOWNLOAD_TIMEOUT);
m_buffer.clear();
}
void HttpDownloader::cancel(bool success)
{
if (!m_reply) return;
m_reply->disconnect(this); // to avoid recursive call on abort()
m_reply->abort();
m_reply->deleteLater();
m_reply = nullptr;
m_timer.stop();
emit finished(success);
}
void HttpDownloader::requestReadyRead()
{
const QByteArray data = m_reply->read(
DOWNLOAD_MAXSIZE - m_buffer.size());
m_buffer.append(data);
if (m_buffer.size() > DOWNLOAD_MAXSIZE) {
cancel(true); // try to use the partial loaded data
} else {
m_timer.start();
}
}
void HttpDownloader::requestError(int networkError)
{
Q_UNUSED(networkError)
cancel();
}
void HttpDownloader::requestFinished()
{
cancel(!m_buffer.isEmpty());
}

View File

@ -1,46 +0,0 @@
#ifndef HTTPDOWNLOADER_H
#define HTTPDOWNLOADER_H
#include <QObject>
#include <QTimer>
#include <QUrl>
class QNetworkAccessManager;
class QNetworkReply;
class HttpDownloader : public QObject
{
Q_OBJECT
public:
explicit HttpDownloader(QObject *parent = nullptr);
QByteArray buffer() const { return m_buffer; }
signals:
void finished(bool success);
public slots:
void get(const QUrl &url);
void post(const QUrl &url, const QByteArray &data);
void cancel(bool success = false);
private slots:
void requestReadyRead();
void requestError(int networkError);
void requestFinished();
private:
void prepareReply();
private:
QNetworkAccessManager *m_networkManager;
QNetworkReply *m_reply;
QTimer m_timer;
QByteArray m_buffer;
};
#endif // HTTPDOWNLOADER_H

View File

@ -0,0 +1,80 @@
#include "netdownloader.h"
#define DOWNLOAD_TIMEOUT 30 // 30 seconds timeout
#define DOWNLOAD_MAXSIZE (64 * 1024)
NetDownloader::NetDownloader(QObject *parent) :
QObject(parent),
m_started(false)
{
setupProcess();
}
void NetDownloader::setupProcess()
{
connect(&m_process, &QProcess::readyReadStandardOutput,
this, &NetDownloader::processReadyRead);
connect(&m_process, &QProcess::errorOccurred,
this, &NetDownloader::processError);
connect(&m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &NetDownloader::processFinished);
}
void NetDownloader::start()
{
QStringList args;
args.append("--max-time");
args.append(QString::number(DOWNLOAD_TIMEOUT));
if (!m_data.isEmpty()) {
args.append("--data");
args.append(QString::fromLatin1(m_data.constData()));
}
args.append(m_url);
m_started = true;
m_buffer.clear();
m_process.start("curl", args, QIODevice::ReadOnly);
if (!m_process.waitForStarted()) {
cancel();
}
}
void NetDownloader::cancel(bool success)
{
if (!m_started) return;
m_started = false;
m_process.kill();
emit finished(success);
}
void NetDownloader::processReadyRead()
{
const QByteArray data = m_process.read(
DOWNLOAD_MAXSIZE - m_buffer.size());
m_buffer.append(data);
if (m_buffer.size() > DOWNLOAD_MAXSIZE) {
cancel(true); // try to use the partial loaded data
}
}
void NetDownloader::processError(QProcess::ProcessError error)
{
Q_UNUSED(error)
cancel();
}
void NetDownloader::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
cancel(exitCode == 0 && exitStatus == QProcess::NormalExit
&& !m_buffer.isEmpty());
}

View File

@ -0,0 +1,44 @@
#ifndef NETDOWNLOADER_H
#define NETDOWNLOADER_H
#include <QProcess>
class NetDownloader : public QObject
{
Q_OBJECT
public:
explicit NetDownloader(QObject *parent = nullptr);
void setUrl(const QString &url) { m_url = url; }
void setData(const QByteArray &data) { m_data = data; }
QByteArray buffer() const { return m_buffer; }
signals:
void finished(bool success);
public slots:
void start();
void cancel(bool success = false);
private slots:
void processReadyRead();
void processError(QProcess::ProcessError error);
void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
private:
void setupProcess();
private:
bool m_started;
QString m_url;
QByteArray m_data;
QProcess m_process;
QByteArray m_buffer;
};
#endif // NETDOWNLOADER_H