assign server and location to client in _read_request()

This commit is contained in:
LuckyLaszlo
2022-08-07 17:37:24 +02:00
parent 4ab099ee4d
commit 1ccf61bc68
5 changed files with 52 additions and 50 deletions

View File

@@ -7,9 +7,12 @@
Client::Client() Client::Client()
: fd(0), : fd(0),
lsocket(NULL),
status(0), status(0),
header_complete(false), header_complete(false),
read_body_size(0) read_body_size(0),
assigned_server(NULL),
assigned_location(NULL)
{ {
return; return;
} }
@@ -59,6 +62,8 @@ void Client::clear()
clear_request(); clear_request();
header_complete = false; header_complete = false;
read_body_size = 0; read_body_size = 0;
assigned_server = NULL;
assigned_location = NULL;
raw_request.clear(); raw_request.clear();
response.clear(); response.clear();
status = 0; status = 0;

View File

@@ -7,6 +7,7 @@
# include <map> # include <map>
# include <vector> # include <vector>
# include "utils.hpp" # include "utils.hpp"
# include "ServerConfig.hpp"
struct Request struct Request
{ {
@@ -26,13 +27,16 @@ class Client
//Client &operator=(Client const &rhs); //Client &operator=(Client const &rhs);
int fd; int fd;
const listen_socket *lsocket;
std::string raw_request; std::string raw_request;
std::string response; std::string response;
unsigned int status; unsigned int status;
listen_socket *lsocket;
bool header_complete; bool header_complete;
size_t read_body_size; size_t read_body_size;
ServerConfig *assigned_server; // cant be const cause of error_pages.operator[]
const LocationConfig *assigned_location;
// const functions ? // const functions ?
http_method get_method(); http_method get_method();

View File

@@ -73,26 +73,26 @@ class Webserv
void _read_request(Client *client); void _read_request(Client *client);
// response.cpp // response.cpp
void _response(Client *client); void _response(Client *client);
void _send_response(Client *client, ServerConfig &server); void _send_response(Client *client);
void _append_base_headers(Client *client); void _append_base_headers(Client *client);
void _construct_response(Client *client, ServerConfig &server); void _construct_response(Client *client);
void _process_method(Client *client, ServerConfig &server, LocationConfig &location); void _process_method(Client *client);
void _insert_status_line(Client *client); void _insert_status_line(Client *client);
void _error_html_response(Client *client, ServerConfig &server); 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, ServerConfig &server, LocationConfig &location); void _get(Client *client);
void _get_file(Client *client, const std::string &path); void _get_file(Client *client, const std::string &path);
void _post(Client *client, ServerConfig &server, LocationConfig &location); void _post(Client *client);
void _post_file(Client *client, const std::string &path); void _post_file(Client *client, const std::string &path);
void _delete(Client *client, ServerConfig &server, LocationConfig &location); void _delete(Client *client);
void _delete_file(Client *client, const std::string &path); void _delete_file(Client *client, const std::string &path);
ServerConfig &_determine_process_server(Client *client); ServerConfig *_determine_process_server(Client *client); // cant be const cause of error_pages.operator[]
LocationConfig &_determine_location(ServerConfig &server, const std::string &path); 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;
// cgi_script.cpp // cgi_script.cpp
bool _is_cgi(Client *client); bool _is_cgi(Client *client);

View File

@@ -2,8 +2,7 @@
#include "Webserv.hpp" #include "Webserv.hpp"
#define BUFSIZE 8192 #define BUFSIZE 8192
#define MAX_HEADER_SIZE 42000 #define MAX_HEADER_SIZE 42000 // arbitrary
#define MAX_BODY_SIZE 500000 // test macro, replace with server config
void Webserv::_request(Client *client) void Webserv::_request(Client *client)
{ {
@@ -41,9 +40,10 @@ void Webserv::_read_request(Client *client)
{ {
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 ?
// TODO : determine server here for body size limit client->assigned_server = _determine_process_server(client);
client->assigned_location = _determine_location(*client->assigned_server, client->get_path());
if (!client->get_headers("Content-Length").empty() if (!client->get_headers("Content-Length").empty()
&& ::atoi(client->get_headers("Content-Length").c_str()) > MAX_BODY_SIZE) && ::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); _epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
@@ -60,7 +60,7 @@ void Webserv::_read_request(Client *client)
else if (client->header_complete) else if (client->header_complete)
{ {
client->read_body_size += ret; client->read_body_size += ret;
if (client->read_body_size > MAX_BODY_SIZE) 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); _epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);

View File

@@ -3,25 +3,22 @@
void Webserv::_response(Client *client) void Webserv::_response(Client *client)
{ {
client->status = 200; // default value _send_response(client);
ServerConfig &server = _determine_process_server(client);
_send_response(client, server);
if (g_last_signal) if (g_last_signal)
_handle_last_signal(); _handle_last_signal();
} }
void Webserv::_send_response(Client *client, ServerConfig &server) void Webserv::_send_response(Client *client)
{ {
ssize_t ret; ssize_t ret;
std::cerr << "send()\n"; std::cerr << "send()\n";
_append_base_headers(client); _append_base_headers(client);
_construct_response(client, server); _construct_response(client);
_insert_status_line(client); _insert_status_line(client);
if (client->status >= 400) if (client->status >= 400)
_error_html_response(client, server); _error_html_response(client);
std::cerr << "client->response.size() = " << client->response.size() << "\n"; // DEBUG std::cerr << "client->response.size() = " << client->response.size() << "\n"; // DEBUG
ret = ::send(client->fd, client->response.c_str(), client->response.size(), 0); ret = ::send(client->fd, client->response.c_str(), client->response.size(), 0);
@@ -53,19 +50,18 @@ void Webserv::_append_base_headers(Client *client)
client->response.append("Connection: keep-alive" CRLF); client->response.append("Connection: keep-alive" CRLF);
} }
void Webserv::_construct_response(Client *client, ServerConfig &server) void Webserv::_construct_response(Client *client)
{ {
// TODO : Move this in read(), stop read if content too large // TODO : Move this in read(), stop read if content too large
if (client->get_body().size() > server.client_body_limit) if (client->get_body().size() > client->assigned_server->client_body_limit)
{ {
client->status = 413; client->status = 413;
return; return;
} }
LocationConfig &location = _determine_location(server, client->get_path()); _process_method(client);
_process_method(client, server, location);
} }
void Webserv::_process_method(Client *client, ServerConfig &server, LocationConfig &location) void Webserv::_process_method(Client *client)
{ {
unsigned int allow_methods = ANY_METHODS; // TEMP VARIABLE unsigned int allow_methods = ANY_METHODS; // TEMP VARIABLE
// after update in ConfigParser, use the "allow_methods" of location. // after update in ConfigParser, use the "allow_methods" of location.
@@ -80,11 +76,11 @@ void Webserv::_process_method(Client *client, ServerConfig &server, LocationConf
switch (client->get_method()) switch (client->get_method())
{ {
case (GET): case (GET):
_get(client, server, location); break; _get(client); break;
case (POST): case (POST):
_post(client, server, location); break; _post(client); break;
case (DELETE): case (DELETE):
_delete(client, server, location); break; _delete(client); break;
default: default:
break; break;
} }
@@ -108,27 +104,26 @@ void Webserv::_insert_status_line(Client *client)
client->response.insert(0, status_line); client->response.insert(0, status_line);
} }
void Webserv::_error_html_response(Client *client, ServerConfig &server) void Webserv::_error_html_response(Client *client)
{ {
if (server.error_pages[client->status].empty()) if (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]);
_append_body(client, html_page, "html"); _append_body(client, html_page, "html");
} }
else else
_get_file(client, server.error_pages[client->status]); _get_file(client, client->assigned_server->error_pages[client->status]);
} }
#define INDEX "index.html" // temp wip #define INDEX "index.html" // temp wip
void Webserv::_get(Client *client, ServerConfig &server, LocationConfig &location) void Webserv::_get(Client *client)
{ {
(void)server; // To remove from arg if we determine its useless
std::string path = client->get_path(); std::string path = client->get_path();
if (path == "/") // TODO : index and autoindex if (path == "/") // TODO : index and autoindex
path.append(INDEX); path.append(INDEX);
path.insert(0, location.root); path.insert(0, client->assigned_location->root);
std::cerr << "path = " << path << "\n"; std::cerr << "path = " << path << "\n";
@@ -232,15 +227,14 @@ void Webserv::_append_body(Client *client, const std::string &body, const std::s
client->response.append(body); client->response.append(body);
} }
void Webserv::_post(Client *client, ServerConfig &server, LocationConfig &location) void Webserv::_post(Client *client)
{ {
(void)server; // To remove from arg if we determine its useless
/* /*
WIP WIP
https://www.rfc-editor.org/rfc/rfc9110.html#name-post https://www.rfc-editor.org/rfc/rfc9110.html#name-post
*/ */
std::string path = client->get_path(); std::string path = client->get_path();
path.insert(0, location.root); path.insert(0, client->assigned_location->root);
/* CGI Here ? */ /* CGI Here ? */
@@ -298,15 +292,14 @@ void Webserv::_post_file(Client *client, const std::string &path)
} }
} }
void Webserv::_delete(Client *client, ServerConfig &server, LocationConfig &location) void Webserv::_delete(Client *client)
{ {
(void)server; // To remove from arg if we determine its useless
/* /*
WIP WIP
https://www.rfc-editor.org/rfc/rfc9110.html#name-delete https://www.rfc-editor.org/rfc/rfc9110.html#name-delete
*/ */
std::string path = client->get_path(); std::string path = client->get_path();
path.insert(0, location.root); path.insert(0, client->assigned_location->root);
/* CGI Here ? */ /* CGI Here ? */
@@ -337,7 +330,7 @@ void Webserv::_delete_file(Client *client, const std::string &path)
} }
} }
ServerConfig &Webserv::_determine_process_server(Client *client) ServerConfig *Webserv::_determine_process_server(Client *client)
{ {
/* /*
http://nginx.org/en/docs/http/request_processing.html http://nginx.org/en/docs/http/request_processing.html
@@ -362,12 +355,12 @@ ServerConfig &Webserv::_determine_process_server(Client *client)
++it; ++it;
} }
if (it != _servers.end()) if (it != _servers.end())
return (*it); return (&(*it));
else else
return (*default_server); return (&(*default_server));
} }
LocationConfig &Webserv::_determine_location(ServerConfig &server, const std::string &path) const LocationConfig *Webserv::_determine_location(const ServerConfig &server, const std::string &path) const
{ {
/* /*
Assume there is at least one location in vector<LocationConfig> for path "/" Assume there is at least one location in vector<LocationConfig> for path "/"
@@ -376,7 +369,7 @@ LocationConfig &Webserv::_determine_location(ServerConfig &server, const std::st
for path "/", and filled with fields "root" and "index" based on parent server block for path "/", and filled with fields "root" and "index" based on parent server block
*/ */
std::vector<LocationConfig>::iterator it = server.locations.begin(); std::vector<LocationConfig>::const_iterator it = server.locations.begin();
while (it != server.locations.end()) while (it != server.locations.end())
{ {
if (it->path.compare(0, path.size(), path)) if (it->path.compare(0, path.size(), path))
@@ -384,9 +377,9 @@ LocationConfig &Webserv::_determine_location(ServerConfig &server, const std::st
++it; ++it;
} }
if (it != server.locations.end()) if (it != server.locations.end())
return (*it); return (&(*it));
else else
return (server.locations.front()); return (&(server.locations.front()));
} }
std::string Webserv::_determine_file_extension(const std::string &path) const std::string Webserv::_determine_file_extension(const std::string &path) const