refactor(server): refactor event loop
This commit is contained in:
parent
b64a41d84f
commit
970ab847fc
@ -1,5 +1,4 @@
|
|||||||
#include <webserv/client/Client.hpp>
|
#include <webserv/client/Client.hpp>
|
||||||
|
|
||||||
#include <webserv/http/HttpHeaders.hpp> // for HttpHeaders
|
#include <webserv/http/HttpHeaders.hpp> // for HttpHeaders
|
||||||
#include <webserv/log/Log.hpp> // for Log, LOCATION
|
#include <webserv/log/Log.hpp> // for Log, LOCATION
|
||||||
#include <webserv/router/Router.hpp> // for Router
|
#include <webserv/router/Router.hpp> // for Router
|
||||||
@ -26,7 +25,7 @@ Client::~Client()
|
|||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
Log::info("Client disconnected, fd: " + std::to_string(client_socket_->getFd()));
|
Log::info("Client disconnected, fd: " + std::to_string(client_socket_->getFd()));
|
||||||
server_.removeFromEpoll(*client_socket_);
|
server_.remove(*client_socket_);
|
||||||
};
|
};
|
||||||
|
|
||||||
int Client::getStatusCode() const
|
int Client::getStatusCode() const
|
||||||
@ -55,7 +54,7 @@ void Client::request()
|
|||||||
if (bytesRead == 0)
|
if (bytesRead == 0)
|
||||||
{
|
{
|
||||||
Log::info("Client closed connection, fd: " + std::to_string(client_socket_->getFd())); // TODO weird
|
Log::info("Client closed connection, fd: " + std::to_string(client_socket_->getFd())); // TODO weird
|
||||||
server_.removeClient(*this); // CRITICAL: RETURN IMMEDIATELY
|
server_.disconnect(*this); // CRITICAL: RETURN IMMEDIATELY
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
#include <webserv/server/Server.hpp>
|
|
||||||
|
|
||||||
#include <webserv/client/Client.hpp> // for Client
|
#include <webserv/client/Client.hpp> // for Client
|
||||||
#include <webserv/config/ConfigManager.hpp> // for ConfigManager
|
#include <webserv/config/ConfigManager.hpp> // for ConfigManager
|
||||||
#include <webserv/config/ServerConfig.hpp> // for ServerConfig
|
#include <webserv/config/ServerConfig.hpp> // for ServerConfig
|
||||||
#include <webserv/log/Log.hpp> // for Log, LOCATION
|
#include <webserv/log/Log.hpp> // for Log, LOCATION
|
||||||
|
#include <webserv/server/Server.hpp>
|
||||||
#include <webserv/socket/Socket.hpp> // for Socket
|
#include <webserv/socket/Socket.hpp> // for Socket
|
||||||
|
|
||||||
#include <cerrno> // for errno
|
#include <cerrno> // for errno
|
||||||
@ -69,7 +68,7 @@ void Server::start()
|
|||||||
eventLoop();
|
eventLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::addToEpoll(const Socket &socket, uint32_t events) const
|
void Server::add(const Socket &socket, uint32_t events) const
|
||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
int fd = socket.getFd();
|
int fd = socket.getFd();
|
||||||
@ -83,14 +82,14 @@ void Server::addToEpoll(const Socket &socket, uint32_t events) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::removeClient(const Client &client)
|
void Server::disconnect(const Client &client)
|
||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
int client_fd = client.getSocket().getFd();
|
int client_fd = client.getSocket().getFd();
|
||||||
clients_.erase(client_fd);
|
clients_.erase(client_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::removeFromEpoll(const Socket &socket) const
|
void Server::remove(const Socket &socket) const
|
||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
int filedes = socket.getFd();
|
int filedes = socket.getFd();
|
||||||
@ -114,7 +113,7 @@ void Server::setupServerSocket(const ServerConfig &config)
|
|||||||
serverSocket->listen(SOMAXCONN);
|
serverSocket->listen(SOMAXCONN);
|
||||||
int server_fd = serverSocket->getFd();
|
int server_fd = serverSocket->getFd();
|
||||||
|
|
||||||
addToEpoll(*serverSocket, EPOLLIN);
|
add(*serverSocket, EPOLLIN);
|
||||||
|
|
||||||
listeners_.push_back(std::move(serverSocket));
|
listeners_.push_back(std::move(serverSocket));
|
||||||
listener_fds_.insert(server_fd);
|
listener_fds_.insert(server_fd);
|
||||||
@ -132,7 +131,7 @@ void Server::handleConnection(struct epoll_event *event)
|
|||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
Socket &listener = getListener(event->data.fd);
|
Socket &listener = getListener(event->data.fd);
|
||||||
std::unique_ptr<Socket> clientSocket = listener.accept();
|
std::unique_ptr<Socket> clientSocket = listener.accept();
|
||||||
addToEpoll(*clientSocket, EPOLLIN);
|
add(*clientSocket, EPOLLIN);
|
||||||
clients_.insert({clientSocket->getFd(), std::make_unique<Client>(std::move(clientSocket), *this)});
|
clients_.insert({clientSocket->getFd(), std::make_unique<Client>(std::move(clientSocket), *this)});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,6 +184,46 @@ void Server::responseReady(int client_fd) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::handleResponse(struct epoll_event *event)
|
||||||
|
{
|
||||||
|
Log::debug("Attempting to send data to fd: " + std::to_string(event->data.fd));
|
||||||
|
Client &client = getClient(event->data.fd);
|
||||||
|
auto httpResponse = client.getResponse();
|
||||||
|
ssize_t bytesSent = send(event->data.fd, httpResponse.data(), httpResponse.size(), 0);
|
||||||
|
if (bytesSent < 0)
|
||||||
|
{
|
||||||
|
Log::error("Send failed for fd: " + std::to_string(event->data.fd) + " with error: " + std::strerror(errno));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::debug("Sent " + std::to_string(bytesSent) + " bytes to fd: " + std::to_string(event->data.fd));
|
||||||
|
}
|
||||||
|
clients_.erase(event->data.fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::handleEvent(struct epoll_event *event)
|
||||||
|
{
|
||||||
|
Log::trace(LOCATION);
|
||||||
|
if ((event->events & EPOLLERR) > 0 || (event->events & EPOLLHUP) > 0)
|
||||||
|
{
|
||||||
|
Log::error("Epoll error on fd " + std::to_string(event->data.fd));
|
||||||
|
remove(getListener(event->data.fd));
|
||||||
|
close(event->data.fd);
|
||||||
|
}
|
||||||
|
else if (listener_fds_.contains(event->data.fd))
|
||||||
|
{
|
||||||
|
handleConnection(event);
|
||||||
|
}
|
||||||
|
else if ((event->events & EPOLLIN) > 0)
|
||||||
|
{
|
||||||
|
handleRequest(event);
|
||||||
|
}
|
||||||
|
else if ((event->events & EPOLLOUT) > 0)
|
||||||
|
{
|
||||||
|
handleResponse(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Server::eventLoop()
|
void Server::eventLoop()
|
||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
@ -201,38 +240,7 @@ void Server::eventLoop()
|
|||||||
}
|
}
|
||||||
for (int i = 0; i < nfds; ++i)
|
for (int i = 0; i < nfds; ++i)
|
||||||
{
|
{
|
||||||
epoll_event &event = events[i]; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
|
handleEvent(&events[i]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
|
||||||
if ((event.events & EPOLLERR) > 0 || (event.events & EPOLLHUP) > 0)
|
|
||||||
{
|
|
||||||
Log::error("Epoll error on fd " + std::to_string(event.data.fd));
|
|
||||||
removeFromEpoll(getListener(event.data.fd));
|
|
||||||
close(event.data.fd);
|
|
||||||
}
|
|
||||||
else if (listener_fds_.contains(event.data.fd))
|
|
||||||
{
|
|
||||||
handleConnection(&event);
|
|
||||||
}
|
|
||||||
else if ((event.events & EPOLLIN) > 0)
|
|
||||||
{
|
|
||||||
handleRequest(&event);
|
|
||||||
}
|
|
||||||
else if ((event.events & EPOLLOUT) > 0)
|
|
||||||
{
|
|
||||||
Log::debug("Attempting to send data to fd: " + std::to_string(event.data.fd));
|
|
||||||
Client &client = getClient(event.data.fd);
|
|
||||||
auto httpResponse = client.getResponse();
|
|
||||||
ssize_t bytesSent = send(event.data.fd, httpResponse.data(), httpResponse.size(), 0);
|
|
||||||
if (bytesSent < 0)
|
|
||||||
{
|
|
||||||
Log::error("Send failed for fd: " + std::to_string(event.data.fd)
|
|
||||||
+ " with error: " + std::strerror(errno));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log::debug("Sent " + std::to_string(bytesSent) + " bytes to fd: " + std::to_string(event.data.fd));
|
|
||||||
}
|
|
||||||
clients_.erase(event.data.fd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,14 +33,10 @@ class Server
|
|||||||
~Server();
|
~Server();
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void addToEpoll(const Socket &socket, uint32_t events) const;
|
void add(const Socket &socket, uint32_t events) const;
|
||||||
void removeClient(const Client &client);
|
void remove(const Socket &socket) const;
|
||||||
void removeFromEpoll(const Socket &socket) const;
|
void disconnect(const Client &client);
|
||||||
void setupServerSocket(const ServerConfig &config);
|
|
||||||
void handleConnection(struct epoll_event *event);
|
|
||||||
void handleRequest(struct epoll_event *event) const;
|
|
||||||
void responseReady(int client_fd) const;
|
void responseReady(int client_fd) const;
|
||||||
void eventLoop();
|
|
||||||
|
|
||||||
Socket &getListener(int fd) const;
|
Socket &getListener(int fd) const;
|
||||||
Client &getClient(int fd) const;
|
Client &getClient(int fd) const;
|
||||||
@ -53,4 +49,12 @@ class Server
|
|||||||
std::vector<std::unique_ptr<Socket>> listeners_;
|
std::vector<std::unique_ptr<Socket>> listeners_;
|
||||||
std::set<int> listener_fds_;
|
std::set<int> listener_fds_;
|
||||||
std::unordered_map<int, std::unique_ptr<Client>> clients_;
|
std::unordered_map<int, std::unique_ptr<Client>> clients_;
|
||||||
};
|
|
||||||
|
void handleEvent(struct epoll_event *event);
|
||||||
|
void handleConnection(struct epoll_event *event);
|
||||||
|
void handleRequest(struct epoll_event *event) const;
|
||||||
|
void handleResponse(struct epoll_event *event);
|
||||||
|
|
||||||
|
void setupServerSocket(const ServerConfig &config);
|
||||||
|
void eventLoop();
|
||||||
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user