From d663a4c7e6e1f5226bb65152d964011a59c5f0da Mon Sep 17 00:00:00 2001 From: Hugo LAMY Date: Sun, 14 Aug 2022 16:17:24 +0200 Subject: [PATCH 1/8] added debug print --- srcs/Client.cpp | 5 ----- srcs/webserv/cgi_script.cpp | 9 +-------- srcs/webserv/response.cpp | 9 +++++++++ 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/srcs/Client.cpp b/srcs/Client.cpp index f101c03..2de52e4 100644 --- a/srcs/Client.cpp +++ b/srcs/Client.cpp @@ -213,18 +213,13 @@ void Client::fill_script_path(std::string &path, size_t pos) { std::string tmp; - /*DEBUG*/ std::cout << "\n" << B_PURPLE << "debug path dot" << RESET << "\npath:[" << path << "]\n" << "&path[pos]:[" << &path[pos] << "]\n"; if (path[0] == '.') { path.erase(0, 1); pos--; } - /*DEBUG*/ std::cout << "path:[" << path << "]\n" << "&path[pos]:[" << &path[pos] << "]\n"; - _request.script.path = path.substr(0, pos); - /*DEBUG*/ std::cout << "script_path:[" << _request.script.path << "]\n"; _request.script.info = path.substr(pos); - /*DEBUG*/ std::cout << "script_info:[" << _request.script.info << "]\n" << B_PURPLE << "end debug path dot" << RESET << "\n"; } void Client::clear() diff --git a/srcs/webserv/cgi_script.cpp b/srcs/webserv/cgi_script.cpp index e1b4d52..3981666 100644 --- a/srcs/webserv/cgi_script.cpp +++ b/srcs/webserv/cgi_script.cpp @@ -11,7 +11,6 @@ bool Webserv::_is_cgi(Client *client, std::string path) while (pos != NPOS) { pos = _cgi_pos(client, path, pos); - /*DEBUG*/ std::cout << "pos:" << pos << "\n&path[pos]:" << &path[pos] << "\n" << B_YELLOW << "fin debug _cgi_pos()\n\n" << RESET; if (pos == NPOS) break; client->fill_script_path(path, pos); @@ -27,7 +26,6 @@ bool Webserv::_is_cgi(Client *client, std::string path) } } client->clear_script(); - client->clear_script(); client->status = file_mode; // 404 not_found OR 403 forbidden return false; } @@ -40,25 +38,20 @@ size_t Webserv::_cgi_pos(Client *client, std::string &path, size_t pos) size_t len; std::locale loc; // for isalpha() - /*DEBUG*/ it = client->assigned_location->cgi_ext.begin(); std::cout << B_YELLOW << "\nDEBUG _cgi_pos()\n" << RESET << "vector_ext.size():[" << client->assigned_location->cgi_ext.size() << "]\n\n"; v_ext = client->assigned_location->cgi_ext; if (v_ext.empty()) return NPOS; - /*DEBUG*/ std::cout << "ext:[" << *it << "]\n" << "path:[" << path << "]\n\n"; it_end = client->assigned_location->cgi_ext.end(); while (pos < path.size()) { - /*DEBUG*/ std::cout << "\nwhile\n"; if (path.compare(pos, 2, "./") == 0) pos += 2; - /*DEBUG*/ std::cout << "&path[pos]:[" << &path[pos] << "]\n"; pos = path.find('.', pos); if (pos == NPOS) return pos; it = client->assigned_location->cgi_ext.begin(); for ( ; it != it_end; ++it) { - /*DEBUG*/ std::cout << " for\n"; std::cout << " &path[pos]:[" << &path[pos] << "]\n" << " *it:[" << *it << "]\n" << " (*it).size():[" << (*it).size() << "]\n" << " path.substr(pos, (*it).size()):[" << path.substr(pos + 1, (*it).size()) << "]\n\n"; len = (*it).size(); if (path.compare(pos + 1, len, *it) == 0) if ( !std::isalpha(path[pos + 1 + len], loc) ) @@ -164,7 +157,7 @@ std::string Webserv::_exec_script(Client *client, char **env) dup2(FD_RD_FR_PRNT, STDIN_FILENO); dup2(FD_WR_TO_PRNT, STDOUT_FILENO); path = "." + client->get_rq_script_path(); - /*DEBUG*/std::cerr << "execve\n" << "path:[" << path << "]\n"; +/*DEBUG*/std::cerr << "execve:[" << path << "]\n"; execve(path.c_str(), nll, env); // for tests execve crash : //execve("wrong", nll, env); diff --git a/srcs/webserv/response.cpp b/srcs/webserv/response.cpp index 7acae2a..587db23 100644 --- a/srcs/webserv/response.cpp +++ b/srcs/webserv/response.cpp @@ -44,6 +44,8 @@ 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 << B_PURPLE "-----------" RESET "\n\n"; + 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) @@ -77,8 +79,15 @@ void Webserv::_construct_response(Client *client) if (_is_cgi(client, path)) { script_output = _exec_cgi(client); + +/*DEBUG*/ std::cout << "\n" B_PURPLE "[script output]:" RESET "\n"; ::print_special(script_output); std::cout << B_PURPLE "-----------" RESET "\n\n"; +/*DEBUG*/ std::cout << "\n" B_PURPLE "[response]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n"; + _check_script_output(client, script_output); client->response += script_output; + +/*DEBUG*/ std::cout << "\n" B_PURPLE "[response + output]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n"; + return; } _process_method(client, path); From 076f46fb857aa5d65674da7e81e1ffcba2e1d515 Mon Sep 17 00:00:00 2001 From: Eric LAZO Date: Sun, 14 Aug 2022 21:29:20 +0200 Subject: [PATCH 2/8] .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 589577a..88c4209 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ webserv *.log large.jpg +webserv_tester +webserv_tester2 From f6f63931ad1499b7dd64c84d963dc1c434b15c7d Mon Sep 17 00:00:00 2001 From: Hugo LAMY Date: Mon, 15 Aug 2022 00:24:08 +0200 Subject: [PATCH 3/8] litle fix in utils trim + added 2 functions to check script output + created a html page with 4 forms for tests + created 2 cpp forms, with and without creating header content-length --- Makefile | 2 +- default.config | 2 +- srcs/cgi-bin/cgi.cpp | Bin 14576 -> 0 bytes srcs/cgi-bin/cgi_cpp.cpp | 114 ++++++++++++++++++++ srcs/cgi-bin/cgi_cpp_content_length.cpp | 133 ++++++++++++++++++++++++ srcs/utils.cpp | 2 +- srcs/webserv/Webserv.hpp | 2 + srcs/webserv/cgi_script.cpp | 68 ++++++++++-- srcs/webserv/parsing_message_http.cpp | 17 --- srcs/webserv/parsing_message_http.hpp | 32 ------ www/form_get.html | 73 ++++++++++++- www/form_post.html | 13 --- 12 files changed, 385 insertions(+), 73 deletions(-) delete mode 100755 srcs/cgi-bin/cgi.cpp create mode 100644 srcs/cgi-bin/cgi_cpp.cpp create mode 100644 srcs/cgi-bin/cgi_cpp_content_length.cpp delete mode 100644 srcs/webserv/parsing_message_http.cpp delete mode 100644 srcs/webserv/parsing_message_http.hpp delete mode 100644 www/form_post.html diff --git a/Makefile b/Makefile index 8b01509..5cbd75e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ NAME = webserv -CXX = clang++ +CXX = c++ CXXFLAGS = -Wall -Wextra #-Werror CXXFLAGS += $(HEADERS_D:%=-I%) diff --git a/default.config b/default.config index e5cab48..e24a717 100644 --- a/default.config +++ b/default.config @@ -21,7 +21,7 @@ server { location /cgi-bin { root ./srcs/cgi-bin/; - cgi_ext cpp php sh; + cgi_ext out php sh; } location /redirect { diff --git a/srcs/cgi-bin/cgi.cpp b/srcs/cgi-bin/cgi.cpp deleted file mode 100755 index 95013cbab183e1dadb657b89fd40e3c70bfc5ed6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14576 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 RLi+cs2IcQ_l!9CTe*xzN5cL26 diff --git a/srcs/cgi-bin/cgi_cpp.cpp b/srcs/cgi-bin/cgi_cpp.cpp new file mode 100644 index 0000000..8cabc71 --- /dev/null +++ b/srcs/cgi-bin/cgi_cpp.cpp @@ -0,0 +1,114 @@ +# include +# include +# include +# include +# include // getenv + +# define CR "\r" +# define LF "\n" +# define CRLF CR LF +# define NPOS std::string::npos + +std::string trim(std::string str, char del) +{ + size_t pos; + + // delete leadings del + pos = str.find_first_not_of(del); + if (pos == NPOS) + pos = str.size(); + str = str.substr(pos); + + // delete trailing del + pos = str.find_last_not_of(del); + if (pos != NPOS) + str = str.substr(0, pos + 1); + + return str; +} + +std::vector + split(const std::string & input, std::string delim, char ctrim = '\0') +{ + std::vector split_str; + std::string tmp; + size_t start = 0; + size_t end = 0; + size_t len = 0; + + while (end != NPOS) + { + end = input.find(delim, start); + len = end - start; + if (end == NPOS) + len = end; + tmp = input.substr(start, len); + if (ctrim != '\0') + tmp = trim(tmp, ctrim); + if (tmp.size() != 0) + split_str.push_back( tmp ); + start = end + delim.size(); + } + return split_str; +} + +int main (int ac, char **av, char **en) +{ + std::vector split_str; + std::vector sub_split_str; + std::vector::const_iterator it; + char * tmp; + std::string input; + std::string http_header; + std::string http_body; + std::ostringstream strs; + size_t pos; + + std::cin >> input; + + http_header = "Content-Type: text/html; charset=UTF-8" CRLF; + http_header += "Content-Length: "; + + http_body = "\ + \ + \ + \ + CGI\ + \ + \ +

