diff --git a/README.md b/README.md index 9643f38..2750f40 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,6 @@ ## work together -#### next commit - -#### questions -- how should we handle a wrong url like `http://localhost/cgi-bin/wrong.phpp/good.php` ? - - do we serve `./srcs/cgi-bin/good.php` ? - - or do we return 404 "not found" ? --> - for now, execve would crash, but that doesn't produce a 404 error, rather a 500, is it bad ? - - could we use errno after execve to choose an appropriate http error ? subject says : "Checking the value of errno is strictly forbidden after a read or a write operation" -- if a url has a file with extension, but it's not a cgi extension, is it necessary to look further ? - - ex. `http://localhost/file.php/file.py` for `cgi_ext py;` ? -- the response page is received long after the cgi-script is done, why ? --- ## man @@ -243,6 +232,10 @@ SERVER_SOFTWARE : the server software you're using (e.g. Apache 1.3) REDIRECT_STATUS : for exemple, 200 ``` +g 50 34 48 +p 30 23 32 +l 20 14 20 + 71 --- ## http status diff --git a/srcs/Client.cpp b/srcs/Client.cpp index abccc41..25596c1 100644 --- a/srcs/Client.cpp +++ b/srcs/Client.cpp @@ -223,11 +223,6 @@ void Client::fill_script_path(std::string &path, size_t pos) { std::string tmp; - if (path[0] == '.') - { - path.erase(0, 1); - pos--; - } _request.script.path = path.substr(0, pos); _request.script.info = path.substr(pos); } diff --git a/srcs/cgi-bin/Makefile b/srcs/cgi-bin/Makefile index 59f349c..a32e969 100644 --- a/srcs/cgi-bin/Makefile +++ b/srcs/cgi-bin/Makefile @@ -1,3 +1,4 @@ + # - - - - - - # # # # COLORS # @@ -30,11 +31,7 @@ RESET = "\e[0m" # . name is case sensitive . ?= set if not already set # # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # -NAME_1 = $(SRCS_1:.cpp=.out) -NAME_2 = $(SRCS_2:.cpp=.out) -NAME_3 = $(SRCS_3:.cpp=.out) -NAME_4 = $(SRCS_4:.cpp=.out) -NAME_5 = $(SRCS_5:.cpp=.out) +NAME = $(SRCS_X:.cpp=.out) CXX = c++ CXXFLAGS = -Wall -Wextra #-Werror @@ -47,19 +44,24 @@ HEADERS_D = . SRCS_D = . SRCS = cgi_utils.cpp -SRCS_1 = cgi_cpp.cpp -SRCS_2 = cgi_cpp_len.cpp -SRCS_3 = cgi_cpp_len_big.cpp -SRCS_4 = cgi_cpp_len_small.cpp -SRCS_5 = cgi_cpp_status.cpp +SRCS_X = \ + cgi_cpp.cpp \ + cgi_cpp_bad_headers.cpp \ + cgi_cpp_empty.cpp \ + cgi_cpp_empty_lines.cpp \ + cgi_cpp_len.cpp \ + cgi_cpp_len_big.cpp \ + cgi_cpp_len_small.cpp \ + cgi_cpp_no_body.cpp \ + cgi_cpp_no_headers.cpp \ + cgi_cpp_only_crlf.cpp \ + cgi_cpp_sleep.cpp \ + cgi_cpp_status.cpp \ + cgi_cpp_download.cpp \ OBJS_D = builds OBJS = $(SRCS:%.cpp=$(OBJS_D)/%.o) -OBJS_1 = $(SRCS_1:%.cpp=$(OBJS_D)/%.o) -OBJS_2 = $(SRCS_2:%.cpp=$(OBJS_D)/%.o) -OBJS_3 = $(SRCS_3:%.cpp=$(OBJS_D)/%.o) -OBJS_4 = $(SRCS_4:%.cpp=$(OBJS_D)/%.o) -OBJS_5 = $(SRCS_5:%.cpp=$(OBJS_D)/%.o) +OBJS_X = $(SRCS_X:%.cpp=$(OBJS_D)/%.o) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # . target: prerequisites . $@ : target # @@ -67,36 +69,25 @@ OBJS_5 = $(SRCS_5:%.cpp=$(OBJS_D)/%.o) # . recipe . $^ : all prerequisites # # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # -all: cgi_1 cgi_2 cgi_3 cgi_4 cgi_5 -cgi_1: $(NAME_1) -cgi_2: $(NAME_2) -cgi_3: $(NAME_3) -cgi_4: $(NAME_4) -cgi_5: $(NAME_5) +all: $(NAME) $(OBJS_D)/%.o: %.cpp | $(OBJS_D) + @echo $(B_GREEN)"compilation :" $@ $(RESET) $(CXX) $(CXXFLAGS) -c $< -o $@ $(OBJS_D): mkdir $@ -$(NAME_1): $(OBJS) $(OBJS_1) -$(NAME_2): $(OBJS) $(OBJS_2) -$(NAME_3): $(OBJS) $(OBJS_3) -$(NAME_4): $(OBJS) $(OBJS_4) -$(NAME_5): $(OBJS) $(OBJS_5) -$(NAME_1) $(NAME_2) $(NAME_3) $(NAME_4) $(NAME_5): - $(CXX) $^ -o $@ +$(NAME): $(OBJS) $(OBJS_X) +$(NAME): + @echo $(B_YELLOW)"linkage :" $@ $(RESET) + $(CXX) $(OBJS) $(@:%.out=$(OBJS_D)/%.o) -o $@ clean: rm -rf $(OBJS_D) fclean: clean - rm -f $(NAME_1) - rm -f $(NAME_2) - rm -f $(NAME_3) - rm -f $(NAME_4) - rm -f $(NAME_5) + rm -f $(NAME) re: fclean all diff --git a/srcs/cgi-bin/cgi_cpp.cpp b/srcs/cgi-bin/cgi_cpp.cpp index 36845cc..cfce71a 100644 --- a/srcs/cgi-bin/cgi_cpp.cpp +++ b/srcs/cgi-bin/cgi_cpp.cpp @@ -5,25 +5,20 @@ int main (int ac, char **av, char ** env) { - std::string http_header; - std::string http_body; + std::string http_header; + std::string http_body; + std::string rq_body; + + std::cin >> rq_body; (void)ac; (void)av; - // ::sleep(5); + http_header = "Content-Type: text/html; charset=UTF-8" CRLF; - fill_response_basic(env, http_body, http_header); + fill_body_basic(env, http_body, rq_body); - std::cout << http_header; - std::flush(std::cout); - ::sleep(2); - std::cout << CRLF CRLF; - std::flush(std::cout); - ::sleep(2); - std::cout << http_body; - std::flush(std::cout); - ::sleep(2); + std::cout << http_header << CRLF << http_body; return 0; } diff --git a/srcs/cgi-bin/cgi_cpp_bad_headers.cpp b/srcs/cgi-bin/cgi_cpp_bad_headers.cpp new file mode 100644 index 0000000..73846ee --- /dev/null +++ b/srcs/cgi-bin/cgi_cpp_bad_headers.cpp @@ -0,0 +1,24 @@ + +# include "cgi_utils.hpp" + +int main (int ac, char **av, char ** env) +{ + std::string http_header; + std::string http_body; + std::string http_status; + std::string rq_body; + + std::cin >> rq_body; + + (void)ac; + (void)av; + + http_header = "Bad-Headers: wrong"; + + fill_body_basic(env, http_body, rq_body); + + std::cout << http_header << CRLF << http_body; + + return 0; +} + diff --git a/srcs/cgi-bin/cgi_cpp_download.cpp b/srcs/cgi-bin/cgi_cpp_download.cpp new file mode 100644 index 0000000..b0238e8 --- /dev/null +++ b/srcs/cgi-bin/cgi_cpp_download.cpp @@ -0,0 +1,55 @@ + +# include "cgi_utils.hpp" + +int main (int ac, char **av, char ** env) +{ + std::string http_header; + std::string http_body; + std::string rq_body; + std::string form_infos; + std::string path; + std::ifstream ifd; + std::stringstream buf; + size_t status; + + std::cin >> rq_body; + + (void)ac; + (void)av; + (void)env; + + http_header = "Content-Type: image/jpeg" CRLF; + + form_infos = get_form_infos(rq_body); + path = get_value("file", rq_body); + path = "./www/" + path; + + status = ::eval_file_read(path); + if (status) + { + std::cout << "Status: " << status << CRLF CRLF; + return 0; + } + + ifd.open(path.c_str()); + if (!ifd) + { + std::cout << "Status: " << 500 << CRLF CRLF; + return 0; + } + else + { + buf << ifd.rdbuf(); + if (!ifd || !buf) + { + std::cout << "Status: " << 500 << CRLF CRLF; + return 0; + } + } + + std::cout << http_header << CRLF << buf.str(); + + return 0; +} + + diff --git a/srcs/cgi-bin/cgi_cpp_empty.cpp b/srcs/cgi-bin/cgi_cpp_empty.cpp new file mode 100644 index 0000000..9ea9129 --- /dev/null +++ b/srcs/cgi-bin/cgi_cpp_empty.cpp @@ -0,0 +1,12 @@ + +# include "cgi_utils.hpp" + +int main (int ac, char **av, char ** env) +{ + (void)ac; + (void)av; + (void)env; + + return 0; +} + diff --git a/srcs/cgi-bin/cgi_cpp_empty_lines.cpp b/srcs/cgi-bin/cgi_cpp_empty_lines.cpp new file mode 100644 index 0000000..62376b9 --- /dev/null +++ b/srcs/cgi-bin/cgi_cpp_empty_lines.cpp @@ -0,0 +1,23 @@ + +# include "cgi_utils.hpp" + +int main (int ac, char **av, char ** env) +{ + std::string http_header; + std::string http_body; + std::string rq_body; + + std::cin >> rq_body; + + (void)ac; + (void)av; + + http_header = "Content-Type: text/html; charset=UTF-8" CRLF; + + fill_body_basic(env, http_body, rq_body); + + std::cout << http_header << CRLF CRLF CRLF CRLF CRLF << http_body; + + return 0; +} + diff --git a/srcs/cgi-bin/cgi_cpp_len.cpp b/srcs/cgi-bin/cgi_cpp_len.cpp index 566ae7d..641d083 100644 --- a/srcs/cgi-bin/cgi_cpp_len.cpp +++ b/srcs/cgi-bin/cgi_cpp_len.cpp @@ -5,15 +5,20 @@ int main (int ac, char **av, char ** env) { std::string http_header; std::string http_body; + std::string rq_body; + + std::cin >> rq_body; (void)ac; (void)av; - fill_response_basic(env, http_body, http_header); + http_header = "Content-Type: text/html; charset=UTF-8" CRLF; + http_header += "Content-Length: " + itos(http_body.size()) + CRLF; - http_header += "Content-Length: " + itos(http_body.size()); + fill_body_basic(env, http_body, rq_body); - std::cout << http_header << CRLF CRLF << http_body; + + std::cout << http_header << CRLF << http_body; return 0; } diff --git a/srcs/cgi-bin/cgi_cpp_len_big.cpp b/srcs/cgi-bin/cgi_cpp_len_big.cpp index 4d8025e..a006e78 100644 --- a/srcs/cgi-bin/cgi_cpp_len_big.cpp +++ b/srcs/cgi-bin/cgi_cpp_len_big.cpp @@ -3,17 +3,22 @@ int main (int ac, char **av, char ** env) { - std::string http_header; - std::string http_body; + std::string http_header; + std::string http_body; + std::string rq_body; + + std::cin >> rq_body; (void)ac; (void)av; - fill_response_basic(env, http_body, http_header); + http_header = "Content-Type: text/html; charset=UTF-8" CRLF; + http_header += "Content-Length: " + itos(http_body.size() + 100) + CRLF; - http_header += "Content-Length: " + itos(http_body.size() + 100); + fill_body_basic(env, http_body, rq_body); - std::cout << http_header << CRLF CRLF << http_body; + + std::cout << http_header << CRLF << http_body; return 0; } diff --git a/srcs/cgi-bin/cgi_cpp_len_small.cpp b/srcs/cgi-bin/cgi_cpp_len_small.cpp index 4c58df9..3e72d8c 100644 --- a/srcs/cgi-bin/cgi_cpp_len_small.cpp +++ b/srcs/cgi-bin/cgi_cpp_len_small.cpp @@ -3,17 +3,21 @@ int main (int ac, char **av, char ** env) { - std::string http_header; - std::string http_body; + std::string http_header; + std::string http_body; + std::string rq_body; + + std::cin >> rq_body; (void)ac; (void)av; - fill_response_basic(env, http_body, http_header); + http_header = "Content-Type: text/html; charset=UTF-8" CRLF; + http_header += "Content-Length: " + itos(http_body.size() - 100) + CRLF; - http_header += "Content-Length: " + itos(http_body.size() - 100); + fill_body_basic(env, http_body, rq_body); - std::cout << http_header << CRLF CRLF << http_body; + std::cout << http_header << CRLF << http_body; return 0; } diff --git a/srcs/cgi-bin/cgi_cpp_no_body.cpp b/srcs/cgi-bin/cgi_cpp_no_body.cpp new file mode 100644 index 0000000..e97d6b3 --- /dev/null +++ b/srcs/cgi-bin/cgi_cpp_no_body.cpp @@ -0,0 +1,22 @@ + +# include "cgi_utils.hpp" + +int main (int ac, char **av, char ** env) +{ + std::string http_header; + std::string http_status; + std::string rq_body; + + std::cin >> rq_body; + + (void)ac; + (void)av; + (void)env; + + http_header = "Content-Type: text/html; charset=UTF-8" CRLF; + + std::cout << http_header << CRLF; + + return 0; +} + diff --git a/srcs/cgi-bin/cgi_cpp_no_headers.cpp b/srcs/cgi-bin/cgi_cpp_no_headers.cpp new file mode 100644 index 0000000..b563a71 --- /dev/null +++ b/srcs/cgi-bin/cgi_cpp_no_headers.cpp @@ -0,0 +1,24 @@ + +# include "cgi_utils.hpp" + +int main (int ac, char **av, char ** env) +{ + std::string http_header; + std::string http_body; + std::string http_status; + std::string rq_body; + + std::cin >> rq_body; + + (void)ac; + (void)av; + + http_header = CRLF; + + fill_body_basic(env, http_body, rq_body); + + std::cout << CRLF << http_body; + + return 0; +} + diff --git a/srcs/cgi-bin/cgi_cpp_only_crlf.cpp b/srcs/cgi-bin/cgi_cpp_only_crlf.cpp new file mode 100644 index 0000000..0c253b3 --- /dev/null +++ b/srcs/cgi-bin/cgi_cpp_only_crlf.cpp @@ -0,0 +1,15 @@ + +# include "cgi_utils.hpp" + +int main (int ac, char **av, char ** env) +{ + (void)ac; + (void)av; + (void)env; + + std::cout << CRLF CRLF; + + return 0; +} + + diff --git a/srcs/cgi-bin/cgi_cpp_sleep.cpp b/srcs/cgi-bin/cgi_cpp_sleep.cpp new file mode 100644 index 0000000..0948606 --- /dev/null +++ b/srcs/cgi-bin/cgi_cpp_sleep.cpp @@ -0,0 +1,29 @@ + +# include "cgi_utils.hpp" + +int main (int ac, char **av, char ** env) +{ + std::string http_header; + std::string http_body; + std::string rq_body; + size_t time; + std::stringstream ss; + + std::cin >> rq_body; + + (void)ac; + (void)av; + + http_header = "Content-Type: text/html; charset=UTF-8" CRLF; + + fill_body_basic(env, http_body, rq_body); + + ss << get_value("sleep", rq_body); + ss >> time; + sleep(time); + + std::cout << http_header << CRLF << http_body; + + return 0; +} + diff --git a/srcs/cgi-bin/cgi_cpp_status.cpp b/srcs/cgi-bin/cgi_cpp_status.cpp index 7fc2715..1fee0a8 100644 --- a/srcs/cgi-bin/cgi_cpp_status.cpp +++ b/srcs/cgi-bin/cgi_cpp_status.cpp @@ -6,14 +6,19 @@ int main (int ac, char **av, char ** env) std::string http_header; std::string http_body; std::string http_status; + std::string rq_body; + + std::cin >> rq_body; (void)ac; (void)av; - fill_response_basic(env, http_body, http_header); + http_header = "Content-Type: text/html; charset=UTF-8" CRLF; - http_status = get_value("Status"); - http_header += "Status: " + http_status; + fill_body_basic(env, http_body, rq_body); + + http_status = get_value("Status", rq_body); + http_header += "Status: " + http_status + CRLF; std::cout << http_header << CRLF CRLF << http_body; diff --git a/srcs/cgi-bin/cgi_utils.cpp b/srcs/cgi-bin/cgi_utils.cpp index 3be41e3..9e2e7b7 100644 --- a/srcs/cgi-bin/cgi_utils.cpp +++ b/srcs/cgi-bin/cgi_utils.cpp @@ -69,14 +69,6 @@ std::string parse_env(const std::string & env) return ret; } -std::string parse_body() -{ - std::string ret; - - std::cin >> ret; - return ret; -} - std::string print_env(char **env, std::string tag) { std::string ret = ""; @@ -114,7 +106,7 @@ std::string return ret; } -std::string get_form_infos() +std::string get_form_infos(const std::string & rq_body) { std::string form_infos; std::string method; @@ -122,14 +114,14 @@ std::string get_form_infos() method = parse_env("REQUEST_METHOD"); if (method == "POST") - form_infos = parse_body(); + form_infos = rq_body; else if (method == "GET") form_infos = parse_env("QUERY_STRING"); return form_infos; } -std::string get_value(std::string key) +std::string get_value(const std::string & key, const std::string & rq_body) { std::string infos; std::string ret; @@ -137,7 +129,7 @@ std::string get_value(std::string key) size_t end; size_t len; - infos = get_form_infos(); + infos = get_form_infos(rq_body); pos = str_tolower(infos).find(str_tolower(key)); if (pos == NPOS) return ""; @@ -155,15 +147,13 @@ std::string get_value(std::string key) } void - fill_response_basic(char **env, std::string & http_body, std::string & http_header) + fill_body_basic(char **env, std::string & http_body, const std::string & rq_body) { std::string rq_method = "not found"; - std::string rq_body; std::string rq_query; std::string form_infos; rq_method = parse_env("REQUEST_METHOD"); - rq_body = parse_body(); rq_query = parse_env("QUERY_STRING"); if (rq_method == "POST") @@ -189,7 +179,21 @@ void http_body += print_env(env, "p"); http_body += HTML_BODY_BOTTOM; - - http_header = "Content-Type: text/html; charset=UTF-8" CRLF; +} + +size_t eval_file_read(const std::string &path) +{ + 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(), R_OK) == -1) + { + std::perror("err access()"); + return 403; // FORBIDDEN, file doesn't have access permission + } + return 0; } diff --git a/srcs/cgi-bin/cgi_utils.hpp b/srcs/cgi-bin/cgi_utils.hpp index 38446de..6ba5a7a 100644 --- a/srcs/cgi-bin/cgi_utils.hpp +++ b/srcs/cgi-bin/cgi_utils.hpp @@ -5,9 +5,11 @@ # include # include # include +# include # include # include // getenv # include // transform +# include // sleep, close, access # define CR "\r" # define LF "\n" @@ -24,42 +26,43 @@ " "\ " "\ " "\ - "

