AI-Tarpit-Reimagined/src/ServerUtils.cpp

81 lines
2.1 KiB
C++

#include "../include/ServerUtils.h"
#include "../include/WordUtils.h"
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>
#include <netinet/in.h>
#include <thread>
#include <chrono>
using namespace std;
void ServerUtils::serve(map<string, map<string, int>> word_frequencies) {
// server_fd is a file descriptor.
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr = INADDR_ANY;
bind(server_fd, (sockaddr*)&addr, sizeof(addr));
listen(server_fd, 15);
cout << "Server is running on http://localhost:8888 \n";
while (true) {
int client_fd = accept(server_fd, nullptr, nullptr);
thread(process_request, client_fd, word_frequencies).detach();
}
close(server_fd);
}
void ServerUtils::process_request(int client_fd, map<string, map<string, int>> word_frequencies) {
char buffer[1024];
int bytes_received = recv(client_fd, buffer, sizeof(buffer) - 1, 0);
string url;
if (bytes_received > 0) {
buffer[bytes_received] = '\0';
url = WordUtils::extract_url(string(buffer));
} else {
cerr << "AAAA \n";
}
unsigned int hash = WordUtils::hash_url(url);
string headers =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=utf-8\r\n"
"Transfer-Encoding: chunked\r\n"
"Connection: close\r\n\r\n";
send(client_fd, headers.c_str(), headers.size(), 0);
const vector<string> html_chunks = WordUtils::create_tag(word_frequencies, hash);
for (const auto& chunk : html_chunks) {
ostringstream oss;
oss << hex << chunk.size() << "\r\n" << chunk << "\r\n";
string to_send = oss.str();
send(client_fd, to_send.c_str(), to_send.size(), 0);
this_thread::sleep_for(chrono::milliseconds(5));
}
// Send final zero-length chunk to end the response
send(client_fd, "0\r\n\r\n", 5, 0);
close(client_fd);
}