Everything has basically been implemented.

This commit is contained in:
Rasmus Rasmussen 2025-05-19 21:16:38 +02:00
parent 4cec4644fa
commit 5ca72cad99
10 changed files with 108 additions and 125 deletions

View File

@ -48,10 +48,10 @@ cmake_force:
SHELL = /bin/sh SHELL = /bin/sh
# The CMake executable. # The CMake executable.
CMAKE_COMMAND = "/home/skingging/Tar Apps/clion-2025.1.1/bin/cmake/linux/x64/bin/cmake" CMAKE_COMMAND = /usr/bin/cmake
# The command to remove a file. # The command to remove a file.
RM = "/home/skingging/Tar Apps/clion-2025.1.1/bin/cmake/linux/x64/bin/cmake" -E rm -f RM = /usr/bin/cmake -E rm -f
# Escaping for special characters. # Escaping for special characters.
EQUALS = = EQUALS = =
@ -78,7 +78,7 @@ edit_cache/fast: edit_cache
# Special rule for the target rebuild_cache # Special rule for the target rebuild_cache
rebuild_cache: rebuild_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake to regenerate build system..." @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake to regenerate build system..."
"/home/skingging/Tar Apps/clion-2025.1.1/bin/cmake/linux/x64/bin/cmake" --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) /usr/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache .PHONY : rebuild_cache
# Special rule for the target rebuild_cache # Special rule for the target rebuild_cache

View File

@ -17,18 +17,4 @@ struct MetricsExporter {
static void send_data(int client_fd, const string& data); static void send_data(int client_fd, const string& data);
}; };
const string HTML_RESPONSE_HEADER_lol =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=utf-8\r\n"
"Transfer-Encoding: chunked\r\n"
//"Cache-control: max-age=12000\r\n"
"Connection: close\r\n\r\n";
const string BEGINNING =
"<!DOCTYPE html>\n<html><head>\r\n"
"<title>Drip</title>\r\n"
"</head><body>\r\n";
const string END = "</body></html>\r\n";
#endif #endif

14
include/Options.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef OPTIONS_H
#define OPTIONS_H
#include <string>
using namespace std;
class Options {
public:
string word_lists;
string images;
string css;
};
#endif

View File