cgi


" -# define HTML_BODY_BOTTOM " "\ + "

CGI


" +# define HTML_BODY_BOTTOM "

END CGI

"\ + " "\ "" std::string - str_tolower(std::string str); +str_tolower(std::string str); std::string - trim(std::string str, char del); +trim(std::string str, char del); std::vector - split(const std::string & input, std::string delim, char ctrim = '\0'); +split(const std::string & input, std::string delim, char ctrim = '\0'); std::string - itos(int n); +itos(int n); std::string - parse_env(const std::string & env); +parse_env(const std::string & env); std::string - parse_body(); +print_env(char **env, std::string tag = "p"); std::string - print_env(char **env, std::string tag = "p"); +get_form_infos(const std::string & rq_body); std::string - get_form_infos(); +get_value(const std::string & key, const std::string & rq_body); std::string - get_value(std::string key); - -std::string - print_form(std::string form, std::string key = "p", std::string val = "p"); +print_form(std::string form, std::string key = "p", std::string val = "p"); void - fill_response_basic(char **env, std::string & body, std::string & header); +fill_body_basic(char **env, std::string & http_body, const std::string & rq_body); + +size_t +eval_file_read(const std::string &path); #endif diff --git a/srcs/webserv/Webserv.hpp b/srcs/webserv/Webserv.hpp index d7ecf42..24ce1fc 100644 --- a/srcs/webserv/Webserv.hpp +++ b/srcs/webserv/Webserv.hpp @@ -132,17 +132,15 @@ class Webserv void _exec_script(Client *client, char *env[]); 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); + size_t _check_script_fields(const std::string & output, size_t status); + void _check_fields_duplicates(Client *client, std::string & output); void _add_script_body_length_header(std::string & output); void _remove_body_leading_empty_lines(std::string & output); - - - Client *_find_cgi_fd(int cgi_fd); - void _read_cgi_output(Client *client); - void _handle_epoll_error_cgi_fd(uint32_t events, Client *client); - void _cgi_epollhup(uint32_t events, Client *client); - + Client *_find_cgi_fd(int cgi_fd); + void _read_cgi_output(Client *client); + void _handle_epoll_error_cgi_fd(uint32_t events, Client *client); + void _cgi_epollhup(uint32_t events, Client *client); /////////////////////// diff --git a/srcs/webserv/cgi.cpp b/srcs/webserv/cgi.cpp index af77b75..8524713 100644 --- a/srcs/webserv/cgi.cpp +++ b/srcs/webserv/cgi.cpp @@ -18,7 +18,7 @@ bool Webserv::_is_cgi(Client *client, std::string path) if (pos == NPOS) break; client->fill_script_path(path, pos); - script_path = "." + client->get_rq_script_path(); + script_path = client->get_rq_script_path(); file_type = ::eval_file_type(script_path); if (file_type == IS_DIR) // but what if it's a symlink ? continue; @@ -126,7 +126,7 @@ void Webserv::_set_env_vector(Client *client, std::vector &env_vect 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())); // LUKE: To Check 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")); @@ -200,7 +200,7 @@ void Webserv::_exec_script(Client *client, char *env[]) ::close(FD_RD_FR_PRNT); ::close(FD_WR_TO_PRNT); - path = "." + client->get_rq_script_path(); // Wut ? Only relative path ? + path = client->get_rq_script_path(); // Wut ? Only relative path ? /*DEBUG*/std::cerr << "execve:[" << path << "]\n"; if (::execve(path.c_str(), nll, env) == -1) // replace path for debug error forcing { @@ -241,16 +241,14 @@ 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]:" RESET "\n"; ::print_special(output); std::cout << B_PURPLE "-----------" RESET "\n\n"; - _check_script_fields(client, output); -///*DEBUG*/ std::cout << "\n" B_PURPLE "[script fields]:" RESET "\n"; ::print_special(output); std::cout << B_PURPLE "-----------" RESET "\n\n"; +//*DEBUG*/ std::cout << "\n" B_PURPLE "[script status]:" RESET "\n"; ::print_special(output); std::cout << B_PURPLE "-----------" RESET "\n\n"; + client->status = _check_script_fields(output, client->status); + _check_fields_duplicates(client, output); +//*DEBUG*/ std::cout << "\n" B_PURPLE "[script fields]:" 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]:" RESET "\n"; ::print_special(output); std::cout << B_PURPLE "-----------" RESET "\n\n"; +//*DEBUG*/ std::cout << "\n" B_PURPLE "[script empty lines]:" 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]:" RESET "\n"; ::print_special(output); std::cout << B_PURPLE "-----------" RESET "\n\n"; - // _check_script_empty_lines(client, output); - // _check_script_space_colons(client, output); - // _check_script_new_lines(client, output); +//*DEBUG*/ std::cout << "\n" B_PURPLE "[script content length]:" RESET "\n"; ::print_special(output); std::cout << B_PURPLE "-----------" RESET "\n\n"; } void Webserv::_check_script_status(Client *client, std::string & output) @@ -269,7 +267,35 @@ void Webserv::_check_script_status(Client *client, std::string & output) client->status = 200; } -void Webserv::_check_script_fields(Client *client, std::string & output) +size_t Webserv::_check_script_fields(const std::string & output, size_t status) +{ + std::string headers; + std::string body; + size_t pos; + + pos = output.find(CRLF CRLF); + if (pos == NPOS) // there is not empty line + return 500; + headers = output.substr(0, pos); + body = output.substr(pos + CRLF_SIZE * 2); + headers = str_tolower(headers); + pos = headers.find("content-type"); + if (pos == NPOS) // there is no content-type field + { + if (!body.empty()) // there is body + return 500; + if (headers.find("location") == NPOS) // there is no location field + return 500; + } + else if (headers.find("location") != NPOS) // there is a location field + { + if (body.empty()) // there is no body + return 500; + } + return status; +} + +void Webserv::_check_fields_duplicates(Client *client, std::string & output) { std::map srv_fld; // server_field std::map scr_fld; // script_field diff --git a/srcs/webserv/response.cpp b/srcs/webserv/response.cpp index d143e8d..3d922c1 100644 --- a/srcs/webserv/response.cpp +++ b/srcs/webserv/response.cpp @@ -64,7 +64,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 << "\n" 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"; // /* 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); @@ -97,7 +97,6 @@ void Webserv::_append_base_headers(Client *client) client->response.append("Connection: keep-alive" CRLF); } -// TODO HUGO : wip void Webserv::_construct_response(Client *client) { std::string path; diff --git a/www/directory/root.png b/www/directory/root.png new file mode 100644 index 0000000..ebd1548 Binary files /dev/null and b/www/directory/root.png differ diff --git a/www/file.md b/www/file.md new file mode 100644 index 0000000..a8b8ab6 --- /dev/null +++ b/www/file.md @@ -0,0 +1 @@ +some md file to test upload diff --git a/www/form_cgi.html b/www/form_cgi.html index 4dd1d8b..2e73f05 100644 --- a/www/form_cgi.html +++ b/www/form_cgi.html @@ -18,7 +18,6 @@ form { display: flex; flex-direction: column; - border: 1px solid red; margin: 20px; padding: 5px; } @@ -29,10 +28,31 @@ mark { margin: 0px 3px; } + #get form { + border: 1px solid red; + } + #post form { + border: 1px solid green; + } + +

