Merge branch 'hugo3'
+ script output verification works (field duplicate and status)
+ parsing_message_http :
- the file is deleted
- of the three functions it contained, only one still exist
- 'parse_http_headers' is now in utils
+ changes in utils :
- http headers parsing doesn't change key case itself
- a new function change key case tolower case in map<str, str>
- added split_trim() that perform a split and a trim at once
- resolved pbm in trim
- added print_special to print special char '\r' and '\n'
- del_line became extract_line, because it returns the deleted line
- added get line, that does the same without deleting
- moved http_header in utils, and made it more consistent
+ in Client :
- parse_request is now named parse_request_headers to work with parse body
- private function _parse_request_headers is then now _parse_request_fields
(because it doesn't take care of request first line, but only fields)
- added a debug function 'print_client'
This commit is contained in:
@@ -104,9 +104,9 @@ class Webserv
|
||||
char* _dup_env(std::string var, std::string val);
|
||||
char* _dup_env(std::string var, int i);
|
||||
std::string _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);
|
||||
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);
|
||||
// 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);
|
||||
|
||||
@@ -89,6 +89,8 @@ 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);
|
||||
|
||||
pipe(fd_in);
|
||||
pipe(fd_out);
|
||||
@@ -127,17 +129,22 @@ 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;
|
||||
}
|
||||
|
||||
void Webserv::_check_script_output(Client *client, std::string output)
|
||||
void Webserv::_check_script_output(Client *client, std::string & output)
|
||||
{
|
||||
// TODO: it doesn't work with execve error, i don't know why yet ?
|
||||
_check_script_status(client, output);
|
||||
_check_script_fields(client, output);
|
||||
// _check_script_empty_lines(client, output);
|
||||
// _check_script_space_colons(client, output);
|
||||
// _check_script_new_lines(client, output);
|
||||
}
|
||||
|
||||
void Webserv::_check_script_status(Client *client, std::string output)
|
||||
void Webserv::_check_script_status(Client *client, std::string & output)
|
||||
{
|
||||
size_t pos;
|
||||
int status_pos;
|
||||
@@ -147,30 +154,42 @@ void Webserv::_check_script_status(Client *client, std::string output)
|
||||
{
|
||||
status_pos = pos + std::string("Status:").size();
|
||||
client->status = std::strtoul(output.c_str() + status_pos, NULL, 10);
|
||||
::del_line_in_str(&output, pos, CRLF);
|
||||
::extract_line(output, pos, CRLF);
|
||||
}
|
||||
client->status = 200;
|
||||
else
|
||||
client->status = 200;
|
||||
}
|
||||
|
||||
void Webserv::_check_script_fields(Client *client, std::string output)
|
||||
void Webserv::_check_script_fields(Client *client, std::string & output)
|
||||
{
|
||||
std::map<std::string, std::string> srv_fld; // server_field
|
||||
std::map<std::string, std::string> scr_fld; // script_field
|
||||
std::map<std::string, std::string>::iterator it_srv;
|
||||
std::map<std::string, std::string>::iterator it_scr;
|
||||
std::string tmp;
|
||||
size_t pos;
|
||||
|
||||
srv_fld = parse_http_headers(client->response);
|
||||
scr_fld = parse_http_headers(output);
|
||||
// wip: compare both map to supress duplicates
|
||||
// put server headers in map
|
||||
tmp = client->response;
|
||||
pos = tmp.find(CRLF CRLF);
|
||||
if (pos != std::string::npos)
|
||||
tmp.erase(pos);
|
||||
::parse_http_headers(tmp, srv_fld);
|
||||
// put script headers in map
|
||||
tmp = output;
|
||||
pos = tmp.find(CRLF CRLF);
|
||||
if (pos != std::string::npos)
|
||||
tmp.erase(pos);
|
||||
::parse_http_headers(tmp, scr_fld);
|
||||
// compare both map to supress duplicates
|
||||
for (it_srv = srv_fld.begin(); it_srv != srv_fld.end(); it_srv++)
|
||||
{
|
||||
for (it_scr = scr_fld.begin(); it_scr != scr_fld.end(); it_scr++)
|
||||
{
|
||||
if (it_srv->first == it_scr->first)
|
||||
if (str_tolower(it_srv->first) == str_tolower(it_scr->first))
|
||||
{
|
||||
pos = client->response.find(it_srv->first);
|
||||
::del_line_in_str(&client->response, pos, CRLF);
|
||||
::extract_line(client->response, pos, CRLF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,6 @@ void Webserv::_get(Client *client)
|
||||
if (_is_cgi(client))
|
||||
{
|
||||
script_output = _exec_cgi(client);
|
||||
// DEBUG
|
||||
std::cout << "\n____script_output____\n" << script_output << "\n_______________\n";
|
||||
// wip check output of script
|
||||
_check_script_output(client, script_output);
|
||||
client->response += script_output;
|
||||
return;
|
||||
@@ -48,8 +45,6 @@ void Webserv::_get(Client *client)
|
||||
}
|
||||
else
|
||||
_get_file(client, path);
|
||||
|
||||
|
||||
}
|
||||
|
||||
# define MAX_FILESIZE 1000000 // (1Mo)
|
||||
|
||||
@@ -1,64 +1,6 @@
|
||||
|
||||
#include "parsing_message_http.hpp"
|
||||
|
||||
size_t
|
||||
parse_http_first_line(std::string message, std::vector<std::string> &line)
|
||||
{
|
||||
std::vector<std::string> sline;
|
||||
std::string sub;
|
||||
std::string tmp;
|
||||
size_t pos;
|
||||
size_t ret;
|
||||
|
||||
// TODO: check for err in substr
|
||||
pos = message.find(CRLF);
|
||||
sub = message.substr(0, pos);
|
||||
sline = ::split(sub, ' ');
|
||||
ret = sline.size();
|
||||
if (ret != 3)
|
||||
return ret;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
tmp = ::trim(sline[i], ' ');
|
||||
tmp = ::trim(tmp, '\r');
|
||||
line.push_back(tmp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string>
|
||||
parse_http_headers(std::string message)
|
||||
{
|
||||
std::map<std::string, std::string> headers;
|
||||
std::vector<std::string> list;
|
||||
std::vector<std::string>::iterator it;
|
||||
std::string sub;
|
||||
std::string key;
|
||||
std::string val;
|
||||
size_t pos;
|
||||
|
||||
pos = (message).find(CRLF CRLF);
|
||||
sub = (message).substr(0, pos);
|
||||
list = ::split(sub, '\n');
|
||||
if ( maybe_http_first_line( *list.begin() ) )
|
||||
list.erase(list.begin());
|
||||
|
||||
for (it = list.begin(); it != list.end(); it++)
|
||||
{
|
||||
// TODO: if pattern is not "NAME: value" return error
|
||||
pos = (*it).find(':');
|
||||
key = (*it).substr( 0, pos );
|
||||
key = ::trim(key, ' ');
|
||||
key = ::trim(key, '\r');
|
||||
key = ::str_tolower(key);
|
||||
val = (*it).substr( pos + 1 );
|
||||
val = ::trim(val, ' ');
|
||||
val = ::trim(val, '\r');
|
||||
headers.insert( std::pair<std::string, std::string>(key, val) );
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
std::string
|
||||
parse_http_body(std::string message)
|
||||
{
|
||||
@@ -73,18 +15,3 @@ std::string
|
||||
return body;
|
||||
}
|
||||
|
||||
bool maybe_http_first_line(std::string str)
|
||||
{
|
||||
// method SP target SP version https://www.rfc-editor.org/rfc/rfc7230.html#section-3.1.1
|
||||
// version SP status SP reason https://www.rfc-editor.org/rfc/rfc7230.html#section-3.1.2
|
||||
|
||||
std::vector<std::string> sline;
|
||||
|
||||
sline = ::split(str, ' ');
|
||||
if (sline.size() != 3)
|
||||
return false;
|
||||
if (sline[0].find(':') != std::string::npos)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,18 +8,14 @@
|
||||
# include <map>
|
||||
# include "utils.hpp"
|
||||
|
||||
size_t
|
||||
parse_http_first_line(std::string message, std::vector<std::string> &line);
|
||||
|
||||
std::map<std::string, std::string>
|
||||
parse_http_headers(std::string message);
|
||||
parse_http_headers (
|
||||
std::string headers,
|
||||
std::map<std::string, std::string> fields )
|
||||
|
||||
std::string
|
||||
parse_http_body(std::string message);
|
||||
|
||||
bool
|
||||
maybe_http_first_line(std::string);
|
||||
|
||||
// http message structure :
|
||||
//
|
||||
// start-line
|
||||
|
||||
@@ -54,7 +54,7 @@ int Webserv::_read_request(Client *client)
|
||||
|
||||
if (!client->header_complete)
|
||||
{
|
||||
client->parse_request(_servers);
|
||||
client->parse_request_headers(_servers);
|
||||
if (client->status)
|
||||
return READ_COMPLETE;
|
||||
if (client->header_complete)
|
||||
|
||||
Reference in New Issue
Block a user