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 95013cb..0000000 Binary files a/srcs/cgi-bin/cgi.cpp and /dev/null differ 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 @@ - - - - - - - -
- -
- - -