From f6f63931ad1499b7dd64c84d963dc1c434b15c7d Mon Sep 17 00:00:00 2001 From: Hugo LAMY Date: Mon, 15 Aug 2022 00:24:08 +0200 Subject: [PATCH] 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 @@ - - - - - - - -
- -
- - -