bugfix invalid ptr in "ev.data.ptr" after vector<Client> resize/erase

+ persistent connections reintroduced
+ bugfix crash if invalid path in request
This commit is contained in:
LuckyLaszlo
2022-07-31 13:19:11 +02:00
parent af8dc072c1
commit ea3f3a390a
5 changed files with 54 additions and 22 deletions

View File

@@ -6,19 +6,19 @@
# include <string>
# include <map>
struct Client
class Client
{
// public:
public:
// Client(Placeholder);
// Client();
// Client(Client const &src);
// ~Client();
// Client &operator=(Client const &rhs);
// Client &operator=(int);
int fd;
std::string raw_request;
std::map<std::string, std::string> request;
// std::map<std::string, std::string> response;
std::string response;
unsigned int status;
@@ -26,4 +26,8 @@ struct Client
};
#endif
bool operator==(const Client& lhs, const Client& rhs);
bool operator==(const Client& lhs, int fd);
bool operator==(int fd, const Client& rhs);
#endif

View File

@@ -22,5 +22,5 @@ void Webserv::_accept_connection(int fd)
_clients.push_back(Client());
_clients.back().fd = accepted_fd;
_epoll_update(accepted_fd, EPOLLIN, EPOLL_CTL_ADD, &_clients.back());
_epoll_update(accepted_fd, EPOLLIN, EPOLL_CTL_ADD);
}

View File

@@ -15,8 +15,8 @@ void Webserv::_read_request(Client *client)
char buf[BUFSIZE+1];
ssize_t ret;
std::cerr << "recv()\n";
ret = ::recv(client->fd, buf, BUFSIZE, 0);
std::cerr << "recv() on fd(" << client->fd << ") returned = " << ret << "\n" ;
if (ret == -1)
{
std::perror("err recv()");
@@ -25,6 +25,11 @@ void Webserv::_read_request(Client *client)
_close_client(client->fd);
return ;
}
if (ret == 0) // Not sure what to do in case of 0. Just close ?
{
_close_client(client->fd);
return ;
}
/*
if (ret == BUFSIZE)
// send error like "request too long" to client
@@ -33,5 +38,5 @@ void Webserv::_read_request(Client *client)
buf[ret] = '\0';
client->raw_request.append(buf);
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD, client);
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
}

View File

@@ -27,15 +27,14 @@ void Webserv::_send_response(Client *client)
return ;
}
_close_client(client->fd);
/* if (client->raw_request.find("Connection: keep-alive") == std::string::npos)
if (client->raw_request.find("Connection: close") != std::string::npos)
_close_client(client->fd);
else
{
_epoll_update(client->fd, EPOLLIN, EPOLL_CTL_MOD, client);
_epoll_update(client->fd, EPOLLIN, EPOLL_CTL_MOD);
client->raw_request.clear();
client->response.clear();
} */
}
}
void Webserv::_construct_response(Client *client)
@@ -43,13 +42,17 @@ void Webserv::_construct_response(Client *client)
client->status = 200;
client->response.append("Server: Webserv/0.1\r\n");
client->response.append("Connection: close\r\n");
if (client->raw_request.find("Connection: close") != std::string::npos)
client->response.append("Connection: close\r\n");
else
client->response.append("Connection: keep-alive\r\n");
_get_ressource(client);
_insert_status_line(client);
}
#define E400 "\r\n<!DOCTYPE html><html><head><title>400 Bad Request</title></head><body><h1 style=\"text-align:center\">400 Bad Request</h1><hr><p style=\"text-align:center\">Le Webserv/0.1</p></body></html>"
#define E404 "\r\n<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1 style=\"text-align:center\">404 Not Found</h1><hr><p style=\"text-align:center\">Le Webserv/0.1</p></body></html>"
#define E500 "\r\n<!DOCTYPE html><html><head><title>500 Internal Server Error</title></head><body><h1 style=\"text-align:center\">500 Internal Server Error</h1><hr><p style=\"text-align:center\">Le Webserv/0.1</p></body></html>"
void Webserv::_insert_status_line(Client *client)
@@ -63,6 +66,10 @@ void Webserv::_insert_status_line(Client *client)
case (200):
status_line.append("200 OK");
break;
case (400):
status_line.append("400 Not Found");
client->response.append(E400);
break;
case (404):
status_line.append("404 Not Found");
client->response.append(E404);
@@ -88,12 +95,21 @@ void Webserv::_get_ressource(Client *client)
// Mini parsing à l'arrache du PATH
std::string path;
path = client->raw_request.substr(0, client->raw_request.find("\r\n"));
path = path.substr(0, path.rfind(" "));
path = path.substr(path.find("/"));
if (path == "/")
path.append(INDEX);
path.insert(0, ROOT);
try
{
path = client->raw_request.substr(0, client->raw_request.find("\r\n"));
path = path.substr(0, path.rfind(" "));
path = path.substr(path.find("/"));
if (path == "/")
path.append(INDEX);
path.insert(0, ROOT);
}
catch (std::out_of_range& e)
{
std::cout << e.what() << '\n';
client->status = 400;
return ;
}
if (access(path.data(), R_OK) == -1)
{

View File

@@ -4,6 +4,14 @@
#define MAX_EVENTS 42 // arbitrary
#define TIMEOUT 3000
// Temp. To move in other file
bool operator==(const Client& lhs, const Client& rhs)
{ return lhs.fd == rhs.fd; }
bool operator==(const Client& lhs, int fd)
{ return lhs.fd == fd; }
bool operator==(int fd, const Client& rhs)
{ return fd == rhs.fd; }
void Webserv::run()
{
std::cerr << "Server started\n";
@@ -33,15 +41,14 @@ void Webserv::run()
i = 0;
while (i < nfds)
{
// if ((events[i].data.u32 == SERVER_FD) && (events[i].events & EPOLLIN)) // Dont work, see "SERVER_FD" define
// if ((events[i].data.fd == _socket_fd) && (events[i].events & EPOLLIN))
// TODO : handle EPOLLERR and EPOLLHUP
if ((std::find(_listen_sockets.begin(), _listen_sockets.end(), events[i].data.fd) != _listen_sockets.end())
&& (events[i].events & EPOLLIN))
_accept_connection(events[i].data.fd);
else if (events[i].events & EPOLLIN)
_request(static_cast<Client*>(events[i].data.ptr));
_request( &(*std::find(_clients.begin(), _clients.end(), events[i].data.fd)) );
else if (events[i].events & EPOLLOUT)
_response(static_cast<Client*>(events[i].data.ptr));
_response( &(*std::find(_clients.begin(), _clients.end(), events[i].data.fd)) );
++i;
if (!g_run)
break;