From 461c10b6a2fbbdfce4645b54664b6aa505f70101 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Wed, 13 Jul 2022 14:31:34 +0200 Subject: [PATCH] tmp try with luke code --- srcs/Webserv.cpp | 108 ++++++++++++++++++++++++++++++++++++++++++++--- srcs/Webserv.hpp | 19 +++++++-- 2 files changed, 116 insertions(+), 11 deletions(-) diff --git a/srcs/Webserv.cpp b/srcs/Webserv.cpp index d446827..884218a 100644 --- a/srcs/Webserv.cpp +++ b/srcs/Webserv.cpp @@ -3,25 +3,119 @@ Webserv::Webserv() { - _socket_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); + std::cout << "Server init\n"; + _socket_fd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); if (_socket_fd == -1) { - perror("socket(): "); + ::perror("err socket(): "); throw std::runtime_error("Socket init"); } } -Webserv::Webserv(Webserv const &src) +/* Webserv::Webserv(Webserv const &src) { -} +} */ Webserv::~Webserv() { - + std::cout << "Server destroyed\n"; } -Webserv & Webserv::operator=(Webserv const &rhs) +/* Webserv & Webserv::operator=(Webserv const &rhs) { -} \ No newline at end of file +} */ + + /////////////// + // Functions // + +void Webserv::bind(in_port_t port) +{ + // cast invalid ? how to ? + // const struct sockaddr* cast_test = static_cast(addr); + + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = ::htons(port); + addr.sin_addr.s_addr = ::htonl(INADDR_ANY); // htonl useless with 0 value (INADDR_ANY) + + if (::bind(_socket_fd, (const sockaddr*)&addr, sizeof addr) == -1) + { + ::perror("err bind(): "); + throw std::runtime_error("Socket bind"); + } +} + +void Webserv::listen(unsigned int max_connections) +{ + if (::listen(_socket_fd, max_connections) == -1) + { + ::perror("err listen(): "); + throw std::runtime_error("Socket listen"); + } +} + +#define BUFSIZE 8192 +#define MSG_TEST "Le Webserv / 20 =D\n" +#define MSG_BOUNCE "bounced properly ;)\n" // placeholder + +void Webserv::start() +{ + struct sockaddr_in addr; + socklen_t addr_len; + int accepted_fd; + + // poll (or equivalent) + struct pollfd poll_s; + poll_s.fd = _socket_fd; + poll_s.events = POLLIN; + + char buf[BUFSIZE]; // WIP buffer. need to try with std::vector or std::string. + int ret; + + std::cout << "Server started\n"; + while (1) + { + std::cout << "----------\n"; + std::cout << "poll()\n"; // poll (or equivalent) + ::poll(&poll_s, 1, -1); + + std::cout << "accept()\n"; + addr_len = sizeof addr; + accepted_fd = ::accept(_socket_fd, (sockaddr*)&addr, &addr_len); + if (accepted_fd == -1) + { + ::perror("err accept(): "); + continue; + } + + // "Your server must never block and the client can be bounced properly if necessary". + // NO-Block OK, but how to handle it ? Miss the bouncing part. + ::fcntl(accepted_fd, F_SETFL, O_NONBLOCK); + + std::cout << "recv()\n"; + ret = ::recv(accepted_fd, buf, BUFSIZE, 0); + if (ret == -1) + { + ::perror("err recv(): "); + if (::send(accepted_fd, MSG_BOUNCE, sizeof MSG_BOUNCE - 1, 0) == -1) + ::perror("err send(): "); + ::close(accepted_fd); + continue; + } + /* + if (ret == BUFSIZE) + // send error like "request too long" to client + */ + buf[ret] = '\0'; + + std::cout << "send()\n"; + if (::send(accepted_fd, buf, ret, 0) == -1) // echo the read + ::perror("err send(): "); + if (::send(accepted_fd, MSG_TEST, sizeof MSG_TEST - 1, 0) == -1) + ::perror("err send(): "); + + ::close(accepted_fd); + } +} diff --git a/srcs/Webserv.hpp b/srcs/Webserv.hpp index fed19a2..01f87f1 100644 --- a/srcs/Webserv.hpp +++ b/srcs/Webserv.hpp @@ -8,17 +8,28 @@ # include // perror # include # include +# include // close +# include // cout, cin # include // socket, accept, listen, send, recv, bind, connect, setsockopt, getsockname +# include // sockaddr_in +// # include // usefull for what ? +# include // htonl, htons, ntohl, ntohs, inet_addr + +# include // poll +# include // fcntl class Webserv { public: - //Webserv(Placeholder); Webserv(); - Webserv(Webserv const &src); + // Webserv(Webserv const &src); ~Webserv(); - Webserv &operator=(Webserv const &rhs); + // Webserv &operator=(Webserv const &rhs); + + void bind(in_port_t port); + void listen(unsigned int max_connections); + void start(); private: int _socket_fd; @@ -27,4 +38,4 @@ class Webserv }; -#endif \ No newline at end of file +#endif