summaryrefslogtreecommitdiff
path: root/bot/include/http_webhook_server.cpp
diff options
context:
space:
mode:
authorsoler_j <soler_j@etna-alternance.net>2025-04-30 22:30:54 +0200
committersoler_j <soler_j@etna-alternance.net>2025-04-30 22:30:54 +0200
commit976c7a7466ef2852607a83ead4e0ed93550742d8 (patch)
treef3a6996d9b2e283b2501cf1d8b8f0bb82a21a967 /bot/include/http_webhook_server.cpp
parente557ff8f867d777332ab397ba5b3b6be57767972 (diff)
Refactor project structure and remove unused files
- Updated CMakeLists.txt to include source files from the 'src' directory instead of 'include'. - Deleted 'http_webhook_server.cpp' and 'utils.cpp' files as they were no longer needed. - Added 'handle_actions.hpp' and 'handle_actions.cpp' to manage slash command actions. - Implemented 'http_webhook_server.cpp' to handle HTTP webhook server functionality. - Updated 'utils.hpp' to include necessary headers and declarations. - Refactored 'main.cpp' to include 'handle_actions.hpp' and updated slash command handling logic. - Enhanced 'utils.cpp' with utility functions for handling user and guild data.
Diffstat (limited to 'bot/include/http_webhook_server.cpp')
-rw-r--r--bot/include/http_webhook_server.cpp175
1 files changed, 0 insertions, 175 deletions
diff --git a/bot/include/http_webhook_server.cpp b/bot/include/http_webhook_server.cpp
deleted file mode 100644
index 84815b7..0000000
--- a/bot/include/http_webhook_server.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-#include "http_webhook_server.hpp"
-#include <fcntl.h>
-#include <unistd.h>
-#include <cstring>
-#include <algorithm>
-
-HttpWebhookServer::HttpWebhookServer(uint16_t port, Handler handler)
- : port(port), request_handler(handler) {
- setupSocket();
- setupEpoll();
-}
-
-HttpWebhookServer::~HttpWebhookServer() {
- stop();
- if (server_fd != -1) ::close(server_fd);
- if (epoll_fd != -1) ::close(epoll_fd);
-}
-
-void HttpWebhookServer::setupSocket() {
- server_fd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
- if (server_fd == -1) throw std::system_error(errno, std::generic_category());
-
- int opt = 1;
- setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
-
- sockaddr_in addr{};
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = htons(port);
-
- if (::bind(server_fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1)
- throw std::system_error(errno, std::generic_category());
-
- if (::listen(server_fd, 128) == -1)
- throw std::system_error(errno, std::generic_category());
-}
-
-void HttpWebhookServer::setupEpoll() {
- epoll_fd = ::epoll_create1(0);
- if (epoll_fd == -1)
- throw std::system_error(errno, std::generic_category());
-
- epoll_event event{};
- event.events = EPOLLIN | EPOLLET;
- event.data.fd = server_fd;
-
- if (::epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &event) == -1)
- throw std::system_error(errno, std::generic_category());
-}
-
-void HttpWebhookServer::start() {
- running = true;
- epoll_event events[64];
-
- while (running) {
- int nfds = ::epoll_wait(epoll_fd, events, 64, -1);
- if (nfds == -1 && errno != EINTR)
- throw std::system_error(errno, std::generic_category());
-
- for (int i = 0; i < nfds; ++i) {
- if (events[i].data.fd == server_fd) {
- while (true) {
- sockaddr_in client_addr{};
- socklen_t client_len = sizeof(client_addr);
- int client_fd = ::accept4(server_fd, (sockaddr*)&client_addr, &client_len, SOCK_NONBLOCK);
- if (client_fd == -1) break;
-
- epoll_event event{};
- event.events = EPOLLIN | EPOLLET | EPOLLRDHUP;
- event.data.fd = client_fd;
- ::epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &event);
- clients[client_fd] = ClientContext{};
- }
- } else {
- handleClient(events[i].data.fd);
- }
- }
- }
-}
-
-void HttpWebhookServer::stop() {
- running = false;
-}
-
-void HttpWebhookServer::closeClient(int fd) {
- ::epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, nullptr);
- ::close(fd);
- clients.erase(fd);
-}
-
-void HttpWebhookServer::handleClient(int fd) {
- char buffer[4096];
- ssize_t count = ::recv(fd, buffer, sizeof(buffer), MSG_DONTWAIT);
-
- if (count > 0) {
- auto& ctx = clients[fd];
- ctx.input_buffer.append(buffer, count);
-
- if (ctx.input_buffer.find("\r\n\r\n") != std::string::npos) {
- HttpRequest req;
- parseHttpRequest(ctx, req);
-
- HttpResponse res = request_handler(req);
- buildHttpResponse(res, ctx.output_buffer);
-
- epoll_event event{};
- event.events = EPOLLOUT | EPOLLET | EPOLLRDHUP;
- event.data.fd = fd;
- ::epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &event);
- }
- }
- else if (count == 0 || (count == -1 && errno != EAGAIN)) {
- closeClient(fd);
- return;
- }
-
- if (!clients.count(fd)) return; // Client déjà fermé plus haut
-
- auto& ctx = clients[fd];
- if (!ctx.output_buffer.empty()) {
- ssize_t sent = ::send(fd,
- ctx.output_buffer.data() + ctx.bytes_written,
- ctx.output_buffer.size() - ctx.bytes_written,
- MSG_DONTWAIT);
-
- if (sent > 0) ctx.bytes_written += sent;
- if (ctx.bytes_written == ctx.output_buffer.size()) {
- closeClient(fd);
- }
- }
-}
-
-void HttpWebhookServer::parseHttpRequest(ClientContext& ctx, HttpRequest& req) {
- std::istringstream stream(ctx.input_buffer);
- std::string line;
-
- std::getline(stream, line);
- std::istringstream req_line(line);
- req_line >> req.method >> req.path;
-
- while (std::getline(stream, line) && line != "\r") {
- size_t colon = line.find(':');
- if (colon != std::string::npos) {
- std::string key = line.substr(0, colon);
- std::string value = line.substr(colon + 1);
- key.erase(std::remove_if(key.begin(), key.end(), ::isspace), key.end());
- value.erase(0, value.find_first_not_of(" \t\r\n"));
- value.erase(value.find_last_not_of(" \t\r\n") + 1);
- req.headers[key] = value;
- }
- }
-
- size_t header_end = ctx.input_buffer.find("\r\n\r\n");
- if (header_end != std::string::npos) {
- req.body = ctx.input_buffer.substr(header_end + 4);
- if (req.headers.count("Content-Length")) {
- size_t content_length = std::stoul(req.headers["Content-Length"]);
- req.body = req.body.substr(0, content_length);
- }
- }
-}
-
-void HttpWebhookServer::buildHttpResponse(const HttpResponse& res, std::string& output) {
- output = "HTTP/1.1 " + std::to_string(res.status_code) + " OK\r\n";
-
- for (const auto& [key, value] : res.headers) {
- output += key + ": " + value + "\r\n";
- }
-
- if (!res.headers.count("Content-Length")) {
- output += "Content-Length: " + std::to_string(res.body.size()) + "\r\n";
- }
-
- output += "\r\n" + res.body;
-}