145 lines
3.9 KiB
C++
145 lines
3.9 KiB
C++
#include "../include/ServerUtils.h"
|
|
#include "../include/WordUtils.h"
|
|
#include "../include/DataType.h"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <unistd.h>
|
|
#include <netinet/in.h>
|
|
#include <thread>
|
|
#include <chrono>
|
|
|
|
vector<string> _css;
|
|
map<string, map<string, int>> _word_frequencies;
|
|
|
|
void ServerUtils::serve() {
|
|
_word_frequencies = WordUtils::load_data("/home/skingging/Documents/Projects/CPP/AI-Tarpit-Reimagined/wordlist/wordlist-Food.txt");
|
|
_css = WordUtils::load_css("/home/skingging/Documents/Projects/CPP/AI-Tarpit-Reimagined/content/style.css");
|
|
|
|
// 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).detach();
|
|
}
|
|
|
|
close(server_fd);
|
|
}
|
|
|
|
void ServerUtils::process_request(int client_fd) {
|
|
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";
|
|
}
|
|
|
|
if (url == "/style.css") {
|
|
// This sends the header, that instructs how the browser should interpret the data.
|
|
send_header(client_fd, data_type::CSS);
|
|
send_chunked_css(client_fd);
|
|
}
|
|
|
|
else if (url == "/favicon.png") {
|
|
// This sends the header, that instructs how the browser should interpret the data.
|
|
//send_header(client_fd, data_type::IMAGE);
|
|
}
|
|
|
|
else {
|
|
unsigned int hash = WordUtils::hash_url(url);
|
|
send_header(client_fd, data_type::HTML);
|
|
send_chunked_html(client_fd, hash);
|
|
}
|
|
|
|
// Send final zero-length chunk to end the response
|
|
send(client_fd, "0\r\n\r\n", 5, 0);
|
|
|
|
close(client_fd);
|
|
}
|
|
|
|
void ServerUtils::send_header(int client_fd, data_type type) {
|
|
if (type == data_type::HTML) {
|
|
send(client_fd, HTML_RESPONSE_HEADER.c_str(), HTML_RESPONSE_HEADER.size(), 0);
|
|
}
|
|
|
|
else if (type == data_type::CSS) {
|
|
send(client_fd, CSS_RESPONSE_HEADER.c_str(), CSS_RESPONSE_HEADER.size(), 0);
|
|
}
|
|
|
|
else {
|
|
send(client_fd, PNG_RESPONSE_HEADER.c_str(), PNG_RESPONSE_HEADER.size(), 0);
|
|
}
|
|
}
|
|
|
|
void ServerUtils::send_chunked_html(int client_fd, unsigned int hash) {
|
|
string chunk;
|
|
const string hashes = to_string(hash);
|
|
|
|
unsigned short itr = 0;
|
|
unsigned short end = hashes.size();
|
|
|
|
send_data(client_fd, HTML_BEGINNING);
|
|
send_data(client_fd, HTML_NAV);
|
|
send_data(client_fd, HTML_MAIN_1);
|
|
|
|
while (itr < end) {
|
|
ostringstream oss;
|
|
|
|
chunk = WordUtils::create_tag(_word_frequencies, hashes[itr]);
|
|
|
|
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(0));
|
|
|
|
itr++;
|
|
}
|
|
|
|
send_data(client_fd, HTML_MAIN_2);
|
|
send_data(client_fd, HTML_FOOTER);
|
|
send_data(client_fd, HTML_END);
|
|
}
|
|
|
|
void ServerUtils::send_chunked_css(int client_fd) {
|
|
for (size_t i = 0; i < _css.size(); i++) {
|
|
ostringstream oss;
|
|
|
|
oss << hex << _css[i].size() << "\r\n" << _css[i] << "\r\n";
|
|
|
|
string to_send = oss.str();
|
|
|
|
send(client_fd, to_send.c_str(), to_send.size(), 0);
|
|
}
|
|
}
|
|
|
|
void ServerUtils::send_data(int client_fd, string data) {
|
|
ostringstream oss;
|
|
|
|
oss << hex << data.size() << "\r\n" << data << "\r\n";
|
|
|
|
send(client_fd, oss.str().c_str(), oss.str().size(), 0);
|
|
} |