From 05c7faf1f3f1325ad08b662e511ad3d31983231d Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sat, 6 Aug 2022 04:46:40 +0200 Subject: [PATCH] server search for client completed with host:port --- srcs/Client.hpp | 1 + srcs/utils.cpp | 6 ++++++ srcs/utils.hpp | 9 +++++++++ srcs/webserv/Webserv.hpp | 5 +++-- srcs/webserv/accept.cpp | 5 +++-- srcs/webserv/base.cpp | 3 +-- srcs/webserv/close.cpp | 13 +++++++++++++ srcs/webserv/init.cpp | 26 ++++++++++++++++++-------- srcs/webserv/response.cpp | 19 +++++++++++++------ srcs/webserv/run_loop.cpp | 7 ++++--- 10 files changed, 71 insertions(+), 23 deletions(-) diff --git a/srcs/Client.hpp b/srcs/Client.hpp index c23a7de..5a67601 100644 --- a/srcs/Client.hpp +++ b/srcs/Client.hpp @@ -32,6 +32,7 @@ class Client static char buf[MAX_FILESIZE+1]; size_t body_size; unsigned int status; + listen_socket *lsocket; // const functions ? http_method get_method(); diff --git a/srcs/utils.cpp b/srcs/utils.cpp index 87b2741..2144a51 100644 --- a/srcs/utils.cpp +++ b/srcs/utils.cpp @@ -99,3 +99,9 @@ void replace_all_substr(std::string &str, const std::string &ori_substr, const s pos += new_substr.size(); } } + +bool operator==(const listen_socket& lhs, int fd) + { return lhs.fd == fd; } + +bool operator==(int fd, const listen_socket& rhs) + { return fd == rhs.fd; } diff --git a/srcs/utils.hpp b/srcs/utils.hpp index b59df2f..6ea657c 100644 --- a/srcs/utils.hpp +++ b/srcs/utils.hpp @@ -29,6 +29,15 @@ enum http_method ANY_METHODS = 0b11111111, }; +struct listen_socket +{ + int fd; + std::string host; + std::string port; +}; +bool operator==(const listen_socket& lhs, int fd); +bool operator==(int fd, const listen_socket& rhs); + std::vector split(std::string input, char delimiter); bool isNumeric(std::string str); bool isNumeric_btw(int low, int high, std::string str); diff --git a/srcs/webserv/Webserv.hpp b/srcs/webserv/Webserv.hpp index 67e2c13..c5d6409 100644 --- a/srcs/webserv/Webserv.hpp +++ b/srcs/webserv/Webserv.hpp @@ -58,14 +58,14 @@ class Webserv private: int _epfd; - std::vector _listen_sockets; + std::vector _listen_sockets; std::vector _servers; std::vector _clients; std::map _http_status; std::map _mime_types; // accept.cpp - void _accept_connection(int fd); + void _accept_connection(listen_socket &lsocket); // request.cpp void _request(Client *client); void _read_request(Client *client); @@ -106,6 +106,7 @@ class Webserv // close.cpp void _close_client(int fd); void _close_all_clients(); + void _close_all_listen_sockets(); // init.cpp void _bind(int socket_fd, in_port_t port, std::string host); void _listen(int socket_fd, unsigned int max_connections); diff --git a/srcs/webserv/accept.cpp b/srcs/webserv/accept.cpp index f6db17b..ac620db 100644 --- a/srcs/webserv/accept.cpp +++ b/srcs/webserv/accept.cpp @@ -1,7 +1,7 @@ #include "Webserv.hpp" -void Webserv::_accept_connection(int fd) +void Webserv::_accept_connection(listen_socket &lsocket) { struct sockaddr_in addr; socklen_t addr_len; @@ -9,7 +9,7 @@ void Webserv::_accept_connection(int fd) std::cerr << "accept()\n"; addr_len = sizeof addr; - accepted_fd = ::accept(fd, (sockaddr*)&addr, &addr_len); + accepted_fd = ::accept(lsocket.fd, (sockaddr*)&addr, &addr_len); if (accepted_fd == -1) { std::perror("err accept()"); @@ -21,6 +21,7 @@ void Webserv::_accept_connection(int fd) _clients.push_back(Client()); _clients.back().fd = accepted_fd; + _clients.back().lsocket = &lsocket; _epoll_update(accepted_fd, EPOLLIN, EPOLL_CTL_ADD); } diff --git a/srcs/webserv/base.cpp b/srcs/webserv/base.cpp index 3392619..ee59bbd 100644 --- a/srcs/webserv/base.cpp +++ b/srcs/webserv/base.cpp @@ -45,10 +45,9 @@ Webserv::Webserv(std::vector* servers) Webserv::~Webserv() { - //close(_socket_fd); - // TODO : CLOSE ALL _listen_sockets close(_epfd); _close_all_clients(); + _close_all_listen_sockets(); std::cerr << "Server destroyed\n"; } diff --git a/srcs/webserv/close.cpp b/srcs/webserv/close.cpp index 70a1e3f..9b28f6b 100644 --- a/srcs/webserv/close.cpp +++ b/srcs/webserv/close.cpp @@ -32,3 +32,16 @@ void Webserv::_close_all_clients() _clients.pop_back(); } } + +void Webserv::_close_all_listen_sockets() +{ + while (!_listen_sockets.empty()) + { + // _epoll_update(_listen_sockets.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG + if (::close(_listen_sockets.back().fd) == -1) + std::perror("err close()"); + else + std::cerr << "close fd " << _listen_sockets.back().fd << "\n"; + _listen_sockets.pop_back(); + } +} diff --git a/srcs/webserv/init.cpp b/srcs/webserv/init.cpp index 361eaa2..3a33ed1 100644 --- a/srcs/webserv/init.cpp +++ b/srcs/webserv/init.cpp @@ -4,7 +4,9 @@ void Webserv::init_virtual_servers(std::vector* servers) { int ret; - std::vector _open_ports; + std::vector open_sockets; + struct listen_socket new_socket; + std::string host_port; _servers = *servers; _listen_sockets.clear(); @@ -12,7 +14,11 @@ void Webserv::init_virtual_servers(std::vector* servers) while (it != _servers.end()) { - if ( std::find(_open_ports.begin(), _open_ports.end(), std::atoi(it->port.data()) ) != _open_ports.end() ) + host_port.clear(); + host_port.append(it->host); + host_port.append(":"); + host_port.append(it->port); + if ( std::find(open_sockets.begin(), open_sockets.end(), host_port) != open_sockets.end() ) { ++it; continue; @@ -24,27 +30,31 @@ void Webserv::init_virtual_servers(std::vector* servers) std::perror("err socket()"); throw std::runtime_error("Socket init"); } + new_socket.fd = ret; + new_socket.host = it->host; + new_socket.port = it->port; + _listen_sockets.push_back(new_socket); + // HUGO ADD // // allow socket descriptor to be reuseable // I just copied it from https://www.ibm.com/docs/en/i/7.2?topic=designs-example-nonblocking-io-select int on = 1; - if (setsockopt(ret, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) + if (setsockopt(new_socket.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { ::perror("err setsockopt()"); throw std::runtime_error("Socket init"); } // // HUGO ADD END - _listen_sockets.push_back(ret); - _bind(_listen_sockets.back(), std::atoi(it->port.data()), it->host); - _listen(_listen_sockets.back(), 512); // 512 arbitrary + _bind(new_socket.fd, std::atoi(it->port.c_str()), it->host); + _listen(new_socket.fd, 512); // 512 arbitrary - if (_epoll_update(_listen_sockets.back(), EPOLLIN, EPOLL_CTL_ADD) == -1) + if (_epoll_update(new_socket.fd, EPOLLIN, EPOLL_CTL_ADD) == -1) throw std::runtime_error("Socket init"); - _open_ports.push_back(std::atoi(it->port.data())); + open_sockets.push_back(host_port); ++it; } } diff --git a/srcs/webserv/response.cpp b/srcs/webserv/response.cpp index 405d0a7..134dcff 100644 --- a/srcs/webserv/response.cpp +++ b/srcs/webserv/response.cpp @@ -356,24 +356,31 @@ void Webserv::_delete_file(Client *client, const std::string &path) ServerConfig &Webserv::_determine_process_server(Client *client) { /* - TODO : determine virtual server based on ip_address::port and server_name - Ior now its just based on server_name. - (maybe with a map< string, std::vector > where the string is "ip_adress::port") http://nginx.org/en/docs/http/request_processing.html + _determine_process_server() should be complete. + TODO : test it */ std::string &server_name = client->get_headers("Host"); std::vector::iterator it = _servers.begin(); + std::vector::iterator default_server = _servers.end(); + while (it != _servers.end()) { - if ( std::find(it->server_name.begin(), it->server_name.end(), server_name) != it->server_name.end() ) - break; + if (it->host == client->lsocket->host + && it->port == client->lsocket->port) + { + if ( std::find(it->server_name.begin(), it->server_name.end(), server_name) != it->server_name.end() ) + break; + else if (default_server == _servers.end()) + default_server = it; + } ++it; } if (it != _servers.end()) return (*it); else - return (_servers.front()); + return (*default_server); } LocationConfig &Webserv::_determine_location(ServerConfig &server, std::string &path) diff --git a/srcs/webserv/run_loop.cpp b/srcs/webserv/run_loop.cpp index 7f93043..ec9165d 100644 --- a/srcs/webserv/run_loop.cpp +++ b/srcs/webserv/run_loop.cpp @@ -11,6 +11,7 @@ void Webserv::run() int nfds; int i; int count_loop = 0; + std::vector::iterator it_socket; g_run = true; while (g_run) @@ -34,9 +35,9 @@ void Webserv::run() while (i < nfds) { // TODO : handle EPOLLERR and EPOLLHUP - if ((std::find(_listen_sockets.begin(), _listen_sockets.end(), events[i].data.fd) != _listen_sockets.end()) - && (events[i].events & EPOLLIN)) - _accept_connection(events[i].data.fd); + it_socket = std::find(_listen_sockets.begin(), _listen_sockets.end(), events[i].data.fd); + if (it_socket != _listen_sockets.end() && events[i].events & EPOLLIN) + _accept_connection(*it_socket); else if (events[i].events & EPOLLIN) _request( &(*std::find(_clients.begin(), _clients.end(), events[i].data.fd)) ); else if (events[i].events & EPOLLOUT)