diff --git a/Makefile b/Makefile index eb7dd60..9018e0d 100644 --- a/Makefile +++ b/Makefile @@ -45,11 +45,11 @@ HEADERS = Webserv.hpp DEPENDENCIES = $(HEADERS:%=$(HEADERS_D)/%) SRCS = $(MAIN) Webserv.cpp -#MAIN = main.cpp +MAIN = main.cpp #MAIN = main_luke.cpp #MAIN = main_hugo.cpp #MAIN = main_poll.cpp -MAIN = main_select.cpp +#MAIN = main_select.cpp DIR_OBJS = builds OBJS = $(SRCS:%.cpp=$(DIR_OBJS)/%.o) diff --git a/srcs/Webserv.cpp b/srcs/Webserv.cpp index 216dca0..8d2b325 100644 --- a/srcs/Webserv.cpp +++ b/srcs/Webserv.cpp @@ -7,7 +7,7 @@ Webserv::Webserv() std::cout << "Server init\n"; - //_socket_fd = ::socket(AF_INET, SOCK_STREAM, 0); + // create socket descriptor _socket_fd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); if (_socket_fd == -1) { @@ -24,32 +24,18 @@ Webserv::Webserv() } -//Webserv::Webserv(Webserv const &src) -//{ -// -//} - Webserv::~Webserv() { std::cout << "Server destroyed\n"; } -//Webserv & Webserv::operator=(Webserv const &rhs) -//{ -// -//} - - - /////////////// - // Functions // - void Webserv::bind(in_port_t port) { - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_port = ::htons(port); - addr.sin_addr.s_addr = ::htonl(INADDR_ANY); + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = ::htons(port); + addr.sin_addr.s_addr = ::htonl(INADDR_ANY); if (::bind(_socket_fd, (const sockaddr*)&addr, sizeof addr) == -1) { ::perror("err bind(): "); @@ -69,83 +55,70 @@ void Webserv::listen(unsigned int max_connections) #define BUFSIZE 8192 #define MSG_TEST "Le Webserv / 20 =D\n" #define MSG_BOUNCE "bounced properly ;)\n" // placeholder -#define TRUE 1 -#define FALSE 0 -void Webserv::start() +void Webserv::_add_fd(int sd, short event) { - int len, rc; - int listen_sd = -1, new_sd = -1; - int end_server = FALSE, compress_array = FALSE; - int close_conn; - char buffer[80]; -// struct sockaddr_in addr; - struct pollfd fds[200]; - int nfds = 1, current_size = 0, i, j; + struct pollfd new_poll_fd; - memset(fds, 0 , sizeof(fds)); - fds[0].fd = listen_sd; - fds[0].events = POLLIN; + new_poll_fd.fd = sd; + new_poll_fd.events = event; + new_poll_fd.revents = 0; + _fds.push_back(new_poll_fd); +} + +//void Webserv::_accept_sockets(int sd, short event) +//{ +//} + +void Webserv::start(int timeout) +{ + int len; + int rc; + int new_sd = -1; + char buffer[80]; + int current_size = 0; + int end_server = FALSE; + int compress_array = FALSE; + int close_conn; + struct pollfd * fds_ptr; + + // init first struct + _add_fd(_socket_fd, POLLIN); + // init pointer on first element of vector of struct pollfd + fds_ptr = &_fds[0]; std::cout << "Server started\n"; while (end_server == FALSE) { - // *********************************************************** - // * Call poll() * - // *********************************************************** - poll(fds, nfds, -1); + _nfds = _fds.size(); + poll(fds_ptr, _nfds, timeout); - // *********************************************************** - // * One or more descriptors are readable. Need to * - // * determine which ones they are. * - // *********************************************************** - current_size = nfds; - for (i = 0; i < current_size; i++) + current_size = _nfds; + for (int i = 0; i < current_size; i++) { - // ********************************************************* - // * Loop through to find the descriptors that returned * - // * POLLIN and determine whether it's the listening * - // * or the active connection. * - // ********************************************************* - if(fds[i].revents == 0) - continue; - - // ********************************************************* - // * If revents is not POLLIN, it's an unexpected result, * - // * log and end the server. * - // ********************************************************* - if(fds[i].revents != POLLIN) + if(_fds[i].revents == 0) { - printf(" Error! revents = %d\n", fds[i].revents); +std::cout << "here\n"; + continue; + } + + if(_fds[i].revents != POLLIN) + { + printf(" Error! revents = %d\n", _fds[i].revents); end_server = TRUE; break; - } - if (fds[i].fd == listen_sd) - { - // ******************************************************* - // * Listening descriptor is readable. * - // ******************************************************* - printf(" Listening socket is readable\n"); - // ******************************************************* - // * Accept all incoming connections that are * - // * queued up on the listening socket before we * - // * loop back and call poll again. * - // ******************************************************* + if (_fds[i].fd == _socket_fd) + { + printf(" Listening socket is readable\n"); do { - // ***************************************************** - // * Accept each incoming connection. If * - // * accept fails with EWOULDBLOCK, then we * - // * have accepted all of them. Any other * - // * failure on accept will cause us to end the * - // * server. * - // ***************************************************** - new_sd = accept(listen_sd, NULL, NULL); + new_sd = accept(_socket_fd, NULL, NULL); if (new_sd < 0) { - if (errno != EWOULDBLOCK) +printf(" new_sd < 0, = %i\n", new_sd); + if (errno != EWOULDBLOCK && errno != EAGAIN) { perror(" accept() failed"); end_server = TRUE; @@ -153,45 +126,19 @@ void Webserv::start() break; } - // ***************************************************** - // * Add the new incoming connection to the * - // * pollfd structure * - // ***************************************************** printf(" New incoming connection - %d\n", new_sd); - fds[nfds].fd = new_sd; - fds[nfds].events = POLLIN; - nfds++; - - // ***************************************************** - // * Loop back up and accept another incoming * - // * connection * - // ***************************************************** + _add_fd(new_sd, POLLIN); } while (new_sd != -1); } - // ********************************************************* - // * This is not the listening socket, therefore an * - // * existing connection must be readable * - // ********************************************************* - else { - printf(" Descriptor %d is readable\n", fds[i].fd); + printf(" Descriptor %d is readable\n", _fds[i].fd); close_conn = FALSE; - // ******************************************************* - // * Receive all incoming data on this socket * - // * before we loop back and call poll again. * - // ******************************************************* do { - // ***************************************************** - // * Receive data on this connection until the * - // * recv fails with EWOULDBLOCK. If any other * - // * failure occurs, we will close the * - // * connection. * - // ***************************************************** - rc = recv(fds[i].fd, buffer, sizeof(buffer), 0); + rc = recv(_fds[i].fd, buffer, sizeof(buffer), 0); if (rc < 0) { if (errno != EWOULDBLOCK) @@ -202,10 +149,6 @@ void Webserv::start() break; } - // ***************************************************** - // * Check to see if the connection has been * - // * closed by the client * - // ***************************************************** if (rc == 0) { printf(" Connection closed\n"); @@ -213,16 +156,10 @@ void Webserv::start() break; } - // ***************************************************** - // * Data was received * - // ***************************************************** len = rc; printf(" %d bytes received\n", len); - // ***************************************************** - // * Echo the data back to the client * - // ***************************************************** - rc = send(fds[i].fd, buffer, len, 0); + rc = send(_fds[i].fd, buffer, len, 0); if (rc < 0) { perror(" send() failed"); @@ -232,48 +169,37 @@ void Webserv::start() } while(TRUE); - // ******************************************************* - // * If the close_conn flag was turned on, we need * - // * to clean up this active connection. This * - // * clean up process includes removing the * - // * descriptor. * - // ******************************************************* if (close_conn) { - close(fds[i].fd); - fds[i].fd = -1; + close(_fds[i].fd); + _fds[i].fd = -1; compress_array = TRUE; } - } // End of existing connection is readable - } // End of loop through pollable descriptors + } // else + } // for (i = 0; i < current_size; i++) - // *********************************************************** - // * If the compress_array flag was turned on, we need * - // * to squeeze together the array and decrement the number * - // * of file descriptors. We do not need to move back the * - // * events and revents fields because the events will always* - // * be POLLIN in this case, and revents is output. * - // *********************************************************** if (compress_array) { compress_array = FALSE; - for (i = 0; i < nfds; i++) + for (int i = 0; i < _nfds; i++) { - if (fds[i].fd == -1) + if (_fds[i].fd == -1) { - for(j = i; j < nfds; j++) - { - fds[j].fd = fds[j+1].fd; - } + // for(int j = i; j < nfds; j++) + // { + // fds[j].fd = fds[j+1].fd; + // } + _fds.erase(_fds.begin() + i); i--; - nfds--; + // nfds--; } } } - } + } // while (end_server == FALSE) +} /* @@ -322,5 +248,3 @@ void Webserv::start() ::close(accepted_fd); */ - } -} diff --git a/srcs/Webserv.hpp b/srcs/Webserv.hpp index 6a77ce3..db2318e 100644 --- a/srcs/Webserv.hpp +++ b/srcs/Webserv.hpp @@ -4,19 +4,9 @@ # include # include +# include # 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 - # include // close # include // exit # include // cout, cin @@ -30,6 +20,9 @@ # include // fcntl # include // ioctl +# define TRUE 1 +# define FALSE 0 + class Webserv { public: @@ -40,13 +33,17 @@ class Webserv void bind(in_port_t port); void listen(unsigned int max_connections); - void start(); + void start(int timeout); private: int _socket_fd; std::map _request; std::map _response; + std::vector _fds; + int _nfds; + void _add_fd(int sd, short event); + }; #endif diff --git a/srcs/main.cpp b/srcs/main.cpp index 615141f..58f8209 100644 --- a/srcs/main.cpp +++ b/srcs/main.cpp @@ -13,7 +13,7 @@ int main(void) // https://security.stackexchange.com/questions/169213/how-to-chose-a-port-to-run-an-application-on-localhost serv.bind(4040); serv.listen(20); - serv.start(); + serv.start(3 * 60 * 1000); } catch (std::exception& e) { diff --git a/webserv b/webserv index 4711c3c..7136394 100755 Binary files a/webserv and b/webserv differ