Fixed uploading images. Implemented a threadsafe queue and simple IP tracking.
This commit is contained in:
@@ -36,5 +36,18 @@ vector<string> FileUtils::get_image_list(const string& path) {
|
||||
}
|
||||
}
|
||||
|
||||
return images;
|
||||
}
|
||||
|
||||
vector<string> FileUtils::get_wordlists(const string& path) {
|
||||
vector<string> images;
|
||||
const std::string ext(".txt");
|
||||
for (auto &p : filesystem::recursive_directory_iterator(path))
|
||||
{
|
||||
if (p.path().extension() == ext) {
|
||||
images.push_back(p.path().string());
|
||||
}
|
||||
}
|
||||
|
||||
return images;
|
||||
}
|
||||
+66
-19
@@ -4,6 +4,7 @@
|
||||
#include "../include/FileUtils.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -13,15 +14,24 @@
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <random>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
vector<string> css;
|
||||
vector<string> images;
|
||||
unordered_map<string, unordered_map<string, int>> word_frequencies;
|
||||
vector<unordered_map<string, unordered_map<string, int>>> all_lists;
|
||||
shared_ptr<ConcurrentQueue<Track>> t_test;
|
||||
|
||||
void ServerUtils::serve() {
|
||||
word_frequencies = WordUtils::load_data("/home/skingging/Documents/Projects/CPP/AI-Tarpit-Reimagined/wordlist/wordlist-Food.txt");
|
||||
void [[noreturn]] ServerUtils::serve(shared_ptr<ConcurrentQueue<Track>> test) {
|
||||
t_test = std::move(test);
|
||||
css = WordUtils::load_css("/home/skingging/Documents/Projects/CPP/AI-Tarpit-Reimagined/content/style.css");
|
||||
images = FileUtils::get_image_list("/home/skingging/Documents/Projects/CPP/AI-Tarpit-Reimagined/content/");
|
||||
const vector<string> words = FileUtils::get_wordlists("/home/skingging/Documents/Projects/CPP/AI-Tarpit-Reimagined/wordlist/");
|
||||
|
||||
for (const auto& word : words) {
|
||||
all_lists.push_back(WordUtils::load_data(word));
|
||||
}
|
||||
|
||||
// server_fd is a file descriptor.
|
||||
const int server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
@@ -30,9 +40,13 @@ void ServerUtils::serve() {
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(8888);
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
bind(server_fd, reinterpret_cast<sockaddr *>(&addr), sizeof(addr));
|
||||
listen(server_fd, 15);
|
||||
|
||||
if (bind(server_fd, reinterpret_cast<sockaddr *>(&addr), sizeof(addr)) != 0) {
|
||||
cout << "Please wait for the pipe to close.";
|
||||
return;
|
||||
}
|
||||
|
||||
listen(server_fd, 50);
|
||||
|
||||
cout << "Server is running on http://localhost:8888 \n";
|
||||
|
||||
@@ -47,7 +61,7 @@ void ServerUtils::serve() {
|
||||
|
||||
void ServerUtils::process_request(const int client_fd) {
|
||||
char buffer[1024];
|
||||
const int bytes_received = recv(client_fd, buffer, sizeof(buffer) - 1, 0);
|
||||
const unsigned long bytes_received = recv(client_fd, buffer, sizeof(buffer) - 1, 0);
|
||||
|
||||
string url;
|
||||
|
||||
@@ -55,7 +69,12 @@ void ServerUtils::process_request(const int client_fd) {
|
||||
buffer[bytes_received] = '\0';
|
||||
|
||||
url = WordUtils::extract_url(string(buffer));
|
||||
|
||||
if (url.empty()) {
|
||||
close(client_fd);
|
||||
}
|
||||
} else {
|
||||
close(client_fd);
|
||||
cerr << "AAAA \n";
|
||||
}
|
||||
|
||||
@@ -72,13 +91,17 @@ void ServerUtils::process_request(const int client_fd) {
|
||||
else if (WordUtils::contains_image(url)) {
|
||||
string p = "/home/skingging/Documents/Projects/CPP/AI-Tarpit-Reimagined/content/images/";
|
||||
p += WordUtils::extract_image_name(url);
|
||||
cerr << p << endl;
|
||||
send_image(client_fd, p, image_type::AVIF);
|
||||
}
|
||||
|
||||
else {
|
||||
//unsigned int hash = WordUtils::hash_url(url);
|
||||
//unsigned long hash2 = WordUtils::djb2Hash(url);
|
||||
Track track;
|
||||
track.Ip = get_ip(client_fd);
|
||||
|
||||
// Testing only.
|
||||
track.UserAgent = url;
|
||||
t_test->push(track);
|
||||
|
||||
const unsigned long hash3 = WordUtils::fnv1aHash(url);
|
||||
|
||||
send_header(client_fd, HTML);
|
||||
@@ -114,15 +137,17 @@ void ServerUtils::send_chunked_html(const int client_fd, const size_t hash) {
|
||||
minstd_rand generator(hash);
|
||||
uniform_int_distribution<unsigned short> distribution_1(0, end - 1);
|
||||
uniform_int_distribution<unsigned short> distribution_2(0, images.size() - 1);
|
||||
uniform_int_distribution<unsigned short> distribution_3(0, 8);
|
||||
|
||||
const int link = distribution_1(generator);
|
||||
const int image = distribution_2(generator);
|
||||
const int l = distribution_3(generator);
|
||||
|
||||
while (itr < end) {
|
||||
send_data(client_fd, WordUtils::create_tag(word_frequencies, hashes[itr]));
|
||||
send_data(client_fd, WordUtils::create_tag(all_lists[l], hashes[itr]));
|
||||
|
||||
if (itr == link) {
|
||||
send_data(client_fd, WordUtils::create_link(word_frequencies, hash));
|
||||
send_data(client_fd, WordUtils::create_link(all_lists[l], hash));
|
||||
}
|
||||
|
||||
if (itr == link) {
|
||||
@@ -163,22 +188,23 @@ void ServerUtils::send_image(const int client_fd, const string& path, const imag
|
||||
oss << "Content-Length: " << image.size() << "\r\n";
|
||||
oss << "\r\n";
|
||||
|
||||
//send(client_fd, oss.str().c_str(), oss.str().size(), 0);
|
||||
send_data(client_fd, oss.str());
|
||||
send(client_fd, oss.str().c_str(), oss.str().size(), 0);
|
||||
|
||||
send(client_fd, reinterpret_cast<const char*>(image.data()), image.size(), 0);
|
||||
//send_all(client_fd,reinterpret_cast<const char*>(image.data()), image.size());
|
||||
}
|
||||
|
||||
size_t ServerUtils::send_all(int sockfd, const char *data, const size_t length) {
|
||||
size_t ServerUtils::send_all(const int client_fd, const char *data, const size_t length) {
|
||||
size_t total_sent = 0;
|
||||
while (total_sent < length) {
|
||||
size_t sent = send(sockfd, data + total_sent, length - total_sent, 0);
|
||||
const size_t sent = send(client_fd, data + total_sent, length - total_sent, 0);
|
||||
if (sent <= 0) {
|
||||
return sent; // Error or connection closed
|
||||
}
|
||||
|
||||
total_sent += sent;
|
||||
}
|
||||
|
||||
return total_sent;
|
||||
}
|
||||
|
||||
@@ -187,9 +213,30 @@ void ServerUtils::send_data(const int client_fd, const string& data) {
|
||||
|
||||
oss << hex << data.size() << "\r\n" << data << "\r\n";
|
||||
|
||||
const int result = send(client_fd, oss.str().c_str(), oss.str().size(), 0);
|
||||
send(client_fd, oss.str().c_str(), oss.str().size(), 0);
|
||||
}
|
||||
|
||||
if (result == -1) {
|
||||
return;
|
||||
string ServerUtils::get_ip(const int client_fd) {
|
||||
sockaddr_storage addr{};
|
||||
socklen_t len = sizeof(addr);
|
||||
char ipstr[INET6_ADDRSTRLEN];
|
||||
|
||||
if (getpeername(client_fd, reinterpret_cast<sockaddr *>(&addr), &len) == -1) {
|
||||
perror("getpeername");
|
||||
return "";
|
||||
}
|
||||
|
||||
if (addr.ss_family == AF_INET) {
|
||||
// IPv4
|
||||
sockaddr_in* s = reinterpret_cast<sockaddr_in *>(&addr);
|
||||
inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof(ipstr));
|
||||
} else if (addr.ss_family == AF_INET6) {
|
||||
// IPv6
|
||||
sockaddr_in6* s = reinterpret_cast<sockaddr_in6 *>(&addr);
|
||||
inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof(ipstr));
|
||||
} else {
|
||||
return "Unknown address family";
|
||||
}
|
||||
|
||||
return string(ipstr);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "../include/TrackerUtils.h"
|
||||
#include "../include/ConcurrentQueue.h"
|
||||
#include "../include/Track.h"
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <utility>
|
||||
|
||||
void TrackerUtils::track(const shared_ptr<ConcurrentQueue<Track>> &t_test) {
|
||||
bool running = true;
|
||||
unordered_map<string, int> urls;
|
||||
|
||||
while (running) {
|
||||
auto [Ip, UserAgent] = t_test->wait_and_pop();
|
||||
|
||||
urls[UserAgent]++;
|
||||
|
||||
system("clear");
|
||||
print(urls);
|
||||
|
||||
if (Ip == "STOP") {
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TrackerUtils::print(unordered_map<string, int> tracks) {
|
||||
for (auto it = tracks.begin(); it != tracks.end(); ++it) {
|
||||
cerr << it->first << ": " << it->second << endl;
|
||||
}
|
||||
|
||||
this_thread::sleep_for(chrono::milliseconds(250));
|
||||
}
|
||||
+14
-15
@@ -5,18 +5,17 @@
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
|
||||
// We can just use a unordered_map<string, unordered_map<string, int>> instead
|
||||
// We can just use an unordered_map<string, unordered_map<string, int>> instead
|
||||
unordered_map<string, unordered_map<string, int>> WordUtils::load_data(const string& path) {
|
||||
vector<string> data = split_string(load_file(path), data_type::HTML);
|
||||
|
||||
unordered_map<string, unordered_map<string, int>> word_frequencies = {};
|
||||
|
||||
for (long unsigned int i = 0; i + 1 < data.size(); i++) {
|
||||
transform(data[i].begin(), data[i].end(), data[i].begin(), [](const unsigned char c){ return tolower(c); });
|
||||
transform(data[i+1].begin(), data[i+1].end(), data[i+1].begin(), [](const unsigned char c){ return tolower(c); });
|
||||
ranges::transform(data[i], data[i].begin(), [](const unsigned char c){ return tolower(c); });
|
||||
ranges::transform(data[i+1], data[i+1].begin(), [](const unsigned char c){ return tolower(c); });
|
||||
word_frequencies[data[i]][data[i+1]]++;
|
||||
}
|
||||
|
||||
@@ -27,7 +26,7 @@ vector<string> WordUtils::load_css(const string& path) {
|
||||
return split_string(load_file(path), data_type::CSS);
|
||||
}
|
||||
|
||||
// We can just use a unordered_map<string, unordered_map<string, int>> instead, since we're already sorting before counting.
|
||||
// We can just use an unordered_map<string, unordered_map<string, int>> instead, since we're already sorting before counting.
|
||||
vector<string> WordUtils::predict_next_word(const string& input, const unordered_map<string, unordered_map<string, int>>& word_frequencies, size_t count) {
|
||||
const auto it = word_frequencies.find(input);
|
||||
|
||||
@@ -38,7 +37,7 @@ vector<string> WordUtils::predict_next_word(const string& input, const unordered
|
||||
vector<pair<string, int>> sortedWords(nextWords.begin(), nextWords.end());
|
||||
|
||||
// Sort by frequency (descending)
|
||||
sort(sortedWords.begin(), sortedWords.end(),[](const auto& a, const auto& b) {
|
||||
ranges::sort(sortedWords,[](const auto& a, const auto& b) {
|
||||
return a.second > b.second;
|
||||
});
|
||||
|
||||
@@ -81,7 +80,7 @@ string WordUtils::create_tag(const unordered_map<string, unordered_map<string, i
|
||||
|
||||
string temp_string = "<p>";
|
||||
|
||||
for (unsigned short l = 0; l < tags.size(); l++) {
|
||||
for (size_t l = 0; l < tags.size(); l++) {
|
||||
temp_string += tags[l];
|
||||
temp_string += " ";
|
||||
}
|
||||
@@ -121,7 +120,7 @@ string WordUtils::create_link(const unordered_map<string, unordered_map<string,
|
||||
string temp_string_2 = "<a href=\"";
|
||||
string temp_string;
|
||||
|
||||
for (unsigned short l = 0; l < tags.size(); l++) {
|
||||
for (size_t l = 0; l < tags.size(); l++) {
|
||||
temp_string += tags[l];
|
||||
}
|
||||
|
||||
@@ -138,7 +137,7 @@ string WordUtils::create_link(const unordered_map<string, unordered_map<string,
|
||||
|
||||
string WordUtils::create_image(const string& image) {
|
||||
|
||||
string temp_1 = "<img loading=\"lazy\" src=\"/";
|
||||
string temp_1 = R"(<img loading="lazy" src="/)";
|
||||
temp_1 += image;
|
||||
temp_1 += ".avif";
|
||||
temp_1 += "\">";
|
||||
@@ -194,6 +193,8 @@ string WordUtils::load_file(const string& path) {
|
||||
}
|
||||
|
||||
string WordUtils::extract_url(const string& input) {
|
||||
if (input.empty()) return "";
|
||||
|
||||
const unsigned short first_line_end = input.find('\n');
|
||||
if (first_line_end == string::npos) return "";
|
||||
|
||||
@@ -209,7 +210,7 @@ string WordUtils::extract_url(const string& input) {
|
||||
}
|
||||
|
||||
string WordUtils::extract_image_name(const string& input) {
|
||||
const unsigned short first_line_end = input.find("f");
|
||||
const unsigned short first_line_end = input.find('f');
|
||||
if (first_line_end == string::npos) return "";
|
||||
|
||||
string first_line = input.substr(1, first_line_end);
|
||||
@@ -222,12 +223,10 @@ bool WordUtils::contains_image(const string& input) {
|
||||
|
||||
if (first_line_end == 65535) return false;
|
||||
|
||||
cerr << first_line_end;
|
||||
string type = input.substr(first_line_end + 1, 5);
|
||||
|
||||
string type = input.substr(first_line_end, 3);
|
||||
cerr << type << endl;
|
||||
if (type == "avif") return true;
|
||||
|
||||
if (first_line_end != string::npos) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -253,7 +252,7 @@ unsigned long WordUtils::djb2Hash(const string& str) {
|
||||
}
|
||||
|
||||
unsigned long WordUtils::fnv1aHash(const std::string& str) {
|
||||
const unsigned long prime = 16777619; // A commonly used prime
|
||||
constexpr unsigned long prime = 16777619; // A commonly used prime
|
||||
unsigned long hash = 2166136261; // Initial prime value
|
||||
|
||||
for (const char c : str) {
|
||||
|
||||
+7
-16
@@ -1,8 +1,12 @@
|
||||
#include <csignal>
|
||||
#include <iostream>
|
||||
|
||||
#include "../include/FileUtils.h"
|
||||
#include "../include/WordUtils.h"
|
||||
#include "../include/ServerUtils.h"
|
||||
#include "../include/ConcurrentQueue.h"
|
||||
#include "../include/TrackerUtils.h"
|
||||
#include "../include/Track.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -19,26 +23,13 @@ int main(int argc, const char* argv[]) {
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
auto queue = std::make_shared<ConcurrentQueue<Track>>();
|
||||
|
||||
/*auto lol = WordUtils::load_data("/home/skingging/Documents/Projects/CPP/AI-Tarpit-Reimagined/wordlist/wordlist-Food.txt");
|
||||
string word;
|
||||
|
||||
while (true)
|
||||
{
|
||||
cout << "Please input word: \n";
|
||||
cin >> word;
|
||||
|
||||
vector<string> words = WordUtils::predict_next_word(word, lol, 10);
|
||||
|
||||
for (const auto& out : words)
|
||||
{
|
||||
cout << "Next word is: " << out << endl;
|
||||
}
|
||||
}*/
|
||||
thread(TrackerUtils::track, queue).detach();
|
||||
|
||||
//argv[1]
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
ServerUtils::serve();
|
||||
ServerUtils::serve(queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user