stuff
This commit is contained in:
parent
741d5d96b2
commit
aab0f45d61
7 changed files with 105 additions and 8 deletions
|
@ -2,6 +2,26 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
|
std::string HistoryModel::getRequestHeader(const HistoryItem &item) const
|
||||||
|
{
|
||||||
|
std::stringstream result;
|
||||||
|
result << item.method << " " << item.scheme << "://" << item.host << item.path << " " << item.request_http_version << "\n";
|
||||||
|
for(auto& [k,v] : item.request_headers) {
|
||||||
|
result << k << ": " << v << "\n";
|
||||||
|
}
|
||||||
|
return result.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string HistoryModel::getResponseHeader(const HistoryItem &item) const
|
||||||
|
{
|
||||||
|
std::stringstream result;
|
||||||
|
result << item.response_http_version << " " << item.status_code << " " << item.reason << "\n";
|
||||||
|
for(auto& [k,v] : item.response_headers) {
|
||||||
|
result << k << ": " << v << "\n";
|
||||||
|
}
|
||||||
|
return result.str();
|
||||||
|
}
|
||||||
|
|
||||||
HistoryModel::HistoryModel(QObject *parent)
|
HistoryModel::HistoryModel(QObject *parent)
|
||||||
{
|
{
|
||||||
Q_UNUSED(parent);
|
Q_UNUSED(parent);
|
||||||
|
@ -21,7 +41,7 @@ int HistoryModel::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(parent);
|
Q_UNUSED(parent);
|
||||||
|
|
||||||
return 7;
|
return 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant HistoryModel::data(const QModelIndex &index, int role) const
|
QVariant HistoryModel::data(const QModelIndex &index, int role) const
|
||||||
|
@ -64,6 +84,18 @@ QVariant HistoryModel::data(const QModelIndex &index, int role) const
|
||||||
case 6:{
|
case 6:{
|
||||||
return QString::number(item.size);
|
return QString::number(item.size);
|
||||||
}
|
}
|
||||||
|
case 7:{
|
||||||
|
return QString::fromStdString(getRequestHeader(item));
|
||||||
|
}
|
||||||
|
case 8:{
|
||||||
|
return QString::fromStdString(item.request_content);
|
||||||
|
}
|
||||||
|
case 9:{
|
||||||
|
return QString::fromStdString(getResponseHeader(item));
|
||||||
|
}
|
||||||
|
case 10:{
|
||||||
|
return QString::fromStdString(item.response_content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw std::out_of_range("history model col");
|
throw std::out_of_range("history model col");
|
||||||
} catch (std::out_of_range const& exc) {
|
} catch (std::out_of_range const& exc) {
|
||||||
|
@ -101,6 +133,18 @@ QVariant HistoryModel::headerData(int section, Qt::Orientation orientation, int
|
||||||
case 6: {
|
case 6: {
|
||||||
return "size";
|
return "size";
|
||||||
}
|
}
|
||||||
|
case 7: {
|
||||||
|
return "request headers";
|
||||||
|
}
|
||||||
|
case 8: {
|
||||||
|
return "request content";
|
||||||
|
}
|
||||||
|
case 9: {
|
||||||
|
return "response headers";
|
||||||
|
}
|
||||||
|
case 10: {
|
||||||
|
return "response content";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
|
@ -16,10 +16,12 @@ struct HistoryItem {
|
||||||
std::string reason;
|
std::string reason;
|
||||||
double rtt = 0.0;
|
double rtt = 0.0;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
std::string request_content;
|
std::string request_http_version;
|
||||||
std::string response_content;
|
|
||||||
std::map<std::string, std::string> request_headers;
|
std::map<std::string, std::string> request_headers;
|
||||||
|
std::string request_content;
|
||||||
|
std::string response_http_version;
|
||||||
std::map<std::string, std::string> response_headers;
|
std::map<std::string, std::string> response_headers;
|
||||||
|
std::string response_content;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HistoryModel : public QAbstractTableModel
|
class HistoryModel : public QAbstractTableModel
|
||||||
|
@ -28,6 +30,8 @@ class HistoryModel : public QAbstractTableModel
|
||||||
private:
|
private:
|
||||||
mutable std::mutex history_mutex;
|
mutable std::mutex history_mutex;
|
||||||
std::vector<HistoryItem>* current_items = nullptr;
|
std::vector<HistoryItem>* current_items = nullptr;
|
||||||
|
std::string getRequestHeader(const HistoryItem& item) const;
|
||||||
|
std::string getResponseHeader(const HistoryItem& item) const;
|
||||||
public:
|
public:
|
||||||
HistoryModel(QObject *parent = nullptr);
|
HistoryModel(QObject *parent = nullptr);
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
|
|
@ -45,9 +45,14 @@ void MainWindow::updateHistory() {
|
||||||
void MainWindow::on_selectionChange(const QItemSelection &selection)
|
void MainWindow::on_selectionChange(const QItemSelection &selection)
|
||||||
{
|
{
|
||||||
if(!selection.indexes().isEmpty()) {
|
if(!selection.indexes().isEmpty()) {
|
||||||
auto index = selection.indexes().value(0);
|
auto index = selection.indexes().at(7);
|
||||||
qDebug() << history_proxy.itemData(index)[0].toInt();
|
ui->textEdit->setText(history_proxy.data(index).toString());
|
||||||
//ui->textEdit->setText();
|
index = selection.indexes().at(8);
|
||||||
|
ui->textEdit_2->setText(history_proxy.data(index).toString());
|
||||||
|
index = selection.indexes().at(9);
|
||||||
|
ui->textEdit_3->setText(history_proxy.data(index).toString());
|
||||||
|
index = selection.indexes().at(10);
|
||||||
|
ui->textEdit_4->setText(history_proxy.data(index).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,13 +85,37 @@ class LittleSnitchBridge:
|
||||||
self.q = Queue()
|
self.q = Queue()
|
||||||
self.thread = NetworkThread("network", self.q)
|
self.thread = NetworkThread("network", self.q)
|
||||||
self.thread.start()
|
self.thread.start()
|
||||||
|
|
||||||
def request(self, flow):
|
def request(self, flow):
|
||||||
self.q.put({'msg': 'request', 'flow': flow.get_state()})
|
self.q.put({'msg': 'request', 'flow': flow.get_state()})
|
||||||
|
|
||||||
|
def requestheaders(self, flow):
|
||||||
|
self.q.put({'msg': 'requestheaders', 'flow': flow.get_state()})
|
||||||
|
|
||||||
def response(self, flow):
|
def response(self, flow):
|
||||||
self.q.put({'msg': 'response', 'flow': flow.get_state()})
|
self.q.put({'msg': 'response', 'flow': flow.get_state()})
|
||||||
|
|
||||||
|
def responseheaders(self, flow):
|
||||||
|
self.q.put({'msg': 'responseheaders', 'flow': flow.get_state()})
|
||||||
|
|
||||||
|
def error(self, flow):
|
||||||
|
self.q.put({'msg': 'error', 'flow': flow.get_state()})
|
||||||
|
|
||||||
|
def websocket_handshake(self):
|
||||||
|
self.q.put({'msg': 'websocket_handshake', 'flow': flow.get_state()})
|
||||||
|
|
||||||
|
def websocket_start(self, flow):
|
||||||
|
self.q.put({'msg': 'websocket_start', 'flow': flow.get_state()})
|
||||||
|
|
||||||
|
def websocket_message(self, flow):
|
||||||
|
self.q.put({'msg': 'websocket_message', 'flow': flow.get_state()})
|
||||||
|
|
||||||
|
def websocket_error(self, flow):
|
||||||
|
self.q.put({'msg': 'websocket_error', 'flow': flow.get_state()})
|
||||||
|
|
||||||
|
def websocket_end(self, flow):
|
||||||
|
self.q.put({'msg': 'websocket_end', 'flow': flow.get_state()})
|
||||||
|
|
||||||
addons = [
|
addons = [
|
||||||
LittleSnitchBridge()
|
LittleSnitchBridge()
|
||||||
]
|
]
|
||||||
|
|
|
@ -51,13 +51,31 @@ void NetworkThread::process() {
|
||||||
std::string msg_type;
|
std::string msg_type;
|
||||||
if(!json_get(j, msg_type, "msg")) {
|
if(!json_get(j, msg_type, "msg")) {
|
||||||
qDebug() << "broken message received " << response.to_string().c_str();
|
qDebug() << "broken message received " << response.to_string().c_str();
|
||||||
|
} else if(msg_type == "responseheaders") {
|
||||||
|
qDebug() << "received " << msg_type.c_str();
|
||||||
} else if(msg_type == "response") {
|
} else if(msg_type == "response") {
|
||||||
qDebug() << "received " << msg_type.c_str();
|
qDebug() << "received " << msg_type.c_str();
|
||||||
emit httpMessage(j);
|
emit httpMessage(j);
|
||||||
|
} else if(msg_type == "requestheaders") {
|
||||||
|
qDebug() << "received " << msg_type.c_str();
|
||||||
} else if(msg_type == "request") {
|
} else if(msg_type == "request") {
|
||||||
qDebug() << "received " << msg_type.c_str();
|
qDebug() << "received " << msg_type.c_str();
|
||||||
} else if(msg_type == "ping") {
|
} else if(msg_type == "ping") {
|
||||||
qDebug() << "received " << msg_type.c_str();
|
qDebug() << "received " << msg_type.c_str();
|
||||||
|
} else if(msg_type == "error") {
|
||||||
|
qDebug() << "received " << msg_type.c_str();
|
||||||
|
|
||||||
|
// websocket events
|
||||||
|
} else if(msg_type == "websocket_handshake") {
|
||||||
|
qDebug() << "received " << msg_type.c_str();
|
||||||
|
} else if(msg_type == "websocket_start") {
|
||||||
|
qDebug() << "received " << msg_type.c_str();
|
||||||
|
std::cout << std::setw(4) << j << "\n\n";
|
||||||
|
} else if(msg_type == "websocket_message") {
|
||||||
|
qDebug() << "received " << msg_type.c_str();
|
||||||
|
} else if(msg_type == "websocket_end") {
|
||||||
|
qDebug() << "received " << msg_type.c_str();
|
||||||
|
} else if(msg_type == "websocket_error") {
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "unknown or broken message type received: " << msg_type.c_str();
|
qDebug() << "unknown or broken message type received: " << msg_type.c_str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,9 @@ std::vector<HistoryItem>* Session::getHistoryItems() {
|
||||||
i.reason = std::string((const char*)sqlite3_column_text(stmt_get_all_history, j++));
|
i.reason = std::string((const char*)sqlite3_column_text(stmt_get_all_history, j++));
|
||||||
i.rtt = sqlite3_column_double(stmt_get_all_history, j++);
|
i.rtt = sqlite3_column_double(stmt_get_all_history, j++);
|
||||||
i.size = sqlite3_column_int(stmt_get_all_history, j++);
|
i.size = sqlite3_column_int(stmt_get_all_history, j++);
|
||||||
|
i.request_http_version = std::string((const char*)sqlite3_column_text(stmt_get_all_history, j++));
|
||||||
i.request_content = std::string((const char*)sqlite3_column_text(stmt_get_all_history, j++));
|
i.request_content = std::string((const char*)sqlite3_column_text(stmt_get_all_history, j++));
|
||||||
|
i.response_http_version = std::string((const char*)sqlite3_column_text(stmt_get_all_history, j++));
|
||||||
i.response_content = std::string((const char*)sqlite3_column_text(stmt_get_all_history, j++));
|
i.response_content = std::string((const char*)sqlite3_column_text(stmt_get_all_history, j++));
|
||||||
i.request_headers = getRequestHeader(i.id);
|
i.request_headers = getRequestHeader(i.id);
|
||||||
i.response_headers = getResponseHeader(i.id);
|
i.response_headers = getResponseHeader(i.id);
|
||||||
|
|
|
@ -66,7 +66,7 @@ private:
|
||||||
const char* get_setting = R"rstr( SELECT value FROM setting WHERE key=?; )rstr";
|
const char* get_setting = R"rstr( SELECT value FROM setting WHERE key=?; )rstr";
|
||||||
const char* get_request_headers = R"rstr( SELECT * FROM response_header WHERE response_id=?; )rstr";
|
const char* get_request_headers = R"rstr( SELECT * FROM response_header WHERE response_id=?; )rstr";
|
||||||
const char* get_response_headers = R"rstr( SELECT * FROM request_header WHERE request_id=?; )rstr";
|
const char* get_response_headers = R"rstr( SELECT * FROM request_header WHERE request_id=?; )rstr";
|
||||||
const char* get_all_history = R"rstr( SELECT f.id,req.timestamp_start,req.method,req.scheme,req.host,req.port,req.path,res.status_code,res.reason,res.timestamp_end-res.timestamp_start,length(res.content),req.content,res.content FROM flow f JOIN request req ON f.request_id=req.id JOIN response res ON f.response_id=res.id; )rstr";
|
const char* get_all_history = R"rstr( SELECT f.id,req.timestamp_start,req.method,req.scheme,req.host,req.port,req.path,res.status_code,res.reason,res.timestamp_end-res.timestamp_start,length(res.content),req.http_version,req.content,res.http_version,res.content FROM flow f JOIN request req ON f.request_id=req.id JOIN response res ON f.response_id=res.id; )rstr";
|
||||||
|
|
||||||
const char* insert_request = R"rstr( INSERT INTO request (server_ip_address, tls, content, scheme, method, host, port, http_version, path, timestamp_start, timestamp_end, error) VALUES (?,?,?,?,?,?,?,?,?,?,?,?); )rstr";
|
const char* insert_request = R"rstr( INSERT INTO request (server_ip_address, tls, content, scheme, method, host, port, http_version, path, timestamp_start, timestamp_end, error) VALUES (?,?,?,?,?,?,?,?,?,?,?,?); )rstr";
|
||||||
const char* insert_request_header = R"rstr( INSERT INTO request_header (key, value, request_id) VALUES (?,?,?); )rstr";
|
const char* insert_request_header = R"rstr( INSERT INTO request_header (key, value, request_id) VALUES (?,?,?); )rstr";
|
||||||
|
|
Loading…
Reference in a new issue