diff --git a/includes/webserv.hpp b/includes/webserv.hpp index 7074b52..9e136c5 100644 --- a/includes/webserv.hpp +++ b/includes/webserv.hpp @@ -14,6 +14,7 @@ #define HOME "www" #define BUFFSIZE 65536 +#define LIFE_TIME 5 #define MAX_CLIENT 1000 #define WHITESPACE " \n\r\t\f\v" diff --git a/src/Client/Client.cpp b/src/Client/Client.cpp index b4b437d..67dfef0 100644 --- a/src/Client/Client.cpp +++ b/src/Client/Client.cpp @@ -250,6 +250,11 @@ bool Client::TimeToDie(void) return (false); } +serverListen Client::getIpPort() +{ + return (connected_to); +} + void Client::updateTimeToDie(void) { gettimeofday(&_time, NULL); diff --git a/src/Client/Client.hpp b/src/Client/Client.hpp index 975e0d9..d7c376a 100644 --- a/src/Client/Client.hpp +++ b/src/Client/Client.hpp @@ -60,6 +60,7 @@ public: bool isEmpty(void); bool TimeToDie(void); void updateTimeToDie(void); + serverListen getIpPort(void); public: int parseRequest(void); diff --git a/src/Server/Server.cpp b/src/Server/Server.cpp index cfe1ebb..37b1fd3 100644 --- a/src/Server/Server.cpp +++ b/src/Server/Server.cpp @@ -101,20 +101,63 @@ void Server::readSocket(Client &client, int fd) } int Server::delete_client(std::map &client_map, int fd) +{ + if (client_map[fd]->getRequest().getConnection() == "close") + { + int ret; + ret = epoll_ctl(_epoll_fd, EPOLL_CTL_DEL, fd, NULL); + close(fd); + client_map[fd]->clear(); + delete (client_map[fd]); + client_map.erase(fd); + DBOUT << RED << + "deleting client " + << fd + << ENDL; + return (ret); + } + else + { + int ret; + struct epoll_event ev; + t_tmp_fd *tmp_fd; + + ev.events = EPOLLIN; + ev.data.fd = fd; + ret = epoll_ctl(_epoll_fd, EPOLL_CTL_MOD, fd, &ev); + + //Добавляю фд в список + tmp_fd = new t_tmp_fd; + tmp_fd->ip_port = client_map[fd]->getIpPort(); + gettimeofday(&tmp_fd->last_modif, NULL); + free_socket[fd] = tmp_fd; + + //Удаляю клиента + client_map[fd]->clear(); + delete (client_map[fd]); + client_map.erase(fd); + DBOUT << RED << + "deleting client " + << ENDL; + return (ret); + } +} +int Server::delete_fd(std::map &map, int fd) { int ret; ret = epoll_ctl(_epoll_fd, EPOLL_CTL_DEL, fd, NULL); + delete map[fd]; close(fd); - client_map[fd]->clear(); - delete (client_map[fd]); - client_map.erase(fd); + map.erase(fd); DBOUT << RED << - "deleting client " - << fd - << ENDL; + "deleting fd " + << fd + << ENDL; + return (ret); } + void Server::setup_server_socks(std::map &configurations_map) { unsigned int server_events = EPOLLIN; @@ -170,6 +213,17 @@ void Server::add_to_epoll_list(int fd, unsigned int ep_events) << ENDL; } +bool Server::TimeToDie(struct timeval &last_modif, int lifeTime) +{ + struct timeval curTime; + + gettimeofday(&curTime, NULL); + if ((curTime.tv_sec - last_modif.tv_sec) >= lifeTime) + return (true); + else + return (false); +} + void sigHandler(int sig) { if (sig == SIGINT) @@ -181,6 +235,8 @@ void Server::run(void) std::map client_map; std::map configurations_map; + std::map::iterator free_it; + unsigned int client_events = EPOLLIN; std::signal(SIGINT, sigHandler); @@ -194,10 +250,17 @@ void Server::run(void) { int ready_num = epoll_wait(_epoll_fd, _events, MAX_CLIENT, 5000); - // DBOUT << TURQ << "ready_num " << ready_num << ENDL; + DBOUT << TURQ << "ready_num " << ready_num << ENDL; if (ready_num < 0) throw std::logic_error("epoll_ret"); + free_it = free_socket.begin(); + for (; free_it != free_socket.end(); free_it++) + { + if (TimeToDie(free_it->second->last_modif, LIFE_TIME)) + delete_fd(free_socket, free_it->first); + } + for (int i = 0; i < ready_num; i++) { int fd = _events[i].data.fd; @@ -222,14 +285,20 @@ void Server::run(void) } else { - /* if (client_map.find(fd) == client_map.end()) */ - /* client_map[fd] = new Client(); */ - if (events & EPOLLIN) + free_it = free_socket.find(fd); + if (free_it != free_socket.end()) + { + client_map[fd] = new Client(free_it->second->ip_port); + delete free_it->second; + free_socket.erase(fd); + } + else if (events & EPOLLIN) { readSocket(*client_map[fd], fd); if (client_map[fd]->done) { delete_client(client_map, fd); + delete_fd(free_socket, fd); } else if (client_map[fd]->readyToSend()) { diff --git a/src/Server/Server.hpp b/src/Server/Server.hpp index 7bbc950..18d98cf 100644 --- a/src/Server/Server.hpp +++ b/src/Server/Server.hpp @@ -48,6 +48,14 @@ class Server size_t left; enum e_req_status req_status; } t_client_status; + typedef struct s_tmp_fd + { + serverListen ip_port; + struct timeval last_modif; + }t_tmp_fd; + bool TimeToDie(struct timeval &last_modif, int lifeTime); + int delete_fd(std::map &map, int fd); + std::map free_socket; public: Server();