get form

@@ -42,6 +62,8 @@


+

expectation:

+

normal output


@@ -53,6 +75,8 @@


+

expectation:

+

normal output


@@ -64,6 +88,8 @@


+

expectation:

+

normal output


@@ -75,6 +101,8 @@


+

expectation:

+

normal output


@@ -151,9 +179,132 @@ +

expectation:

+

depend on status code

+ +
+ +
+

get form

+

to /cgi-bin/cgi_cpp_empty_lines.out

+
+
+
+

+ +

expectation:

+

normal output

+
+
+ +
+

get form

+

to /cgi-bin/cgi_cpp_sleep.out

+
+
+
+

+
+

+ +

expectation:

+

the request will sleep for chosen seconds

+

but other request chould not be blocked

+
+
+ +
+

get form

+

to /cgi-bin/cgi_cpp_no_body.out

+
+
+
+

+ +

expectation:

+

blank page

+
+
+ +
+

get form

+

to /cgi-bin/cgi_cpp_bad_headers.out

+
+
+
+

+ +

expectation:

+

error 500

+
+
+ +
+

get form

+

to /cgi-bin/cgi_cpp_empty.out

+
+
+
+

+ +

expectation:

+

error 500

+
+
+ +
+

get form

+

to /cgi-bin/cgi_cpp_no_headers.out

