_request() and _response() refactoring
+ Wip redirection (weird behavior) + 505 HTTP Version Not Supported
This commit is contained in:
3
memo.txt
3
memo.txt
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -57,6 +57,11 @@ void Webserv::run()
|
||||
std::vector<Client>().swap(_clients);
|
||||
break;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user