merge, the whole thing is cleaner
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
|
||||
NAME = webserv
|
||||
CXX = clang++
|
||||
CXX = c++
|
||||
|
||||
CXXFLAGS = -Wall -Wextra #-Werror
|
||||
CXXFLAGS += $(HEADERS_D:%=-I%)
|
||||
|
||||
@@ -1,29 +1,35 @@
|
||||
|
||||
server {
|
||||
|
||||
# this is a comment
|
||||
|
||||
server_name our_server;
|
||||
server_name server1;
|
||||
|
||||
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 / {
|
||||
allow_methods GET;
|
||||
root ./www/;
|
||||
}
|
||||
|
||||
# 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;
|
||||
@@ -31,18 +37,18 @@ server {
|
||||
|
||||
location /cgi-bin {
|
||||
root ./srcs/cgi-bin/;
|
||||
cgi_ext cpp php sh;
|
||||
cgi_ext out 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;
|
||||
}
|
||||
@@ -89,5 +95,13 @@ server {
|
||||
# allow_methods DELETE;
|
||||
# }
|
||||
|
||||
|
||||
}
|
||||
|
||||
server {
|
||||
server_name server2;
|
||||
|
||||
listen 0.0.0.0:4040;
|
||||
|
||||
index index.html;
|
||||
root ./www2/;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
# import and run all tests
|
||||
|
||||
#test_files=("test_template.sh" "test_header.sh" "test_body.sh")
|
||||
#test_files=("test_template.sh" "test_header.sh" "test_path.sh")
|
||||
test_files=("test_path.sh")
|
||||
test_files=("test_template.sh" "test_header.sh" "test_path.sh")
|
||||
#test_files=("test_path.sh")
|
||||
|
||||
|
||||
test_all()
|
||||
|
||||
14
memo.txt
14
memo.txt
@@ -1,25 +1,21 @@
|
||||
IN 42 SUBJECT AND/OR PRIORITY :
|
||||
- CGI (TODO HUGO)
|
||||
- chunked request (need testing)
|
||||
|
||||
- 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
|
||||
- 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 :
|
||||
- dans config, check erreur si port > 16bits
|
||||
(peut-être check si ip > 32bits)
|
||||
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")
|
||||
- do correct handling of special character in url (/rfc2119_files/errata.js.t%C3%A9l%C3%A9chargement -> /rfc2119_files/errata.js.téléchargement)
|
||||
|
||||
@@ -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";
|
||||
@@ -215,18 +218,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()
|
||||
@@ -412,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";
|
||||
///////////////////////
|
||||
|
||||
Binary file not shown.
114
srcs/cgi-bin/cgi_cpp.cpp
Normal file
114
srcs/cgi-bin/cgi_cpp.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
# 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
|
||||
|
||||
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 = '\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 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 = "\
|
||||
<!DOCTYPE html>\
|
||||
<html>\
|
||||
<head>\
|
||||
<title>CGI</title>\
|
||||
</head>\
|
||||
<body>\
|
||||
<h2>cgi</h2>\
|
||||
";
|
||||
|
||||
http_body += "<h3>";
|
||||
tmp = getenv("REQUEST_METHOD");
|
||||
if (tmp != NULL)
|
||||
http_body += tmp;
|
||||
else
|
||||
http_body = "method not foud";
|
||||
http_body += "</h3>";
|
||||
|
||||
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;
|
||||
|
||||
std::cout << http_header << CRLF CRLF << http_body;
|
||||
return 0;
|
||||
}
|
||||
|
||||
133
srcs/cgi-bin/cgi_cpp_content_length.cpp
Normal file
133
srcs/cgi-bin/cgi_cpp_content_length.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
# 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
|
||||
|
||||
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 = '\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;
|
||||
|
||||
std::cout
|
||||
<< "<!DOCTYPE html>"
|
||||
<< "<html>"
|
||||
<< "<head>"
|
||||
<< " <title>CGI</title>"
|
||||
<< "</head>"
|
||||
<< "<body>"
|
||||
<< " <h2>cgi</h2>"
|
||||
<< " <h3>";
|
||||
|
||||
tmp = getenv("REQUEST_METHOD");
|
||||
if (tmp != NULL)
|
||||
output = tmp;
|
||||
else
|
||||
output = "method not foud";
|
||||
|
||||
std::cout
|
||||
<< output
|
||||
<< " </h3>"
|
||||
<< " <h3>http-request-body-message content :</h3>";
|
||||
|
||||
|
||||
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
|
||||
<< "<p>"
|
||||
<< sub_split_str[0]
|
||||
<< " : "
|
||||
<< sub_split_str[1]
|
||||
<< "</p>";
|
||||
}
|
||||
|
||||
tmp = getenv("QUERY_STRING");
|
||||
if (tmp == NULL)
|
||||
std::cout << "query not foud";
|
||||
|
||||
std::cout
|
||||
<< " <h3>http-uri-query content :</h3>";
|
||||
|
||||
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
|
||||
<< "<h3>"
|
||||
<< sub_split_str[0]
|
||||
<< "</h3>"
|
||||
<< "<p>"
|
||||
<< sub_split_str[1]
|
||||
<< "</p>";
|
||||
}
|
||||
|
||||
|
||||
std::cout
|
||||
<< "</body>"
|
||||
<< "</html>";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
# include <cstdlib> // strtol, stroul
|
||||
# include <iostream> // cout, cin
|
||||
# include <fstream> // ifstream
|
||||
//# include <unistd.h> // access()
|
||||
# include <dirent.h> // opendir(), doesn't work...
|
||||
# include <sys/stat.h> // stat(), replaces opendir() don't bother with ERRNO ?
|
||||
# include <algorithm> // sort() in Post
|
||||
|
||||
@@ -23,43 +21,37 @@ class ConfigParser {
|
||||
|
||||
public:
|
||||
|
||||
ConfigParser(const char* path); // a string?
|
||||
|
||||
// might not need this either, ask Luke
|
||||
ConfigParser();
|
||||
~ConfigParser();
|
||||
ConfigParser(const std::string &config_file);
|
||||
|
||||
void read_config(const std::string &config_file);
|
||||
|
||||
std::vector<ServerConfig> * parse(); // const?
|
||||
|
||||
|
||||
// i thought if it were an instance of this class you could call
|
||||
// private member functions from anywhere...
|
||||
// private member functions from anywhere... // QUESTION : Wut ?
|
||||
void print_content() const;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
std::string _content;
|
||||
|
||||
// not sure i even need this...
|
||||
ConfigParser();
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
/* Extra */
|
||||
std::string _pre_set_val_check(const std::string key, \
|
||||
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<ServerConfig> *servers);
|
||||
bool _find_root_path_location(std::vector<LocationConfig> locations) const;
|
||||
|
||||
@@ -1,31 +1,14 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* LocationConfig.hpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/07/23 16:08:00 by me #+# #+# */
|
||||
/* Updated: 2022/08/15 19:37:34 by erlazo ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef LOCATIONCONFIG_HPP
|
||||
# define LOCATIONCONFIG_HPP
|
||||
|
||||
# include <map>
|
||||
# include <vector>
|
||||
# include <string>
|
||||
# include <iostream>
|
||||
# include <sys/stat.h> // stat()
|
||||
|
||||
# include "utils.hpp"
|
||||
|
||||
// again, struct instead?
|
||||
class LocationConfig
|
||||
struct LocationConfig
|
||||
{
|
||||
public:
|
||||
|
||||
std::string path; // /path and /path/ are fine
|
||||
// i remove trailing / systematically
|
||||
std::string root;
|
||||
@@ -91,13 +74,4 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,13 +10,9 @@
|
||||
# include <string> // string
|
||||
# include <iostream> // cout, cin
|
||||
|
||||
// a class that's all public? just so we have options?
|
||||
class ServerConfig
|
||||
struct ServerConfig
|
||||
{
|
||||
public:
|
||||
|
||||
std::vector<std::string> server_name;
|
||||
// we could shove default in here if we wanted to...
|
||||
|
||||
std::string host;
|
||||
std::string port;
|
||||
@@ -24,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<std::string> index;
|
||||
std::map<int, std::string> error_pages;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
|
||||
|
||||
|
||||
#include "ConfigParser.hpp"
|
||||
|
||||
// should i be sending & references?
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
|
||||
#include "ConfigParser.hpp"
|
||||
|
||||
// Default
|
||||
// possibly remove...
|
||||
ConfigParser::ConfigParser()
|
||||
ConfigParser::ConfigParser() {};
|
||||
ConfigParser::~ConfigParser() {};
|
||||
|
||||
ConfigParser::ConfigParser(const std::string &config_file)
|
||||
{
|
||||
std::cout << "Default Constructor\n";
|
||||
read_config(config_file);
|
||||
}
|
||||
|
||||
ConfigParser::ConfigParser(const char* path)
|
||||
void ConfigParser::read_config(const std::string &config_file)
|
||||
{
|
||||
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);
|
||||
@@ -35,19 +38,9 @@ ConfigParser::ConfigParser(const char* path)
|
||||
_content.append(tmp + '\n');
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
else
|
||||
throw std::invalid_argument("failed to open config");
|
||||
}
|
||||
|
||||
// might not need this...
|
||||
ConfigParser::~ConfigParser()
|
||||
{
|
||||
// do i need to destroy anything, won't it handle itself?
|
||||
}
|
||||
|
||||
|
||||
// const?
|
||||
std::vector<ServerConfig> * ConfigParser::parse()
|
||||
{
|
||||
@@ -156,7 +149,7 @@ LocationConfig ConfigParser::_parse_location(size_t *start)
|
||||
|
||||
|
||||
// should i be sending pointers or references?
|
||||
void ConfigParser::_set_server_values(ServerConfig *server, \
|
||||
void ConfigParser::_set_server_values(ServerConfig *server,
|
||||
const std::string key, std::string value)
|
||||
{
|
||||
// should i be sending pointers or references?
|
||||
@@ -181,7 +174,7 @@ void ConfigParser::_set_server_values(ServerConfig *server, \
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
@@ -222,6 +215,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")
|
||||
{
|
||||
@@ -231,7 +227,7 @@ void ConfigParser::_set_server_values(ServerConfig *server, \
|
||||
else if (key == "error_page")
|
||||
{
|
||||
std::string path = tmp_val[size - 1];
|
||||
for (size_t i = 0; i < size() - 1; i++)
|
||||
for (size_t i = 0; i < size - 1; i++)
|
||||
{
|
||||
if (!(isNumeric_btw(400, 599, tmp_val[i])))
|
||||
throw std::invalid_argument("invalid error code");
|
||||
@@ -247,7 +243,7 @@ void ConfigParser::_set_server_values(ServerConfig *server, \
|
||||
|
||||
|
||||
// should i be sending pointers or references?
|
||||
void ConfigParser::_set_location_values(LocationConfig *location, \
|
||||
void ConfigParser::_set_location_values(LocationConfig *location,
|
||||
const std::string key, std::string value)
|
||||
{
|
||||
// should i be sending pointers or references?
|
||||
|
||||
@@ -22,7 +22,7 @@ void ConfigParser::_post_processing(std::vector<ServerConfig> *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
|
||||
|
||||
@@ -11,15 +11,9 @@ 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<ServerConfig>* servers = configParser.parse();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -226,7 +227,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);
|
||||
|
||||
@@ -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();
|
||||
@@ -65,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<std::string, std::string> & fields );
|
||||
void str_map_key_tolower(std::map<std::string, std::string> & mp);
|
||||
void throw_test();
|
||||
// debug
|
||||
void throw_test();
|
||||
void print_special(std::string str);
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -5,13 +5,12 @@ 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)
|
||||
{
|
||||
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) )
|
||||
@@ -147,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);
|
||||
@@ -157,21 +148,21 @@ 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);
|
||||
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);
|
||||
std::cerr << "execve crashed.\n";
|
||||
// TODO HUGO : check errno
|
||||
}
|
||||
else
|
||||
else //parent
|
||||
{
|
||||
close(FD_RD_FR_PRNT);
|
||||
close(FD_WR_TO_PRNT);
|
||||
@@ -189,9 +180,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;
|
||||
}
|
||||
|
||||
@@ -199,6 +188,8 @@ void Webserv::_check_script_output(Client *client, std::string & output)
|
||||
{
|
||||
_check_script_status(client, output);
|
||||
_check_script_fields(client, 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);
|
||||
@@ -255,3 +246,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<std::string, std::string> field;
|
||||
std::map<std::string, std::string>::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 * 2));
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 1000000 // (1Mo)
|
||||
# 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)
|
||||
{
|
||||
|
||||
@@ -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<MultipartBody>::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
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
|
||||
#ifndef PARSING_MESSAGE_HTTP_HPP
|
||||
# define PARSING_MESSAGE_HTTP_HPP
|
||||
|
||||
# include <iostream>
|
||||
# include <string>
|
||||
# include <vector>
|
||||
# include <map>
|
||||
# include "utils.hpp"
|
||||
|
||||
std::map<std::string, std::string>
|
||||
parse_http_headers (
|
||||
std::string headers,
|
||||
std::map<std::string, std::string> 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
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
#include "parsing_request.hpp"
|
||||
|
||||
@@ -47,6 +47,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 << "\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);
|
||||
if (ret == -1)
|
||||
@@ -55,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;
|
||||
@@ -83,8 +90,16 @@ 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 << 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;
|
||||
}
|
||||
_process_method(client, path);
|
||||
@@ -157,12 +172,17 @@ void Webserv::_append_body(Client *client, const std::string &body, const std::s
|
||||
ServerConfig *_determine_process_server(Client *client, std::vector<ServerConfig> &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<ServerConfig>::iterator it = servers.begin();
|
||||
std::vector<ServerConfig>::iterator default_server = servers.end();
|
||||
|
||||
|
||||
@@ -3,11 +3,82 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
<style>
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: auto;
|
||||
}
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid red;
|
||||
margin: 20px auto;
|
||||
padding: 5px;
|
||||
}
|
||||
form > * {
|
||||
display: flex;
|
||||
margin: 5px auto 5px 5px;
|
||||
}
|
||||
mark {
|
||||
margin: 0px 3px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<form method="get">
|
||||
|
||||
<form method="get" action="/cgi-bin/cgi_cpp.out">
|
||||
|
||||
<p><mark>get</mark> form</p>
|
||||
<p>to <mark>/cgi-bin/cgi_cpp.out</mark></p>
|
||||
<label for="fname">First name:</label><br>
|
||||
<input type="text" id="fname" name="fname" value="John"><br>
|
||||
<label for="lname">Last name:</label><br>
|
||||
<input type="text" id="lname" name="lname" value="Doe"><br><br>
|
||||
|
||||
<input type="submit" value="submit">
|
||||
</form>
|
||||
<br>
|
||||
|
||||
<form method="post" action="/cgi-bin/cgi_cpp.out">
|
||||
|
||||
<p><mark>post</mark> form</p>
|
||||
<p>to <mark>/cgi-bin/cgi_cpp.out</mark></p>
|
||||
<label for="fname">First name:</label><br>
|
||||
<input type="text" id="fname" name="fname" value="John"><br>
|
||||
<label for="lname">Last name:</label><br>
|
||||
<input type="text" id="lname" name="lname" value="Doe"><br><br>
|
||||
|
||||
<input type="submit" value="submit">
|
||||
</form>
|
||||
<br>
|
||||
|
||||
<form method="get" action="/cgi-bin/cgi_cpp_content_length.out">
|
||||
|
||||
<p><mark>get</mark> form</p>
|
||||
<p>to <mark>/cgi-bin/cgi_cpp_content_length.out</mark></p>
|
||||
<label for="fname">First name:</label><br>
|
||||
<input type="text" id="fname" name="fname" value="John"><br>
|
||||
<label for="lname">Last name:</label><br>
|
||||
<input type="text" id="lname" name="lname" value="Doe"><br><br>
|
||||
|
||||
<input type="submit" value="submit">
|
||||
</form>
|
||||
<br>
|
||||
|
||||
<form method="post" action="/cgi-bin/cgi_cpp_content_length.out">
|
||||
|
||||
<p><mark>post</mark> form</p>
|
||||
<p>to <mark>/cgi-bin/cgi_cpp_content_length.out</mark></p>
|
||||
<label for="fname">First name:</label><br>
|
||||
<input type="text" id="fname" name="fname" value="John"><br>
|
||||
<label for="lname">Last name:</label><br>
|
||||
<input type="text" id="lname" name="lname" value="Doe"><br><br>
|
||||
|
||||
<input type="submit" value="submit">
|
||||
</form>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<form method="post">
|
||||
<input type="submit" value="submit">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
11
www2/index.html
Normal file
11
www2/index.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Le Webserv</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1 style="text-align:center">( ͡◉ ͜ ʖ ͡◉) Le index du serveur 2 ! </h1>
|
||||
<hr>
|
||||
<p style="text-align:center">˚ಎ˚</p>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user