#include "session.h" Session::Session(QObject *parent) : QObject(parent) { } Session::~Session() { unload(); } void Session::open_db(std::filesystem::path path) { if(db) { unload(); } auto rc = sqlite3_open(path.c_str(), &db); if(rc != SQLITE_OK) { qDebug("cannot open database"); qDebug() << sqlite3_errmsg(db); unload(); throw; } } void Session::prepare(const char* query, sqlite3_stmt** stmt) { auto rc = sqlite3_prepare_v2(db, query, strlen(query), stmt, 0); if(rc != SQLITE_OK) { qDebug() << "cannot prepare statement"; qDebug() << query; qDebug() << sqlite3_errmsg(db); unload(); throw; } } bool Session::prepare_and_exec(const char* query) { sqlite3_stmt* res; prepare(query, &res); bool result = sqlite3_step(res)==SQLITE_OK; sqlite3_finalize(res); return result; } void Session::prepare_tables() { sqlite3_stmt* res; prepare(check_tbl, &res); auto s = "session"; sqlite3_bind_text(res, 1, s, strlen(s), nullptr); auto rc = sqlite3_step(res); sqlite3_finalize(res); if(rc == SQLITE_ROW) { prepare(check_session_info, &res); auto v = "version"; sqlite3_bind_text(res, 1, v, strlen(v), nullptr); rc = sqlite3_step(res); if(rc == SQLITE_ROW) { const char* version = (const char*)sqlite3_column_text(res, 1); if(std::atoi(version) != LITTLESNITCH_VERSION) { qDebug() << "version " << version << " is not supported!"; unload(); throw; } qDebug() << "loaded session with version " << version; sqlite3_finalize(res); return; } else { qDebug("broken database, was not able to check session info"); qDebug() << sqlite3_errmsg(db); unload(); throw; } } prepare_and_exec(create_request_tbl); prepare_and_exec(create_request_header_tbl); prepare_and_exec(create_response_tbl); prepare_and_exec(create_response_header_tbl); 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); prepare(insert_response_header, &stmt_insert_response_header); prepare(insert_flow, &stmt_insert_flow); prepare(insert_session, &stmt_insert_session); } void Session::load(std::filesystem::path path) { open_db(path); prepare_tables(); loaded = true; } void Session::unload() { if(db) { sqlite3_close(db); } loaded = false; } bool Session::isLoaded() { return loaded; } void Session::bind_text(sqlite3_stmt* stmt, int id, std::string text) { qDebug() << id << " " << text.c_str() << " " << strlen(text.c_str()); sqlite3_bind_text(stmt, id, text.c_str(), -1, SQLITE_TRANSIENT); } void Session::saveRequest(http::Flow flow) { bind_text(stmt_insert_request, 1, flow.request.server_conn_id); bind_text(stmt_insert_request, 2, flow.request.server_ip_address); sqlite3_bind_int(stmt_insert_request, 3, flow.request.tls); bind_text(stmt_insert_request, 4, flow.request.content); bind_text(stmt_insert_request, 5, flow.request.scheme); bind_text(stmt_insert_request, 6, flow.request.method); bind_text(stmt_insert_request, 7, flow.request.host); bind_text(stmt_insert_request, 8, flow.request.address); sqlite3_bind_int(stmt_insert_request, 9, flow.request.port); bind_text(stmt_insert_request, 10, flow.request.http_version); bind_text(stmt_insert_request, 11, flow.request.path); sqlite3_bind_double(stmt_insert_request, 12, flow.request.timestamp_start); sqlite3_bind_double(stmt_insert_request, 13, flow.request.timestamp_end); bind_text(stmt_insert_request, 14, 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); throw; } } void Session::saveResponse(http::Flow flow) { throw; }