Merge branch 'hugo5'

This commit is contained in:
Hugo LAMY
2022-08-15 21:18:06 +02:00
11 changed files with 309 additions and 160 deletions

View File

@@ -6,7 +6,7 @@ CXXFLAGS = -Wall -Wextra #-Werror
CXXFLAGS += $(HEADERS_D:%=-I%)
CXXFLAGS += -std=c++98
CXXFLAGS += -g
CXXFLAGS += -fno-limit-debug-info
#CXXFLAGS += -fno-limit-debug-info
CXXFLAGS += -MMD -MP #header dependencie
#CXXFLAGS += -O3
@@ -18,7 +18,7 @@ HEADERS_D = srcs \
SRCS_D = srcs \
srcs/webserv \
srcs/config
srcs/config \
SRCS = main.cpp \
base.cpp init.cpp close.cpp epoll_update.cpp signal.cpp \
@@ -36,9 +36,12 @@ OBJS_D = builds
OBJS = $(SRCS:%.cpp=$(OBJS_D)/%.o)
DEPS = $(OBJS:.o=.d) #header dependencie
# --------------------
# ------ RULES -------
# --------------------
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# . target: prerequisites . $@ : target #
# RULES . recipe . $< : 1st prerequisite #
# . @recipe (silent) . $^ : all prerequisites #
# . target: VAR = assignment . | : order-only prereq. #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
all: $(NAME)
@@ -53,6 +56,16 @@ $(NAME): $(OBJS)
$(CXX) $^ -o $(NAME)
echo "$(_GREEN)\r\33[2K\r$(NAME) created 😎$(_END)"
# CGI
cgi:
make -C srcs/cgi-bin
cgiclean:
make clean -C srcs/cgi-bin
cgifclean:
make fclean -C srcs/cgi-bin
cgire:
make re -C srcs/cgi-bin
clean:
rm -rf $(OBJS_D)

86
srcs/cgi-bin/Makefile Normal file
View File

@@ -0,0 +1,86 @@
# - - - - - - #
# #
# COLORS #
# #
# - - - - - - #
GRAY = "\e[0;30m"
RED = "\e[0;31m"
GREEN = "\e[0;32m"
YELLOW = "\e[0;33m"
BLUE = "\e[0;34m"
PURPLE = "\e[0;35m"
CYAN = "\e[0;36m"
WHITE = "\e[0;37m"
B_GRAY = "\e[1;30m"
B_RED = "\e[1;31m"
B_GREEN = "\e[1;32m"
B_YELLOW = "\e[1;33m"
B_BLUE = "\e[1;34m"
B_PURPLE = "\e[1;35m"
B_CYAN = "\e[1;36m"
B_WHITE = "\e[1;37m"
RESET = "\e[0m"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# . name = value \ . += append to a variable #
# VARIABLES . value . != set result of command #
# . name is case sensitive . ?= set if not already set #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
NAME_1 = $(SRCS_1:.cpp=.out)
NAME_2 = $(SRCS_2:.cpp=.out)
CXX = c++
CXXFLAGS = -Wall -Wextra #-Werror
CXXFLAGS += $(HEADERS_D:%=-I%)
CXXFLAGS += -std=c++98
CXXFLAGS += -g
VPATH = $(SRCS_D)
HEADERS_D = .
SRCS_D = .
SRCS = cgi_utils.cpp
SRCS_1 = cgi_cpp.cpp
SRCS_2 = cgi_cpp_content_length.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)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# . target: prerequisites . $@ : target #
# RULES . recipe . $< : 1st prerequisite #
# . recipe . $^ : all prerequisites #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
all: cgi_1 cgi_2
cgi_1: $(NAME_1)
cgi_2: $(NAME_2)
$(OBJS_D)/%.o: %.cpp | $(OBJS_D)
$(CXX) $(CXXFLAGS) -c $< -o $@
$(OBJS_D):
mkdir $@
$(NAME_1): $(OBJS) $(OBJS_1)
$(NAME_2): $(OBJS) $(OBJS_2)
$(NAME_1) $(NAME_2):
$(CXX) $^ -o $@
clean:
rm -rf $(OBJS_D)
fclean: clean
rm -f $(NAME_1)
rm -f $(NAME_2)
re: fclean all
.PHONY : all clean fclean re

4
srcs/cgi-bin/cgi Executable file
View File

@@ -0,0 +1,4 @@
#! /bin/bash
echo "status: 100\r\n"
echo "\r\n\r\n"
echo "hiii"

View File