cgi

\ + "; + + http_body += "

"; + tmp = getenv("REQUEST_METHOD"); + if (tmp != NULL) + http_body += tmp; + else + http_body = "method not foud"; + http_body += "

"; + + split_str = split(input, "&"); + for (it = split_str.begin(); it != split_str.end(); ++it) + { + sub_split_str = split(*it, "="); + http_body += "

"; + http_body += sub_split_str[0]; + http_body += "

"; + http_body += "

"; + http_body += sub_split_str[1]; + http_body += "

"; + } + + http_body += "\ + \ + \ + "; + + strs << http_body.size(); + http_header += strs.str(); + http_header += CRLF CRLF; + + std::cout << http_header << CRLF CRLF << http_body; + return 0; +} + diff --git a/srcs/cgi-bin/cgi_cpp_content_length.cpp b/srcs/cgi-bin/cgi_cpp_content_length.cpp new file mode 100644 index 0000000..9bb5089 --- /dev/null +++ b/srcs/cgi-bin/cgi_cpp_content_length.cpp @@ -0,0 +1,133 @@ +# include +# include +# include +# include +# include // getenv + +# define CR "\r" +# define LF "\n" +# define CRLF CR LF +# define NPOS std::string::npos + +std::string trim(std::string str, char del) +{ + size_t pos; + + // delete leadings del + pos = str.find_first_not_of(del); + if (pos == NPOS) + pos = str.size(); + str = str.substr(pos); + + // delete trailing del + pos = str.find_last_not_of(del); + if (pos != NPOS) + str = str.substr(0, pos + 1); + + return str; +} + +std::vector + split(const std::string & input, std::string delim, char ctrim = '\0') +{ + std::vector split_str; + std::string tmp; + size_t start = 0; + size_t end = 0; + size_t len = 0; + + while (end != NPOS) + { + end = input.find(delim, start); + len = end - start; + if (end == NPOS) + len = end; + tmp = input.substr(start, len); + if (ctrim != '\0') + tmp = trim(tmp, ctrim); + if (tmp.size() != 0) + split_str.push_back( tmp ); + start = end + delim.size(); + } + return split_str; +} + +int main (int ac, char **av, char **en) { + std::vector split_str; + std::vector sub_split_str; + std::vector::const_iterator it; + char * tmp; + std::string output; + std::ostringstream strs; + size_t pos; + + std::cout << "Content-Type: text/html; charset=UTF-8" << CRLF CRLF; + + std::cout + << "" + << "" + << "" + << " CGI" + << "" + << "" + << "

cgi

" + << "

"; + + tmp = getenv("REQUEST_METHOD"); + if (tmp != NULL) + output = tmp; + else + output = "method not foud"; + + std::cout + << output + << "

