classDiagram direction TB class Server { +Server(const ConfigManager&) +~Server() +start() +addToEpoll(Socket&, uint32_t) +removeFromEpoll(Socket&) +setupServerSocket(ServerConfig&) +handleConnection(epoll_event*) +handleRequest(epoll_event*) +responseReady(int) +eventLoop() +getListener(int) Socket& +getClient(int) Client& +getConfig(int) ServerConfig& +getConfig(Socket&) ServerConfig& -int epoll_fd_ -ConfigManager& configManager_ -vector> listeners_ -unordered_map fdToConfig_ -unordered_map> clients_ } class Socket { +Socket() +Socket(int) +~Socket() +listen(int) void +bind(string, int) void +accept() Socket* +recv(void*, size_t) ssize_t +send(const void*, size_t) ssize_t +setNonBlocking() void +getFd() int -int _fd } class Client { +Client(unique_ptr, Server&, ServerConfig&) +~Client()std::move(clientSocket), *this, getConfig(listener) +request() void +getResponse() string -unique_ptr client_socket_ -Server& server -ServerConfig& server_config } class ConfigManager { +init(string) +getInstance() ConfigManager& +getServerConfigs() vector -bool _initialized -vector serverConfigs } class ServerConfig { +ServerConfig(string) +getHost() string +getPort() int +getRoot() string +getCgiPass() string +getCgiExt() string +getErrorPages() map +getIndexFiles() vector +getLocation(string) LocationConfig& +getLocationPaths() vector +setServerFD(int) +getServerFD() int -string host -int port -int server_fd -string root -string cgi_pass -string cgi_ext -map error_page -vector index_files -map locations } class LocationConfig { +LocationConfig(string) -string path -bool autoIndex -string indexFile -map directives } Server "1" o-- "1..*" Socket : listens on Server "1" o-- "0..*" Client : manages Server "1" -- "1" ConfigManager : uses Client "1" *-- "1" Socket : owns Client "1" -- "1" Server : references Client "1" -- "1" ServerConfig : references ServerConfig "1" o-- "*" LocationConfig : has