@@ -1,114 +1,51 @@
# include <iostream>
# include <string>
# include <sstream>
# include <vector>
# include <stdlib.h> // getenv
# define CR "\r"
# define LF "\n"
# define CRLF CR LF
# define NPOS std::string::npos
# include "cgi_utils.hpp"
std::string trim(std::string str, char del)
int main (int ac, char **av, char ** env)
{
size_t pos;
std::string rq_method = "not found";
std::string rq_body = "";
std::string rq_query = "";
std::string form_infos = "";
std::string http_header = "";
std::string http_body = "";
// delete leadings del
pos = str.find_first_not_of(del);
if (pos == NPOS)
pos = str.size();
str = str.substr(pos);
(void)ac;
(void)av;
// delete trailing del
pos = str.find_last_not_of(del);
if (pos != NPOS)
str = str.substr(0, pos + 1);
rq_method = parse_env("REQUEST_METHOD");
rq_body = parse_body();
rq_query = parse_env("QUERY_STRING");
return str;
}
if (rq_method == "POST")
form_infos = rq_body;
else if (rq_method == "GET")
form_infos = rq_query;
std::vector<std::string>
split(const std::string & input, std::string delim, char ctrim = '\0')
{
std::vector<std::string> split_str;
std::string tmp;
size_t start = 0;
size_t end = 0;
size_t len = 0;
http_body = HTML_BODY_TOP;
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;
}
http_body += "<br><h3>method used: </h3>";
http_body += "<p>" + rq_method + "</p>";
int main (int ac, char **av, char **en)
{
std::vector<std::string> split_str;
std::vector<std::string> sub_split_str;
std::vector<std::string>::const_iterator it;
char * tmp;
std::string input;
std::string http_header;
std::string http_body;
std::ostringstream strs;
size_t pos;
http_body += "<br><h3>form body: </h3>";
http_body += "<p>" + rq_body + "</p>";
std::cin >> input;
http_body += "<br><h3>form query: </h3>";
http_body += "<p>" + rq_query + "</p>";
http_header = "Content-Type: text/html; charset=UTF-8" CRLF;
http_header += "Content-Length: ";
http_body += "<br><br><h3>output:</h3><br>";
http_body += print_form(form_infos, "p", "p");
http_body = "\
<!DOCTYPE html>\
<html>\
<head>\
<title>CGI</title>\
</head>\
<body>\
<h2>cgi</h2>\
";
http_body += "<br><br><h3>cgi_env_variables:</h3><br>";
http_body += print_env(env, "p");
http_body += "<h3>";
tmp = getenv("REQUEST_METHOD");
if (tmp != NULL)
http_body += tmp;
else
http_body = "method not foud";
http_body += "</h3>";
http_body += HTML_BODY_BOTTOM;
split_str = split(input, "&");
for (it = split_str.begin(); it != split_str.end(); ++it)
{
sub_split_str = split(*it, "=");
http_body += "<h3>";
http_body += sub_split_str[0];
http_body += "</h3>";
http_body += "<p>";
http_body += sub_split_str[1];
http_body += "</p>";
}
http_body += "\
</body>\
</html>\
";
strs << http_body.size();
http_header += strs.str();
http_header += CRLF CRLF;
http_header = "Content-Type: text/html; charset=UTF-8" CRLF;
http_header += "Content-Length: " + itos(http_body.size() - 10);
std::cout << http_header << CRLF CRLF << http_body;
return 0;
}

View File

@@ -1,65 +1,14 @@
# include <iostream>
# include <string>
# include <sstream>
# include <vector>
# include <stdlib.h> // getenv
# define CR "\r"
# define LF "\n"
# define CRLF CR LF
# define NPOS std::string::npos
# include "cgi_utils.hpp"
std::string trim(std::string str, char del)
int main ()
{
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<std::string>
split(const std::string & input, std::string delim, char ctrim = '\0')
{
std::vector<std::string> 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<std::string> split_str;
std::vector<std::string> sub_split_str;
std::vector<std::string>::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;

View File

@@ -0,0 +1,3 @@
h1, h2, h3, p {
display: inline;
}

104
srcs/cgi-bin/cgi_utils.cpp Normal file
View File

@@ -0,0 +1,104 @@
#include "cgi_utils.hpp"
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<std::string>
split(const std::string & input, std::string delim, char ctrim)
{
std::vector<std::string> 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;
}
std::string itos(int n)
{
std::stringstream strs;
strs << n;
return ( strs.str() );
}
std::string parse_env(const std::string & env)
{
std::string ret = "";
char * ret_env;
ret_env = getenv(env.c_str());
if (ret_env != NULL)
ret = ret_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 = "";
for (int i = 0; env[i] != NULL; ++i)
{
ret += "<" + tag + ">";
ret += env[i];
ret += "</" + tag + "><br>";
}
return ret;
}
std::string
print_form(std::string form, std::string tag_key, std::string tag_val)
{
std::vector<std::string> split_str;
std::vector<std::string> sub_split_str;
std::vector<std::string>::const_iterator it;
std::string ret = "";
split_str = split(form, "&");
for (it = split_str.begin(); it != split_str.end(); ++it)
{
sub_split_str = split(*it, "=");
ret += "<br><" + tag_key + ">" + sub_split_str[0] + ": </" + tag_key + ">";
ret += "<" + tag_val + ">" + sub_split_str[1] + "</" + tag_val + ">";
}
return ret;
}

View File

@@ -0,0 +1,52 @@
#ifndef CGI_UTILS_HPP
# define CGI_UTILS_HPP
# include <iostream>
# include <string>
# include <sstream>
# include <vector>
# include <stdlib.h> // getenv
# define CR "\r"
# define LF "\n"
# define CRLF CR LF
# define CRLF_SIZE 2
# define NPOS std::string::npos
# define HTML_BODY_TOP "<!DOCTYPE html>"\
"<html>"\
" <head>"\
" <meta charset=\"UTF-8\">"\
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"\
" <title>CGI</title>"\
" <link href=\"./cgi_style.css\" type=\"text/css\" rel=\"stylesheet\">"\
" </head>"\
" <body>"\
" <h1>cgi</h1><br>"
# define HTML_BODY_BOTTOM " </body>"\
"</html>"
std::string
trim(std::string str, char del);
std::vector<std::string>
split(const std::string & input, std::string delim, char ctrim = '\0');
std::string
itos(int n);
std::string
parse_env(const std::string & env);
std::string
parse_body();
std::string
print_env(char **env, std::string tag = "p");
std::string
print_form(std::string form, std::string key = "p", std::string val = "p");
#endif

View File

@@ -187,9 +187,13 @@ std::string Webserv::_exec_script(Client *client, char **env)
void Webserv::_check_script_output(Client *client, std::string & output)
{
_check_script_status(client, output);
/*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";
_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";
_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);

View File

@@ -90,15 +90,12 @@ 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";
/*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";
_check_script_output(client, script_output);
client->response += script_output;
/*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";
///*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;
}