Something went wrong. Try again.
An HTTP server written in C++98 projects.intra.42.fr/projects/webserv
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314/* ************************************************************************** *//* *//* ::: :::::::: *//* parse_srever.cpp :+: :+: :+: *//* +:+ +:+ +:+ *//* By: bcausseq <bcausseq@42angouleme.fr> +#+ +:+ +#+ *//* +#+#+#+#+#+ +#+ *//* Created: 2026/09/27 00:18:38 by bcausseq #+# #+# *//* Updated: 2026/09/27 00:28:59 by bcausseq ### ########.fr *//* *//* ************************************************************************** */
#include "config.hpp"#include "ParserExceptions.hpp"#include "parse_utils.hpp"
#include <climits>#include <cstdlib>#include <iostream>#include <string>#include <sstream>
static voidhandle_root(std::string& line, Config& server, unsigned int& line_nbr){ size_t ws = line.find_first_of(' '); if (ws == line.npos) { std::string errs("Missing root path. Problem : "); errs += itos(line_nbr); throw (ParserExceptions(errs)); } std::string root = line.substr(ws + 1);
if (root.empty()) { std::string errs("Root for the server can't be empty"); throw (ParserExceptions(errs)); }
trim_comma(root); if (check_root(root, line_nbr)) server.set_root(root);}
static voidhandle_index(std::string& line, Config& server, unsigned int& line_nbr){ size_t fws = line.find_first_of(' '); if (fws == line.npos) { std::string errs("Missing the error code and the path. Problem line : "); errs += itos(line_nbr); throw (ParserExceptions(errs)); }
std::string indexes = line.substr(fws + 1); trim_comma(indexes);
std::stringstream ss(indexes); std::string tmp; while (getline(ss, tmp, ' ')) server.get_index().push_back(tmp);}
static voidhandle_server_names(std::string& line, Config& server, unsigned int& line_nbr){ size_t fws = line.find_first_of(' '); if (fws == line.npos) { std::string errs("Missing the server Name. Problem line : "); errs += itos(line_nbr); throw (ParserExceptions(errs)); }
std::string names = line.substr(fws + 1); trim_comma(names);
std::stringstream ss(names); std::string tmp; while (getline(ss, tmp, ' ')) server.get_server_name().push_back(tmp);}
static boolcheck_port(std::string& port, unsigned int& line_nbr){ const std::string port_accept = "0123456789";
for (auto it = port.begin(); it != port.end(); ++it) { if (port_accept.find(*it) == port_accept.npos) { std::string errs("Wrong character in the port. Problem line : "); errs += itos(line_nbr); throw (ParserExceptions(errs)); } } return (true);}
static voidcheck_host(std::string& host, unsigned int& line_nbr){ const std::string host_accept = "0123456789.";
for (auto it = host.begin(); it != host.end(); ++it) { if (host_accept.find(*it) == host_accept.npos) { std::string errs("Wrong character in the host. Problem line : "); errs += itos(line_nbr); throw (ParserExceptions(errs)); } }}
static voidhandle_listen(std::string& line, Config& server, unsigned int& line_nbr){ errno = 0;
host_port port_host;
size_t fws = line.find_first_of(' '); if (fws == line.npos) return ;
std::string listens = line.substr(fws + 1); std::string host; trim_comma(listens);
if (listens.find(':') != listens.npos) { host = listens.substr(0, listens.find(':') - 1); check_host(host, line_nbr); port_host.host = host; listens = listens.substr(listens.find(':') + 1); }
if (check_port(listens, line_nbr)) { char *errs; long port = strtol(listens.c_str(), &errs, 10); if (*errs || errno == ERANGE || port < 0 || port > USHRT_MAX) { std::string errs("Port incorrect. Problem line : "); errs += itos(line_nbr); throw (ParserExceptions(errs)); }
unsigned short shport = static_cast<unsigned short>(port); port_host.port = shport;
const host_port check = server.get_port();
if (check.host != "" || check.port != 0) { std::string errs("Multiple definition of listen in the file. Problem line : "); errs += itos(line_nbr); throw (ParserExceptions(errs)); }
server.set_port(port_host); }}static voidhandle_error_page(std::string& line, Config& server, unsigned int& line_nbr){ errno = 0;
size_t fws = line.find_first_of(' '); if (fws == line.npos) { std::string errs("Missing the error code and the path. Problem line : "); errs += itos(line_nbr); throw (ParserExceptions(errs)); } size_t lws = line.find_last_of(' '); if (lws == line.npos) { std::string errs("Missing path. Problem line : "); errs += itos(line_nbr); throw (ParserExceptions(errs)); }
std::string index = line.substr(fws + 1, lws - fws - 1); std::string value = line.substr(lws + 1, line.size() - lws - 1); trim_comma(value);
char *errs; long lindex = strtol(index.c_str(), &errs, 10);
if (*errs || errno == ERANGE || lindex < 0 || lindex > INT_MAX) { std::string errs("Error in the index. Problem line : "); errs += itos(line_nbr); throw (ParserExceptions(errs)); }
short shindex = static_cast<short>(lindex); server.set_error_page(shindex, value);}
static boolcontrol_body_size(std::string& test, unsigned int& line_nbr){ const std::string acceptedparam = "0123456789KMG";
for (auto it = test.begin(); it != test.end(); ++it) { if (acceptedparam.find(*it) == std::string::npos) { std::string errs("Wrong character in the body_size. Problem line : "); errs += itos(line_nbr); throw (ParserExceptions(errs)); } }
return (true);}
static voidhandle_body_size(std::string& line, Config& server, unsigned int& line_nbr){ const std::string coef = "KMG"; size_t index = 0;
size_t ws = line.find_first_of(' '); std::string trimed = line.substr(ws + 1);
trim_comma(trimed);
if (!control_body_size(trimed, line_nbr)) return ; char *errs; long res = strtol(trimed.c_str(), &errs, 10); if (*errs) { index = coef.find(*errs); for (size_t i = 0; i <= index; ++i) res *= 1024; }
server.set_max_body_size(res);}
static voidappend_location(std::string& line, Config& server, Location*& location, state_machine& state){ size_t fws = line.find_first_of(' '); size_t bracket = line.find('{'); std::string path(line.substr(fws, bracket - fws - 1)); size_t lws = path.find_first_of(" \t"); if (lws != path.npos) path = path.substr(0, lws - 1);
server.get_location().push_back(Location()); location = &(server.get_location().back()); location->set_path(path); state = LOCATION;}
voidin_server(std::string& line, Config& server, Location*& location, state_machine& state,std::vector<Config>& s, unsigned int& line_curr_serv, unsigned int& line_nbr){ if (!line.rfind("location", 0) && line.find("{") != std::string::npos) { append_location(line, server, location, state); return ; } else if (!line.rfind('}', 0)) { s.push_back(server); server = server.reset_params(); line_curr_serv = 0; state = LOOKING_SERVER; return ; }
if (line.find(';') == line.npos) { std::string errs("Please end all of your line with ';'. Problem line : "); errs += itos(line_nbr); throw (ParserExceptions(errs)); }
if (!line.rfind("error_page", 0)) handle_error_page(line, server, line_nbr);
else if (!line.rfind("max_body_size", 0)) handle_body_size(line, server, line_nbr);
else if (!line.rfind("root", 0)) handle_root(line, server, line_nbr);
else if (!line.rfind("index", 0)) handle_index(line, server, line_nbr);
else if (!line.rfind("server_name", 0)) handle_server_names(line, server, line_nbr);
else if (!line.rfind("listen", 0)) handle_listen(line, server, line_nbr);
else std::cerr << "Wrong field for the location part at line " << line_nbr << std::endl << "line : " << line << std::endl;}