Request logging
This commit is contained in:
parent
4ecade7b2e
commit
db24653f7d
12
KShare.pro
12
KShare.pro
@ -64,7 +64,9 @@ SOURCES += main.cpp\
|
||||
uploaders/default/imgursettingsdialog.cpp \
|
||||
uploaders/default/imgplusuploader.cpp \
|
||||
filenamevalidator.cpp \
|
||||
logs/requestlogging.cpp
|
||||
logs/requestlogging.cpp \
|
||||
logs/historydialog.cpp \
|
||||
monospacetextdialog.cpp
|
||||
|
||||
HEADERS += mainwindow.hpp \
|
||||
cropeditor/cropeditor.hpp \
|
||||
@ -109,7 +111,9 @@ HEADERS += mainwindow.hpp \
|
||||
uploaders/default/imgursettingsdialog.hpp \
|
||||
uploaders/default/imgplusuploader.hpp \
|
||||
filenamevalidator.hpp \
|
||||
logs/requestlogging.hpp
|
||||
logs/requestlogging.hpp \
|
||||
logs/historydialog.h \
|
||||
monospacetextdialog.h
|
||||
|
||||
nopkg {
|
||||
# win32 {
|
||||
@ -161,7 +165,9 @@ FORMS += mainwindow.ui \
|
||||
settingsdialog.ui \
|
||||
aboutbox.ui \
|
||||
hotkeyinputdialog.ui \
|
||||
uploaders/default/imgursettingsdialog.ui
|
||||
uploaders/default/imgursettingsdialog.ui \
|
||||
logs/historydialog.ui \
|
||||
monospacetextdialog.ui
|
||||
|
||||
DISTFILES += \
|
||||
README.md \
|
||||
|
@ -3,9 +3,19 @@
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <logs/requestlogging.hpp>
|
||||
|
||||
QNetworkAccessManager ioutils::networkManager;
|
||||
|
||||
void addLogEntry(QNetworkReply *reply, QByteArray data) {
|
||||
requestlogging::RequestContext ctx;
|
||||
|
||||
ctx.reply = reply;
|
||||
ctx.response = data;
|
||||
|
||||
requestlogging::addEntry(ctx);
|
||||
}
|
||||
|
||||
void ioutils::postMultipart(QUrl target,
|
||||
QList<QPair<QString, QString>> headers,
|
||||
QHttpMultiPart *body,
|
||||
@ -17,6 +27,7 @@ void ioutils::postMultipart(QUrl target,
|
||||
QNetworkReply *reply = networkManager.post(req, body);
|
||||
QObject::connect(reply, &QNetworkReply::finished, [reply, callback] {
|
||||
QByteArray data = reply->readAll();
|
||||
addLogEntry(reply, data);
|
||||
callback(QJsonDocument::fromJson(data), data, reply);
|
||||
delete reply;
|
||||
});
|
||||
@ -32,7 +43,9 @@ void ioutils::postMultipartData(QUrl target,
|
||||
}
|
||||
QNetworkReply *reply = networkManager.post(req, body);
|
||||
QObject::connect(reply, &QNetworkReply::finished, [reply, callback] {
|
||||
callback(reply->readAll(), reply);
|
||||
QByteArray data = reply->readAll();
|
||||
addLogEntry(reply, data);
|
||||
callback(data, reply);
|
||||
delete reply;
|
||||
});
|
||||
}
|
||||
@ -47,6 +60,7 @@ void ioutils::getJson(QUrl target,
|
||||
QNetworkReply *reply = networkManager.get(req);
|
||||
QObject::connect(reply, &QNetworkReply::finished, [reply, callback] {
|
||||
QByteArray data = reply->readAll();
|
||||
addLogEntry(reply, data);
|
||||
callback(QJsonDocument::fromJson(data), data, reply);
|
||||
reply->deleteLater();
|
||||
});
|
||||
@ -63,6 +77,7 @@ void ioutils::postJson(QUrl target,
|
||||
QNetworkReply *reply = networkManager.post(req, body);
|
||||
QObject::connect(reply, &QNetworkReply::finished, [reply, callback] {
|
||||
QByteArray data = reply->readAll();
|
||||
addLogEntry(reply, data);
|
||||
callback(QJsonDocument::fromJson(data), data, reply);
|
||||
delete reply;
|
||||
});
|
||||
@ -75,7 +90,9 @@ void ioutils::getData(QUrl target, QList<QPair<QString, QString>> headers, std::
|
||||
}
|
||||
QNetworkReply *reply = networkManager.get(req);
|
||||
QObject::connect(reply, &QNetworkReply::finished, [reply, callback] {
|
||||
callback(reply->readAll(), reply);
|
||||
QByteArray data = reply->readAll();
|
||||
addLogEntry(reply, data);
|
||||
callback(data, reply);
|
||||
delete reply;
|
||||
});
|
||||
}
|
||||
@ -90,7 +107,9 @@ void ioutils::postData(QUrl target,
|
||||
}
|
||||
QNetworkReply *reply = networkManager.post(req, body);
|
||||
QObject::connect(reply, &QNetworkReply::finished, [reply, callback] {
|
||||
callback(reply->readAll(), reply);
|
||||
QByteArray data = reply->readAll();
|
||||
addLogEntry(reply, data);
|
||||
callback(data, reply);
|
||||
delete reply;
|
||||
});
|
||||
}
|
||||
|
37
logs/historydialog.cpp
Normal file
37
logs/historydialog.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "historydialog.h"
|
||||
#include "requestlogging.hpp"
|
||||
#include "ui_historydialog.h"
|
||||
|
||||
#include <monospacetextdialog.h>
|
||||
|
||||
using requestlogging::LoggedRequest;
|
||||
|
||||
HistoryDialog::HistoryDialog(QWidget *parent) : QDialog(parent), ui(new Ui::HistoryDialog) {
|
||||
ui->setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
ui->treeWidget->setColumnWidth(0, 50);
|
||||
ui->treeWidget->setColumnWidth(1, 150);
|
||||
ui->treeWidget->setColumnWidth(2, 50);
|
||||
ui->treeWidget->setColumnWidth(3, 100);
|
||||
|
||||
QList<LoggedRequest> requests = requestlogging::getRequests();
|
||||
for (LoggedRequest req : requests) {
|
||||
ui->treeWidget->addTopLevelItem(new QTreeWidgetItem(
|
||||
{ req.getType(), req.getUrl(), QString::number(req.getResponseCode()), req.getTime() + " UTC" }));
|
||||
}
|
||||
}
|
||||
|
||||
HistoryDialog::~HistoryDialog() {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void HistoryDialog::on_treeWidget_doubleClicked(const QModelIndex &) {
|
||||
QString file = ui->treeWidget->currentItem()->text(3);
|
||||
file = settings::dir().absoluteFilePath("responses/" + file.left(file.length() - 4));
|
||||
|
||||
QFile dataFile(file);
|
||||
if (!dataFile.open(QIODevice::ReadOnly)) return;
|
||||
MonospaceTextDialog *dialog = new MonospaceTextDialog(file, dataFile.readAll());
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->show();
|
||||
}
|
24
logs/historydialog.h
Normal file
24
logs/historydialog.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef HISTORYDIALOG_H
|
||||
#define HISTORYDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class HistoryDialog;
|
||||
}
|
||||
|
||||
class HistoryDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit HistoryDialog(QWidget *parent = 0);
|
||||
~HistoryDialog();
|
||||
|
||||
private slots:
|
||||
void on_treeWidget_doubleClicked(const QModelIndex &);
|
||||
|
||||
private:
|
||||
Ui::HistoryDialog *ui;
|
||||
};
|
||||
|
||||
#endif // HISTORYDIALOG_H
|
88
logs/historydialog.ui
Normal file
88
logs/historydialog.ui
Normal file
@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>HistoryDialog</class>
|
||||
<widget class="QDialog" name="HistoryDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Request History</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>URL</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Status</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Time</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>HistoryDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>HistoryDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -13,6 +13,7 @@
|
||||
QDir responses(settings::dir().absoluteFilePath("responses"));
|
||||
QString requestPath = settings::dir().absoluteFilePath("history");
|
||||
|
||||
|
||||
void requestlogging::addEntry(RequestContext context) {
|
||||
if (!responses.exists()) responses.mkpath(".");
|
||||
QString timeNow = QDateTime::currentDateTime().toUTC().toString("yyyy-MM-dd HH-mm-ss-zzz");
|
||||
@ -29,14 +30,15 @@ void requestlogging::addEntry(RequestContext context) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto header : context.reply->rawHeaderList()) responseFile.write(header + "\n");
|
||||
for (auto header : context.reply->rawHeaderList())
|
||||
responseFile.write(header + ": " + context.reply->rawHeader(header) + "\n");
|
||||
responseFile.write("\n\n" + context.response);
|
||||
responseFile.close();
|
||||
|
||||
QTextStream(&requestFile) << ioutils::methodString(context.reply->operation()) << " " // $type
|
||||
<< context.reply->url().toString() << " " // $url
|
||||
<< context.reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() // $status
|
||||
<< timeNow; // $time
|
||||
QTextStream(&requestFile) << ioutils::methodString(context.reply->operation()) << " " // $type
|
||||
<< context.reply->url().toString() << " " // $url
|
||||
<< context.reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() << " " // $status
|
||||
<< timeNow.replace(" ", "_"); // $time
|
||||
requestFile.close();
|
||||
}
|
||||
|
||||
@ -46,6 +48,7 @@ QList<LoggedRequest> requestlogging::getRequests() {
|
||||
QList<LoggedRequest> ret;
|
||||
|
||||
QFile requestFile(requestPath);
|
||||
if (!requestFile.exists() || !requestFile.open(QIODevice::ReadOnly)) return ret;
|
||||
|
||||
QByteArray line;
|
||||
while ((line = requestFile.readLine()).size() != 0) {
|
||||
@ -54,9 +57,8 @@ QList<LoggedRequest> requestlogging::getRequests() {
|
||||
stream >> r.type;
|
||||
stream >> r.url;
|
||||
stream >> r.responseCode;
|
||||
QString time;
|
||||
stream >> time;
|
||||
r.time = QDateTime::fromString(time, "yyyy-MM-dd HH-mm-ss-zzz");
|
||||
stream >> r.time;
|
||||
r.time = r.time.replace("_", " ");
|
||||
ret.append(r);
|
||||
}
|
||||
|
||||
|
@ -5,14 +5,12 @@
|
||||
#include <QNetworkReply>
|
||||
#include <settings.hpp>
|
||||
|
||||
struct RequestContext {
|
||||
QByteArray response;
|
||||
QString sender;
|
||||
QNetworkReply *reply;
|
||||
};
|
||||
|
||||
namespace requestlogging {
|
||||
void addEntry(RequestContext context);
|
||||
struct RequestContext {
|
||||
QByteArray response;
|
||||
QNetworkReply *reply;
|
||||
};
|
||||
|
||||
class LoggedRequest {
|
||||
friend QList<LoggedRequest> getRequests();
|
||||
@ -24,24 +22,25 @@ public:
|
||||
QString getType() {
|
||||
return type;
|
||||
}
|
||||
QDateTime getTime() {
|
||||
QString getTime() {
|
||||
return time;
|
||||
}
|
||||
int getResponseCode() {
|
||||
return responseCode;
|
||||
}
|
||||
QByteArray getResponse() {
|
||||
return QFile(settings::dir().absoluteFilePath("responses/" + time.toString("yyyy-MM-dd HH-mm-ss-zzz"))).readAll();
|
||||
return QFile(settings::dir().absoluteFilePath("responses/" + time)).readAll();
|
||||
}
|
||||
|
||||
private:
|
||||
QString url;
|
||||
QString type;
|
||||
QDateTime time;
|
||||
QString time;
|
||||
int responseCode;
|
||||
};
|
||||
|
||||
QList<LoggedRequest> getRequests();
|
||||
void addEntry(RequestContext context);
|
||||
}
|
||||
|
||||
#endif // REQUESTLOGGING_HPP
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <colorpicker/colorpickerscene.hpp>
|
||||
#include <formats.hpp>
|
||||
#include <hotkeying.hpp>
|
||||
#include <logs/historydialog.h>
|
||||
#include <platformbackend.hpp>
|
||||
#include <recording/recordingformats.hpp>
|
||||
#include <settings.hpp>
|
||||
@ -181,3 +182,8 @@ void MainWindow::on_actionActive_window_triggered() {
|
||||
void MainWindow::on_actionAbort_triggered() {
|
||||
controller->abort();
|
||||
}
|
||||
|
||||
void MainWindow::on_history_clicked() {
|
||||
HistoryDialog *dialog = new HistoryDialog;
|
||||
dialog->show();
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ private slots:
|
||||
void on_actionAbout_triggered();
|
||||
void on_actionActive_window_triggered();
|
||||
void on_actionAbort_triggered();
|
||||
void on_history_clicked();
|
||||
|
||||
public:
|
||||
static MainWindow *inst();
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>352</width>
|
||||
<height>220</height>
|
||||
<width>340</width>
|
||||
<height>239</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -25,13 +25,6 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="settings">
|
||||
<property name="text">
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
@ -44,15 +37,30 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="settings">
|
||||
<property name="text">
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="history">
|
||||
<property name="text">
|
||||
<string>Open request history</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>352</width>
|
||||
<height>25</height>
|
||||
<width>340</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
@ -91,7 +99,6 @@
|
||||
<addaction name="menuUtilities"/>
|
||||
<addaction name="menuRecording"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
<action name="actionQuit">
|
||||
<property name="text">
|
||||
<string>&Quit</string>
|
||||
|
13
monospacetextdialog.cpp
Normal file
13
monospacetextdialog.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "monospacetextdialog.h"
|
||||
#include "ui_monospacetextdialog.h"
|
||||
|
||||
MonospaceTextDialog::MonospaceTextDialog(QString name, QByteArray data, QWidget *parent)
|
||||
: QDialog(parent), ui(new Ui::MonospaceTextDialog) {
|
||||
ui->setupUi(this);
|
||||
setWindowTitle(name);
|
||||
ui->textEdit->setText(data);
|
||||
}
|
||||
|
||||
MonospaceTextDialog::~MonospaceTextDialog() {
|
||||
delete ui;
|
||||
}
|
21
monospacetextdialog.h
Normal file
21
monospacetextdialog.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef MONOSPACETEXTDIALOG_H
|
||||
#define MONOSPACETEXTDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class MonospaceTextDialog;
|
||||
}
|
||||
|
||||
class MonospaceTextDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MonospaceTextDialog(QString name, QByteArray data, QWidget *parent = 0);
|
||||
~MonospaceTextDialog();
|
||||
|
||||
private:
|
||||
Ui::MonospaceTextDialog *ui;
|
||||
};
|
||||
|
||||
#endif // MONOSPACETEXTDIALOG_H
|
73
monospacetextdialog.ui
Normal file
73
monospacetextdialog.ui
Normal file
@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MonospaceTextDialog</class>
|
||||
<widget class="QDialog" name="MonospaceTextDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>MonospaceTextDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>MonospaceTextDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
Loading…
Reference in New Issue
Block a user