@ -6,17 +6,17 @@
#include "../include/DataType.h" #include "../include/DataType.h"
#include "../include/Track.h" #include "../include/Track.h"
#include "../include/ConcurrentQueue.h" #include "../include/ConcurrentQueue.h"
#include "../include/Options.h"
using namespace std; using namespace std;
class ServerUtils { class ServerUtils {
public: public:
static void serve(shared_ptr<ConcurrentQueue<Track>> cq_track); static void serve(shared_ptr<ConcurrentQueue<Track>> cq_track, const Options& options);
private: private:
static void process_request(int client_fd); static void process_request(int client_fd);
static void send_header(int client_fd, data_type type); static void send_html(int client_fd, size_t hash);
static void send_chunked_html(int client_fd, size_t hash); static void send_css(int client_fd);
static void send_chunked_css(int client_fd);
static void send_data(int client_fd, const string& data); static void send_data(int client_fd, const string& data);
static void send_image(int client_fd, const string& path, image_type type); static void send_image(int client_fd, const string& path, image_type type);
static size_t send_all(int client_fd, const char* data, size_t length); static size_t send_all(int client_fd, const char* data, size_t length);
@ -26,14 +26,12 @@ class ServerUtils {
const string HTML_RESPONSE_HEADER = const string HTML_RESPONSE_HEADER =
"HTTP/1.1 200 OK\r\n" "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=utf-8\r\n" "Content-Type: text/html; charset=utf-8\r\n"
"Transfer-Encoding: chunked\r\n"
"Cache-control: max-age=12000\r\n" "Cache-control: max-age=12000\r\n"
"Connection: close\r\n\r\n"; "Connection: close\r\n\r\n";
const string CSS_RESPONSE_HEADER = const string CSS_RESPONSE_HEADER =
"HTTP/1.1 200 OK\r\n" "HTTP/1.1 200 OK\r\n"
"Content-Type: text/css; charset=utf-8\r\n" "Content-Type: text/css; charset=utf-8\r\n"
"Transfer-Encoding: chunked\r\n"
"Cache-control: max-age=12000\r\n" "Cache-control: max-age=12000\r\n"
"Connection: close\r\n\r\n"; "Connection: close\r\n\r\n";

View File

@ -10,7 +10,7 @@ using namespace std;
struct WordUtils { struct WordUtils {
static unordered_map<string, unordered_map<string, int>> load_data(const string& path); static unordered_map<string, unordered_map<string, int>> load_data(const string& path);
static vector<string> load_css(const string& path); static string load_css(const string& path);
static vector<string> predict_next_word(const string& input, const unordered_map<string, unordered_map<string, int>>& word_frequencies, size_t count); static vector<string> predict_next_word(const string& input, const unordered_map<string, unordered_map<string, int>>& word_frequencies, size_t count);
static vector<string> predict_next_word_2(const string& input, const unordered_map<string, unordered_map<string, int>>& word_frequencies, size_t count); static vector<string> predict_next_word_2(const string& input, const unordered_map<string, unordered_map<string, int>>& word_frequencies, size_t count);
static string load_file(const string& path); static string load_file(const string& path);

View File

@ -34,7 +34,7 @@ void [[noreturn]] MetricsExporter::serve(shared_ptr<unordered_map<uint32_t, Craw
listen(server_fd, 50); listen(server_fd, 50);
cout << "Server is running on http://localhost:8889 \n"; cout << "Exporter is running on http://localhost:8889 \n";
while (true) { while (true) {
int client_fd = accept(server_fd, nullptr, nullptr); int client_fd = accept(server_fd, nullptr, nullptr);
@ -46,20 +46,21 @@ void [[noreturn]] MetricsExporter::serve(shared_ptr<unordered_map<uint32_t, Craw
} }
void MetricsExporter::process_request(const int client_fd) { void MetricsExporter::process_request(const int client_fd) {
send_data(client_fd, HTML_RESPONSE_HEADER_lol); send_data(client_fd, "HTTP/1.1 200 OK\r\nContent-Type: text/plain; version=0.0.4\r\n\r\n");
ostringstream oss; ostringstream oss;
oss << BEGINNING; oss << "links_pressed_total: ";
for (auto it = crawler_->begin(); it != crawler_->end(); ++it) { int total = 0;
oss << it->second.links_pressed << ": " << it->second.user_agent << endl;
for (const auto &[user_agent, links_pressed]: *crawler_ | views::values) {
total += links_pressed;
} }
oss << END; oss << total << "\r\n";
send_data(client_fd, oss.str()); send(client_fd, oss.str().c_str(), oss.str().size(), 0);
send(client_fd, "0\r\n\r\n", 5, 0);
close(client_fd); close(client_fd);
} }

View File

@ -2,37 +2,34 @@
#include "../include/WordUtils.h" #include "../include/WordUtils.h"
#include "../include/DataType.h" #include "../include/DataType.h"
#include "../include/FileUtils.h" #include "../include/FileUtils.h"
#include "../include/Options.h"
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <sstream>
#include <unistd.h> #include <unistd.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <thread> #include <thread>
#include <chrono> #include <chrono>
#include <cstring> #include <cstring>
#include <random> #include <random>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <cstdint> #include <cstdint>
#include <iomanip>
vector<string> css; string css;
vector<string> images; vector<string> images;
vector<unordered_map<string, unordered_map<string, int>>> all_lists; vector<unordered_map<string, unordered_map<string, int>>> all_lists;
shared_ptr<ConcurrentQueue<Track>> tracks; shared_ptr<ConcurrentQueue<Track>> tracks;
Options options_;
void [[noreturn]] ServerUtils::serve(shared_ptr<ConcurrentQueue<Track>> cq_track) { void [[noreturn]] ServerUtils::serve(shared_ptr<ConcurrentQueue<Track>> cq_track, const Options& options) {
options_ = options;
tracks = std::move(cq_track); tracks = std::move(cq_track);
css = WordUtils::load_css("/home/skingging/Documents/Projects/CPP/AI-Tarpit-Reimagined/content/style.css"); css = WordUtils::load_css(options_.css);
images = FileUtils::get_image_list("/home/skingging/Documents/Projects/CPP/AI-Tarpit-Reimagined/content/"); images = FileUtils::get_image_list(options_.images);
const vector<string> words = FileUtils::get_wordlists("/home/skingging/Documents/Projects/CPP/AI-Tarpit-Reimagined/wordlist/"); const vector<string> words = FileUtils::get_wordlists(options_.word_lists);
for (const auto& word : words) { for (const auto& word : words) {
all_lists.push_back(WordUtils::load_data(word)); all_lists.push_back(WordUtils::load_data(word));
@ -59,7 +56,7 @@ void [[noreturn]] ServerUtils::serve(shared_ptr<ConcurrentQueue<Track>> cq_track
int client_fd = accept(server_fd, nullptr, nullptr); int client_fd = accept(server_fd, nullptr, nullptr);
if (client_fd == -1) continue; if (client_fd == -1) continue;
//cerr << client_fd << endl;
thread(process_request, client_fd).detach(); thread(process_request, client_fd).detach();
} }
@ -90,16 +87,10 @@ void ServerUtils::process_request(const int client_fd) {
cerr << "AAAA \n"; cerr << "AAAA \n";
} }
Track track;
track.Ip = ip;
track.UserAgent = user_agent;
tracks->push(track);
if (url == "/style.css") { if (url == "/style.css") {
// This sends the header, that instructs how the browser should interpret the data. // This sends the header, that instructs how the browser should interpret the data.
send_header(client_fd, CSS); //send_header(client_fd, CSS);
send_chunked_css(client_fd); send_css(client_fd);
} }
else if (url == "/favicon.png") { else if (url == "/favicon.png") {
@ -113,76 +104,71 @@ void ServerUtils::process_request(const int client_fd) {
} }
else { else {
Track track;
track.Ip = ip;
track.UserAgent = user_agent;
tracks->push(track);
const unsigned long hash3 = WordUtils::fnv1aHash(url); const unsigned long hash3 = WordUtils::fnv1aHash(url);
send_header(client_fd, HTML); //send_header(client_fd, HTML);
send_chunked_html(client_fd, hash3); send_html(client_fd, hash3);
} }
// Send final zero-length chunk to end the response
send(client_fd, "0\r\n\r\n", 5, 0);
close(client_fd); close(client_fd);
} }
void ServerUtils::send_header(const int client_fd, const data_type type) { void ServerUtils::send_html(const int client_fd, const size_t hash) {
if (type == HTML) [[likely]] {
send_data(client_fd, HTML_RESPONSE_HEADER);
}
else if (type == CSS) [[unlikely]] {
send_data(client_fd, CSS_RESPONSE_HEADER);
}
}
void ServerUtils::send_chunked_html(const int client_fd, const size_t hash) {
const string hashes = to_string(hash); const string hashes = to_string(hash);
unsigned short itr = 0; unsigned short itr = 0;
const unsigned short end = hashes.size(); const unsigned short end = hashes.size();
send_data(client_fd, HTML_BEGINNING);
send_data(client_fd, HTML_NAV);
send_data(client_fd, HTML_MAIN_1);
minstd_rand generator(hash); minstd_rand generator(hash);
uniform_int_distribution<unsigned short> distribution_1(0, end - 1); uniform_int_distribution<unsigned short> distribution(0, end - 1);
const int link = distribution_1(generator); const int link = distribution(generator);
distribution_1.param(uniform_int_distribution<unsigned short>::param_type(0, images.size() - 1)); distribution.param(uniform_int_distribution<unsigned short>::param_type(0, images.size() - 1));
const int image = distribution_1(generator); const int image = distribution(generator);
distribution_1.param(uniform_int_distribution<unsigned short>::param_type(0, 8)); distribution.param(uniform_int_distribution<unsigned short>::param_type(0, 8));
const int l = distribution_1(generator); const int l = distribution(generator);
distribution_1.param(uniform_int_distribution<unsigned short>::param_type(0, end - 2)); distribution.param(uniform_int_distribution<unsigned short>::param_type(0, end - 2));
const int img = distribution_1(generator); const int img = distribution(generator);
string html = HTML_RESPONSE_HEADER;
html += HTML_BEGINNING;
html += '\n';
html += HTML_NAV;
html += '\n';
html += HTML_MAIN_1;
while (itr < end) { while (itr < end) {
send_data(client_fd, WordUtils::create_tag_2(all_lists[l], hashes[itr])); html += WordUtils::create_tag_2(all_lists[l], hashes[itr]);
//send_data(client_fd, WordUtils::create_tag_2(all_lists[l], hashes[itr]));
if (itr == link) { if (itr == link) {
send_data(client_fd, WordUtils::create_link(all_lists[l], hash)); html += WordUtils::create_link(all_lists[l], hash);
//send_data(client_fd, WordUtils::create_link(all_lists[l], hash));
} }
if (itr == img) { if (itr == img) {
send_data(client_fd, WordUtils::create_image(images[image])); html += WordUtils::create_image(images[image]);
//send_data(client_fd, WordUtils::create_image(images[image]));
} }
//this_thread::sleep_for(chrono::milliseconds(75));
itr++; itr++;
} }
send_data(client_fd, HTML_MAIN_2); html += HTML_MAIN_2;
send_data(client_fd, HTML_FOOTER); html += HTML_FOOTER;
send_data(client_fd, HTML_END); html += HTML_END;
send_data(client_fd, html);
} }
void ServerUtils::send_chunked_css(const int client_fd) { void ServerUtils::send_css(const int client_fd) {
for (const auto & cs : css) { send_data(client_fd, CSS_RESPONSE_HEADER + css);
send_data(client_fd, cs);
//this_thread::sleep_for(chrono::milliseconds(25));
}
} }
void ServerUtils::send_image(const int client_fd, const string& path, const image_type type) { void ServerUtils::send_image(const int client_fd, const string& path, const image_type type) {
@ -225,17 +211,7 @@ size_t ServerUtils::send_all(const int client_fd, const char *data, const size_t
} }
void ServerUtils::send_data(const int client_fd, const string& data) { void ServerUtils::send_data(const int client_fd, const string& data) {
char size_hex[20]; // hold 64-bit hex value send(client_fd, data.c_str(), data.size(), 0);
snprintf(size_hex, sizeof(size_hex), "%zx", data.size());
string message;
message.reserve(strlen(size_hex) + 4 + data.size());
message += size_hex;
message += "\r\n";
message += data;
message += "\r\n";
send(client_fd, message.c_str(), message.size(), 0);
} }
uint32_t ServerUtils::get_ip_2(const int client_fd) { uint32_t ServerUtils::get_ip_2(const int client_fd) {

View File

@ -26,14 +26,6 @@ void [[noreturn]] TrackerUtils::track(const shared_ptr<ConcurrentQueue<Track>>&
continue; continue;
} }
/*vector<string> temp = WordUtils::split_string(track.Ip, IP);
const int ip1 = stoi(temp[0]);
const int ip2 = stoi(temp[1]);
const int ip3 = stoi(temp[2]);
const int ip4 = stoi(temp[3]);
const uint32_t ip = static_cast<uint32_t>(ip1 << 24) | static_cast<uint32_t>(ip2 << 16) | static_cast<uint32_t>(ip3 << 8) | static_cast<uint32_t>(ip4);*/
(*urls)[track.Ip].links_pressed++; (*urls)[track.Ip].links_pressed++;
(*urls)[track.Ip].user_agent = track.UserAgent; (*urls)[track.Ip].user_agent = track.UserAgent;
} }

View File

@ -26,8 +26,8 @@ unordered_map<string, unordered_map<string, int>> WordUtils::load_data(const str
return word_frequencies; return word_frequencies;
} }
vector<string> WordUtils::load_css(const string& path) { string WordUtils::load_css(const string& path) {
return split_string(load_file(path), data_type::CSS); return load_file(path);
} }
vector<string> WordUtils::predict_next_word(const string& input, const unordered_map<string, unordered_map<string, int>>& word_frequencies, const size_t count) { vector<string> WordUtils::predict_next_word(const string& input, const unordered_map<string, unordered_map<string, int>>& word_frequencies, const size_t count) {

View File

@ -2,17 +2,19 @@
#include <iostream> #include <iostream>
#include "../include/FileUtils.h" #include "../include/FileUtils.h"
#include "../include/WordUtils.h"
#include "../include/ServerUtils.h" #include "../include/ServerUtils.h"
#include "../include/ConcurrentQueue.h" #include "../include/ConcurrentQueue.h"
#include "../include/TrackerUtils.h" #include "../include/TrackerUtils.h"
#include "../include/Track.h" #include "../include/Track.h"
#include "../include/MetricsExporter.h" #include "../include/MetricsExporter.h"
#include "../include/Options.h"
using namespace std; using namespace std;
int main(int argc, const char* argv[]) { int main(const int argc, const char* argv[]) {
/*if (argc > 2) Options options;
if (argc > 4)
{ {
cout << "Too many arguments"; cout << "Too many arguments";
return 0; return 0;
@ -22,20 +24,34 @@ int main(int argc, const char* argv[]) {
{ {
cout << "Filepath: " << argv[1] << " doesn't exist."; cout << "Filepath: " << argv[1] << " doesn't exist.";
return 0; return 0;
}*/ }
options.word_lists = argv[1];
cout << "lol" << endl; if (!FileUtils::fileExists(argv[2]))
{
cout << "Filepath: " << argv[2] << " doesn't exist.";
return 0;
}
options.css = argv[2];
auto queue = std::make_shared<ConcurrentQueue<Track>>(); if (!FileUtils::fileExists(argv[3]))
auto metrics = std::make_shared<unordered_map<uint32_t, Crawler>>(); {
cout << "Filepath: " << argv[3] << " doesn't exist.";
return 0;
}
options.images = argv[3];
cout << options.word_lists << " " << options.css << " " << options.images << " " << endl;
auto queue = make_shared<ConcurrentQueue<Track>>();
auto metrics = make_shared<unordered_map<uint32_t, Crawler>>();
thread(TrackerUtils::track, queue, metrics).detach(); thread(TrackerUtils::track, queue, metrics).detach();
thread(MetricsExporter::serve, metrics).detach(); thread(MetricsExporter::serve, metrics).detach();
//argv[1]
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
ServerUtils::serve(queue); ServerUtils::serve(queue, options);
return 0; return 0;
} }