clean comment and stuff
This commit is contained in:
4
Makefile
4
Makefile
@@ -65,11 +65,11 @@ cgire:
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJS_D)
|
||||
echo "$(_RED).o Files Deleted 😱$(_END)"
|
||||
echo "$(_CYAN).o Files Deleted 🤫$(_END)"
|
||||
|
||||
fclean: clean
|
||||
rm -f $(NAME)
|
||||
echo "$(_RED)$(NAME) Deleted 😱$(_END)"
|
||||
echo "$(_CYAN)$(NAME) Deleted 🤫$(_END)"
|
||||
|
||||
re: fclean all
|
||||
|
||||
|
||||
9
memo.txt
9
memo.txt
@@ -7,21 +7,12 @@
|
||||
- handle redirection (Work, but weird behavior need deeper test)
|
||||
- Ecrire des tests !
|
||||
|
||||
- cgi_cpp_status.cpp with POST dont show error page. Normal or not ?
|
||||
|
||||
- check status in autoindex
|
||||
|
||||
- merge changes from hugo5 to master (attention a pas casse svp :clown:)
|
||||
|
||||
-- changer le 4040 port par default cgi
|
||||
|
||||
----Priorité modérée------------------------
|
||||
- namespace utils ?
|
||||
- change "std::string" to reference "std::string &" in most functions
|
||||
and add "const" if apropriate.
|
||||
- peut-être check si ip > 32bits
|
||||
|
||||
|
||||
----Priorité faible------------------------
|
||||
- idealy, we should not clear() raw_request after a response,
|
||||
but just the part we actually parsed for this response.
|
||||
|
||||
@@ -112,7 +112,6 @@ void Client::parse_request_headers(std::vector<ServerConfig> &servers)
|
||||
_check_request_errors();
|
||||
if (status)
|
||||
return;
|
||||
_parse_port_hostname(get_rq_headers("Host")); // use getter for headers because it works case insensitive
|
||||
|
||||
// DEBUG
|
||||
// std::cerr << get_rq_method_str() << " " << get_rq_target() << " " << get_rq_version() << "\n";
|
||||
@@ -260,8 +259,6 @@ void Client::clear_request_vars()
|
||||
_request.multi_bodys.clear();
|
||||
_request.abs_path.clear();
|
||||
_request.query.clear();
|
||||
_request.port.clear();
|
||||
_request.hostname.clear();
|
||||
}
|
||||
|
||||
void Client::clear_script()
|
||||
@@ -298,8 +295,6 @@ std::cout << "\n=== DEBUG PRINT CLIENT ===\n";
|
||||
<< "get_rq_query() : [" << get_rq_query() << "]\n"
|
||||
<< "get_rq_version() : [" << get_rq_version() << "]\n"
|
||||
<< "get_rq_body() : [" << get_rq_body() << "]\n"
|
||||
<< "get_rq_port() : [" << get_rq_port() << "]\n"
|
||||
<< "get_rq_hostname() : [" << get_rq_hostname() << "]\n"
|
||||
<< "get_rq_script_path() : [" << get_rq_script_path() << "]\n"
|
||||
<< "get_rq_script_info() : [" << get_rq_script_info() << "]\n"
|
||||
<< "headers :\n";
|
||||
@@ -327,8 +322,6 @@ std::string Client::get_rq_abs_path() const { return _request.abs_path; }
|
||||
std::string Client::get_rq_query() const { return _request.query; }
|
||||
std::string Client::get_rq_version() const { return _request.version; }
|
||||
std::string Client::get_rq_body() const { return _request.body; }
|
||||
std::string Client::get_rq_port() const { return _request.port; }
|
||||
std::string Client::get_rq_hostname() const { return _request.hostname; }
|
||||
std::string Client::get_rq_script_path()const { return _request.script.path; }
|
||||
std::string Client::get_rq_script_info()const { return _request.script.info; }
|
||||
|
||||
@@ -411,26 +404,6 @@ void Client::_parse_request_fields()
|
||||
::str_map_key_tolower(_request.headers);
|
||||
}
|
||||
|
||||
// TODO : I think its now useless. Probably to delete.
|
||||
void Client::_parse_port_hostname(std::string host)
|
||||
{
|
||||
size_t pos;
|
||||
|
||||
if (host == "")
|
||||
std::cerr << "no host\n";
|
||||
|
||||
pos = host.find(':');
|
||||
// port :
|
||||
if (pos == NPOS)
|
||||
_request.port = "4040"; // TODO: make equal to default port in config
|
||||
else
|
||||
_request.port = host.substr(pos);
|
||||
if (_request.port == ":")
|
||||
_request.port = "";
|
||||
// hostname :
|
||||
_request.hostname = host.substr(0, pos);
|
||||
}
|
||||
|
||||
void Client::_check_request_errors()
|
||||
{
|
||||
// /* Debug */ std::cerr << "Content-Length=" << get_rq_headers("Content-Length") << "\n";
|
||||
|
||||
@@ -35,8 +35,6 @@ struct Request
|
||||
std::map<std::string, std::string> headers;
|
||||
std::string body;
|
||||
std::vector<MultipartBody> multi_bodys;
|
||||
std::string port;
|
||||
std::string hostname;
|
||||
struct Script script;
|
||||
};
|
||||
|
||||
@@ -64,7 +62,6 @@ class Client
|
||||
bool header_complete;
|
||||
bool body_complete;
|
||||
bool request_complete;
|
||||
// size_t read_body_size; // unused for now
|
||||
ServerConfig *assigned_server; // cant be const cause of error_pages.operator[]
|
||||
const LocationConfig *assigned_location;
|
||||
|
||||
@@ -91,8 +88,6 @@ class Client
|
||||
std::string get_rq_query() const;
|
||||
std::string get_rq_version() const;
|
||||
std::string get_rq_body() const;
|
||||
std::string get_rq_port() const;
|
||||
std::string get_rq_hostname() const;
|
||||
std::string get_rq_script_path() const;
|
||||
std::string get_rq_script_info() const;
|
||||
std::string get_rq_headers(const std::string & key) const;
|
||||
@@ -120,7 +115,6 @@ class Client
|
||||
void _parse_request_line();
|
||||
void _parse_request_fields();
|
||||
void _parse_request_target( std::string target );
|
||||
void _parse_port_hostname(std::string host);
|
||||
void _parse_chunked_body(size_t pos);
|
||||
void _parse_multipart_body(size_t pos);
|
||||
void _check_request_errors();
|
||||
|
||||
@@ -36,8 +36,6 @@ void Client::_parse_multipart_body(size_t pos)
|
||||
}
|
||||
start_pos += sizeof("boundary=")-1;
|
||||
boundary = boundary.substr(start_pos);
|
||||
std::cerr << "boundary =|" << boundary << "|\n";
|
||||
|
||||
|
||||
// Search boundary
|
||||
start_pos = raw_request.find("--" + boundary, pos);
|
||||
@@ -48,7 +46,7 @@ void Client::_parse_multipart_body(size_t pos)
|
||||
}
|
||||
start_pos += sizeof("--")-1 + boundary.size() + CRLF_SIZE;
|
||||
|
||||
while (1) // TODO : test loop for multi body
|
||||
while (1)
|
||||
{
|
||||
end_pos = raw_request.find("--" + boundary, start_pos);
|
||||
if (end_pos == NPOS)
|
||||
@@ -56,9 +54,6 @@ void Client::_parse_multipart_body(size_t pos)
|
||||
status = 400; std::cerr << "_parse_multipart_body() error 3\n";
|
||||
return;
|
||||
}
|
||||
/* // Maye useful for multi body (remove "start_pos - CRLF_SIZE" if used)
|
||||
end_pos = raw_request.rfind(CRLF, end_pos); if (end_pos == NPOS) {status = 400; return; } */
|
||||
|
||||
new_body.body = raw_request.substr(start_pos, end_pos - start_pos - CRLF_SIZE);
|
||||
|
||||
// Split headers from body
|
||||
@@ -74,7 +69,6 @@ void Client::_parse_multipart_body(size_t pos)
|
||||
}
|
||||
tmp_pos += CRLF_SIZE*2;
|
||||
new_body.body.erase(0, tmp_pos);
|
||||
// ::print_map(new_body.headers);
|
||||
}
|
||||
else
|
||||
{ // No headers case
|
||||
@@ -94,10 +88,5 @@ void Client::_parse_multipart_body(size_t pos)
|
||||
&& raw_request[start_pos] == '-'
|
||||
&& raw_request[start_pos+1] == '-')
|
||||
break;
|
||||
|
||||
/* ::print_special(raw_request);
|
||||
std::cerr << "start_pos = " << start_pos << "\n";
|
||||
std::cerr << "raw_request.size() = " << raw_request.size() << "\n";
|
||||
std::cerr << raw_request.substr(start_pos); */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,4 +92,3 @@ fclean: clean
|
||||
re: fclean all
|
||||
|
||||
.PHONY : all clean fclean re
|
||||
|
||||
|
||||
@@ -14,46 +14,41 @@
|
||||
# include <cstdlib> // strtol, stroul
|
||||
# include <iostream> // cout, cin
|
||||
# include <fstream> // ifstream
|
||||
# include <sys/stat.h> // stat(), replaces opendir() don't bother with ERRNO ?
|
||||
# include <algorithm> // sort() in Post
|
||||
|
||||
class ConfigParser {
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
ConfigParser();
|
||||
~ConfigParser();
|
||||
ConfigParser(const std::string &config_file);
|
||||
ConfigParser();
|
||||
~ConfigParser();
|
||||
ConfigParser(const std::string &config_file);
|
||||
|
||||
void read_config(const std::string &config_file);
|
||||
void read_config(const std::string &config_file);
|
||||
|
||||
std::vector<ServerConfig> * parse(); // const?
|
||||
std::vector<ServerConfig> *parse() const;
|
||||
|
||||
void print_content() const;
|
||||
|
||||
// i thought if it were an instance of this class you could call
|
||||
// private member functions from anywhere... // QUESTION : Wut ?
|
||||
void print_content() const;
|
||||
private:
|
||||
std::string _content;
|
||||
|
||||
ServerConfig _parse_server(size_t *start) const;
|
||||
LocationConfig _parse_location(size_t *start) const;
|
||||
|
||||
private:
|
||||
std::string _content;
|
||||
void _set_server_values(ServerConfig *server, const std::string &key, std::string value) const;
|
||||
void _set_location_values(LocationConfig *location, const std::string &key, std::string value) const;
|
||||
|
||||
ServerConfig _parse_server(size_t *start);
|
||||
LocationConfig _parse_location(size_t *start);
|
||||
/* Extra */
|
||||
std::string _pre_set_val_check(const std::string &key,
|
||||
const std::string &value) const;
|
||||
|
||||
void _set_server_values(ServerConfig *server, const std::string key, std::string value);
|
||||
void _set_location_values(LocationConfig *location, const std::string key, std::string value);
|
||||
std::string _get_first_word(size_t *curr) const;
|
||||
std::string _get_rest_of_line(size_t *curr) const;
|
||||
|
||||
/* Extra */
|
||||
std::string _pre_set_val_check(const std::string key,
|
||||
const std::string value);
|
||||
|
||||
std::string _get_first_word(size_t *curr); // const?
|
||||
std::string _get_rest_of_line(size_t *curr); // const?
|
||||
|
||||
/* Post Processing */
|
||||
void _post_processing(std::vector<ServerConfig> *servers);
|
||||
bool _find_root_path_location(std::vector<LocationConfig> locations) const;
|
||||
/* Post Processing */
|
||||
void _post_processing(std::vector<ServerConfig> *servers) const;
|
||||
bool _find_root_path_location(std::vector<LocationConfig> locations) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
|
||||
#include "ConfigParser.hpp"
|
||||
|
||||
// should i be sending & references?
|
||||
// const?
|
||||
std::string ConfigParser::_pre_set_val_check(const std::string key,
|
||||
const std::string value)
|
||||
std::string ConfigParser::_pre_set_val_check(const std::string &key,
|
||||
const std::string &value) const
|
||||
{
|
||||
|
||||
// check key for ;
|
||||
// check values for ; at end and right number of words depending on key
|
||||
|
||||
// std::cout << "pre check\n";
|
||||
if (key.find_first_of(";") != NPOS)
|
||||
throw std::invalid_argument("bad config file arguments");
|
||||
|
||||
@@ -30,9 +27,8 @@ std::string ConfigParser::_pre_set_val_check(const std::string key,
|
||||
return (value.substr(0, i));
|
||||
}
|
||||
|
||||
// const?
|
||||
// assumes curr is on a space or \t or \n
|
||||
std::string ConfigParser::_get_first_word(size_t *curr)
|
||||
std::string ConfigParser::_get_first_word(size_t *curr) const
|
||||
{
|
||||
size_t start;
|
||||
|
||||
@@ -45,9 +41,8 @@ std::string ConfigParser::_get_first_word(size_t *curr)
|
||||
return (key);
|
||||
}
|
||||
|
||||
// const?
|
||||
// also assumes curr is on a space \t or \n
|
||||
std::string ConfigParser::_get_rest_of_line(size_t *curr)
|
||||
std::string ConfigParser::_get_rest_of_line(size_t *curr) const
|
||||
{
|
||||
size_t start;
|
||||
|
||||
|
||||
@@ -41,8 +41,7 @@ void ConfigParser::read_config(const std::string &config_file)
|
||||
}
|
||||
}
|
||||
|
||||
// const?
|
||||
std::vector<ServerConfig> * ConfigParser::parse()
|
||||
std::vector<ServerConfig> * ConfigParser::parse() const
|
||||
{
|
||||
std::vector<ServerConfig> * ret = new std::vector<ServerConfig>();
|
||||
|
||||
@@ -67,7 +66,7 @@ std::vector<ServerConfig> * ConfigParser::parse()
|
||||
return (ret);
|
||||
}
|
||||
|
||||
ServerConfig ConfigParser::_parse_server(size_t *start)
|
||||
ServerConfig ConfigParser::_parse_server(size_t *start) const
|
||||
{
|
||||
ServerConfig ret;
|
||||
size_t curr = _content.find_first_not_of(" \t\n", *start);
|
||||
@@ -78,7 +77,6 @@ ServerConfig ConfigParser::_parse_server(size_t *start)
|
||||
|
||||
if ((curr = _content.find_first_of(" \t\n", curr + 1)) == NPOS)
|
||||
throw std::invalid_argument("bad config file syntax");
|
||||
// are there other things to check for?
|
||||
while (curr != NPOS) // here curr == { + 1
|
||||
{
|
||||
// so this moves curr to past the word...
|
||||
@@ -104,7 +102,7 @@ ServerConfig ConfigParser::_parse_server(size_t *start)
|
||||
|
||||
|
||||
|
||||
LocationConfig ConfigParser::_parse_location(size_t *start)
|
||||
LocationConfig ConfigParser::_parse_location(size_t *start) const
|
||||
{
|
||||
LocationConfig ret;
|
||||
size_t curr = *start;
|
||||
@@ -148,11 +146,9 @@ LocationConfig ConfigParser::_parse_location(size_t *start)
|
||||
|
||||
|
||||
|
||||
// should i be sending pointers or references?
|
||||
void ConfigParser::_set_server_values(ServerConfig *server,
|
||||
const std::string key, std::string value)
|
||||
const std::string &key, std::string value) const
|
||||
{
|
||||
// should i be sending pointers or references?
|
||||
value = _pre_set_val_check(key, value);
|
||||
|
||||
std::vector<std::string> tmp_val = ::split(value, ' ');
|
||||
@@ -174,11 +170,11 @@ void ConfigParser::_set_server_values(ServerConfig *server,
|
||||
}
|
||||
}
|
||||
else if (key == "listen" && size == 1 && server->host == ""
|
||||
&& server->port == "") // QUESTION LUKE : C'est quoi cette condition ? Si listen est vide ? Je comprends pas trop.
|
||||
&& server->port == "")
|
||||
{
|
||||
if (tmp_val[0].find_first_of(":") == NPOS)
|
||||
{
|
||||
if (!::isNumeric_btw(0, 65535, tmp_val[0]))
|
||||
if (!::is_numeric_btw(0, 65535, tmp_val[0]))
|
||||
throw std::invalid_argument("bad port number");
|
||||
server->host = "0.0.0.0";
|
||||
server->port = tmp_val[0];
|
||||
@@ -192,10 +188,10 @@ void ConfigParser::_set_server_values(ServerConfig *server,
|
||||
throw std::invalid_argument("bad host ip");
|
||||
for (size_t i = 0; i < ip.size(); i++)
|
||||
{
|
||||
if (!::isNumeric_btw(0, 255, ip[i]))
|
||||
if (!::is_numeric_btw(0, 255, ip[i]))
|
||||
throw std::invalid_argument("bad host ip");
|
||||
}
|
||||
if (!::isNumeric_btw(0, 65535, tmp2[1]))
|
||||
if (!::is_numeric_btw(0, 65535, tmp2[1]))
|
||||
throw std::invalid_argument("bad port number");
|
||||
server->host = tmp2[0];
|
||||
server->port = tmp2[1];
|
||||
@@ -206,13 +202,12 @@ void ConfigParser::_set_server_values(ServerConfig *server,
|
||||
// remove trailing /
|
||||
if (tmp_val[0][tmp_val[0].size() - 1] == '/')
|
||||
tmp_val[0].erase(tmp_val[0].size() - 1, 1);
|
||||
// tmp_val[0].push_back('/');
|
||||
server->root = tmp_val[0];
|
||||
}
|
||||
else if (key == "client_body_limit" && size == 1
|
||||
&& server->client_body_limit == 0)
|
||||
{
|
||||
if (!::isNumeric(tmp_val[0]))
|
||||
if (!::is_numeric(tmp_val[0]))
|
||||
throw std::invalid_argument("client_body_limit not a number");
|
||||
server->client_body_limit = std::strtoul(tmp_val[0].c_str(), NULL, 10);
|
||||
if (errno == ERANGE || server->client_body_limit > (ULONG_MAX / KB) )
|
||||
@@ -229,7 +224,7 @@ void ConfigParser::_set_server_values(ServerConfig *server,
|
||||
std::string path = tmp_val[size - 1];
|
||||
for (size_t i = 0; i < size - 1; i++)
|
||||
{
|
||||
if (!(isNumeric_btw(400, 599, tmp_val[i])))
|
||||
if (!(is_numeric_btw(400, 599, tmp_val[i])))
|
||||
throw std::invalid_argument("invalid error code");
|
||||
int status_code = std::strtoul(tmp_val[i].c_str(), NULL, 10);
|
||||
if (server->error_pages.find(status_code) != server->error_pages.end())
|
||||
@@ -242,11 +237,9 @@ void ConfigParser::_set_server_values(ServerConfig *server,
|
||||
}
|
||||
|
||||
|
||||
// should i be sending pointers or references?
|
||||
void ConfigParser::_set_location_values(LocationConfig *location,
|
||||
const std::string key, std::string value)
|
||||
const std::string &key, std::string value) const
|
||||
{
|
||||
// should i be sending pointers or references?
|
||||
value = _pre_set_val_check(key, value);
|
||||
|
||||
std::vector<std::string> tmp_val = ::split(value, ' ');
|
||||
@@ -259,7 +252,6 @@ void ConfigParser::_set_location_values(LocationConfig *location,
|
||||
// remove trailing /
|
||||
if (tmp_val[0][tmp_val[0].size() - 1] == '/')
|
||||
tmp_val[0].erase(tmp_val[0].size() - 1, 1);
|
||||
// tmp_val[0].push_back('/');
|
||||
location->root = tmp_val[0];
|
||||
}
|
||||
else if (key == "autoindex" && size == 1)
|
||||
@@ -306,7 +298,6 @@ void ConfigParser::_set_location_values(LocationConfig *location,
|
||||
}
|
||||
else if (key == "upload_dir" && size == 1 && location->upload_dir == "")
|
||||
{
|
||||
// what checks to do?
|
||||
// add trailing /
|
||||
if (tmp_val[0][tmp_val[0].size() - 1] != '/')
|
||||
tmp_val[0].push_back('/');
|
||||
|
||||
@@ -3,21 +3,18 @@
|
||||
|
||||
#include "ConfigParser.hpp"
|
||||
|
||||
void ConfigParser::_post_processing(std::vector<ServerConfig> *servers)
|
||||
void ConfigParser::_post_processing(std::vector<ServerConfig> *servers) const
|
||||
{
|
||||
std::vector<ServerConfig>::iterator it = servers->begin();
|
||||
|
||||
while (it != servers->end())
|
||||
{
|
||||
// host and port are Mandatory
|
||||
if (it->host == "")
|
||||
throw std::invalid_argument("Config file needs a host and port");
|
||||
|
||||
// root is mandatory
|
||||
if (it->root == "")
|
||||
throw std::invalid_argument("Config file needs a root");
|
||||
|
||||
// index is mandatory in Server
|
||||
if (it->index.empty())
|
||||
throw std::invalid_argument("Config file needs an Index");
|
||||
|
||||
|
||||
@@ -15,24 +15,9 @@ int main(int ac, char **av)
|
||||
ConfigParser configParser(config);
|
||||
// configParser.print_content();
|
||||
|
||||
// i don't love that servers_config has to be a pointer...
|
||||
servers_config = configParser.parse();
|
||||
|
||||
// use an iterator you moron
|
||||
for (std::vector<ServerConfig>::iterator it = servers_config->begin(); it < servers_config->end(); it++)
|
||||
{
|
||||
(void)0;
|
||||
// std::cout << it->server_name << " ";
|
||||
// it->print_all();
|
||||
}
|
||||
|
||||
|
||||
// Webserv serv(configParser.parse());
|
||||
// is this better or worse than using
|
||||
|
||||
Webserv serv;
|
||||
|
||||
// serv.init_virtual_servers();
|
||||
serv.init_virtual_servers(servers_config);
|
||||
delete servers_config;
|
||||
servers_config = NULL;
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
|
||||
#include "utils.hpp"
|
||||
|
||||
void throw_test()
|
||||
{
|
||||
static int i = 0;
|
||||
++i;
|
||||
if (i % 8 == 0)
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
// notice : the use of getline make it such as
|
||||
// it doesn't identify multiple delim as one :
|
||||
// " something \n else " -> 1 - something
|
||||
@@ -72,19 +64,6 @@ std::string trim(std::string str, char del)
|
||||
return str;
|
||||
}
|
||||
|
||||
//// trim a set of char
|
||||
//std::string trim(std::string str, std::string del)
|
||||
//{
|
||||
// std::string new_str;
|
||||
//
|
||||
// while (new_str.compare(str) != 0)
|
||||
// {
|
||||
// for (size_t i = 0; i < del.size(); i++)
|
||||
// trim(str, del[i]);
|
||||
// }
|
||||
// return str;
|
||||
//}
|
||||
|
||||
std::string itos(int n)
|
||||
{
|
||||
std::stringstream strs;
|
||||
@@ -93,7 +72,7 @@ std::string itos(int n)
|
||||
return ( strs.str() );
|
||||
}
|
||||
|
||||
bool isNumeric(std::string str)
|
||||
bool is_numeric(std::string str)
|
||||
{
|
||||
for (size_t i = 0; i < str.length(); i++)
|
||||
{
|
||||
@@ -103,7 +82,7 @@ bool isNumeric(std::string str)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isNumeric_btw(int low, int high, std::string str)
|
||||
bool is_numeric_btw(int low, int high, std::string str)
|
||||
{
|
||||
for (size_t i = 0; i < str.length(); i++)
|
||||
{
|
||||
@@ -155,7 +134,7 @@ file_type eval_file_type(const std::string &path)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
if (stat(path.c_str(), &s) != -1)
|
||||
if (::stat(path.c_str(), &s) != -1)
|
||||
{
|
||||
if (S_ISREG(s.st_mode))
|
||||
return (IS_FILE);
|
||||
@@ -305,6 +284,15 @@ void str_map_key_tolower(std::map<std::string, std::string> & mp)
|
||||
}
|
||||
|
||||
// DEBUG
|
||||
|
||||
void throw_test()
|
||||
{
|
||||
static int i = 0;
|
||||
++i;
|
||||
if (i % 8 == 0)
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
void print_special(std::string str)
|
||||
{
|
||||
char c;
|
||||
@@ -318,10 +306,12 @@ void print_special(std::string str)
|
||||
std::cout << YELLOW << "\\n" << RESET << "\n";
|
||||
else
|
||||
std::cout << c;
|
||||
fflush(stdout);
|
||||
std::fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
// OVERLOADS
|
||||
|
||||
bool operator==(const listen_socket& lhs, int fd)
|
||||
{ return lhs.fd == fd; }
|
||||
|
||||
|
||||
@@ -45,8 +45,6 @@ enum http_method
|
||||
POST = 1 << 1,
|
||||
DELETE = 1 << 2,
|
||||
ANY_METHODS = 0b11111111,
|
||||
// ALL_METHODS = 0b11111111,
|
||||
// i would prefer this...
|
||||
};
|
||||
|
||||
struct listen_socket
|
||||
@@ -60,8 +58,8 @@ bool operator==(int fd, const listen_socket& rhs);
|
||||
|
||||
std::vector<std::string> split(std::string input, char delimiter);
|
||||
std::vector<std::string> split_trim(std::string input, std::string delim = "\n", char ctrim = '\0');
|
||||
bool isNumeric(std::string str);
|
||||
bool isNumeric_btw(int low, int high, std::string str);
|
||||
bool is_numeric(std::string str);
|
||||
bool is_numeric_btw(int low, int high, std::string str);
|
||||
std::string itos(int n);
|
||||
std::string trim(std::string str, char del);
|
||||
http_method str_to_http_method(std::string &str);
|
||||
@@ -76,7 +74,7 @@ size_t parse_http_headers (std::string headers, std::map<std::string, std::
|
||||
void str_map_key_tolower(std::map<std::string, std::string> & mp);
|
||||
// debug
|
||||
void throw_test();
|
||||
void print_special(std::string str);
|
||||
void print_special(std::string str);
|
||||
|
||||
|
||||
/* Template */
|
||||
|
||||
@@ -38,10 +38,6 @@ extern bool g_run;
|
||||
extern int g_last_signal;
|
||||
void signal_handler(int signum);
|
||||
|
||||
// these might only be TMP
|
||||
# define FAILURE -1
|
||||
# define SUCCESS 1
|
||||
|
||||
# define MIME_TYPE_DEFAULT "application/octet-stream"
|
||||
|
||||
class Webserv
|
||||
@@ -49,13 +45,7 @@ class Webserv
|
||||
public:
|
||||
// base.cpp
|
||||
Webserv();
|
||||
// Webserv(Webserv const &src);
|
||||
|
||||
// what should it take as arg, *, &, ?
|
||||
// Webserv(std::vector<ServerConfig>& servers);
|
||||
|
||||
~Webserv();
|
||||
// Webserv &operator=(Webserv const &rhs);
|
||||
|
||||
// init.cpp
|
||||
void init_virtual_servers(std::vector<ServerConfig>* servers);
|
||||
|
||||
@@ -18,7 +18,12 @@ void Webserv::_accept_connection(listen_socket &lsocket)
|
||||
_handle_last_signal();
|
||||
return ;
|
||||
}
|
||||
::fcntl(accepted_fd, F_SETFL, O_NONBLOCK);
|
||||
if (::fcntl(accepted_fd, F_SETFL, O_NONBLOCK) == -1)
|
||||
{
|
||||
std::perror("err fcntl()");
|
||||
if (::close(accepted_fd) == -1)
|
||||
std::perror("err close()");
|
||||
}
|
||||
|
||||
infos = _extract_infos(addr);
|
||||
Client new_client(accepted_fd, &lsocket, infos["port"], infos["ip"]);
|
||||
|
||||
@@ -19,30 +19,6 @@ Webserv::Webserv()
|
||||
std::signal(SIGINT, signal_handler);
|
||||
}
|
||||
|
||||
/* Webserv::Webserv(Webserv const &src)
|
||||
{
|
||||
|
||||
} */
|
||||
|
||||
// we'll come back to this
|
||||
/*
|
||||
Webserv::Webserv(std::vector<ServerConfig>* servers)
|
||||
: _servers(servers)
|
||||
{
|
||||
// talk to luke about what all this does
|
||||
// the Param Constructor might need to do dif stuff
|
||||
std::cout << "Server init\n";
|
||||
|
||||
_epfd = ::epoll_create1(0); // (EPOLL_CLOEXEC) for CGI fork ?
|
||||
if (_epfd == -1)
|
||||
{
|
||||
std::perror("err epoll_create1(): ");
|
||||
throw std::runtime_error("Epoll init");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
Webserv::~Webserv()
|
||||
{
|
||||
close(_epfd);
|
||||
@@ -50,8 +26,3 @@ Webserv::~Webserv()
|
||||
_close_all_listen_sockets();
|
||||
std::cerr << "Server destroyed\n";
|
||||
}
|
||||
|
||||
/* Webserv & Webserv::operator=(Webserv const &rhs)
|
||||
{
|
||||
|
||||
} */
|
||||
|
||||
@@ -101,7 +101,6 @@ void Webserv::_cgi_open_pipes(Client *client)
|
||||
|
||||
void Webserv::_write_body_to_cgi(Client *client)
|
||||
{
|
||||
std::cerr << "_write_body_to_cgi()"; // DEBUG
|
||||
ssize_t ret;
|
||||
std::string body = client->get_rq_body();
|
||||
|
||||
@@ -157,25 +156,24 @@ std::string Webserv::_dup_env(std::string var, int i)
|
||||
return (str);
|
||||
}
|
||||
|
||||
// TODO : verifier que les variables sont corrects
|
||||
/*
|
||||
https://www.rfc-editor.org/rfc/rfc3875#section-4.1
|
||||
*/
|
||||
void Webserv::_set_env_vector(Client *client, std::vector<std::string> &env_vector)
|
||||
{
|
||||
env_vector.push_back(_dup_env("AUTH_TYPE")); // authentification not supporte
|
||||
env_vector.push_back(_dup_env("AUTH_TYPE")); // authentification not supported
|
||||
env_vector.push_back(_dup_env("CONTENT_LENGTH" , client->get_rq_body().size()));
|
||||
env_vector.push_back(_dup_env("CONTENT_TYPE" , client->get_rq_headers("Content-Type")));
|
||||
env_vector.push_back(_dup_env("GATEWAY_INTERFACE" , "CGI/1.1")); // https://www.rfc-editor.org/rfc/rfc3875#section-4.1.4
|
||||
env_vector.push_back(_dup_env("PATH_INFO" , client->get_rq_script_info())); // LUKE: To Check
|
||||
env_vector.push_back(_dup_env("PATH_TRANSLATED")); // not supported // LUKE: Why not supported ?
|
||||
env_vector.push_back(_dup_env("PATH_INFO" , client->get_rq_script_info()));
|
||||
env_vector.push_back(_dup_env("PATH_TRANSLATED")); // not used
|
||||
env_vector.push_back(_dup_env("QUERY_STRING" , client->get_rq_query()));
|
||||
env_vector.push_back(_dup_env("REMOTE_ADDR" , client->get_cl_ip()));
|
||||
env_vector.push_back(_dup_env("REMOTE_HOST" , client->get_cl_ip())); // equal to REMOTE_ADDR or empty
|
||||
env_vector.push_back(_dup_env("REMOTE_IDENT")); // authentification not supported
|
||||
env_vector.push_back(_dup_env("REMOTE_USER")); // authentification not supported
|
||||
env_vector.push_back(_dup_env("REQUEST_METHOD" , client->get_rq_method_str()));
|
||||
env_vector.push_back(_dup_env("SCRIPT_NAME" , "/" + client->get_rq_script_path())); // LUKE: To Check
|
||||
env_vector.push_back(_dup_env("SCRIPT_NAME" , "/" + client->get_rq_script_path()));
|
||||
env_vector.push_back(_dup_env("SERVER_NAME" , client->get_cl_lsocket()->host));
|
||||
env_vector.push_back(_dup_env("SERVER_PORT" , client->get_cl_lsocket()->port));
|
||||
env_vector.push_back(_dup_env("SERVER_PROTOCOL" , "HTTP/1.1"));
|
||||
@@ -279,15 +277,10 @@ void Webserv::_check_script_output(Client *client, std::string & output)
|
||||
_check_script_status(client, output);
|
||||
if (client->status >= 400 && client->status < 600)
|
||||
return;
|
||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[script status]:\n" << "client->status:[" << client->status << "]" RESET "\n"; ::print_special(output); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
client->status = _check_script_fields(output, client->status);
|
||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[script fields]:\n" << "client->status:[" << client->status << "]" RESET "\n"; ::print_special(output); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
_check_fields_duplicates(client, output);
|
||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[fields duplicates]:\n" << "client->status:[" << client->status << "]" RESET "\n"; ::print_special(output); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
_remove_body_leading_empty_lines(output);
|
||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[script empty lines]:\n" << "client->status:[" << client->status << "]" RESET "\n"; ::print_special(output); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
_add_script_body_length_header(output);
|
||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[script content length]:\n" << "client->status:[" << client->status << "]" RESET "\n"; ::print_special(output); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
}
|
||||
|
||||
void Webserv::_check_script_status(Client *client, std::string & output)
|
||||
@@ -424,4 +417,3 @@ void Webserv::_add_script_body_length_header(std::string & output)
|
||||
tmp += CRLF;
|
||||
output.insert(0, tmp);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,8 @@ void Webserv::_read_cgi_output(Client *client)
|
||||
{
|
||||
char buf[BUFSIZE];
|
||||
ssize_t ret;
|
||||
std::cerr << "_read_cgi_output()" << "\n"; // Debug
|
||||
std::cerr << "cgi_pid = " << client->cgi_pid << "\n"; // Debug
|
||||
std::cerr << "client fd = " << client->get_cl_fd() << "\n"; // Debug
|
||||
std::cerr << "cgi fd = " << client->cgi_pipe_r_from_child << "\n"; // Debug
|
||||
|
||||
ret = ::read(client->cgi_pipe_r_from_child, buf, BUFSIZE);
|
||||
std::cerr << "cgi read ret = " << ret << "\n"; // Debug
|
||||
if (ret == -1)
|
||||
{
|
||||
std::perror("err read(cgi_fd)");
|
||||
@@ -29,10 +24,6 @@ void Webserv::_read_cgi_output(Client *client)
|
||||
void Webserv::_handle_epollerr_cgi_output(uint32_t events, Client *client)
|
||||
{
|
||||
(void)events;
|
||||
std::cerr << "cgi EPOLLERR" << "\n";
|
||||
std::cerr << "cgi_pid = " << client->cgi_pid << "\n";
|
||||
std::cerr << "client fd = " << client->get_cl_fd() << "\n";
|
||||
std::cerr << "cgi fd = " << client->cgi_pipe_r_from_child << "\n";
|
||||
|
||||
client->status = 500;
|
||||
client->cgi_state = CGI_NO_CGI;
|
||||
@@ -40,7 +31,6 @@ void Webserv::_handle_epollerr_cgi_output(uint32_t events, Client *client)
|
||||
// Common with EPOLLHUP
|
||||
pid_t wait_ret;
|
||||
wait_ret = ::waitpid(client->cgi_pid, NULL, WNOHANG);
|
||||
std::cerr << "cgi EPOLLERR waitpid ret = " << wait_ret << "\n";
|
||||
if (wait_ret == client->cgi_pid)
|
||||
{
|
||||
_epoll_update(client->cgi_pipe_r_from_child, 0, EPOLL_CTL_DEL);
|
||||
@@ -55,17 +45,10 @@ void Webserv::_handle_epollerr_cgi_output(uint32_t events, Client *client)
|
||||
void Webserv::_handle_epollhup_cgi_output(uint32_t events, Client *client)
|
||||
{
|
||||
(void)events;
|
||||
(void)client;
|
||||
|
||||
/* std::cerr << "cgi EPOLLHUP" << "\n";
|
||||
std::cerr << "cgi_pid = " << client->cgi_pid << "\n";
|
||||
std::cerr << "client fd = " << client->get_cl_fd() << "\n";
|
||||
std::cerr << "cgi fd = " << client->cgi_pipe_r_from_child << "\n"; */
|
||||
|
||||
// Common with EPOLLERR
|
||||
pid_t wait_ret;
|
||||
wait_ret = ::waitpid(client->cgi_pid, NULL, WNOHANG);
|
||||
// std::cerr << "cgi EPOLLHUP waitpid ret = " << wait_ret << "\n";
|
||||
if (wait_ret == client->cgi_pid)
|
||||
{
|
||||
_epoll_update(client->cgi_pipe_r_from_child, 0, EPOLL_CTL_DEL);
|
||||
|
||||
@@ -9,12 +9,10 @@ void Webserv::_close_client(int fd)
|
||||
{
|
||||
if (*it == fd)
|
||||
{
|
||||
// _epoll_update(fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG
|
||||
std::cerr << "close client fd " << fd << "\n";
|
||||
if (::close(fd) == -1)
|
||||
std::perror("err close()");
|
||||
_close_client_cgi_pipes(&(*it));
|
||||
// it->clear(); // PISTE, debug normalement superflu
|
||||
_clients.erase(it);
|
||||
break;
|
||||
}
|
||||
@@ -48,15 +46,7 @@ void Webserv::_close_client_cgi_pipes(Client *client)
|
||||
void Webserv::_close_all_clients()
|
||||
{
|
||||
_close_all_clients_fd();
|
||||
|
||||
_clients.clear();
|
||||
// REMPLACEMENT ->
|
||||
/* while (!_clients.empty())
|
||||
{
|
||||
std::cerr << "_clients.pop_back() " << &_clients.back() << "\n";
|
||||
_clients.back().clear();
|
||||
_clients.pop_back();
|
||||
} */
|
||||
}
|
||||
|
||||
void Webserv::_close_all_clients_fd()
|
||||
@@ -66,7 +56,6 @@ void Webserv::_close_all_clients_fd()
|
||||
std::vector<Client>::iterator it_end = _clients.end();
|
||||
while (it != it_end)
|
||||
{
|
||||
// _epoll_update(_clients.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG
|
||||
std::cerr << "close client fd " << it->get_cl_fd() << "\n";
|
||||
if (::close(it->get_cl_fd()) == -1)
|
||||
std::perror("err close()");
|
||||
@@ -80,7 +69,6 @@ void Webserv::_close_all_clients_cgi_pipes()
|
||||
std::vector<Client>::iterator it_end = _clients.end();
|
||||
while (it != it_end)
|
||||
{
|
||||
// _epoll_update(_clients.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG
|
||||
_close_client_cgi_pipes(&(*it));
|
||||
++it;
|
||||
}
|
||||
@@ -91,7 +79,6 @@ void Webserv::_close_all_listen_sockets()
|
||||
{ // TODO : change like clients (clear in place of pop_back)
|
||||
while (!_listen_sockets.empty())
|
||||
{
|
||||
// _epoll_update(_listen_sockets.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG
|
||||
std::cerr << "close lsocket fd " << _listen_sockets.back().fd << "\n";
|
||||
if (::close(_listen_sockets.back().fd) == -1)
|
||||
std::perror("err close()");
|
||||
@@ -99,11 +86,11 @@ void Webserv::_close_all_listen_sockets()
|
||||
}
|
||||
}
|
||||
|
||||
void Webserv::_reopen_lsocket(std::vector<listen_socket>::iterator it)
|
||||
{
|
||||
/*
|
||||
** Many common code with init_virtual_servers(). Could refactor it.
|
||||
*/
|
||||
void Webserv::_reopen_lsocket(std::vector<listen_socket>::iterator it)
|
||||
{
|
||||
int ret;
|
||||
|
||||
std::cerr << "close lsocket " << it->fd << "\n";
|
||||
@@ -119,9 +106,8 @@ void Webserv::_reopen_lsocket(std::vector<listen_socket>::iterator it)
|
||||
}
|
||||
it->fd = ret;
|
||||
|
||||
// HUGO ADD
|
||||
// From : https://www.ibm.com/docs/en/i/7.2?topic=designs-example-nonblocking-io-select
|
||||
// allow socket descriptor to be reuseable
|
||||
// I just copied it from https://www.ibm.com/docs/en/i/7.2?topic=designs-example-nonblocking-io-select
|
||||
int on = 1;
|
||||
if (setsockopt(it->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
||||
{
|
||||
@@ -129,7 +115,6 @@ void Webserv::_reopen_lsocket(std::vector<listen_socket>::iterator it)
|
||||
_listen_sockets.erase(it);
|
||||
return;
|
||||
}
|
||||
// HUGO ADD END
|
||||
|
||||
try {
|
||||
_bind(it->fd, std::strtoul(it->port.c_str(), NULL, 10), it->host);
|
||||
@@ -164,8 +149,5 @@ void Webserv::_handle_epoll_error_client(uint32_t events, int fd)
|
||||
std::cerr << "EPOLLERR on client fd " << fd << "\n"; // DEBUG
|
||||
if (events & EPOLLHUP)
|
||||
std::cerr << "EPOLLHUP on client fd " << fd << "\n"; // DEBUG
|
||||
if (std::find(_clients.begin(), _clients.end(), fd) != _clients.end())
|
||||
std::cerr << "Found the client in _clients" << "\n"; // DEBUG
|
||||
|
||||
_close_client(fd); // " EPOLLHUP on client fd 8 " en boucle quand on mattraque un peu les CGI, donc il ne le trouve pas dans _clients. Etrange.
|
||||
_close_client(fd);
|
||||
}
|
||||
|
||||
@@ -35,18 +35,14 @@ void Webserv::init_virtual_servers(std::vector<ServerConfig>* servers)
|
||||
new_socket.port = it->port;
|
||||
_listen_sockets.push_back(new_socket);
|
||||
|
||||
// HUGO ADD
|
||||
//
|
||||
// From : https://www.ibm.com/docs/en/i/7.2?topic=designs-example-nonblocking-io-select
|
||||
// allow socket descriptor to be reuseable
|
||||
// I just copied it from https://www.ibm.com/docs/en/i/7.2?topic=designs-example-nonblocking-io-select
|
||||
int on = 1;
|
||||
if (setsockopt(new_socket.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
||||
if (setsockopt(new_socket.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
||||
{
|
||||
::perror("err setsockopt()");
|
||||
throw std::runtime_error("Socket init");
|
||||
}
|
||||
//
|
||||
// HUGO ADD END
|
||||
|
||||
_bind(new_socket.fd, std::strtoul(it->port.c_str(), NULL, 10), it->host);
|
||||
_listen(new_socket.fd, 42); // 42 arbitrary
|
||||
@@ -69,7 +65,6 @@ void Webserv::_bind(int socket_fd, in_port_t port, std::string host)
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = ::htons(port);
|
||||
addr.sin_addr.s_addr = ::htonl(::inet_addr(host.c_str()));
|
||||
// addr.sin_addr.s_addr = ::htonl(INADDR_ANY); // htonl useless with 0 value (INADDR_ANY) ?
|
||||
|
||||
if (::bind(socket_fd, (const sockaddr*)&addr, sizeof addr) == -1)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "Webserv.hpp"
|
||||
#define MAX_FILESIZE 1 * MB // unused
|
||||
|
||||
// const?
|
||||
/*
|
||||
https://www.rfc-editor.org/rfc/rfc9110.html#name-get
|
||||
*/
|
||||
@@ -84,7 +83,11 @@ if (size > MAX_FILESIZE)
|
||||
*/
|
||||
|
||||
|
||||
// const?
|
||||
/*
|
||||
<a href="http://nginx.org/">nginx.org</a>.<br/>
|
||||
<a href="/test/test_deeper/index1.html">index1.html</a>
|
||||
<a href="/test/test_deeper/..">..</a>
|
||||
*/
|
||||
void Webserv::_autoindex(Client *client, const std::string &path)
|
||||
{
|
||||
std::cout << "_autoindex()\n";
|
||||
@@ -93,7 +96,6 @@ void Webserv::_autoindex(Client *client, const std::string &path)
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
|
||||
// std::cout << "Path in auto is: " << path << '\n';
|
||||
if ( (dir = opendir(path.c_str()) ) != NULL)
|
||||
{
|
||||
dir_list.append(AUTOINDEX_START);
|
||||
@@ -117,13 +119,6 @@ void Webserv::_autoindex(Client *client, const std::string &path)
|
||||
dir_list.append("</a>");
|
||||
dir_list.append("\n");
|
||||
}
|
||||
|
||||
// <a href="http://nginx.org/">nginx.org</a>.<br/>
|
||||
// <a href="/test/test_deeper/index1.html">index1.html</a>
|
||||
|
||||
// apparently this is more than good enough!
|
||||
// <a href="/test/test_deeper/..">..</a>
|
||||
|
||||
dir_list.append(AUTOINDEX_END);
|
||||
closedir (dir);
|
||||
client->status = 200;
|
||||
|
||||
@@ -8,16 +8,14 @@ void Webserv::_post(Client *client, const std::string &path)
|
||||
{
|
||||
(void)path; // unused, we use "assigned_location->upload_dir" instead
|
||||
std::cout << "_post()\n";
|
||||
std::cerr << "upload_dir = " << client->assigned_location->upload_dir << "\n";
|
||||
|
||||
|
||||
if (client->get_rq_abs_path() != client->assigned_location->path)
|
||||
client->status = 404; // 404 ? J'ai un doute.
|
||||
client->status = 404; // 404 or other status better ?
|
||||
else if (client->assigned_location->upload_dir.empty())
|
||||
client->status = 404; // 404 ? J'ai un doute.
|
||||
client->status = 404; // 404 or other status better ?
|
||||
else if (client->get_rq_multi_bodys().empty())
|
||||
{
|
||||
client->status = 415;
|
||||
client->status = 415; // Unsupported Media Type
|
||||
client->response.append("Accept: multipart/form-data"); // empty, no encoding accepted
|
||||
client->response.append(CRLF);
|
||||
}
|
||||
@@ -25,7 +23,7 @@ void Webserv::_post(Client *client, const std::string &path)
|
||||
_upload_files(client);
|
||||
}
|
||||
|
||||
// #include <ctime> // could add date to DEFAULT_NAME to avoid overwriting files
|
||||
// #include <ctime> // TODO: could add date to DEFAULT_NAME to avoid overwriting files
|
||||
#define DEFAULT_NAME "unnamed_file"
|
||||
void Webserv::_upload_files(Client *client)
|
||||
{
|
||||
@@ -58,7 +56,7 @@ void Webserv::_upload_files(Client *client)
|
||||
{
|
||||
filename = filename.substr(pos + sizeof("filename=")-1);
|
||||
std::cerr << "filename ="<< filename << "\n";
|
||||
// A l'arrache pour enlever les "
|
||||
// Pour enlever les "
|
||||
filename.erase(0, 1);
|
||||
std::cerr << "filename ="<< filename << "\n";
|
||||
filename.erase(filename.size()-1, 1);
|
||||
@@ -69,7 +67,7 @@ void Webserv::_upload_files(Client *client)
|
||||
filename = DEFAULT_NAME + ::itos(i_name++);
|
||||
|
||||
std::cerr << "filename ="<< filename << "\n";
|
||||
path = client->assigned_location->upload_dir; // Assume there a final '/'
|
||||
path = client->assigned_location->upload_dir;
|
||||
path.append(filename);
|
||||
|
||||
|
||||
@@ -78,7 +76,6 @@ void Webserv::_upload_files(Client *client)
|
||||
else
|
||||
file_existed = true;
|
||||
|
||||
// How to determine status 403 for file that dont already exist ? access() on the upload_dir ?
|
||||
if (file_existed && ::access(path.c_str(), W_OK) == -1)
|
||||
{
|
||||
std::perror("err access()");
|
||||
|
||||
@@ -36,22 +36,15 @@ int Webserv::_read_request(Client *client)
|
||||
ssize_t ret;
|
||||
|
||||
ret = ::recv(client->get_cl_fd(), buf, BUFSIZE, 0);
|
||||
std::cerr << "recv() on fd(" << client->get_cl_fd() << ") returned = " << ret << "\n" ;
|
||||
std::cerr << "recv() on fd(" << client->get_cl_fd() << ") ret = " << ret << "\n" ;
|
||||
if (ret == -1)
|
||||
{
|
||||
std::perror("err recv()");
|
||||
return READ_CLOSE;
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
std::cerr << "recv() read 0, then close client" << "\n"; // DEBUG
|
||||
return READ_CLOSE;
|
||||
}
|
||||
client->raw_request.append(buf, ret);
|
||||
// ::print_special(client->raw_request);
|
||||
// std::cerr << "__raw_request__\n" << client->raw_request << "\n______\n"; // DEBUG
|
||||
|
||||
// print_special(client->raw_request);
|
||||
|
||||
if (!client->header_complete)
|
||||
{
|
||||
@@ -73,7 +66,6 @@ int Webserv::_read_request(Client *client)
|
||||
}
|
||||
if (client->header_complete)
|
||||
{
|
||||
// client->read_body_size += ret; // Not accurate, part of body could have been read with headers, unused for now
|
||||
client->parse_request_body();
|
||||
if (client->status || client->body_complete)
|
||||
return READ_COMPLETE;
|
||||
|
||||
@@ -22,10 +22,9 @@ void Webserv::_response(Client *client)
|
||||
else if (ret == SEND_COMPLETE)
|
||||
{
|
||||
if (client->get_rq_headers("Connection") == "close"
|
||||
|| client->status == 400 // TODO: Refactoring
|
||||
|| client->status == 400
|
||||
|| client->status == 408
|
||||
|| client->status == 413)
|
||||
// || client->cgi_state == CGI_OUTPUT_COMPLETE) // DEBUG
|
||||
_close_client(client->get_cl_fd());
|
||||
else
|
||||
{
|
||||
@@ -42,9 +41,7 @@ int Webserv::_send_response(Client *client)
|
||||
std::cerr << "send()\n";
|
||||
|
||||
if (client->response.empty())
|
||||
{
|
||||
_append_base_headers(client);
|
||||
}
|
||||
|
||||
if (!client->status)
|
||||
{
|
||||
@@ -58,34 +55,27 @@ int Webserv::_send_response(Client *client)
|
||||
if (client->status >= 400)
|
||||
_error_html_response(client);
|
||||
|
||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[response + output + headers]:" RESET "\n"; ::print_special(client->response); std::cout << "\n" B_PURPLE "-----------" RESET "\n\n";
|
||||
|
||||
// /* Debug */ std::cerr << "client->response.size() = " << client->response.size() << "\n"; // DEBUG
|
||||
ret = ::send(client->get_cl_fd(), client->response.c_str(), client->response.size(), 0);
|
||||
if (ret == -1)
|
||||
{
|
||||
std::perror("err send()");
|
||||
std::cerr << "client.fd =" << client->get_cl_fd() << "\n"; // DEBUG
|
||||
return SEND_CLOSE;
|
||||
}
|
||||
if (ret == 0) // actually never happen ?
|
||||
if (ret == 0)
|
||||
{
|
||||
std::cerr << "SEND RET 0 for client.fd =" << client->get_cl_fd() << "\n"; // DEBUG
|
||||
std::cerr << "send() ret == 0 never happens ?" << "\n"; // Debug
|
||||
return SEND_CLOSE;
|
||||
}
|
||||
// /* Debug */ std::cerr << "ret send() = " << ret << "\n"; // DEBUG
|
||||
|
||||
return SEND_COMPLETE;
|
||||
}
|
||||
|
||||
void Webserv::_append_base_headers(Client *client)
|
||||
{
|
||||
std::cerr << "_append_base_headers()\n"; // debug
|
||||
|
||||
client->response.append("Server: Webserv/0.1" CRLF);
|
||||
|
||||
if (client->get_rq_headers("Connection") == "close"
|
||||
|| client->status == 400 // TODO: Refactoring
|
||||
|| client->status == 400
|
||||
|| client->status == 408
|
||||
|| client->status == 413)
|
||||
client->response.append("Connection: close" CRLF);
|
||||
@@ -97,7 +87,7 @@ void Webserv::_construct_response(Client *client)
|
||||
{
|
||||
std::string path;
|
||||
std::string script_output;
|
||||
|
||||
|
||||
path = _replace_url_root(client, client->get_rq_abs_path());
|
||||
if (client->cgi_state == CGI_READY_TO_EXEC)
|
||||
{
|
||||
@@ -108,13 +98,9 @@ void Webserv::_construct_response(Client *client)
|
||||
}
|
||||
else if (client->cgi_state == CGI_OUTPUT_COMPLETE)
|
||||
{
|
||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[response]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[script output]:" RESET "\n"; ::print_special(client->cgi_output); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
_check_script_output(client, client->cgi_output); // FD_CGI : adjust for client->cgi_output;
|
||||
_check_script_output(client, client->cgi_output);
|
||||
if (client->status < 400 || client->status >= 600)
|
||||
client->response += client->cgi_output;
|
||||
// client->cgi_state = CGI_NO_CGI; // Not indispensable, reset when client.clear()
|
||||
// /*DEBUG*/ std::cout << "\n" B_PURPLE "[response + output]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n";
|
||||
}
|
||||
else if (_is_cgi(client, path))
|
||||
_cgi_open_pipes(client);
|
||||
@@ -124,9 +110,6 @@ void Webserv::_construct_response(Client *client)
|
||||
|
||||
void Webserv::_process_method(Client *client, std::string &path)
|
||||
{
|
||||
// std::cerr << "allow_methods = " << http_methods_to_str(client->assigned_location->allow_methods) << "\n"; // debug
|
||||
std::cerr << "Path again: " << path << '\n'; // debug
|
||||
|
||||
switch (client->get_rq_method())
|
||||
{
|
||||
case (GET):
|
||||
@@ -142,13 +125,10 @@ void Webserv::_process_method(Client *client, std::string &path)
|
||||
|
||||
std::string Webserv::_replace_url_root(Client *client, std::string path)
|
||||
{
|
||||
// /* Debug */ std::cerr << "assigned_location->path = " << client->assigned_location->path << "\n"; // debug
|
||||
// /* Debug */ std::cerr << "path before = " << path << "\n"; // DEBUG
|
||||
if (client->assigned_location->path == "/")
|
||||
path.insert(0, client->assigned_location->root);
|
||||
else
|
||||
path.replace(0, client->assigned_location->path.size(), client->assigned_location->root);
|
||||
// /* Debug */ std::cerr << "path after = " << path << "\n"; // DEBUG
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -212,4 +192,3 @@ void Webserv::_append_body(Client *client, const std::string &body, const std::s
|
||||
client->response.append(CRLF);
|
||||
client->response.append(body);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ void Webserv::run()
|
||||
Client *client_cgi_input = NULL;
|
||||
Client *client_cgi_output = NULL;
|
||||
|
||||
std::signal(SIGPIPE, signal_handler);
|
||||
std::signal(SIGINT, signal_handler);
|
||||
g_run = true;
|
||||
while (g_run)
|
||||
{
|
||||
@@ -29,7 +31,11 @@ void Webserv::run()
|
||||
if (errno_copy == EINTR)
|
||||
g_run = false;
|
||||
else
|
||||
{
|
||||
std::signal(SIGPIPE, SIG_DFL);
|
||||
std::signal(SIGINT, SIG_DFL);
|
||||
throw std::runtime_error("Epoll wait");
|
||||
}
|
||||
}
|
||||
else if (nfds == 0 && !_clients.empty())
|
||||
_timeout();
|
||||
@@ -101,4 +107,6 @@ void Webserv::run()
|
||||
}
|
||||
}
|
||||
}
|
||||
std::signal(SIGPIPE, SIG_DFL);
|
||||
std::signal(SIGINT, SIG_DFL);
|
||||
}
|
||||
|
||||
@@ -14,16 +14,10 @@ void Webserv::_handle_last_signal()
|
||||
if (g_last_signal == SIGPIPE)
|
||||
{
|
||||
std::cerr << "SIGPIPE\n";
|
||||
// if (_actual_client)
|
||||
// {
|
||||
// _close_client(_actual_client->fd);
|
||||
// _actual_client = NULL;
|
||||
// }
|
||||
}
|
||||
else if (g_last_signal == SIGINT)
|
||||
{
|
||||
g_run = false;
|
||||
// maybe a throw here instead of "g_run" ?
|
||||
}
|
||||
g_last_signal = 0;
|
||||
}
|
||||
|
||||
@@ -12,12 +12,7 @@ void Webserv::_timeout()
|
||||
std::cerr << "timeout request fd " << it->get_cl_fd() << "\n";
|
||||
it->status = 408;
|
||||
_epoll_update(it->get_cl_fd(), EPOLLOUT, EPOLL_CTL_MOD);
|
||||
|
||||
// DEBUG, close without repsonse 408
|
||||
/* _close_client(it->get_cl_fd());
|
||||
it = _clients.begin(); */
|
||||
}
|
||||
// else // DEBUG
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user