Merge remote-tracking branch 'origin/master' into eric_config_parser
This commit is contained in:
3
memo.txt
3
memo.txt
@@ -1,11 +1,10 @@
|
|||||||
IN 42 SUBJECT, PRIORITY :
|
IN 42 SUBJECT, PRIORITY :
|
||||||
- chunked request (response not mandatory it seems)
|
- chunked request (response not mandatory it seems)
|
||||||
- 505 HTTP Version Not Supported
|
|
||||||
- CGI
|
- CGI
|
||||||
- index (default file directory)
|
- index (default file directory)
|
||||||
- Ecrire des tests !
|
- Ecrire des tests !
|
||||||
|
|
||||||
- handle redirection
|
- handle redirection (weird behavior, to fix)
|
||||||
- upload files with config "upload_repo"
|
- upload files with config "upload_repo"
|
||||||
-----------------------------
|
-----------------------------
|
||||||
- autoindex (done, need test)
|
- autoindex (done, need test)
|
||||||
|
|||||||
@@ -12,15 +12,6 @@
|
|||||||
# define LF "\n"
|
# define LF "\n"
|
||||||
# define CRLF CR LF
|
# define CRLF CR LF
|
||||||
|
|
||||||
// enum http_method
|
|
||||||
// {
|
|
||||||
// UNKNOWN = 0b00000000,
|
|
||||||
// GET = 0b00000001,
|
|
||||||
// POST = 0b00000010,
|
|
||||||
// DELETE = 0b00000100,
|
|
||||||
// ANY_METHODS = 0b11111111,
|
|
||||||
// };
|
|
||||||
|
|
||||||
enum http_method
|
enum http_method
|
||||||
{
|
{
|
||||||
UNKNOWN = 0b0,
|
UNKNOWN = 0b0,
|
||||||
|
|||||||
@@ -72,36 +72,29 @@ class Webserv
|
|||||||
void _accept_connection(listen_socket &lsocket);
|
void _accept_connection(listen_socket &lsocket);
|
||||||
// request.cpp
|
// request.cpp
|
||||||
void _request(Client *client);
|
void _request(Client *client);
|
||||||
void _read_request(Client *client);
|
int _read_request(Client *client);
|
||||||
// response.cpp
|
// response.cpp
|
||||||
void _response(Client *client);
|
void _response(Client *client);
|
||||||
void _send_response(Client *client);
|
int _send_response(Client *client);
|
||||||
|
|
||||||
void _append_base_headers(Client *client);
|
void _append_base_headers(Client *client);
|
||||||
void _construct_response(Client *client);
|
void _construct_response(Client *client);
|
||||||
void _process_method(Client *client);
|
void _process_method(Client *client);
|
||||||
void _insert_status_line(Client *client);
|
void _insert_status_line(Client *client);
|
||||||
void _error_html_response(Client *client);
|
void _error_html_response(Client *client);
|
||||||
void _append_body(Client *client, const std::string &body, const std::string &file_extension = "");
|
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[]
|
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;
|
const LocationConfig *_determine_location(const ServerConfig &server, const std::string &path) const;
|
||||||
std::string _determine_file_extension(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
|
// cgi_script.cpp
|
||||||
bool _is_cgi(Client *client);
|
bool _is_cgi(Client *client);
|
||||||
void _exec_cgi(Client *client);
|
void _exec_cgi(Client *client);
|
||||||
|
|||||||
@@ -30,6 +30,13 @@
|
|||||||
# define S201 "201 Created"
|
# define S201 "201 Created"
|
||||||
# define S204 "204 No Content"
|
# 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 S400 "400 Bad Request"
|
||||||
# define S403 "403 Forbidden"
|
# define S403 "403 Forbidden"
|
||||||
# define S404 "404 Not Found"
|
# define S404 "404 Not Found"
|
||||||
@@ -38,5 +45,6 @@
|
|||||||
|
|
||||||
# define S500 "500 Internal Server Error"
|
# define S500 "500 Internal Server Error"
|
||||||
# define S501 "501 Not Implemented"
|
# define S501 "501 Not Implemented"
|
||||||
|
# define S505 "505 HTTP Version Not Supported"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -99,6 +99,13 @@ void Webserv::_init_http_status_map()
|
|||||||
_http_status.insert(status_pair(201, S201));
|
_http_status.insert(status_pair(201, S201));
|
||||||
_http_status.insert(status_pair(204, S204));
|
_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(400, S400));
|
||||||
_http_status.insert(status_pair(403, S403));
|
_http_status.insert(status_pair(403, S403));
|
||||||
_http_status.insert(status_pair(404, S404));
|
_http_status.insert(status_pair(404, S404));
|
||||||
|
|||||||
@@ -4,14 +4,31 @@
|
|||||||
#define BUFSIZE 8192
|
#define BUFSIZE 8192
|
||||||
#define MAX_HEADER_SIZE 42000 // arbitrary
|
#define MAX_HEADER_SIZE 42000 // arbitrary
|
||||||
|
|
||||||
|
enum read_return
|
||||||
|
{
|
||||||
|
READ_IN_PROGRESS,
|
||||||
|
READ_COMPLETE,
|
||||||
|
READ_CLOSE,
|
||||||
|
};
|
||||||
|
|
||||||
void Webserv::_request(Client *client)
|
void Webserv::_request(Client *client)
|
||||||
{
|
{
|
||||||
_read_request(client);
|
int ret = _read_request(client);
|
||||||
|
|
||||||
if (g_last_signal)
|
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];
|
char buf[BUFSIZE];
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
@@ -24,13 +41,12 @@ void Webserv::_read_request(Client *client) // Messy, Need refactoring
|
|||||||
std::perror("err recv()");
|
std::perror("err recv()");
|
||||||
std::cerr << "client ptr =" << client << "\n"; // DEBUG
|
std::cerr << "client ptr =" << client << "\n"; // DEBUG
|
||||||
std::cerr << "client.fd =" << client->fd << "\n"; // DEBUG
|
std::cerr << "client.fd =" << client->fd << "\n"; // DEBUG
|
||||||
_close_client(client->fd);
|
return READ_CLOSE;
|
||||||
return ;
|
|
||||||
}
|
}
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
_close_client(client->fd);
|
std::cerr << "recv() read 0, then close client" << "\n"; // DEBUG
|
||||||
return ;
|
return READ_CLOSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
client->raw_request.append(buf, ret);
|
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)
|
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->header_complete = true;
|
||||||
client->parse_request(); // TODO : split function to avoid useless parsing ?
|
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_server = _determine_process_server(client);
|
||||||
client->assigned_location = _determine_location(*client->assigned_server, client->get_path());
|
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()
|
if (!client->get_headers("Content-Length").empty()
|
||||||
&& ::atoi(client->get_headers("Content-Length").c_str()) > (int)client->assigned_server->client_body_limit)
|
&& ::atoi(client->get_headers("Content-Length").c_str()) > (int)client->assigned_server->client_body_limit)
|
||||||
{
|
{
|
||||||
client->status = 413;
|
client->status = 413;
|
||||||
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
|
return READ_COMPLETE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (client->raw_request.size() > MAX_HEADER_SIZE)
|
else if (client->raw_request.size() > MAX_HEADER_SIZE)
|
||||||
{
|
{
|
||||||
client->status = 400;
|
client->status = 400;
|
||||||
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
|
return READ_COMPLETE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (client->header_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)
|
if (client->read_body_size > client->assigned_server->client_body_limit)
|
||||||
{
|
{
|
||||||
client->status = 413;
|
client->status = 413;
|
||||||
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
|
return READ_COMPLETE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
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
|
client->parse_request(); // reparse for the body
|
||||||
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
|
return READ_COMPLETE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (client->header_complete && client->get_headers("Content-Type").empty() && client->get_headers("Content-Length").empty() )
|
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 READ_COMPLETE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return READ_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,37 @@
|
|||||||
|
|
||||||
#include "Webserv.hpp"
|
#include "Webserv.hpp"
|
||||||
|
|
||||||
|
enum send_return
|
||||||
|
{
|
||||||
|
SEND_IN_PROGRESS, // unused
|
||||||
|
SEND_COMPLETE,
|
||||||
|
SEND_CLOSE,
|
||||||
|
};
|
||||||
|
|
||||||
void Webserv::_response(Client *client)
|
void Webserv::_response(Client *client)
|
||||||
{
|
{
|
||||||
_send_response(client);
|
int ret = _send_response(client);
|
||||||
|
|
||||||
if (g_last_signal)
|
if (g_last_signal)
|
||||||
_handle_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;
|
ssize_t ret;
|
||||||
|
|
||||||
@@ -27,18 +50,11 @@ void Webserv::_send_response(Client *client)
|
|||||||
{
|
{
|
||||||
std::perror("err send()");
|
std::perror("err send()");
|
||||||
std::cerr << "client.fd =" << client->fd << "\n"; // DEBUG
|
std::cerr << "client.fd =" << client->fd << "\n"; // DEBUG
|
||||||
_close_client(client->fd);
|
return SEND_CLOSE;
|
||||||
return ;
|
|
||||||
}
|
}
|
||||||
std::cerr << "ret send() = " << ret << "\n"; // DEBUG
|
std::cerr << "ret send() = " << ret << "\n"; // DEBUG
|
||||||
|
|
||||||
if (client->get_headers("Connection") == "close")
|
return SEND_COMPLETE;
|
||||||
_close_client(client->fd);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_epoll_update(client->fd, EPOLLIN, EPOLL_CTL_MOD);
|
|
||||||
client->clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Webserv::_append_base_headers(Client *client)
|
void Webserv::_append_base_headers(Client *client)
|
||||||
@@ -59,6 +75,24 @@ void Webserv::_construct_response(Client *client)
|
|||||||
client->status = 413;
|
client->status = 413;
|
||||||
return;
|
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);
|
_process_method(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +139,7 @@ void Webserv::_insert_status_line(Client *client)
|
|||||||
|
|
||||||
void Webserv::_error_html_response(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;
|
std::string html_page = HTML_ERROR;
|
||||||
::replace_all_substr(html_page, STATUS_PLACEHOLDER, _http_status[client->status]);
|
::replace_all_substr(html_page, STATUS_PLACEHOLDER, _http_status[client->status]);
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ void Webserv::run()
|
|||||||
std::vector<Client>().swap(_clients);
|
std::vector<Client>().swap(_clients);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << e.what() << '\n';
|
||||||
|
++i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user