Merge remote-tracking branch 'origin/master' into eric_config_parser

This commit is contained in:
Me
2022-08-09 02:38:09 +02:00
8 changed files with 118 additions and 60 deletions

View File

@@ -1,11 +1,10 @@
IN 42 SUBJECT, PRIORITY :
- chunked request (response not mandatory it seems)
- 505 HTTP Version Not Supported
- CGI
- index (default file directory)
- Ecrire des tests !
- handle redirection
- handle redirection (weird behavior, to fix)
- upload files with config "upload_repo"
-----------------------------
- autoindex (done, need test)

View File

@@ -12,15 +12,6 @@
# define LF "\n"
# define CRLF CR LF
// enum http_method
// {
// UNKNOWN = 0b00000000,
// GET = 0b00000001,
// POST = 0b00000010,
// DELETE = 0b00000100,
// ANY_METHODS = 0b11111111,
// };
enum http_method
{
UNKNOWN = 0b0,

View File

@@ -72,36 +72,29 @@ class Webserv
void _accept_connection(listen_socket &lsocket);
// request.cpp
void _request(Client *client);
void _read_request(Client *client);
int _read_request(Client *client);
// response.cpp
void _response(Client *client);
void _send_response(Client *client);
int _send_response(Client *client);
void _append_base_headers(Client *client);
void _construct_response(Client *client);
void _process_method(Client *client);
void _insert_status_line(Client *client);
void _error_html_response(Client *client);
void _append_body(Client *client, const std::string &body, const std::string &file_extension = "");
void _get(Client *client);
// void _get(Client *client, ServerConfig &server, LocationConfig &location);
// in progress
void _autoindex(Client *client, std::string &path);
void _get_file(Client *client, const std::string &path);
void _post(Client *client);
void _post_file(Client *client, const std::string &path);
void _delete(Client *client);
void _delete_file(Client *client, const std::string &path);
ServerConfig *_determine_process_server(Client *client); // cant be const cause of error_pages.operator[]
const LocationConfig *_determine_location(const ServerConfig &server, const std::string &path) const;
std::string _determine_file_extension(const std::string &path) const;
// method_get.cpp
void _get(Client *client);
void _get_file(Client *client, const std::string &path);
void _autoindex(Client *client, std::string &path);
// method_post.cpp
void _post(Client *client);
void _post_file(Client *client, const std::string &path);
// method_delete.cpp
void _delete(Client *client);
void _delete_file(Client *client, const std::string &path);
// cgi_script.cpp
bool _is_cgi(Client *client);
void _exec_cgi(Client *client);

View File

@@ -30,6 +30,13 @@
# define S201 "201 Created"
# define S204 "204 No Content"
# define S301 "301 Moved Permanently"
# define S302 "302 Found"
# define S303 "303 See Other"
# define S304 "304 Not Modified" // unused
# define S307 "307 Temporary Redirect"
# define S308 "308 Permanent Redirect"
# define S400 "400 Bad Request"
# define S403 "403 Forbidden"
# define S404 "404 Not Found"
@@ -38,5 +45,6 @@
# define S500 "500 Internal Server Error"
# define S501 "501 Not Implemented"
# define S505 "505 HTTP Version Not Supported"
#endif

View File

@@ -99,6 +99,13 @@ void Webserv::_init_http_status_map()
_http_status.insert(status_pair(201, S201));
_http_status.insert(status_pair(204, S204));
_http_status.insert(status_pair(301, S301));
_http_status.insert(status_pair(302, S302));
_http_status.insert(status_pair(303, S303));
_http_status.insert(status_pair(304, S304));
_http_status.insert(status_pair(307, S307));
_http_status.insert(status_pair(308, S308));
_http_status.insert(status_pair(400, S400));
_http_status.insert(status_pair(403, S403));
_http_status.insert(status_pair(404, S404));

View File

@@ -4,14 +4,31 @@
#define BUFSIZE 8192
#define MAX_HEADER_SIZE 42000 // arbitrary
enum read_return
{
READ_IN_PROGRESS,
READ_COMPLETE,
READ_CLOSE,
};
void Webserv::_request(Client *client)
{
_read_request(client);
int ret = _read_request(client);
if (g_last_signal)
_handle_last_signal();
_handle_last_signal();
if (ret == READ_CLOSE)
{
_close_client(client->fd);
}
else if (ret == READ_COMPLETE)
{
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
}
}
void Webserv::_read_request(Client *client) // Messy, Need refactoring
int Webserv::_read_request(Client *client) // Messy, Need refactoring
{
char buf[BUFSIZE];
ssize_t ret;
@@ -24,13 +41,12 @@ void Webserv::_read_request(Client *client) // Messy, Need refactoring
std::perror("err recv()");
std::cerr << "client ptr =" << client << "\n"; // DEBUG
std::cerr << "client.fd =" << client->fd << "\n"; // DEBUG
_close_client(client->fd);
return ;
return READ_CLOSE;
}
if (ret == 0)
{
_close_client(client->fd);
return ;
std::cerr << "recv() read 0, then close client" << "\n"; // DEBUG
return READ_CLOSE;
}
client->raw_request.append(buf, ret);
@@ -38,23 +54,29 @@ void Webserv::_read_request(Client *client) // Messy, Need refactoring
{
if (client->raw_request.find(CRLF CRLF) != std::string::npos)
{
// std::cerr << "Raw_request :\n|||||||||||||||||||||||||||||\n " << client->raw_request << "\n|||||||||||||||||||||||||||||\n"; // DEBUG
client->header_complete = true;
client->parse_request(); // TODO : split function to avoid useless parsing ?
if (client->status) // WIP, need to change client->parse_request() for status update
return READ_COMPLETE;
client->assigned_server = _determine_process_server(client);
client->assigned_location = _determine_location(*client->assigned_server, client->get_path());
if (client->get_version().compare(0, sizeof("HTTP/1") - 1, "HTTP/1") != 0)
{ // TODO : move in Client parsing ?
client->status = 505;
return READ_COMPLETE;
}
if (!client->get_headers("Content-Length").empty()
&& ::atoi(client->get_headers("Content-Length").c_str()) > (int)client->assigned_server->client_body_limit)
{
client->status = 413;
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
return;
return READ_COMPLETE;
}
}
else if (client->raw_request.size() > MAX_HEADER_SIZE)
{
client->status = 400;
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
return;
return READ_COMPLETE;
}
}
else if (client->header_complete)
@@ -63,22 +85,21 @@ void Webserv::_read_request(Client *client) // Messy, Need refactoring
if (client->read_body_size > client->assigned_server->client_body_limit)
{
client->status = 413;
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
return;
return READ_COMPLETE;
}
if ((int)client->read_body_size > ::atoi(client->get_headers("Content-Length").c_str()))
if ((int)client->read_body_size >= ::atoi(client->get_headers("Content-Length").c_str()))
{
client->parse_request(); // reparse for the body
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
return;
return READ_COMPLETE;
}
}
if (client->header_complete && client->get_headers("Content-Type").empty() && client->get_headers("Content-Length").empty() )
{
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
return;
return READ_COMPLETE;
}
return READ_IN_PROGRESS;
}

