diff --git a/default.json b/default.json index 8e524d7..05d1d2c 100644 --- a/default.json +++ b/default.json @@ -4,12 +4,12 @@ "servers": [ { "server_name": "localhost", - "listens": ["15000", "[::]:88"], + "listens": ["80", "localhost:80", "localhost", "[::]:443"], "return": "301 https://$host$uri" }, { "server_name": "localhost", - "listens": ["150005", "[::]:88"], + "listens": ["8080"], "root": "./public", "index": ["index.html"], "locations": diff --git a/srcs/load/Env.hpp b/srcs/load/Env.hpp index 5bb79e6..4abc255 100644 --- a/srcs/load/Env.hpp +++ b/srcs/load/Env.hpp @@ -3,7 +3,7 @@ class Env { //int _max_clients; - std::vector _servers; + std::vector _servers; public: Env(JSONNode *conf) { JSONList servers = conf->obj()["servers"]->lst(); @@ -11,17 +11,16 @@ class Env { string th[8]= {"first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eigth"}; for (std::vector::iterator it = servers.begin(); it < servers.end(); it++) { - Server *server = new Server(*it); - server->launch(); + Server server(*it); _servers.push_back(server); //delete *it; cout << th[i] << " server launched.\n"; i++; } while(1) { - for (std::vector::iterator it = _servers.begin(); + for (std::vector::iterator it = _servers.begin(); it < _servers.end(); it++) { - (*it)->check(); + (*it).check(); } } //delete conf; diff --git a/srcs/load/Server.hpp b/srcs/load/Server.hpp index 83ea9cd..897957f 100644 --- a/srcs/load/Server.hpp +++ b/srcs/load/Server.hpp @@ -1,138 +1,33 @@ #include "../webserv.hpp" #include "Route.hpp" +#include "Socket.hpp" + class Server { - string _name; - std::vector _listens; - int _port; + string _name; + std::vector _sockets; std::map _routes; - int _master_socket; - struct sockaddr_in _address; public: Server(JSONNode *server) { - _port = 80; JSONObject datas = server->obj(); if (datas["server_name"]) _name = datas["server_name"]->str(); if (datas["listens"]) { JSONList listens = datas["listens"]->lst(); - for (JSONList::iterator i = listens.begin(); i < listens.end(); i++) - _listens.push_back((*i)->str()); - _port = std::atoi(_listens.front().c_str()); + for (JSONList::iterator i = listens.begin(); i < listens.end(); i++) { + //_listens.push_back((*i)->str()); + Socket sock((*i)->str()); + _sockets.push_back(sock); + } + //_port = std::atoi(_listens.front().c_str()); } //_routes["default"] = new Route(datas["root"], datas["return"], datas["index"], datas["autoindex"]); } - void launch() { - int opt = 1; - - _master_socket = socket(AF_INET, SOCK_STREAM, 0); - if (_master_socket == 0) { - cout << strerror(errno) << "\n"; - exit(EXIT_FAILURE); - } - - if (setsockopt(_master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, - sizeof(opt)) < 0) { - cout << strerror(errno) << "\n"; - exit(EXIT_FAILURE); - } - - _address.sin_family = AF_INET; - _address.sin_addr.s_addr = INADDR_ANY; - _address.sin_port = htons(_port); - if (bind(_master_socket, (struct sockaddr *)&_address, sizeof(_address)) < 0) { - cout << strerror(errno) << "\n"; - exit(EXIT_FAILURE); + void check() { + for (std::vector::iterator it = _sockets.begin(); it < _sockets.end(); it++){ + (*it).check(); } - cout << "Listener on port " << _port << "\n"; - - if (listen(_master_socket, 3) < 0) { - cout << strerror(errno) << "\n"; - exit(EXIT_FAILURE); - } - - cout << "Waiting for connections ..." << "\n"; } - - void check() { - int new_socket, activity, i, valread, sd; - char buffer[30000]; - char _404[72] = - "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!"; - - int max_clients = 30; - int client_socket[30]; - fd_set readfds; - int max_sd = _master_socket; - - - - int addrlen = sizeof(_address); - for (i = 0; i < max_clients; i++) - client_socket[i] = 0; - FD_ZERO(&readfds); - FD_SET(_master_socket, &readfds); - - for (i = 0; i < max_clients; i++) { - sd = client_socket[i]; - if (sd > 0) - FD_SET(sd, &readfds); - if (sd > max_sd) - max_sd = sd; - } - - activity = select(max_sd + 1, &readfds, NULL, NULL, NULL); - - if ((activity < 0) && (errno != EINTR)) - cout << strerror(errno) << "\n"; - - if (FD_ISSET(_master_socket, &readfds)) { - if ((new_socket = accept(_master_socket, (struct sockaddr *)&_address, - (socklen_t *)&addrlen)) < 0) { - cout << strerror(errno) << "\n"; - exit(EXIT_FAILURE); - } -#ifdef __APPLE__ - fcntl(new_socket, F_GETNOSIGPIPE); -#endif - cout << "New connection, socket fd is " << new_socket - << ", ip is : " << inet_ntoa(_address.sin_addr) - << ", port : " << ntohs(_address.sin_port) << "\n"; - - for (i = 0; i < max_clients; i++) { - if (client_socket[i] == 0) { - client_socket[i] = new_socket; - cout << "Adding to list of sockets as " << i - << "\n"; - break; - } - } - } - - for (i = 0; i < max_clients; i++) { - sd = client_socket[i]; - if (FD_ISSET(sd, &readfds)) { - valread = read(sd, buffer, 30000); - if (valread == 0) { - getpeername(sd, (struct sockaddr *)&_address, - (socklen_t *)&addrlen); - cout << "Host disconnected, ip " - << inet_ntoa(_address.sin_addr) << ", port " - << ntohs(_address.sin_port) << "\n"; - close(sd); - client_socket[i] = 0; - } else -#ifdef __linux__ - send(sd, _404, strlen(_404), MSG_NOSIGNAL); -#elif __APPLE__ - send(sd, _404, strlen(_404), 0); -#endif - - } - } - } - - }; diff --git a/srcs/load/Socket.hpp b/srcs/load/Socket.hpp new file mode 100644 index 0000000..6183d89 --- /dev/null +++ b/srcs/load/Socket.hpp @@ -0,0 +1,135 @@ +#include "../webserv.hpp" + +class Socket { + string _ip; + int _port; + int _master_socket; + struct sockaddr_in _address; + int _max_clients; + int _client_socket[30]; + public: + Socket(string def) { + size_t split = def.rfind(':'); + + string tmp = def.substr(0, split - 1); + _ip = isInt(tmp) ? "localhost" : tmp; + tmp = def.substr(split + 1, def.length() - split - 1).c_str(); + _port = !isInt(tmp) ? 80 : std::atoi(tmp.c_str()); + + _max_clients = 30; + + int opt = 1; + _master_socket = socket(AF_INET, SOCK_STREAM, 0); + if (_master_socket == 0) { + cout << "Socket creation: " << strerror(errno) << "\n"; + exit(EXIT_FAILURE); + } + int opt_ret = setsockopt(_master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)); + if (opt_ret < 0) { + cout << "Sockopt: " << strerror(errno) << "\n"; + exit(EXIT_FAILURE); + } + + _address.sin_family = AF_INET; + _address.sin_addr.s_addr = INADDR_ANY; + _address.sin_port = htons(_port); + + if (bind(_master_socket, (struct sockaddr *)&_address, sizeof(_address)) < 0) { + cout << "Bind: " << strerror(errno) << "\n"; + cout << "Socket destroyed!\n"; + return ; + exit(EXIT_FAILURE); + } + cout << "Listener on port " << _port << "\n"; + + if (listen(_master_socket, 3) < 0) { + cout << "Listen: " << strerror(errno) << "\n"; + exit(EXIT_FAILURE); + } + for (int i = 0; i < _max_clients; i++) + _client_socket[i] = 0; + } + void check() { + int new_socket, activity, i, valread, sd; + char buffer[1024]; + char r404[72] = "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!"; + + fd_set readfds; + int max_sd = _master_socket; + + int addrlen = sizeof(_address); + FD_ZERO(&readfds); + FD_SET(_master_socket, &readfds); + + for (i = 0; i < _max_clients; i++) { + sd = _client_socket[i]; + if (sd > 0) + FD_SET(sd, &readfds); + if (sd > max_sd) + max_sd = sd; + } + + activity = select(max_sd + 1, &readfds, NULL, NULL, NULL); + + if ((activity < 0) && (errno != EINTR)) + cout << "Select: " << strerror(errno) << "\n"; + + if (FD_ISSET(_master_socket, &readfds)) { + new_socket = accept(_master_socket, (struct sockaddr *)&_address,(socklen_t *)&addrlen); + if (new_socket < 0) { + cout << "Accept: " << strerror(errno) << "\n"; + exit(EXIT_FAILURE); + } +#ifdef __APPLE__ + fcntl(new_socket, F_GETNOSIGPIPE); +#endif + cout << "New connection, socket fd is " << new_socket + << ", ip is : " << inet_ntoa(_address.sin_addr) + << ", port : " << ntohs(_address.sin_port) << "\n"; + for (i = 0; i < _max_clients; i++) { + if (_client_socket[i] == 0) { + _client_socket[i] = new_socket; + cout << "Adding to list of sockets as " << i << "\n"; + break; + } + } + } + cout << "Socket: " << _ip << ":" << _port << "\n"; + for (i = 0; i < _max_clients; i++) { + sd = _client_socket[i]; + if (FD_ISSET(sd, &readfds)) { + cout << "Client " << i << ": set\n"; + valread = read(sd, buffer, 1024); + if (valread == 0) { + getpeername(sd, (struct sockaddr *)&_address, + (socklen_t *)&addrlen); + cout << "Host disconnected, ip " + << inet_ntoa(_address.sin_addr) << ", port " + << ntohs(_address.sin_port) << "\n"; + close(sd); + _client_socket[i] = 0; + } else { + cout << buffer << "\n"; +#ifdef __linux__ + send(sd, r404, strlen(r404), MSG_NOSIGNAL); +#elif __APPLE__ + send(sd, r404, strlen(r404), 0); +#endif + } + + } + } + } + /* + Socket& operator=(Socket &src) { + _ip = src._ip; + _port = src._port; + _master_socket = src._master_socket; + _address = src._address; + return src; + } +*/ +}; + + + diff --git a/srcs/tools.cpp b/srcs/tools.cpp index e459e9c..ca02037 100644 --- a/srcs/tools.cpp +++ b/srcs/tools.cpp @@ -10,3 +10,9 @@ void *ft_memset(void *b, int c, size_t len) { *(unsigned char *)(b_cpy + i++) = (unsigned char)c; return ((void *)b); } + +bool isInt(string str) { + for (string::iterator it = str.begin(); it < str.end(); it++) + if (*it < '0' || *it > '9') return false; + return true; +} diff --git a/srcs/webserv.hpp b/srcs/webserv.hpp index f1c3731..d32b285 100644 --- a/srcs/webserv.hpp +++ b/srcs/webserv.hpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -16,11 +17,13 @@ #include #include #include -#include "json/Parser.hpp" -#include "load/Env.hpp" using std::string; using std::cout; using std::strerror; void *ft_memset(void *b, int c, size_t len); +bool isInt(string str); + +#include "json/Parser.hpp" +#include "load/Env.hpp"