2020-09-10 19:26:41 +00:00
|
|
|
#pragma once
|
|
|
|
|
2021-03-03 16:12:12 +00:00
|
|
|
//major minor patch
|
|
|
|
#define LITTLESNITCH_VERSION 100
|
|
|
|
|
2020-09-10 19:26:41 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <map>
|
|
|
|
#include <vector>
|
|
|
|
#include <iostream>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <string>
|
|
|
|
|
2021-03-03 16:12:12 +00:00
|
|
|
#include <qdebug.h>
|
|
|
|
|
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
|
|
|
|
using json = nlohmann::json;
|
|
|
|
|
|
|
|
template<typename T, typename K>
|
|
|
|
bool json_get(json j, T& value, K key) noexcept {
|
|
|
|
try {
|
|
|
|
j[key].get_to(value);
|
|
|
|
return true;
|
|
|
|
} catch (nlohmann::detail::type_error& err) {
|
|
|
|
std::cout << "key " << key << " error " << err.what();
|
|
|
|
} catch (nlohmann::detail::out_of_range& err) {
|
|
|
|
std::cout << "key " << key << " error " << err.what();
|
|
|
|
} catch (nlohmann::detail::other_error& err) {
|
|
|
|
std::cout << "key " << key << " error " << err.what();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T, typename K, typename... Ks>
|
|
|
|
bool json_get(json j, T& value, K key, Ks... keys) noexcept {
|
|
|
|
try {
|
|
|
|
return json_get(j[key], value, keys...);
|
|
|
|
} catch (nlohmann::detail::type_error& err) {
|
|
|
|
std::cout << "key " << key << " error " << err.what();
|
|
|
|
} catch (nlohmann::detail::out_of_range& err) {
|
|
|
|
std::cout << "key " << key << " error " << err.what();
|
|
|
|
} catch (nlohmann::detail::other_error& err) {
|
|
|
|
std::cout << "key " << key << " error " << err.what();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-06 21:43:48 +00:00
|
|
|
//! represents one item in the http history.
|
2020-09-10 19:26:41 +00:00
|
|
|
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;
|
|
|
|
std::string request_http_version;
|
|
|
|
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::string response_content;
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace http {
|
|
|
|
|
|
|
|
struct Request
|
|
|
|
{
|
|
|
|
std::string server_ip_address;
|
|
|
|
|
|
|
|
bool tls;
|
|
|
|
std::string content;
|
|
|
|
std::string scheme;
|
|
|
|
std::string method;
|
|
|
|
std::string host;
|
|
|
|
unsigned short port;
|
|
|
|
std::string http_version;
|
|
|
|
std::string path;
|
|
|
|
double timestamp_start;
|
|
|
|
double timestamp_end;
|
|
|
|
std::vector<std::tuple<std::string,std::string>> headers;
|
|
|
|
|
|
|
|
std::string error;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Response {
|
|
|
|
int status_code;
|
|
|
|
std::string http_version;
|
|
|
|
std::string reason;
|
|
|
|
std::string content;
|
|
|
|
double timestamp_start;
|
|
|
|
double timestamp_end;
|
|
|
|
std::vector<std::tuple<std::string,std::string>> headers;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Flow {
|
|
|
|
std::string uid;
|
|
|
|
Request request;
|
|
|
|
Response response;
|
|
|
|
};
|
|
|
|
|
2021-03-19 16:40:33 +00:00
|
|
|
|
|
|
|
inline void to_json(json& j, const Flow& flow) {}
|
|
|
|
|
|
|
|
inline void from_json(const json& j, Flow& flow) {
|
|
|
|
//std::cout << std::setw(4) << j << "\n\n";
|
|
|
|
json j_flow;
|
|
|
|
if(!json_get(j, j_flow, "flow")) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
json_get(j_flow, flow.uid, "id");
|
|
|
|
if(json j_request; json_get(j_flow, j_request, "request")) {
|
|
|
|
json_get(j_request, flow.request.tls, "server_conn", "tls_established");
|
|
|
|
json_get(j_request, flow.request.port, "port");
|
|
|
|
json_get(j_request, flow.request.host, "host");
|
|
|
|
json_get(j_request, flow.request.scheme, "scheme");
|
|
|
|
json_get(j_request, flow.request.path, "path");
|
|
|
|
json_get(j_request, flow.request.content, "content");
|
|
|
|
json_get(j_request, flow.request.method, "method");
|
|
|
|
json_get(j_request, flow.request.http_version, "http_version");
|
|
|
|
json_get(j_request, flow.request.timestamp_start, "timestamp_start");
|
|
|
|
json_get(j_request, flow.request.timestamp_end, "timestamp_end");
|
|
|
|
|
|
|
|
json j_headers;
|
|
|
|
if(json_get(j_request, j_headers, "headers")) {
|
|
|
|
for(auto& [k,v] : j_headers.items()) {
|
|
|
|
flow.request.headers.push_back(std::make_tuple(v.at(0), v.at(1)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(json j_response; json_get(j_flow, j_response, "response")) {
|
|
|
|
json_get(j_response, flow.response.status_code, "status_code");
|
|
|
|
json_get(j_response, flow.response.http_version, "http_version");
|
|
|
|
json_get(j_response, flow.response.reason, "reason");
|
|
|
|
json_get(j_response, flow.response.content, "content");
|
|
|
|
json_get(j_response, flow.response.timestamp_start, "timestamp_start");
|
|
|
|
json_get(j_response, flow.response.timestamp_end, "timestamp_end");
|
|
|
|
|
|
|
|
json j_headers;
|
|
|
|
if(json_get(j_response, j_headers, "headers")) {
|
|
|
|
for(auto& [k,v] : j_headers.items()) {
|
|
|
|
flow.response.headers.push_back(std::make_tuple(v.at(0), v.at(1)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-10 19:26:41 +00:00
|
|
|
}
|
2021-03-19 16:40:33 +00:00
|
|
|
|
|
|
|
Q_DECLARE_METATYPE(http::Flow)
|