diff --git a/CMakeLists.txt b/CMakeLists.txt index a09b24e..3e97434 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,11 +36,13 @@ add_executable(littlesnitch networkthread.cpp session.cpp httpflow.cpp + historymodel.cpp mainwindow.h httpflow.h networkthread.h session.h includes.h + historymodel.h mainwindow.ui ) diff --git a/historymodel.cpp b/historymodel.cpp new file mode 100644 index 0000000..c0daf61 --- /dev/null +++ b/historymodel.cpp @@ -0,0 +1,78 @@ +#include "historymodel.h" +#include + +HistoryModel::HistoryModel(QObject *parent) +{ + Q_UNUSED(parent); +} + +int HistoryModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + + if(current_items) { + return current_items->size(); + } + return 0; +} + +int HistoryModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + + return 7; +} + +QVariant HistoryModel::data(const QModelIndex &index, int role) const +{ + if(role != Qt::DisplayRole) { + return QVariant(); + } + + if(!current_items) { + return QVariant(); + } + + int row = index.row(); + int col = index.column(); + try { + auto item = current_items->at(row); + switch(col) { + case 0: { + return QString::number(item.id); + } + case 1: { + QDateTime timestamp; + timestamp.setTime_t(item.timestamp); + return timestamp.toString(Qt::SystemLocaleShortDate); + } + case 2: { + std::string url = item.scheme + "://" + item.host + ":" + std::to_string(item.port) + item.path; + return QString::fromStdString(url); + } + case 3: { + return item.status_code; + } + case 4: { + return QString::fromStdString(item.reason); + } + case 5: { + return item.rtt; + } + case 6:{ + return QString::number(item.size); + } + } + } catch (std::out_of_range const& exc) { + qDebug() << "historymodel data " << exc.what(); + } + return QVariant(); +} + +void HistoryModel::update(std::vector *items) +{ + if(current_items) { + delete current_items; + } + current_items = items; +} diff --git a/historymodel.h b/historymodel.h new file mode 100644 index 0000000..66e3b96 --- /dev/null +++ b/historymodel.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +struct HistoryItem { + int id = -1; + double timestamp = 0; + std::string method; + std::string scheme; + std::string host; + unsigned short port = 0; + std::string path; + int status_code = 0; + std::string reason; + double rtt = 0.0; + size_t size = 0; +}; + +class HistoryModel : public QAbstractTableModel +{ + Q_OBJECT +private: + std::vector* current_items = nullptr; +public: + HistoryModel(QObject *parent = nullptr); + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + void update(std::vector* items); +}; diff --git a/httpflow.h b/httpflow.h index 131e612..f64d328 100644 --- a/httpflow.h +++ b/httpflow.h @@ -131,20 +131,6 @@ struct Flow { Response response; }; -struct HistoryItem { - int id; - double timestamp; - std::string method; - std::string scheme; - std::string host; - unsigned short port; - std::string path; - int status_code; - std::string reason; - double rtt; - int size; -}; - inline void to_json(json& j, const Flow& flow) {} inline void from_json(const json& j, Flow& flow) { diff --git a/mainwindow.cpp b/mainwindow.cpp index feb16ac..5c0df19 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,5 +1,5 @@ #include "mainwindow.h" - +#include #include "./ui_mainwindow.h" #include #include "networkthread.h" @@ -21,19 +21,12 @@ MainWindow::MainWindow(QWidget *parent) connect(worker, SIGNAL (httpMessage(http::Flow)), this, SLOT (updateHistory()), Qt::QueuedConnection); thread->start(); + history_model.update(current_session->getHistoryItems()); + ui->setupUi(this); ui->historyHTTPTable->setShowGrid(true); ui->historyHTTPTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->historyHTTPTable->setColumnCount(7); - ui->historyHTTPTable->setRowCount(1); - - /* - ui->historyHTTPTable->setItem(0,0,new QTableWidgetItem(QString::number(data.index))); - ui->historyHTTPTable->setItem(0,1,new QTableWidgetItem(QString::fromStdString(data.method))); - ui->historyHTTPTable->setItem(0,2,new QTableWidgetItem(QString::fromStdString(data.url))); - ui->historyHTTPTable->setItem(0,3,new QTableWidgetItem(QString::number(data.ttl))); - ui->historyHTTPTable->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); -*/ + ui->historyHTTPTable->setModel(&history_model); } MainWindow::~MainWindow() @@ -42,28 +35,7 @@ MainWindow::~MainWindow() } void MainWindow::updateHistory() { - int i = 0; - auto items = current_session->getHistoryItems(); - for(auto& item : *items) { - ui->historyHTTPTable->setRowCount(i+1); - int j = 0; - ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(QString::number(item.id))); - QDateTime timestamp; - timestamp.setTime_t(item.timestamp); - ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(timestamp.toString(Qt::SystemLocaleShortDate))); - std::string url = item.scheme + "://" + item.host + ":" + std::to_string(item.port) + item.path; - ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(QString::fromStdString(url))); - ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(item.status_code)); - ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(QString::fromStdString(item.reason))); - ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(item.rtt)); - ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(item.size)); - i++; - } - delete items; - //ui->historyHTTPTable->setItem(0,0,new QTableWidgetItem(QString::fromStdString(flow.request.server_conn_id))); - //ui->historyHTTPTable->setItem(0,1,new QTableWidgetItem(QString::fromStdString(flow.request.method))); - //ui->historyHTTPTable->setItem(0,2,new QTableWidgetItem(QString::fromStdString(flow.request.host))); - //ui->historyHTTPTable->setItem(0,3,new QTableWidgetItem(QString::number(data.ttl))); + history_model.update(current_session->getHistoryItems()); ui->historyHTTPTable->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); } @@ -71,3 +43,7 @@ void MainWindow::on_searchEdit_textEdited(const QString &arg1) { emit updateHistory(); } + +void MainWindow::on_historyHTTPTable_cellClicked(int row, int column) +{ +} diff --git a/mainwindow.h b/mainwindow.h index e317664..ebfa2ba 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -18,6 +18,7 @@ private: Ui::MainWindow *ui; QThread* thread; Session* current_session; + HistoryModel history_model; public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); @@ -25,4 +26,5 @@ public slots: void updateHistory(); private slots: void on_searchEdit_textEdited(const QString &arg1); + void on_historyHTTPTable_cellClicked(int row, int column); }; diff --git a/mainwindow.ui b/mainwindow.ui index b599b4d..40596e4 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -73,7 +73,7 @@ 100 - + @@ -110,7 +110,7 @@ 200 - + @@ -163,7 +163,7 @@ 800 - 100 + 200 @@ -179,97 +179,93 @@ - - - - 9 - 40 - 769 - 109 - - - - true - - - QAbstractItemView::SelectRows - - - Qt::SolidLine - - - true - - - false - - - - - - 101 - 9 - 142 - 25 - - - - - - - 9 - 9 - 86 - 25 - - - - - 0 - 0 - - - - - all - + + + + + + 0 + 0 + + + + + all + + + + + ID + + + + + Method + + + + + URL + + + + + Code + + + + + Tags + + + - - - ID - + + - - - Method - + + + + + 0 + 0 + + + + + 300 + 0 + + + + + 1 + 0 + + + + true + + + QAbstractItemView::SelectRows + + + Qt::SolidLine + + + true + + + 19 + + - - - URL - - - - - Code - - - - - Tags - - - + - tabWidget - widget_2 - splitter_2 - widget - splitter @@ -277,7 +273,7 @@ 0 0 818 - 22 + 20 diff --git a/networkthread.h b/networkthread.h index d0d8bd8..a30104e 100644 --- a/networkthread.h +++ b/networkthread.h @@ -9,6 +9,7 @@ class NetworkThread : public QObject { Q_OBJECT private: + std::set received; zmq::context_t context; zmq::socket_t *socket; std::set accepted_flows; diff --git a/session.cpp b/session.cpp index 50f8d73..569e790 100644 --- a/session.cpp +++ b/session.cpp @@ -133,15 +133,16 @@ std::optional Session::getSetting(std::string key) { return std::nullopt; } -std::vector* Session::getHistoryItems() { +std::vector* Session::getHistoryItems() { + // todo check reset return code sqlite3_reset(stmt_get_all_history); - std::vector* result = new std::vector(); + std::vector* result = new std::vector(); auto rc = sqlite3_step(stmt_get_all_history); while(rc == SQLITE_ROW) { int j = 0; - http::HistoryItem i; + HistoryItem i; i.id = sqlite3_column_int(stmt_get_all_history, j++); i.timestamp = sqlite3_column_double(stmt_get_all_history, j++); i.method = std::string((const char*)sqlite3_column_text(stmt_get_all_history, j++)); diff --git a/session.h b/session.h index dd71a9a..2720297 100644 --- a/session.h +++ b/session.h @@ -3,6 +3,7 @@ #include #include #include +#include #include class Session : public QObject @@ -103,7 +104,7 @@ public: void unload(); bool isLoaded(); std::optional getSetting(std::string key); - std::vector* getHistoryItems(); + std::vector* getHistoryItems(); public slots: int saveRequest(http::Flow flow); int saveRequestHeader(std::string key, std::string value, int id); diff --git a/test.sh b/test.sh index fa74647..e555c56 100755 --- a/test.sh +++ b/test.sh @@ -1,19 +1,17 @@ #!/bin/sh -mitmdump -k -p 8888 -s mitmaddon/littlesnitch.py & +mitmdump -k -p 1878 -s mitmaddon/littlesnitch.py & +export mitmpid=$! ./build/littlesnitch & -sleep 1 -echo "sending requests" -curl -x http://localhost:8888 -k https://blog.fefe.de -curl -x http://localhost:8888 -k https://blog.fefe.de -curl -x http://localhost:8888 -k https://blog.fefe.de - -killall mitmdump -sleep 1 -killall mitmdump +sleep 5 +curl -x http://localhost:1878 -k https://yolo.jetzt sleep 2 -killall mitmdump -sleep 3 -killall mitmdump -killall mitmdump +curl -x http://localhost:1878 -k https://get.yolo.jetzt + +sleep 2 +kill -9 $mitmpid +kill -9 $mitmpid +sleep 2 +kill -9 $mitmpid +kill -9 $mitmpid