diff --git a/.gitignore b/.gitignore index 2a4ddb9..8668e2b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ * +!srcs/*/ !srcs/*/*.cpp !srcs/*/*.hpp !srcs/*.hpp diff --git a/Makefile b/Makefile index 420352c..a618b2a 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,14 @@ NAME= server -SRCS= srcs/server.cpp srcs/tools.cpp +SRCS= srcs/webserv.cpp srcs/tools.cpp OBJS= $(SRCS:.cpp=.o) CXX=c++ -CXXFLAGS= -g -Werror -Wextra -Wall -std=c++98 +CXXFLAGS= -Werror -Wextra -Wall -std=c++98 all : $(NAME) $(NAME): $(OBJS) - $(CXX) -g $(OBJS) -o $(NAME) + $(CXX) $(OBJS) -o $(NAME) clean: rm -rf $(OBJS) diff --git a/srcs/json/Parser.hpp b/srcs/json/Parser.hpp index a024071..af4990b 100644 --- a/srcs/json/Parser.hpp +++ b/srcs/json/Parser.hpp @@ -3,8 +3,6 @@ class JSONParser { std::fstream file; - JSONNode *root; - JSONNode *current; Tokenizer tokenizer; public: diff --git a/srcs/json/Token.hpp b/srcs/json/Token.hpp index 43a3ccd..d639e25 100644 --- a/srcs/json/Token.hpp +++ b/srcs/json/Token.hpp @@ -92,8 +92,7 @@ class Tokenizer { Token getToken() { char c; if (file.eof()) { - cout << "Exhaused tokens" - << "\n"; + cout << "Exhaused tokens" << "\n"; // throw std::exception("Exhausted tokens"); } prevPos = file.tellg(); diff --git a/srcs/load/Env.hpp b/srcs/load/Env.hpp new file mode 100644 index 0000000..5753018 --- /dev/null +++ b/srcs/load/Env.hpp @@ -0,0 +1,23 @@ +#include "../webserv.hpp" +#include "Server.hpp" + +class Env { + //int _max_clients; + std::vector _servers; + public: + Env(JSONNode *conf) { + conf->obj()["max_clients"]->nbr(); + JSONList servers = conf->obj()["servers"]->lst(); + int i = 0; + 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); + delete *it; + server->launch(); + cout << th[i] << " server launched."; + i++; + } + delete conf; + } +}; diff --git a/srcs/load/Route.hpp b/srcs/load/Route.hpp new file mode 100644 index 0000000..9ce3355 --- /dev/null +++ b/srcs/load/Route.hpp @@ -0,0 +1,12 @@ +#include "../webserv.hpp" + +class Route { + string _root; + string _ret; + std::vector _indexs; + bool _autoindex; + public: + Route(); + ~Route(); + +}; diff --git a/srcs/load/Server.hpp b/srcs/load/Server.hpp new file mode 100644 index 0000000..a85a04f --- /dev/null +++ b/srcs/load/Server.hpp @@ -0,0 +1,127 @@ +#include "../webserv.hpp" +#include "Route.hpp" + +class Server { + string _name; + std::vector _listens; + int _port; + std::map _routes; + + public: + Server(JSONNode *server) { + JSONObject datas = server->obj(); + _name = datas["server_name"]->str(); + JSONList listens = datas["listens"]->lst(); + for (JSONList::iterator i = listens.begin(); i < listens.end(); i++) + _listens.push_back((*i)->str()); + //_routes["default"] = new Route(datas["root"], datas["return"], datas["index"], datas["autoindex"]); + } + void launch() { + int opt = 1; + int master_socket, addrlen, new_socket, client_socket[30], + max_clients = 30, activity, i, valread, sd; + struct sockaddr_in address; + char buffer[30000]; + char _404[72] = + "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!"; + int max_sd; + fd_set readfds; + + for (i = 0; i < max_clients; i++) + client_socket[i] = 0; + + if ((master_socket = socket(AF_INET, SOCK_STREAM, 0)) == 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); + } + cout << "Listener on port " << _port << "\n"; + + if (listen(master_socket, 3) < 0) { + cout << strerror(errno) << "\n"; + exit(EXIT_FAILURE); + } + + addrlen = sizeof(address); + cout << "Waiting for connections ..." << "\n"; + + while (1) { + FD_ZERO(&readfds); + FD_SET(master_socket, &readfds); + max_sd = master_socket; + + 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/server.cpp b/srcs/server.cpp index 835d3ed..b161aca 100644 --- a/srcs/server.cpp +++ b/srcs/server.cpp @@ -1,20 +1,9 @@ #include "webserv.hpp" -#define PORT 80 +#include "json/Parser.hpp" +#include "load/Env.hpp" int main(int ac, char **av) { Env env; - int opt = 1; - int master_socket, addrlen, new_socket, client_socket[30], - max_clients = 30, activity, i, valread, sd; - int max_sd; - struct sockaddr_in address; - - char buffer[30000]; - - fd_set readfds; - - char _404[72] = - "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!"; if (ac > 1) { @@ -26,108 +15,17 @@ int main(int ac, char **av) { cout << "Setting environment...\n"; env.max_clients = conf->obj()["max_clients"]->nbr(); JSONList servers = conf->obj()["servers"]->lst(); - for (std::vector::iterator i = servers.begin(); - i < servers.end(); i++) { - JSONObject datas = (*i)->obj(); - Server *server = - new Server(datas["server_name"]->str(), datas["root"]->str(), - datas["return"]->str(), datas["listen"], - datas["index"], datas["location"]); - delete *i; + int i = 0; + 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); + delete *it; + server->launch(); + cout << th[i] << " server launched."; + i++; } delete conf; - cout << "Environment setup.\n"; - } - - for (i = 0; i < max_clients; i++) - client_socket[i] = 0; - - if ((master_socket = socket(AF_INET, SOCK_STREAM, 0)) == 0) { - std::cout << std::strerror(errno) << std::endl; - exit(EXIT_FAILURE); - } - - if (setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, - sizeof(opt)) < 0) { - std::cout << std::strerror(errno) << std::endl; - 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) { - std::cout << std::strerror(errno) << std::endl; - exit(EXIT_FAILURE); - } - std::cout << "Listener on port " << PORT << std::endl; - - if (listen(master_socket, 3) < 0) { - std::cout << std::strerror(errno) << std::endl; - exit(EXIT_FAILURE); - } - - addrlen = sizeof(address); - std::cout << "Waiting for connections ..." << std::endl; - - while (1) { - FD_ZERO(&readfds); - FD_SET(master_socket, &readfds); - max_sd = master_socket; - - 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)) - std::cout << std::strerror(errno) << std::endl; - - if (FD_ISSET(master_socket, &readfds)) { - if ((new_socket = accept(master_socket, (struct sockaddr *)&address, - (socklen_t *)&addrlen)) < 0) { - std::cout << std::strerror(errno) << std::endl; - exit(EXIT_FAILURE); - } -#ifdef __APPLE__ - fcntl(new_socket, F_GETNOSIGPIPE); -#endif - std::cout << "New connection, socket fd is " << new_socket - << ", ip is : " << inet_ntoa(address.sin_addr) - << ", port : " << ntohs(address.sin_port) << std::endl; - - for (i = 0; i < max_clients; i++) { - if (client_socket[i] == 0) { - client_socket[i] = new_socket; - std::cout << "Adding to list of sockets as " << i - << std::endl; - 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); - std::cout << "Host disconnected, ip " - << inet_ntoa(address.sin_addr) << ", port " - << ntohs(address.sin_port) << std::endl; - close(sd); - client_socket[i] = 0; - } else - send(sd, _404, strlen(_404), MSG_NOSIGNAL); - } - } } return (0); } diff --git a/srcs/webserv.cpp b/srcs/webserv.cpp index 8da4649..90de446 100644 --- a/srcs/webserv.cpp +++ b/srcs/webserv.cpp @@ -1 +1,16 @@ #include "webserv.hpp" + +int main(int ac, char **av) { + + if (ac > 1) { + + cout << "Parsing configuration file...\n"; + JSONParser parser(av[1]); + JSONNode *conf = parser.parse(); + cout << "Configuration parsed.\n"; + + cout << "Setting environment...\n"; + Env env(conf); + } + return (0); +} diff --git a/srcs/webserv.hpp b/srcs/webserv.hpp index 224ff85..f1c3731 100644 --- a/srcs/webserv.hpp +++ b/srcs/webserv.hpp @@ -1,6 +1,4 @@ #pragma once -#include "json/Parser.hpp" - #include #include #include @@ -18,32 +16,11 @@ #include #include #include +#include "json/Parser.hpp" +#include "load/Env.hpp" -class Route { - std::vector _location; - std::vector _index; - std::string _root; - - public: - Route(std::string location, std::string root, std::string index); - ~Route(); -}; - -class Server { - unsigned int _port; - std::string _server_name; - std::vector *_routes; - - public: - Server(std::string name, std::string root, std::string return, - JSONNode *listens, JSONNode *indexs, JSONNode *locations); - ~Server(); -}; - -class Env { - public: - std::vector *servers; - int max_clients; -}; +using std::string; +using std::cout; +using std::strerror; void *ft_memset(void *b, int c, size_t len);