" + << "

http-request-body-message content :

"; + + + std::cin >> output; + split_str = split(output, "&"); + output.clear(); + for (it = split_str.begin(); it != split_str.end(); ++it) + { + sub_split_str = split(*it, "="); + + std::cout + << "

" + << sub_split_str[0] + << " : " + << sub_split_str[1] + << "

"; + } + + tmp = getenv("QUERY_STRING"); + if (tmp == NULL) + std::cout << "query not foud"; + + std::cout + << "

http-uri-query content :

"; + + output = tmp; + split_str = split(output, "&"); + output.clear(); + for (it = split_str.begin(); it != split_str.end(); ++it) + { + sub_split_str = split(*it, "="); + + std::cout + << "

" + << sub_split_str[0] + << "

" + << "

" + << sub_split_str[1] + << "

"; + } + + + std::cout + << "" + << ""; + + return 0; +} + diff --git a/srcs/utils.cpp b/srcs/utils.cpp index c1dc152..532deff 100644 --- a/srcs/utils.cpp +++ b/srcs/utils.cpp @@ -226,7 +226,7 @@ std::string begin = str.rfind(delim, pos); if (begin == NPOS) begin = 0; - else + else if (begin < pos) begin += delim.size(); end = str.find(delim, pos); diff --git a/srcs/webserv/Webserv.hpp b/srcs/webserv/Webserv.hpp index f55024c..d8cca1f 100644 --- a/srcs/webserv/Webserv.hpp +++ b/srcs/webserv/Webserv.hpp @@ -114,6 +114,8 @@ class Webserv void _check_script_output(Client *client, std::string & output); void _check_script_status(Client *client, std::string & output); void _check_script_fields(Client *client, std::string & output); + void _add_script_body_length_header(std::string & output); + void _remove_body_leading_empty_lines(std::string & output); // epoll_update.cpp int _epoll_update(int fd, uint32_t events, int op); int _epoll_update(int fd, uint32_t events, int op, void *ptr); diff --git a/srcs/webserv/cgi_script.cpp b/srcs/webserv/cgi_script.cpp index 3981666..7978ddb 100644 --- a/srcs/webserv/cgi_script.cpp +++ b/srcs/webserv/cgi_script.cpp @@ -140,8 +140,6 @@ std::string Webserv::_exec_script(Client *client, char **env) std::string body = client->get_rq_body(); int fd_in[2]; int fd_out[2]; - int save_in = dup(STDIN_FILENO); - int save_out = dup(STDOUT_FILENO); std::string path; pipe(fd_in); @@ -150,7 +148,7 @@ std::string Webserv::_exec_script(Client *client, char **env) pid = fork(); if (pid == -1) std::cerr << "fork crashed" << std::endl; - else if (pid == 0) + else if (pid == 0) // child { close(FD_WR_TO_CHLD); close(FD_RD_FR_CHLD); @@ -162,9 +160,10 @@ std::string Webserv::_exec_script(Client *client, char **env) // for tests execve crash : //execve("wrong", nll, env); std::cerr << "execve crashed.\n"; + // TODO HUGO : check errno } - else + else //parent { close(FD_RD_FR_PRNT); close(FD_WR_TO_PRNT); @@ -182,9 +181,7 @@ std::string Webserv::_exec_script(Client *client, char **env) } if (script_output.empty()) script_output = "Status: 500\r\n\r\n"; - - dup2(save_in, STDIN_FILENO); - dup2(save_out, STDOUT_FILENO); + return script_output; } @@ -192,6 +189,8 @@ void Webserv::_check_script_output(Client *client, std::string & output) { _check_script_status(client, output); _check_script_fields(client, output); + _add_script_body_length_header(output); + _remove_body_leading_empty_lines(output); // _check_script_empty_lines(client, output); // _check_script_space_colons(client, output); // _check_script_new_lines(client, output); @@ -248,3 +247,58 @@ void Webserv::_check_script_fields(Client *client, std::string & output) } } +void Webserv::_remove_body_leading_empty_lines(std::string & output) +{ + size_t pos; + size_t pos_empty; + + pos = output.find(CRLF CRLF); + if (pos == NPOS) + return; + pos += CRLF_SIZE * 2; + pos_empty = pos; + while (pos_empty == pos) + { + pos = output.find(CRLF, pos); + if (pos == pos_empty) + extract_line(output, pos, CRLF); + } +} + +void Webserv::_add_script_body_length_header(std::string & output) +{ + std::map field; + std::map::iterator it; + std::stringstream str_len; + std::string tmp; + size_t pos; + size_t len; + + pos = output.find(CRLF CRLF); + if (pos != NPOS) + tmp = output.substr(pos + CRLF_SIZE); + len = tmp.size(); + str_len << len; + + // put script headers in map + tmp = output; + pos = tmp.find(CRLF CRLF); + if (pos != NPOS) + tmp.erase(pos); + ::parse_http_headers(tmp, field); + // case insensitive search in map for "Content-Length" + tmp = "Content-Length"; + for (it = field.begin(); it != field.end(); ++it) + { + if (str_tolower(it->first) == str_tolower(tmp)) + { + pos = output.find(it->first); + ::extract_line(output, pos, CRLF); + } + } + tmp += ": "; + tmp += str_len.str(); + tmp += CRLF; + output.insert(0, tmp); +} + diff --git a/srcs/webserv/parsing_message_http.cpp b/srcs/webserv/parsing_message_http.cpp deleted file mode 100644 index 2712f20..0000000 --- a/srcs/webserv/parsing_message_http.cpp +++ /dev/null @@ -1,17 +0,0 @@ - -#include "parsing_message_http.hpp" - -std::string - parse_http_body(std::string message) -{ - std::string body; - size_t pos; - - pos = message.find(CRLF CRLF); - pos += std::string(CRLF CRLF).size(); - // TODO: copying just like that might fail in case of binary or images - body = message.substr(pos); - - return body; -} - diff --git a/srcs/webserv/parsing_message_http.hpp b/srcs/webserv/parsing_message_http.hpp deleted file mode 100644 index d1e77ed..0000000 --- a/srcs/webserv/parsing_message_http.hpp +++ /dev/null @@ -1,32 +0,0 @@ - -#ifndef PARSING_MESSAGE_HTTP_HPP -# define PARSING_MESSAGE_HTTP_HPP - -# include -# include -# include -# include -# include "utils.hpp" - -std::map - parse_http_headers ( - std::string headers, - std::map fields ) - -std::string - parse_http_body(std::string message); - -// http message structure : -// -// start-line -// request-line -// method SP target SP version -// response-line -// version SP status SP reason -// header-fields -// name ":" SP value -// CRLF -// body - -#endif - diff --git a/www/form_get.html b/www/form_get.html index 626478d..8379b2d 100644 --- a/www/form_get.html +++ b/www/form_get.html @@ -3,11 +3,82 @@ + -
+ + + +

