From a2d4e88c96c021e6c2c0fea8787514f68ad272a1 Mon Sep 17 00:00:00 2001 From: nicolas-arnaud Date: Mon, 7 Nov 2022 15:37:15 +0100 Subject: [PATCH] exported sockets to Env. fixed get_route and correct_uri. added listen_t struct. removed ipv6 parts. --- default.json | 7 ++--- includes/Env.hpp | 2 ++ includes/Route.hpp | 4 ++- includes/Server.hpp | 6 ++--- includes/Socket.hpp | 21 ++++----------- includes/webserv.hpp | 6 +++++ srcs/load/Env.cpp | 42 +++++++++++++++++++++++++---- srcs/load/Route.cpp | 53 +++++++++++++++++++++++++++---------- srcs/load/Server.cpp | 63 ++++++++++++++++++++++++-------------------- srcs/load/Socket.cpp | 40 ++++++++++++---------------- srcs/tools.cpp | 10 +++++++ 11 files changed, 160 insertions(+), 94 deletions(-) diff --git a/default.json b/default.json index a9333b4..f469081 100644 --- a/default.json +++ b/default.json @@ -4,12 +4,12 @@ "servers": [ { "server_name": "localhost", - "listens": ["80", "localhost:80", "localhost", "[::]:443"], + "listens": ["localhost:8080", "localhost"], "return": "301 https://$host$uri" }, { "server_name": "localhost", - "listens": ["8080"], + "listens": ["192.168.62.61:8080"], "root": "./public", "indexs": ["index.html"], "locations": @@ -21,7 +21,8 @@ }, "img/": { - "root": "images/" + "root": "images/", + "autoindex": true } } diff --git a/includes/Env.hpp b/includes/Env.hpp index 7cb8690..e6e4b77 100644 --- a/includes/Env.hpp +++ b/includes/Env.hpp @@ -3,9 +3,11 @@ class Env { std::vector _servers; + std::vector _sockets; public: Env(JSONNode *conf); void set_fds(); void refresh(); + Server *choose_server(Socket *sock, string host); }; diff --git a/includes/Route.hpp b/includes/Route.hpp index 9c277f4..85725ca 100644 --- a/includes/Route.hpp +++ b/includes/Route.hpp @@ -3,14 +3,16 @@ class Route { protected: + string _location; string _root; string _ret; std::vector _indexs; bool _autoindex; public: - Route(JSONNode *datas); + Route(string location, JSONNode *datas); ~Route(void); + string getLocation(void); string getRoot(void); string getReturn(void); std::vector getIndexs(void); diff --git a/includes/Server.hpp b/includes/Server.hpp index d7c18dd..76bb661 100644 --- a/includes/Server.hpp +++ b/includes/Server.hpp @@ -3,13 +3,11 @@ class Server : public Route { string _name; - std::vector _sockets; std::map _routes; - public: + std::vector _listens; Server(JSONNode *server); ~Server(); - void set_fds(); - void refresh(); + std::vector get_sockets(JSONNode *server); Route *get_route(string uri); }; diff --git a/includes/Socket.hpp b/includes/Socket.hpp index dde61b4..bf6d339 100644 --- a/includes/Socket.hpp +++ b/includes/Socket.hpp @@ -2,33 +2,22 @@ #include "webserv.hpp" class Socket { - Server *_server; - string _ip; - int _port; int _master_socket; - struct sockaddr_in _address; int _clients_amount; std::vector _clients; public: + struct sockaddr_in _address; + listen_t _listen; static fd_set _readfds; static int _max_fd; static int _min_fd; static int _amount; - Socket(Server *server, string def); + Socket(listen_t listen); ~Socket(); int launch(); void set_fds(); - void refresh(); - void answer(int fd, string request); + void refresh(Env *env); + void answer(Env *env, int fd, string request); void send_answer(int fd, string msg); - /* - Socket& operator=(Socket &src) { - _ip = src._ip; - _port = src._port; - _master_socket = src._master_socket; - _address = src._address; - return src; - } -*/ }; diff --git a/includes/webserv.hpp b/includes/webserv.hpp index 9bad44a..9f0d43f 100644 --- a/includes/webserv.hpp +++ b/includes/webserv.hpp @@ -41,9 +41,15 @@ class JSONNode; typedef std::map JSONObject; typedef std::vector JSONList; +typedef struct listen_s { + string ip; + int port; +} listen_t; + void *ft_memset(void *b, int c, size_t len); bool isInt(string str); std::vector split(string str, char delim); +listen_t get_listen_t(string listen); #include "Nodes.hpp" #include "Token.hpp" diff --git a/srcs/load/Env.cpp b/srcs/load/Env.cpp index 8588775..50e6385 100644 --- a/srcs/load/Env.cpp +++ b/srcs/load/Env.cpp @@ -10,6 +10,8 @@ Env::Env(JSONNode *conf) { it < servers.end(); it++) { Server *server = new Server(*it); _servers.push_back(server); + std::vector tmp_s = server->get_sockets(*it); + _sockets.insert(_sockets.end(), tmp_s.begin(), tmp_s.end()); // delete *it; cout << th[i] << " server launched.\n"; i++; @@ -19,16 +21,46 @@ Env::Env(JSONNode *conf) { } delete conf; } + +Server *Env::choose_server(Socket *sock, string host) { + std::vector exact; + std::vector inrange; + string ip = inet_ntoa(sock->_address.sin_addr); + int port = ntohs(sock->_address.sin_port); + + cout << "Which server for " << ip << ":" << port << "?\n"; + cout << "Socket: " << sock->_listen.ip << ":" << sock->_listen.port << "\n"; + (void)host; + for (std::vector::iterator sit = _servers.begin(); + sit < _servers.end(); sit++) { + std::vector serv_listens = (*sit)->_listens; + for (std::vector::iterator it = serv_listens.begin(); + it < serv_listens.end(); it++) { + if (sock->_listen.port != (*it).port) + continue; + if (sock->_listen.ip == (*it).ip) + exact.push_back(*sit); + else if (sock->_listen.ip == (*it).ip) + inrange.push_back(*sit); + // else if (is_ip_into(sock->_listen.ip, (*it).ip)) + } + } + if (exact.at(0)) + return (exact.at(0)); + else + return (inrange.at(0)); +} + void Env::set_fds() { - for (std::vector::iterator it = _servers.begin(); - it < _servers.end(); it++) { + for (std::vector::iterator it = _sockets.begin(); + it < _sockets.end(); it++) { (*it)->set_fds(); } } void Env::refresh() { - for (std::vector::iterator it = _servers.begin(); - it < _servers.end(); it++) { - (*it)->refresh(); + for (std::vector::iterator it = _sockets.begin(); + it < _sockets.end(); it++) { + (*it)->refresh(this); } } diff --git a/srcs/load/Route.cpp b/srcs/load/Route.cpp index d72d930..1d8be95 100644 --- a/srcs/load/Route.cpp +++ b/srcs/load/Route.cpp @@ -1,16 +1,18 @@ #include "webserv.hpp" -Route::Route(JSONNode *datas) { +Route::Route(string location, JSONNode *datas) : _location(location) { JSONObject object = datas->obj(); - if (object["root"]) - _root = object["root"]->str(); - if (object["return"]) - _ret = object["return"]->str(); - if (object["autoindex"]) - _autoindex = object["autoindex"]->boo(); - if (object["indexs"]) { - JSONList indexs = object["indexs"]->lst(); - for (JSONList::iterator it = indexs.begin(); it < indexs.end(); it++) { + JSONNode *tmp; + if ((tmp = object["root"])) + _root = tmp->str(); + if ((tmp = object["return"])) + _ret = tmp->str(); + if ((tmp = object["autoindex"])) + _autoindex = tmp->boo(); + if ((tmp = object["indexs"])) { + JSONList indexs = tmp->lst(); + for (JSONList::iterator it = indexs.begin(); + it < indexs.end(); it++) { _indexs.push_back((*it)->str()); } } @@ -18,6 +20,7 @@ Route::Route(JSONNode *datas) { Route::~Route(void) {} +string Route::getLocation(void) {return _location; } string Route::getRoot(void) { return _root; } string Route::getReturn(void) { return _ret; } std::vector Route::getIndexs(void) { return _indexs; } @@ -52,11 +55,30 @@ string Route::getAutoindex(string uri) { string Route::correctUri(string uri) { std::stringstream ret; - int slash_pos; - string root = _root; + //int slash_pos; + //string root = _root; + //int i = 0; + std::vector::iterator it; + std::vector::iterator it2; cout << "Correcting request: " << uri - << " with root: " << root << "\n"; + << " with root: " << _root << "\n"; + ret << _root; + std::vector loc_split = split(_location, '/'); + std::vector uri_split = split(uri, '/'); + it2 = uri_split.begin(); + for (it = loc_split.begin(); it < loc_split.end(); it++) { + while (*it2 == "") + it2++; + while (*it == "") + it++; + it2++; + } + + while (it2 < uri_split.end()) { + ret << "/" << *(it2++); + } + /* int i = 0; while (uri.at(i) == '/') i++; @@ -64,9 +86,12 @@ string Route::correctUri(string uri) { while ((slash_pos = root.find('/')) > 0) { ret << root.substr(0, slash_pos); root.erase(0, slash_pos); - uri = uri.substr(uri.find('/'), uri.length()); + if (uri.find('/')) + uri = uri.substr(uri.find('/'), uri.length()); } ret << uri; + */ cout << "resutlt: " << ret.str() << "\n"; return ret.str(); } + diff --git a/srcs/load/Server.cpp b/srcs/load/Server.cpp index 8bcd6d4..f6d3e67 100644 --- a/srcs/load/Server.cpp +++ b/srcs/load/Server.cpp @@ -1,45 +1,52 @@ #include "webserv.hpp" -Server::Server(JSONNode *server) : Route(server) { +Server::Server(JSONNode *server) : Route("/", server) { JSONObject datas = server->obj(); if (datas["server_name"]) _name = datas["server_name"]->str(); - if (datas["listens"]) { - JSONList listens = datas["listens"]->lst(); - for (JSONList::iterator it = listens.begin(); it < listens.end(); - it++) { - Socket *sock = new Socket(this, (*it)->str()); - if (sock->launch() == EXIT_SUCCESS) - _sockets.push_back(sock); - else - delete sock; - } - } if (datas["locations"]) { JSONObject locations = datas["locations"]->obj(); for (JSONObject::iterator it = locations.begin(); it != locations.end(); it++) { - Route *route = new Route((*it).second); + Route *route = new Route((*it).first, (*it).second); _routes[(*it).first] = route; } } } -Server::~Server(void) { cout << "Server destroyed!\n"; } - -void Server::set_fds(void) { - for (std::vector::iterator it = _sockets.begin(); - it < _sockets.end(); it++) { - (*it)->set_fds(); +std::vector Server::get_sockets(JSONNode *server) { + JSONObject datas = server->obj(); + std::vector ret; + listen_t listen; + if (datas["listens"]) { + JSONList listens = datas["listens"]->lst(); + for (JSONList::iterator it = listens.begin(); it != listens.end(); + it++) { + listen = get_listen_t((*it)->str()); + cout << listen.ip << ":" << listen.port << " socket creation...\n"; + if (listen.ip.at(0) == '[') { + cout << "Listen: IPv6 isn't supported\n"; + continue; + } + _listens.push_back(listen); + Socket *sock = new Socket(listen); + if (sock->launch() == EXIT_SUCCESS) + ret.push_back(sock); + else + delete sock; + } + } else { + listen = get_listen_t("localhost:80"); + Socket *sock = new Socket(listen); + _listens.push_back(listen); + if (sock->launch() == EXIT_SUCCESS) { + ret.push_back(sock); + } } + return ret; } -void Server::refresh(void) { - for (std::vector::iterator it = _sockets.begin(); - it < _sockets.end(); it++) { - (*it)->refresh(); - } -} +Server::~Server(void) { cout << "Server destroyed!\n"; } Route *Server::get_route(string uri) { cout << uri << "\n"; @@ -50,10 +57,10 @@ Route *Server::get_route(string uri) { root = split((*rit).first, '/'); std::vector::iterator root_it = root.begin(); - for (std::vector::iterator it = req.begin(); - it < req.end(); it++) { + for (std::vector::iterator it = req.begin(); it < req.end(); + it++) { if (*it == "") - continue ; + continue; cout << *it << " - " << *root_it << "\n"; if (*it != *(root_it++)) break; diff --git a/srcs/load/Socket.cpp b/srcs/load/Socket.cpp index 1a844a8..9821852 100644 --- a/srcs/load/Socket.cpp +++ b/srcs/load/Socket.cpp @@ -1,17 +1,7 @@ #include "webserv.hpp" -Socket::Socket(Server *server, string def) : _server(server) { - size_t sep_pos = def.rfind(':'); - size_t ip6_endpos = def.rfind(']'); - - string tmp = def.substr(0, sep_pos); - if (ip6_endpos > sep_pos) - _ip = def; - else - _ip = isInt(tmp) || tmp == "localhost" ? "127.0.0.1" : tmp; - tmp = def.substr(sep_pos + 1, def.length() - sep_pos - 1).c_str(); - _port = !isInt(tmp) ? 80 : std::atoi(tmp.c_str()); +Socket::Socket(listen_t listen) : _listen(listen) { _clients_amount = 0; } Socket::~Socket() { @@ -21,6 +11,9 @@ Socket::~Socket() { int Socket::launch() { int opt = 1; + string ip = _listen.ip; + int port = _listen.port; + _master_socket = socket(AF_INET, SOCK_STREAM, 0); if (_master_socket == 0) { cout << "Socket creation: " << strerror(errno) << "\n"; @@ -33,19 +26,16 @@ int Socket::launch() { return (EXIT_FAILURE); } - if (_ip.at(0) == '[') - _address.sin_family = AF_INET6; - else - _address.sin_family = AF_INET; - _address.sin_addr.s_addr = inet_addr(_ip.c_str()); - _address.sin_port = htons(_port); + _address.sin_family = AF_INET; + _address.sin_addr.s_addr = inet_addr(ip.c_str()); + _address.sin_port = htons(port); if (bind(_master_socket, (struct sockaddr *)&_address, sizeof(_address)) < 0) { cout << "Bind: " << strerror(errno) << "\n"; return (EXIT_FAILURE); } - cout << "Listener " << _ip << " on port " << _port << "\n"; + cout << "Listener " << ip << " on port " << port << "\n"; if (listen(_master_socket, 3) < 0) { cout << "Listen: " << strerror(errno) << "\n"; @@ -69,7 +59,7 @@ void Socket::set_fds() { } } -void Socket::refresh() { +void Socket::refresh(Env *env) { std::vector::iterator it; int valread; int addrlen = sizeof(_address); @@ -101,25 +91,29 @@ void Socket::refresh() { _clients.erase(it); } else { buffer[valread] = '\0'; - answer(*it, buffer); + answer(env, *it, buffer); } } } } -void Socket::answer(int fd, string request) { - string uri = split(request, ' ').at(1); +void Socket::answer(Env *env, int fd, string request) { + std::vector lines = split(request, '\n'); + string uri = split(lines.at(0), ' ').at(1); cout << uri << "\n"; cout << request << "\n|===|===|===|\n"; std::stringstream answer; answer << "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: "; - Route *route = _server->get_route(uri); + Server *server = env->choose_server(this, split(lines.at(1), ' ').at(1)); + Route *route = server->get_route(uri); + cout << "Route find: " << route->getLocation() << "\n"; answer << route->getAutoindex(uri); cout << answer.str() << "\n|===|===|===|\n"; send_answer(fd, answer.str()); } + void Socket::send_answer(int fd, string msg) { #ifdef __linux__ send(fd, msg.c_str(), msg.length(), MSG_NOSIGNAL); diff --git a/srcs/tools.cpp b/srcs/tools.cpp index 9bd58c2..2db8e22 100644 --- a/srcs/tools.cpp +++ b/srcs/tools.cpp @@ -27,3 +27,13 @@ std::vector split(string str, char delim) { } return tokens; } +listen_t get_listen_t(string listen) { + listen_t ret; + size_t sep_pos = listen.rfind(':'); + + string tmp = listen.substr(0, sep_pos); + ret.ip = isInt(tmp) ? "0.0.0.0" : (tmp == "localhost" ? "127.0.0.1" : tmp); + tmp = listen.substr(sep_pos + 1, listen.length() - sep_pos - 1).c_str(); + ret.port = !isInt(tmp) ? 80 : std::atoi(tmp.c_str()); + return ret; +}