View File

@@ -1,14 +1,37 @@
#include "Webserv.hpp"
enum send_return
{
SEND_IN_PROGRESS, // unused
SEND_COMPLETE,
SEND_CLOSE,
};
void Webserv::_response(Client *client)
{
_send_response(client);
int ret = _send_response(client);
if (g_last_signal)
_handle_last_signal();
if (ret == SEND_CLOSE)
{
_close_client(client->fd);
}
else if (ret == SEND_COMPLETE)
{
if (client->get_headers("Connection") == "close")
_close_client(client->fd);
else
{
_epoll_update(client->fd, EPOLLIN, EPOLL_CTL_MOD);
client->clear();
}
}
}
void Webserv::_send_response(Client *client)
int Webserv::_send_response(Client *client)
{
ssize_t ret;
@@ -27,18 +50,11 @@ void Webserv::_send_response(Client *client)
{
std::perror("err send()");
std::cerr << "client.fd =" << client->fd << "\n"; // DEBUG
_close_client(client->fd);
return ;
return SEND_CLOSE;
}
std::cerr << "ret send() = " << ret << "\n"; // DEBUG
if (client->get_headers("Connection") == "close")
_close_client(client->fd);
else
{
_epoll_update(client->fd, EPOLLIN, EPOLL_CTL_MOD);
client->clear();
}
return SEND_COMPLETE;
}
void Webserv::_append_base_headers(Client *client)
@@ -59,6 +75,24 @@ void Webserv::_construct_response(Client *client)
client->status = 413;
return;
}
/* if (client->assigned_location->redirect_status)
{
// (for codes 301, 302, 303, 307, and 308)
client->status = client->assigned_location->redirect_status;
client->response.append("Location: ");
client->response.append(client->assigned_location->redirect_uri);
client->response.append(CRLF);
} */
if (client->get_path().find("redirect_test") != std::string::npos) // Test block
{ // Weird behavior. The web browser seems to wait for a complete response until timeout.
// (for codes 301, 302, 303, 307, and 308)
client->status = 307;
client->response.append("Location: ");
client->response.append("https://www.rfc-editor.org/rfc/rfc3875#section-3.3");
client->response.append(CRLF);
client->response.append(CRLF);
return ;
}
_process_method(client);
}
@@ -105,7 +139,7 @@ void Webserv::_insert_status_line(Client *client)
void Webserv::_error_html_response(Client *client)
{
if (client->assigned_server->error_pages[client->status].empty())
if (!client->assigned_server || client->assigned_server->error_pages[client->status].empty())
{
std::string html_page = HTML_ERROR;
::replace_all_substr(html_page, STATUS_PLACEHOLDER, _http_status[client->status]);

View File

@@ -57,6 +57,11 @@ void Webserv::run()
std::vector<Client>().swap(_clients);
break;
}
catch (const std::exception& e)
{
std::cerr << e.what() << '\n';
++i;
}
}
}
}