From e2d1cdfede38e34866c07af8d1b517e714f55794 Mon Sep 17 00:00:00 2001 From: End Date: Tue, 18 Aug 2020 15:13:45 +0200 Subject: [PATCH] completed dumping of relevant attributes --- httpflow.h | 48 ++++++++++++++++++------ mainwindow.cpp | 4 +- session.cpp | 100 +++++++++++++++++++++++++++++++++++++++++-------- session.h | 10 ++--- 4 files changed, 128 insertions(+), 34 deletions(-) diff --git a/httpflow.h b/httpflow.h index bbce0bc..b9bf209 100644 --- a/httpflow.h +++ b/httpflow.h @@ -139,22 +139,46 @@ inline void from_json(const json& j, Flow& flow) { if(!j.contains("flow")) { return; } + auto j_flow = j.at("flow"); - j.at("flow").at("id").get_to(flow.id); + j_flow.at("id").get_to(flow.uid); - if(j.at("flow").contains("server_conn")) { - j.at("flow").at("server_conn").at("tls_established").get_to(flow.request.tls); + if(j_flow.contains("server_conn")) { + j_flow.at("server_conn").at("tls_established").get_to(flow.request.tls); } - if(j.at("flow").contains("request")) { - j.at("flow").at("request").at("port").get_to(flow.request.port); - j.at("flow").at("request").at("host").get_to(flow.request.host); - j.at("flow").at("request").at("scheme").get_to(flow.request.scheme); - j.at("flow").at("request").at("path").get_to(flow.request.path); - j.at("flow").at("request").at("content").get_to(flow.request.content); - j.at("flow").at("request").at("method").get_to(flow.request.method); - j.at("flow").at("request").at("http_version").get_to(flow.request.http_version); + // todo might crash with fabricated/missing json, add parser exception handling + if(j_flow.contains("request")) { + auto j_request = j_flow.at("request"); - //j.at("server_conn").at("address").get_to(flow.server_conn_address); + j_request.at("port").get_to(flow.request.port); + j_request.at("host").get_to(flow.request.host); + j_request.at("scheme").get_to(flow.request.scheme); + j_request.at("path").get_to(flow.request.path); + j_request.at("content").get_to(flow.request.content); + j_request.at("method").get_to(flow.request.method); + j_request.at("http_version").get_to(flow.request.http_version); + j_request.at("timestamp_start").get_to(flow.request.timestamp_start); + j_request.at("timestamp_end").get_to(flow.request.timestamp_end); + + auto j_headers = j_request.at("headers"); + for(auto& [k,v] : j_headers.items()) { + flow.request.headers.push_back(std::make_tuple(v.at(0), v.at(1))); + } + } + if(j_flow.contains("response")) { + auto j_response = j_flow.at("response"); + + j_response.at("status_code").get_to(flow.response.status_code); + j_response.at("http_version").get_to(flow.response.http_version); + j_response.at("reason").get_to(flow.response.reason); + j_response.at("content").get_to(flow.response.content); + j_response.at("timestamp_start").get_to(flow.response.timestamp_start); + j_response.at("timestamp_end").get_to(flow.response.timestamp_end); + + auto j_headers = j_response.at("headers"); + for(auto& [k,v] : j_headers.items()) { + flow.response.headers.push_back(std::make_tuple(v.at(0), v.at(1))); + } } } diff --git a/mainwindow.cpp b/mainwindow.cpp index ec61810..74bae7f 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -17,7 +17,7 @@ MainWindow::MainWindow(QWidget *parent) worker->moveToThread(thread); connect(thread, SIGNAL (started()), worker, SLOT (process())); //connect(worker, SIGNAL (error(QString)), this, SLOT (errorString(QString))); - connect(worker, SIGNAL (httpMessage(http::Flow)), current_session, SLOT (saveRequest(http::Flow)), Qt::QueuedConnection); + connect(worker, SIGNAL (httpMessage(http::Flow)), current_session, SLOT (saveFlow(http::Flow)), Qt::QueuedConnection); connect(worker, SIGNAL (httpMessage(http::Flow)), this, SLOT (updateHistory()), Qt::QueuedConnection); thread->start(); @@ -46,7 +46,7 @@ void MainWindow::updateHistory() { //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))); - //ui->historyHTTPTable->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); + ui->historyHTTPTable->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); } void MainWindow::on_searchEdit_textEdited(const QString &arg1) diff --git a/session.cpp b/session.cpp index 420a978..f704fd7 100644 --- a/session.cpp +++ b/session.cpp @@ -84,7 +84,6 @@ void Session::prepare_tables() { prepare_and_exec(create_flow_tbl); prepare_and_exec(create_session_tbl); - prepare(last_inserted_id, &stmt_last_inserted_id); prepare(insert_request, &stmt_insert_request); prepare(insert_request_header, &stmt_insert_request_header); prepare(insert_response, &stmt_insert_response); @@ -112,22 +111,13 @@ bool Session::isLoaded() { } void Session::bind_text(sqlite3_stmt* stmt, int id, std::string text) { - qDebug() << id << " " << text.c_str() << " " << strlen(text.c_str()); + //qDebug() << id << " " << text.c_str() << " " << strlen(text.c_str()); sqlite3_bind_text(stmt, id, text.c_str(), -1, SQLITE_TRANSIENT); } -int Session::get_last_id() { - auto rc = sqlite3_step(stmt_insert_request); - sqlite3_reset(stmt_insert_request); - if(rc != SQLITE_DONE) { - qDebug() << "error getting last id" << rc; - qDebug() << sqlite3_errmsg(db); - return -1; - } - return -1; -} - int Session::saveRequest(http::Flow flow) { + sqlite3_reset(stmt_insert_request); + int j = 1; bind_text(stmt_insert_request, j++, flow.request.server_ip_address); @@ -150,23 +140,103 @@ int Session::saveRequest(http::Flow flow) { bind_text(stmt_insert_request, j++, flow.request.error); auto rc = sqlite3_step(stmt_insert_request); - sqlite3_reset(stmt_insert_request); if(rc != SQLITE_DONE) { qDebug() << "inserting request failed" << rc; qDebug() << sqlite3_errmsg(db); return -1; } + int id = sqlite3_last_insert_rowid(db); + for(auto&[k,v] : flow.request.headers) { + saveRequestHeader(k,v,id); + } + return id; +} + +int Session::saveRequestHeader(std::string key, std::string value, int id) { + sqlite3_reset(stmt_insert_request_header); + + int j = 1; + + bind_text(stmt_insert_request_header, j++, key); + bind_text(stmt_insert_request_header, j++, value); + sqlite3_bind_int(stmt_insert_request_header, j++, id); + + auto rc = sqlite3_step(stmt_insert_request_header); + if(rc != SQLITE_DONE) { + qDebug() << "inserting request header failed" << rc; + qDebug() << sqlite3_errmsg(db); + return -1; + } + + return sqlite3_last_insert_rowid(db); } int Session::saveResponse(http::Flow flow) { + sqlite3_reset(stmt_insert_response); + + int j = 1; + + sqlite3_bind_int(stmt_insert_response, j++, flow.response.status_code); + bind_text(stmt_insert_response, j++, flow.response.http_version); + bind_text(stmt_insert_response, j++, flow.response.reason); + bind_text(stmt_insert_response, j++, flow.response.content); + + sqlite3_bind_double(stmt_insert_response, j++, flow.response.timestamp_start); + sqlite3_bind_double(stmt_insert_response, j++, flow.response.timestamp_end); auto rc = sqlite3_step(stmt_insert_response); - sqlite3_reset(stmt_insert_response); if(rc != SQLITE_DONE) { qDebug() << "inserting response failed" << rc; qDebug() << sqlite3_errmsg(db); return -1; } + int id = sqlite3_last_insert_rowid(db); + + for(auto&[k,v] : flow.response.headers) { + saveResponseHeader(k,v,id); + } + + return id; +} + +int Session::saveResponseHeader(std::string key, std::string value, int id) { + sqlite3_reset(stmt_insert_response_header); + + int j = 1; + + bind_text(stmt_insert_response_header, j++, key); + bind_text(stmt_insert_response_header, j++, value); + sqlite3_bind_int(stmt_insert_response_header, j++, id); + + auto rc = sqlite3_step(stmt_insert_response_header); + if(rc != SQLITE_DONE) { + qDebug() << "inserting response header failed" << rc; + qDebug() << sqlite3_errmsg(db); + return -1; + } + + return sqlite3_last_insert_rowid(db); +} + +int Session::saveFlow(http::Flow flow) { + int request_id = saveRequest(flow); + int response_id = saveResponse(flow); + + int j = 1; + + bind_text(stmt_insert_flow, j++, flow.uid); + sqlite3_bind_int(stmt_insert_flow, j++, request_id); + sqlite3_bind_int(stmt_insert_flow, j++, response_id); + + auto rc = sqlite3_step(stmt_insert_flow); + sqlite3_reset(stmt_insert_flow); + if(rc != SQLITE_DONE) { + qDebug() << "inserting flow failed" << rc; + qDebug() << sqlite3_errmsg(db); + return -1; + } + + return sqlite3_last_insert_rowid(db); } diff --git a/session.h b/session.h index a1d9379..e5ca9fc 100644 --- a/session.h +++ b/session.h @@ -60,20 +60,18 @@ private: key TEXT UNIQUE NOT NULL PRIMARY KEY, value TEXT ); )rstr"; - const char* last_inserted_id = R"rstr( SELECT last_insert_rowid(); )rstr"; const char* check_tbl = R"rstr( SELECT name FROM sqlite_master WHERE type='table' AND name=?; )rstr"; const char* check_session_info = R"rstr( SELECT value FROM session WHERE key=?; )rstr"; - const char* insert_request = R"rstr( INSERT INTO request (server_ip_address, tls, content, scheme, method, host, address, 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, address, 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_response = R"rstr( INSERT INTO response (status_code, http_version, reason, content, timestamp_start, timestamp_end) VALUES (?,?,?,?,?,?); )rstr"; const char* insert_response_header = R"rstr( INSERT INTO response_header (key, value, response_id) VALUES (?,?,?); )rstr"; - const char* insert_flow = R"rstr( INSERT INTO flow (request_id, response_id) VALUES (?,?); )rstr"; + const char* insert_flow = R"rstr( INSERT INTO flow (uid, request_id, response_id) VALUES (?,?,?); )rstr"; const char* insert_session = R"rstr( INSERT INTO session (key, value) VALUES (?,?); )rstr"; sqlite3* db = nullptr; bool loaded = false; - sqlite3_stmt* stmt_last_inserted_id = nullptr; sqlite3_stmt* stmt_insert_request = nullptr; sqlite3_stmt* stmt_insert_request_header = nullptr; sqlite3_stmt* stmt_insert_response = nullptr; @@ -86,7 +84,6 @@ private: void prepare(const char* query, sqlite3_stmt** stmt); bool prepare_and_exec(const char* query); void bind_text(sqlite3_stmt* stmt, int id, std::string text); - int get_last_id(); public: explicit Session(QObject *parent = nullptr); ~Session(); @@ -96,7 +93,10 @@ public: bool isLoaded(); public slots: int saveRequest(http::Flow flow); + int saveRequestHeader(std::string key, std::string value, int id); int saveResponse(http::Flow flow); + int saveResponseHeader(std::string key, std::string value, int id); + int saveFlow(http::Flow flow); signals: };