/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* Connection.hpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: acossari +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/08/28 09:21:04 by acossari #+# #+# */ /* Updated: 2026/08/29 18:07:36 by acossari ### ########.fr */ /* */ /* ************************************************************************** */ #pragma once #include #include #include "net/ByteBuffer.hpp" #include "net/FileDescriptor.hpp" namespace webserv { class Connection final { public: enum class Lifecycle { Alive, Done, Fatal }; struct Outcome { Lifecycle lifecycle; std::uint32_t desiredEvents; }; // ByteBuffer::CAPACITY is 64 KiB. // At most 16 KiB are copied per 48 KiB appended: 16 / 48 = 1 / 3. // A lower threshold reduces copying but leaves less unread work available. // The 16 KiB value is a fixed compromise, not a measured optimum. static constexpr std::size_t LOW_WATERMARK = 16uz * 1024; explicit Connection(FileDescriptor socket); // Each Connection has a unique identity and remains in its original slot. Connection(const Connection&) = delete; Connection& operator=(const Connection&) = delete; Connection(Connection&&) = delete; Connection& operator=(Connection&&) = delete; int fd() const noexcept { return socket_.get(); } Outcome onClientEvent(std::uint32_t events); std::uint32_t desiredEvents() noexcept; void close() noexcept { socket_.reset(); } private: // recv() returning zero means the client has finished sending data. // readClosed_ records this. receive() still returns true because this // is not an error and the socket may still send its buffered response. // Only a recv() error returns false. bool receive(); bool transmit(); // TEMP echo path: queues received bytes unchanged for sending back to // the client. void forwardReceivedBytes(); FileDescriptor socket_; ByteBuffer receiveBuffer_; ByteBuffer sendBuffer_; bool readClosed_ = false; }; } // namespace webserv