+
+
+
+

+ +

expectation:

+

error 500

+
+
+ +
+

get form

+

to /cgi-bin/cgi_cpp_only_crlf.out

+
+
+
+

+ +

expectation:

+

error 500

+
+
+ +
+

WIP

+

get form

+

to /cgi-bin/cgi_cpp_download.out

+
+ + + +

expectation:

+

get a file in list

+

from ./www/user_files/

+ + +

post form

@@ -163,6 +314,8 @@


+

expectation:

+

normal output


@@ -174,6 +327,8 @@


+

expectation:

+

normal output


@@ -185,6 +340,8 @@


+

expectation:

+

normal output


@@ -196,6 +353,8 @@


+

expectation:

+

normal output


@@ -272,6 +431,114 @@ +

expectation:

+

depend on status code

+ +
+ +
+

post form

+

to /cgi-bin/cgi_cpp_empty_lines.out

+
+
+
+

+ +

expectation:

+

normal output

+
+
+ +
+

post form

+

to /cgi-bin/cgi_cpp_sleep.out

+
+
+
+

+
+

+ +

expectation:

+

the request will sleep for chosen seconds

+

but other request chould not be blocked

+
+
+ +
+

post form

+

to /cgi-bin/cgi_cpp_no_body.out

+
+
+
+

+ +

expectation:

+

blank page

+
+
+ +
+

post form

+

to /cgi-bin/cgi_cpp_bad_headers.out

+
+
+
+

+ +

expectation:

+

error 500

+
+
+ +
+

post form

+

to /cgi-bin/cgi_cpp_empty.out

+
+
+
+

+ +

expectation:

+

error 500

+
+
+ +
+

post form

+

to /cgi-bin/cgi_cpp_no_headers.out

+
+
+
+

+ +

expectation:

+

error 500

+
+
+ +
+

post form

+

to /cgi-bin/cgi_cpp_only_crlf.out

+
+
+
+

+ +

expectation:

+

error 500

+
+
+ +
+

WIP

+

post form

+

to /cgi-bin/cgi_cpp_upload.out

+
+ + +

expectation:

+

upload file in ./www/user_files/

diff --git a/www/subject.pdf b/www/subject.pdf new file mode 100644 index 0000000..005f6c2 Binary files /dev/null and b/www/subject.pdf differ diff --git a/www/user_files/duck.jpg b/www/user_files/duck.jpg new file mode 100644 index 0000000..1a7c38d Binary files /dev/null and b/www/user_files/duck.jpg differ