get form

+

to /cgi-bin/cgi_cpp.out

+
+
+
+

+
+
+ +
+ +

post form

+

to /cgi-bin/cgi_cpp.out

+
+
+
+

+ + +
+
+ +
+ +

get form

+

to /cgi-bin/cgi_cpp_content_length.out

+
+
+
+

+ + +
+
+ +
+ +

post form

+

to /cgi-bin/cgi_cpp_content_length.out

+
+
+
+

+ + +
+
+ diff --git a/www/form_post.html b/www/form_post.html deleted file mode 100644 index ae36576..0000000 --- a/www/form_post.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - -
- -
- - - From b9d4317f513bdef5d552eab6c8ebf2f49e629ed6 Mon Sep 17 00:00:00 2001 From: Hugo LAMY Date: Mon, 15 Aug 2022 01:52:36 +0200 Subject: [PATCH 4/8] in _is_cgi, fix error in return http error status + fix error in checking script output : reverse order between calcul of content_length and erasing empty line --- default.config | 10 +++++----- srcs/webserv/cgi_script.cpp | 5 ++--- srcs/webserv/response.cpp | 9 +++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/default.config b/default.config index 125be8b..721ac51 100644 --- a/default.config +++ b/default.config @@ -31,11 +31,11 @@ server { upload_dir ./www/uploaded/; } -# location /srcs/cgi-bin/ { -# root ./srcs/cgi-bin/; -# allow_methods POST; -# cgi_ext php; -# } + location /srcs/cgi-bin/ { + root ./srcs/cgi-bin/; + allow_methods POST; + cgi_ext php; + } location /list { autoindex on; diff --git a/srcs/webserv/cgi_script.cpp b/srcs/webserv/cgi_script.cpp index 7978ddb..7385301 100644 --- a/srcs/webserv/cgi_script.cpp +++ b/srcs/webserv/cgi_script.cpp @@ -5,7 +5,7 @@ bool Webserv::_is_cgi(Client *client, std::string path) { std::string script_path; size_t file_type; - size_t file_mode; + size_t file_mode = client->status; size_t pos = 0; while (pos != NPOS) @@ -160,7 +160,6 @@ std::string Webserv::_exec_script(Client *client, char **env) // for tests execve crash : //execve("wrong", nll, env); std::cerr << "execve crashed.\n"; - // TODO HUGO : check errno } else //parent @@ -189,8 +188,8 @@ void Webserv::_check_script_output(Client *client, std::string & output) { _check_script_status(client, output); _check_script_fields(client, output); - _add_script_body_length_header(output); _remove_body_leading_empty_lines(output); + _add_script_body_length_header(output); // _check_script_empty_lines(client, output); // _check_script_space_colons(client, output); // _check_script_new_lines(client, output); diff --git a/srcs/webserv/response.cpp b/srcs/webserv/response.cpp index 20f9e41..556ab4d 100644 --- a/srcs/webserv/response.cpp +++ b/srcs/webserv/response.cpp @@ -47,7 +47,7 @@ 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 << B_PURPLE "-----------" RESET "\n\n"; +/*DEBUG*/ std::cout << "\n" B_PURPLE "[response + output + headers]:" RESET "\n"; ::print_special(client->response); std::cout << "\n" B_PURPLE "-----------" RESET "\n\n"; std::cerr << "client->response.size() = " << client->response.size() << "\n"; // DEBUG ret = ::send(client->get_cl_fd(), client->response.c_str(), client->response.size(), 0); @@ -86,13 +86,14 @@ void Webserv::_construct_response(Client *client) { script_output = _exec_cgi(client); -/*DEBUG*/ std::cout << "\n" B_PURPLE "[script output]:" RESET "\n"; ::print_special(script_output); std::cout << B_PURPLE "-----------" RESET "\n\n"; -/*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(script_output); std::cout << B_PURPLE "-----------" RESET "\n\n"; +///*DEBUG*/ std::cout << "\n" B_PURPLE "[response]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n"; _check_script_output(client, script_output); client->response += script_output; -/*DEBUG*/ std::cout << "\n" B_PURPLE "[response + output]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n"; +/*DEBUG*/ std::cout << B_YELLOW "inside cgi" RESET "\n"; +///*DEBUG*/ std::cout << "\n" B_PURPLE "[response + output]:" RESET "\n"; ::print_special(client->response); std::cout << B_PURPLE "-----------" RESET "\n\n"; return; } From 9ac84f706d7a54db91880a97274b4bc1c4fb973f Mon Sep 17 00:00:00 2001 From: Hugo LAMY Date: Mon, 15 Aug 2022 02:07:06 +0200 Subject: [PATCH 5/8] fix error in check scrip output length --- srcs/webserv/cgi_script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srcs/webserv/cgi_script.cpp b/srcs/webserv/cgi_script.cpp index 7385301..e572749 100644 --- a/srcs/webserv/cgi_script.cpp +++ b/srcs/webserv/cgi_script.cpp @@ -275,7 +275,7 @@ void Webserv::_add_script_body_length_header(std::string & output) pos = output.find(CRLF CRLF); if (pos != NPOS) - tmp = output.substr(pos + CRLF_SIZE); + tmp = output.substr(pos + (CRLF_SIZE * 2)); len = tmp.size(); str_len << len; From a284e400c1a158425652c466ddf63abb4ed89a9c Mon Sep 17 00:00:00 2001 From: lperrey Date: Mon, 15 Aug 2022 02:14:27 +0200 Subject: [PATCH 6/8] changed client_body_limit (now in KB) + multiples little adjusts --- default.config | 32 +++++++----------------- memo.txt | 7 ++---- srcs/Client.cpp | 9 ++++--- srcs/config/ConfigParser.hpp | 21 +++++----------- srcs/config/LocationConfig.hpp | 29 +--------------------- srcs/config/ServerConfig.hpp | 11 ++------- srcs/config/extraConfig.cpp | 4 +-- srcs/config/parser.cpp | 45 ++++++++++++---------------------- srcs/config/postProcessing.cpp | 2 +- srcs/main.cpp | 11 ++------- srcs/utils.hpp | 2 ++ srcs/webserv/method_get.cpp | 2 +- 12 files changed, 48 insertions(+), 127 deletions(-) diff --git a/default.config b/default.config index 721ac51..2325bae 100644 --- a/default.config +++ b/default.config @@ -7,28 +7,19 @@ server { listen 0.0.0.0:4040; # client_body_limit asdfa; - client_body_limit 3000000; + client_body_limit 5000; + # Max == 18446744073709551615 / 1024 == 18014398509481984 index index.html; # this is another comment + #index mdr.html; # this is another comment root ./www/; error_page 404 ./www/error_pages/error_404.html; - -# something to do with /upload - - location /upload { - root ./www/test/; - index submit_form.html; -# upload_dir ./www/uploaded/; -# cgi_ext php; - } - - location /uploaded { -# autoindex on; - root ./www/uploaded/; - upload_dir ./www/uploaded/; + location / { + allow_methods GET; + root ./www/; } location /srcs/cgi-bin/ { @@ -46,22 +37,17 @@ server { cgi_ext out php sh; } - location /cgi-bin { - root ./srcs/cgi-bin/; - cgi_ext cpp php sh; - } - location /upload { allow_methods POST; autoindex on; - upload_dir ./www/user_files/; # TODO: append a '/' if there is none ? + upload_dir ./www/user_files/; # root doesn’t matter if used only with POST and no CGI } location /the_dump { - allow_methods GET; + allow_methods GET DELETE; root ./www/user_files; - autoindex on; + #autoindex on; } location /redirect { diff --git a/memo.txt b/memo.txt index 1e57ae9..057462b 100644 --- a/memo.txt +++ b/memo.txt @@ -4,9 +4,6 @@ IN 42 SUBJECT AND/OR PRIORITY : - Need to test normal body parsing - upload files testing and adjustements -- https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size -Config en Ko (value * 2^10) serait plus commode que en octet -Et 0 valeur special pour desactiver - Ecrire des tests ! - handle redirection (Work, but weird behavior need deeper test) @@ -17,9 +14,9 @@ Et 0 valeur special pour desactiver ----------------------------- Si ce n'est pas deja fait : -- dans config, check erreur si port > 16bits -(peut-être check si ip > 32bits) +peut-être check si ip > 32bits ----------------------------- +- client_body_limit 0 valeur special pour desactiver dans config - gerer le champ "Accept" du client - gerer les ".." dans un URL (verifier que l'on ne sort pas du dossier "root") - do correct handling of special character in url (/rfc2119_files/errata.js.t%C3%A9l%C3%A9chargement -> /rfc2119_files/errata.js.téléchargement) diff --git a/srcs/Client.cpp b/srcs/Client.cpp index bd81115..6b04f61 100644 --- a/srcs/Client.cpp +++ b/srcs/Client.cpp @@ -183,8 +183,11 @@ void Client::_parse_chunked_body(size_t pos) /* endptr_copy = endptr; */ (void)endptr_copy; chunk_size = std::strtoul(&_request.body[pos], &endptr, 16); -/* if (chunk_size == LONG_MAX && errno == ERANGE) - status = 413; */ + if (errno == ERANGE) + { + status = 413; + return ; + } /* if (endptr == endptr_copy) { std::cerr << "parse_request_body(), no conversion possible\n"; @@ -407,7 +410,7 @@ void Client::_parse_port_hostname(std::string host) void Client::_check_request_errors() { - std::cerr << "Content-Length=" << get_rq_headers("Content-Length") << "\n"; + std::cerr << "Content-Length=" << get_rq_headers("Content-Length") << "\n"; std::cerr << "strtoul=" << std::strtoul(get_rq_headers("Content-Length").c_str(), NULL, 10) << "\n"; std::cerr << "client_body_limit=" << assigned_server->client_body_limit << "\n"; /////////////////////// diff --git a/srcs/config/ConfigParser.hpp b/srcs/config/ConfigParser.hpp index cc84993..58f5b11 100644 --- a/srcs/config/ConfigParser.hpp +++ b/srcs/config/ConfigParser.hpp @@ -14,8 +14,6 @@ # include // strtol, stroul # include // cout, cin # include // ifstream -//# include // access() -# include // opendir(), doesn't work... # include // stat(), replaces opendir() don't bother with ERRNO ? # include // sort() in Post @@ -23,21 +21,17 @@ class ConfigParser { public: - // canonical? - - ConfigParser(const char* path); // a string? + ConfigParser(); ~ConfigParser(); + ConfigParser(const std::string &config_file); - // ideally i wouldn't have one cuz it makes no sense, when would i use it? -// ConfigParser & operator=(const ConfigParser& rhs); - + void read_config(const std::string &config_file); std::vector * parse(); // const? -// std::vector parse(); // const? // i thought if it were an instance of this class you could call -// private member functions from anywhere... - void _print_content() const; +// private member functions from anywhere... // QUESTION : Wut ? + void print_content() const; private: @@ -45,25 +39,22 @@ private: // explicit? // what exaclty does explicit do again? - ConfigParser(); // might need a path as arg? + // ConfigParser(); // should this be in private since it always needs a path? ServerConfig _parse_server(size_t *start); LocationConfig _parse_location(size_t *start); - 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 _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 *servers); bool _find_root_path_location(std::vector locations); // const? diff --git a/srcs/config/LocationConfig.hpp b/srcs/config/LocationConfig.hpp index b6d96b3..2c89222 100644 --- a/srcs/config/LocationConfig.hpp +++ b/srcs/config/LocationConfig.hpp @@ -1,32 +1,14 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* LocationConfig.hpp :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: lperrey +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2022/07/23 16:08:00 by me #+# #+# */ -/* Updated: 2022/08/12 18:12:23 by lperrey ### ########.fr */ -/* */ -/* ************************************************************************** */ #ifndef LOCATIONCONFIG_HPP # define LOCATIONCONFIG_HPP -# include # include # include -# include -# include // stat() # include "utils.hpp" -// again, struct instead? -class LocationConfig +struct LocationConfig { -public: - // canonic stuff? - std::string path; // /path and /path/ are fine // i remove trailing / systematically std::string root; @@ -87,13 +69,4 @@ public: }; - #endif - - - - - - - - diff --git a/srcs/config/ServerConfig.hpp b/srcs/config/ServerConfig.hpp index 693f0df..8501f6a 100644 --- a/srcs/config/ServerConfig.hpp +++ b/srcs/config/ServerConfig.hpp @@ -10,14 +10,9 @@ # include // string # include // cout, cin -// a class that's all public? just so we have options? -class ServerConfig +struct ServerConfig { -public: - // do i need some canonic stuff? - std::vector server_name; - // we could shove default in here if we wanted to... std::string host; std::string port; @@ -25,9 +20,7 @@ public: std::string root; // ./www/ or www work www/ and www work // i do remove trailing / tho - size_t client_body_limit; // set to default max if none set - // 413 (Request Entity Too Large) if exceeded - // default is 1m 1 000 000 ? + size_t client_body_limit; std::vector index; std::map error_pages; diff --git a/srcs/config/extraConfig.cpp b/srcs/config/extraConfig.cpp index 010bca9..ee958de 100644 --- a/srcs/config/extraConfig.cpp +++ b/srcs/config/extraConfig.cpp @@ -1,6 +1,4 @@ - - #include "ConfigParser.hpp" // should i be sending & references? @@ -63,7 +61,7 @@ std::string ConfigParser::_get_rest_of_line(size_t *curr) } -void ConfigParser::_print_content() const +void ConfigParser::print_content() const { std::cout << _content; } diff --git a/srcs/config/parser.cpp b/srcs/config/parser.cpp index 0159dbb..0c8d0b1 100644 --- a/srcs/config/parser.cpp +++ b/srcs/config/parser.cpp @@ -1,25 +1,26 @@ #include "ConfigParser.hpp" -// Default -ConfigParser::ConfigParser() +ConfigParser::ConfigParser() {}; +ConfigParser::~ConfigParser() {}; + +ConfigParser::ConfigParser(const std::string &config_file) { - std::cout << "Default Constructor\n"; - // don't use yet, you have no idea what the defaults are + read_config(config_file); } -ConfigParser::ConfigParser(const char* path) +void ConfigParser::read_config(const std::string &config_file) { -// std::cout << "Param Constructor\n"; - std::ifstream file; std::string buf; size_t comment; - _content.clear(); - file.open(path); - if (file.is_open()) + file.open(config_file.c_str()); + if (!file) + throw std::invalid_argument("failed to open config"); + else { + _content.clear(); while (!file.eof()) { getline(file, buf); @@ -37,28 +38,9 @@ ConfigParser::ConfigParser(const char* path) _content.append(tmp + '\n'); } } - file.close(); } - else - throw std::invalid_argument("failed to open config"); } -ConfigParser::~ConfigParser() -{ - // do i need to destroy anything, won't it handle itself? -} - -/* -ConfigParser & ConfigParser::operator=(const ConfigParser& rhs) -{ - if (this == rhs) // * & ? - return (*this); // * ? - - // make some stuff equal - return (*this); -} -*/ - // const? std::vector * ConfigParser::parse() { @@ -190,7 +172,7 @@ void ConfigParser::_set_server_values(ServerConfig *server, \ server->server_name.push_back(tmp_val[0]); } else if (key == "listen" && size == 1 && server->host == "" \ - && server->port == "") + && server->port == "") // QUESTION LUKE : C'est quoi cette condition ? Si listen est vide ? Je comprends pas trop. { if (tmp_val[0].find_first_of(":") == NPOS) { @@ -231,6 +213,9 @@ void ConfigParser::_set_server_values(ServerConfig *server, \ if (!::isNumeric(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) ) + throw std::invalid_argument("client_body_limit too big"); + server->client_body_limit = server->client_body_limit * KB; } else if (key == "index") { diff --git a/srcs/config/postProcessing.cpp b/srcs/config/postProcessing.cpp index f4bb1a0..917d595 100644 --- a/srcs/config/postProcessing.cpp +++ b/srcs/config/postProcessing.cpp @@ -22,7 +22,7 @@ void ConfigParser::_post_processing(std::vector *servers) throw std::invalid_argument("Config file needs an Index"); if (it->client_body_limit == 0) - it->client_body_limit = 5000; // what is the recomended size? + it->client_body_limit = 1 * MB; // if error_pages is left empty, we'll use the defaults which diff --git a/srcs/main.cpp b/srcs/main.cpp index 3a44a33..b83bf83 100644 --- a/srcs/main.cpp +++ b/srcs/main.cpp @@ -11,15 +11,8 @@ int main(int ac, char **av) { std::string config = (ac == 2 ? av[1] : "./default.config"); - // like this just looks kinda gross, why bother creating an instance - // and not immediately parsing? like it servers no other purpose... - // what if i call parse directly in the constructor? - // oh because the constructor has no return, but still - // is there a better way? - - ConfigParser configParser(config.c_str()); - - // configParser._print_content(); + ConfigParser configParser(config); + // configParser.print_content(); // i don't love that servers has to be a pointer... std::vector* servers = configParser.parse(); diff --git a/srcs/utils.hpp b/srcs/utils.hpp index ede2808..215f690 100644 --- a/srcs/utils.hpp +++ b/srcs/utils.hpp @@ -22,6 +22,8 @@ # define CRLF CR LF # define CRLF_SIZE 2 # define NPOS std::string::npos +# define KB 1024 +# define MB 1048576 /* Equivalent for end of http header size : ** std::string(CRLF CRLF).size(); diff --git a/srcs/webserv/method_get.cpp b/srcs/webserv/method_get.cpp index 310e27a..d3c1783 100644 --- a/srcs/webserv/method_get.cpp +++ b/srcs/webserv/method_get.cpp @@ -39,7 +39,7 @@ void Webserv::_get(Client *client, std::string &path) _get_file(client, path); } -# define MAX_FILESIZE 1000000 // (1Mo) +# define MAX_FILESIZE 1 * MB void Webserv::_get_file(Client *client, const std::string &path) { /* From 3fe37ea45187372e99eb3b6d1ff2b3c0fc2cd5a6 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Mon, 15 Aug 2022 18:16:11 +0200 Subject: [PATCH 7/8] DELETE method tested and fixed + added 404 for directories without index and autoindex + minors adjustements --- default.config | 2 +- srcs/utils.cpp | 9 +++--- srcs/utils.hpp | 4 +-- srcs/webserv/method_delete.cpp | 28 ++++++++--------- srcs/webserv/method_get.cpp | 53 +++++++++++++++----------------- srcs/webserv/method_post.cpp | 28 +++++++++++------ srcs/webserv/parsing_request.cpp | 2 -- 7 files changed, 62 insertions(+), 64 deletions(-) delete mode 100644 srcs/webserv/parsing_request.cpp diff --git a/default.config b/default.config index 2325bae..e93c393 100644 --- a/default.config +++ b/default.config @@ -47,7 +47,7 @@ server { location /the_dump { allow_methods GET DELETE; root ./www/user_files; - #autoindex on; + autoindex on; } location /redirect { diff --git a/srcs/utils.cpp b/srcs/utils.cpp index 793c46b..d85d5d5 100644 --- a/srcs/utils.cpp +++ b/srcs/utils.cpp @@ -171,18 +171,19 @@ file_type eval_file_type(const std::string &path) return (IS_OTHER); } -size_t eval_file_mode(std::string path, int mode) +// rename in "eval_file_access" ? +size_t eval_file_mode(const std::string &path, int mode) { - if (access(path.c_str(), F_OK) == -1) + if (::access(path.c_str(), F_OK) == -1) { std::perror("err access()"); return 404; // NOT_FOUND, file doesn't exist } - if (access(path.c_str(), mode) == -1) + if (::access(path.c_str(), mode) == -1) { std::perror("err access()"); - return 403; // FORBIDDEN, file doesn't have execution permission + return 403; // FORBIDDEN, file doesn't have access permission } return 0; } diff --git a/srcs/utils.hpp b/srcs/utils.hpp index 215f690..44f5347 100644 --- a/srcs/utils.hpp +++ b/srcs/utils.hpp @@ -67,15 +67,15 @@ std::string trim(std::string str, char del); http_method str_to_http_method(std::string &str); std::string http_methods_to_str(unsigned int methods); file_type eval_file_type(const std::string &path); -size_t eval_file_mode(std::string path, int mode); +size_t eval_file_mode(const std::string &path, int mode); void replace_all_substr(std::string &str, const std::string &ori_substr, const std::string &new_substr); std::string str_tolower(std::string str); std::string extract_line(std::string & str, size_t pos = 0, std::string delim = "\n"); std::string get_line (std::string str, size_t pos = 0, std::string delim = "\n"); size_t parse_http_headers (std::string headers, std::map & fields ); void str_map_key_tolower(std::map & mp); -void throw_test(); // debug +void throw_test(); void print_special(std::string str); diff --git a/srcs/webserv/method_delete.cpp b/srcs/webserv/method_delete.cpp index 40e0e3b..16c7d94 100644 --- a/srcs/webserv/method_delete.cpp +++ b/srcs/webserv/method_delete.cpp @@ -4,7 +4,6 @@ void Webserv::_delete(Client *client, const std::string &path) { /* - WIP https://www.rfc-editor.org/rfc/rfc9110.html#name-delete */ _delete_file(client, path); @@ -12,24 +11,21 @@ void Webserv::_delete(Client *client, const std::string &path) void Webserv::_delete_file(Client *client, const std::string &path) { - if (access(path.c_str(), F_OK) == -1) - { - std::perror("err access()"); - client->status = 404; - return ; - } + std::cout << "_delete_file()\n"; + client->status = ::eval_file_mode(path, W_OK); + if (client->status) + return; - if (access(path.c_str(), W_OK) == -1) - { - std::perror("err access()"); - client->status = 403; - return ; - } - - if (remove(path.c_str()) == -1) + if (std::remove(path.c_str()) == -1) { std::perror("err remove()"); - client->status = 500; + if (errno == ENOTEMPTY || errno == EEXIST) + client->status = 403; + else + client->status = 500; return ; } + + client->status = 204; + client->response.append(CRLF); } diff --git a/srcs/webserv/method_get.cpp b/srcs/webserv/method_get.cpp index d3c1783..4649dd2 100644 --- a/srcs/webserv/method_get.cpp +++ b/srcs/webserv/method_get.cpp @@ -16,9 +16,10 @@ std::string Webserv::_replace_url_root(Client *client, std::string path) // const? void Webserv::_get(Client *client, std::string &path) { - - -// Index/Autoindex block +/* + https://www.rfc-editor.org/rfc/rfc9110.html#name-get +*/ + std::cout << "_get()\n"; if (eval_file_type(path) == IS_DIR) { if (path[path.size() - 1] != '/') @@ -34,12 +35,14 @@ void Webserv::_get(Client *client, std::string &path) } if (client->assigned_location->autoindex == true) _autoindex(client, path); + else + client->status = 404; } else _get_file(client, path); } -# define MAX_FILESIZE 1 * MB +# define MAX_FILESIZE 1 * MB // unused void Webserv::_get_file(Client *client, const std::string &path) { /* @@ -52,21 +55,11 @@ void Webserv::_get_file(Client *client, const std::string &path) std::cout << "_get_file()\n"; - if (access(path.c_str(), F_OK) == -1) - { - std::perror("err access()"); - client->status = 404; - return ; - } + client->status = ::eval_file_mode(path, R_OK); + if (client->status) + return; - if (access(path.c_str(), R_OK) == -1) - { - std::perror("err access()"); - client->status = 403; - return ; - } - - ifd.open(path.c_str(), std::ios::ate); + ifd.open(path.c_str()); if (!ifd) { std::cerr << path << ": ifd.open fail" << '\n'; @@ -74,17 +67,6 @@ void Webserv::_get_file(Client *client, const std::string &path) } else { - /* std::streampos size = ifd.tellg(); - // WIP Low priority : Chunk or not chunk (if filesize too big) - if (size > MAX_FILESIZE) - { - // Then chunk - client->status = 500; // WIP temp - std::cerr << "File too large for non chunk body\n"; - return ; - } */ - - ifd.seekg(0, std::ios::beg); buf << ifd.rdbuf(); if (!ifd || !buf) { @@ -100,6 +82,19 @@ void Webserv::_get_file(Client *client, const std::string &path) } } +/* +// WIP Low priority : Chunk or not chunk (if filesize > MAX_FILESIZE) +// WITH flag "std::ios::ate" for open() +std::streampos size = ifd.tellg(); +ifd.seekg(0, std::ios::beg); +if (size > MAX_FILESIZE) +{ + // Chunked GET here + return ; +} +*/ + + // const? void Webserv::_autoindex(Client *client, const std::string &path) { diff --git a/srcs/webserv/method_post.cpp b/srcs/webserv/method_post.cpp index 9ee0aaa..ce7309b 100644 --- a/srcs/webserv/method_post.cpp +++ b/srcs/webserv/method_post.cpp @@ -5,10 +5,9 @@ void Webserv::_post(Client *client, const std::string &path) { /* - WIP https://www.rfc-editor.org/rfc/rfc9110.html#name-post */ - (void)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"; @@ -31,12 +30,17 @@ void Webserv::_post(Client *client, const std::string &path) // TODO : Loop for multi body void Webserv::_upload_files(Client *client) { + std::cout << "_upload_files()\n"; std::ofstream ofd; std::vector::const_iterator body_it = client->get_rq_multi_bodys().begin(); std::string path; std::string filename; size_t pos; - bool file_existed; + bool file_existed = false; + + client->status = ::eval_file_mode(client->assigned_location->upload_dir, W_OK); + if (client->status) + return; while (body_it != client->get_rq_multi_bodys().end()) { @@ -72,13 +76,13 @@ void Webserv::_upload_files(Client *client) path.append(filename); - if (access(path.c_str(), F_OK) == -1) + if (::access(path.c_str(), F_OK) == -1) file_existed = false; 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) + if (file_existed && ::access(path.c_str(), W_OK) == -1) { std::perror("err access()"); client->status = 403; @@ -103,10 +107,15 @@ void Webserv::_upload_files(Client *client) ofd.close(); } + client->status = 204; + client->response.append(CRLF); + // https://www.rfc-editor.org/rfc/rfc9110.html#name-204-no-content +} + +/* if (file_existed) // with multi body it doesn't make much sense { - // client->status = 200; - client->status = 204; // DEBUG 204 + client->status = 200; client->response.append("Location: "); client->response.append("/index.html"); // WIP client->response.append(CRLF); @@ -115,12 +124,11 @@ void Webserv::_upload_files(Client *client) } else { - // client->status = 201; - client->status = 204; // DEBUG 204 + client->status = 201; client->response.append("Location: "); client->response.append("/index.html"); // WIP client->response.append(CRLF); client->response.append(CRLF); // WIP https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.3-4 } -} +*/ diff --git a/srcs/webserv/parsing_request.cpp b/srcs/webserv/parsing_request.cpp deleted file mode 100644 index d83d9e3..0000000 --- a/srcs/webserv/parsing_request.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "parsing_request.hpp" - From fe89be65f616982ed45ddefee789668e13e63f83 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Mon, 15 Aug 2022 19:31:43 +0200 Subject: [PATCH 8/8] Tested and fixed server_name resolution --- default.config | 13 +++++++++++-- memo.txt | 7 +++---- srcs/webserv/response.cpp | 16 +++++++++++++--- www2/index.html | 11 +++++++++++ 4 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 www2/index.html diff --git a/default.config b/default.config index e93c393..c6341c6 100644 --- a/default.config +++ b/default.config @@ -1,8 +1,9 @@ + server { # this is a comment - server_name our_server; + server_name server1; listen 0.0.0.0:4040; @@ -92,5 +93,13 @@ server { # allow_methods DELETE; # } - +} + +server { + server_name server2; + + listen 0.0.0.0:4040; + + index index.html; + root ./www2/; } diff --git a/memo.txt b/memo.txt index 057462b..7ded14e 100644 --- a/memo.txt +++ b/memo.txt @@ -1,21 +1,20 @@ IN 42 SUBJECT AND/OR PRIORITY : - CGI (TODO HUGO) -- chunked request (need testing) -- Need to test normal body parsing -- upload files testing and adjustements +- Need to test normal body parsing (Verif avec HUGO) - Ecrire des tests ! - handle redirection (Work, but weird behavior need deeper test) -- check return 0 de send() - curl --resolve, for testing hostname + curl -v --resolve server1:4040:127.0.0.1 --resolve server2:4040:127.0.0.1 server1:4040 - test limit de connexions sur listen() ----------------------------- Si ce n'est pas deja fait : peut-être check si ip > 32bits ----------------------------- +- chunked request (need testing) - client_body_limit 0 valeur special pour desactiver dans config - gerer le champ "Accept" du client - gerer les ".." dans un URL (verifier que l'on ne sort pas du dossier "root") diff --git a/srcs/webserv/response.cpp b/srcs/webserv/response.cpp index 556ab4d..c3a7776 100644 --- a/srcs/webserv/response.cpp +++ b/srcs/webserv/response.cpp @@ -57,6 +57,11 @@ int Webserv::_send_response(Client *client) std::cerr << "client.fd =" << client->get_cl_fd() << "\n"; // DEBUG return SEND_CLOSE; } + if (ret == 0) // actually never happen ? + { + std::cerr << "SEND RET 0 for client.fd =" << client->get_cl_fd() << "\n"; // DEBUG + return SEND_CLOSE; + } std::cerr << "ret send() = " << ret << "\n"; // DEBUG return SEND_COMPLETE; @@ -167,12 +172,17 @@ void Webserv::_append_body(Client *client, const std::string &body, const std::s ServerConfig *_determine_process_server(Client *client, std::vector &servers) { /* + Behavior like this : http://nginx.org/en/docs/http/request_processing.html - _determine_process_server() should be complete. - TODO : test it */ - std::string const &server_name = client->get_rq_headers("Host"); + std::string server_name = client->get_rq_headers("Host"); + std::cerr << "server_name = " << server_name << "\n"; + size_t pos = server_name.rfind(':'); + if (pos != NPOS) + server_name.erase(pos); + std::cerr << "server_name = " << server_name << "\n"; + std::vector::iterator it = servers.begin(); std::vector::iterator default_server = servers.end(); diff --git a/www2/index.html b/www2/index.html new file mode 100644 index 0000000..3cf91ae --- /dev/null +++ b/www2/index.html @@ -0,0 +1,11 @@ + + + + Le Webserv + + +

( ͡◉ ͜ ʖ ͡◉) Le index du serveur 2 !

+
+

˚ಎ˚

+ +