diff --git a/Makefile b/Makefile index d59aeba..4ec0e1c 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ NAME= server SRCS= srcs/webserv.cpp srcs/tools.cpp srcs/load/Env.cpp srcs/load/Server.cpp \ - srcs/load/Socket.cpp srcs/load/Route.cpp \ + srcs/load/Route.cpp srcs/sock/Master.cpp srcs/sock/Client.cpp \ srcs/json/Nodes.cpp srcs/json/Token.cpp srcs/json/Parser.cpp OBJS= $(SRCS:.cpp=.o) CXX=c++ diff --git a/includes/Client.hpp b/includes/Client.hpp new file mode 100644 index 0000000..c96cbeb --- /dev/null +++ b/includes/Client.hpp @@ -0,0 +1,24 @@ +#pragma once +#include "webserv.hpp" + +typedef std::map< string, std::vector< string > > request_t; + +class Client { + int _fd; + Master *_parent; + string _header; + string _content; + request_t _request; + + public: + Client(int fd, Master *parent); + ~Client(void); + bool getRequest(string paquet); + bool parseHeader(); + int answer(Env *env); + void call_cgi(string cgi, string path); + void send_404(); + void send_answer(string msg); + bool waitHeader(); + friend class Master; +}; diff --git a/includes/Env.hpp b/includes/Env.hpp index 3c3100a..569b452 100644 --- a/includes/Env.hpp +++ b/includes/Env.hpp @@ -3,11 +3,11 @@ class Env { public: - std::vector _servers; - std::vector _sockets; + std::vector< Server * > _servers; + std::vector< Master * > _masters; Env(JSONNode *conf); + void cycle(void); void set_fds(void); void refresh(void); - Server *choose_server(Socket *sock, string host); - ~Env(); + ~Env(void); }; diff --git a/includes/Master.hpp b/includes/Master.hpp new file mode 100644 index 0000000..9e1c9d2 --- /dev/null +++ b/includes/Master.hpp @@ -0,0 +1,25 @@ +#pragma once +#include "webserv.hpp" + +class Master { + // int _clients_amount; + int _fd; + std::vector< Client * > _childs; + struct sockaddr_in _address; + + public: + Master(listen_t listen); + Master(int fd, Master *parent); + ~Master(void); + + int launch(void); + void set_fds(void); + void refresh(Env *env); + Server *choose_server(Env *env, string host); + + listen_t _listen; + static fd_set _readfds; + static int _max_fd; + static int _min_fd; + static int _amount; +}; diff --git a/includes/Route.hpp b/includes/Route.hpp index 195863f..1de28f2 100644 --- a/includes/Route.hpp +++ b/includes/Route.hpp @@ -4,25 +4,25 @@ class Route { protected: Server *_server; - string _location; - string _root; - string _ret; - bool _autoindex; + string _location; + string _root; + string _ret; + bool _autoindex; public: - std::vector _indexs; - std::vector _headers; - std::map _cgi; + std::vector< string > _indexs; + std::vector< string > _headers; + std::map< string, string > _cgi; Route(Server *server, string location, JSONNode *datas); ~Route(void); - string getLocation(void); - string getRoot(void); - string getReturn(void); - std::vector getIndexsLst(void); - std::vector getHeadersLst(void); - Server *getServer(void); - string getIndex(string uri, string path); - string correctUri(string uri); - friend class Socket; + string getLocation(void); + string getRoot(void); + string getReturn(void); + std::vector< string > getIndexsLst(void); + std::vector< string > getHeadersLst(void); + Server *getServer(void); + string getIndex(string uri, string path); + string correctUri(string uri); + friend class Socket; }; diff --git a/includes/Server.hpp b/includes/Server.hpp index 3040440..1137582 100644 --- a/includes/Server.hpp +++ b/includes/Server.hpp @@ -2,13 +2,14 @@ #include "webserv.hpp" class Server : public Route { - string _name; - std::map _routes; + string _name; + std::map< string, Route * > _routes; + public: - std::vector _listens; + std::vector< listen_t > _listens; Server(JSONNode *server); ~Server(void); - std::vector get_sockets(JSONNode *server); - Route *choose_route(string uri); - string getName(void); + std::vector< Master * > get_sockets(JSONNode *server); + Route *choose_route(string uri); + string getName(void); }; diff --git a/includes/Socket.hpp b/includes/Socket.hpp deleted file mode 100644 index 819bd4d..0000000 --- a/includes/Socket.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include "webserv.hpp" - -class Socket { - int _fd; - //int _clients_amount; - Socket *_parent; - std::vector _childs; - struct sockaddr_in _address; - string _header; - string _content; - std::map > _request; - - bool getRequest(string paquet); - bool parseHeader(); - int answer(Env *env); - void send_answer(string msg); - bool waitHeader(); - Server *choose_server(Env *env, string host); - public: - Socket(listen_t listen); - Socket(int fd, Socket *parent); - ~Socket(void); - - listen_t _listen; - static fd_set _readfds; - static int _max_fd; - static int _min_fd; - static int _amount; - - int launch(void); - void set_fds(void); - void refresh(Env *env); -}; diff --git a/includes/webserv.hpp b/includes/webserv.hpp index 6f032ce..dd5cbc9 100644 --- a/includes/webserv.hpp +++ b/includes/webserv.hpp @@ -1,5 +1,7 @@ #pragma once +#define DEBUG 0 + #include #include #include @@ -11,6 +13,7 @@ #include #include #include + #include #include #include @@ -26,38 +29,39 @@ #include #include -#define DEBUG 0 - using std::cout; using std::strerror; using std::string; typedef struct listen_s { string ip; - int port; + int port; } listen_t; +class JSONNode; class Env; class Server; -class Socket; class Route; -class JSONNode; +class Master; +class Client; + +typedef std::map< string, JSONNode * > JSONObject; +typedef std::vector< JSONNode * > JSONList; -typedef std::map JSONObject; -typedef std::vector JSONList; +void *ft_memset(void *b, int c, size_t len); +bool isInt(string str); +std::vector< string > split(string str, char delim); +listen_t get_listen_t(string listen); +string getMime(string path); +string get_extension(string str); +string read_file(string path); -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); -string getMime(string path); -string get_extension(string str); -string read_file(string path); +#include "Client.hpp" +#include "Master.hpp" #include "Nodes.hpp" #include "Token.hpp" #include "Parser.hpp" #include "Route.hpp" -#include "Socket.hpp" #include "Server.hpp" #include "Env.hpp" diff --git a/public/images/file b/public/images/file new file mode 100644 index 0000000..e69de29 diff --git a/srcs/load/Env.cpp b/srcs/load/Env.cpp index c728434..f1ab64f 100644 --- a/srcs/load/Env.cpp +++ b/srcs/load/Env.cpp @@ -10,27 +10,39 @@ Env::Env(JSONNode *conf) { try { JSONList servers = conf->obj()["servers"]->lst(); - for (std::vector::iterator it = servers.begin(); + for (std::vector< JSONNode * >::iterator it = servers.begin(); 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()); + std::vector< Master * > tmp_s = server->get_sockets(*it); + _masters.insert(_masters.end(), tmp_s.begin(), tmp_s.end()); } } catch (std::exception &e) { cout << e.what(); } delete conf; } - +void Env::cycle(void) { + FD_ZERO(&Master::_readfds); + Master::_max_fd = Master::_min_fd; + cout << "==> Check sockets still alive to listen\n"; + set_fds(); + cout << "|===||===| Waiting some HTTP request... |===||===|\n"; + int activity = select(Master::_max_fd + Master::_amount, + &(Master::_readfds), NULL, NULL, NULL); + if ((activity < 0) && (errno != EINTR)) + cout << "Select: " << strerror(errno) << "\n"; + cout << "==> Handle requests and answers:\n"; + refresh(); +} /*|=======================| * Append each master_sockets and their clients to list of fds SELECT must look * at. */ void Env::set_fds(void) { - for (std::vector::iterator it = _sockets.begin(); - it < _sockets.end(); it++) + for (std::vector< Master * >::iterator it = _masters.begin(); + it < _masters.end(); it++) (*it)->set_fds(); } @@ -40,8 +52,8 @@ void Env::set_fds(void) { */ void Env::refresh(void) { - for (std::vector::iterator it = _sockets.begin(); - it < _sockets.end(); it++) + for (std::vector< Master * >::iterator it = _masters.begin(); + it < _masters.end(); it++) (*it)->refresh(this); } @@ -51,12 +63,12 @@ void Env::refresh(void) { * The destructor call all servers and sockets destructors. */ Env::~Env() { - for (std::vector::iterator it = _servers.begin(); + for (std::vector< Server * >::iterator it = _servers.begin(); it < _servers.end(); it++) { delete *it; } - for (std::vector::iterator it = _sockets.begin(); - it < _sockets.end(); it++) { + for (std::vector< Master * >::iterator it = _masters.begin(); + it < _masters.end(); it++) { delete *it; } } diff --git a/srcs/load/Route.cpp b/srcs/load/Route.cpp index db983bb..15da3d0 100644 --- a/srcs/load/Route.cpp +++ b/srcs/load/Route.cpp @@ -3,7 +3,7 @@ Route::Route(Server *server, string location, JSONNode *datas) : _server(server), _location(location) { JSONObject object = datas->obj(); - JSONNode *tmp; + JSONNode *tmp; if ((tmp = object["root"])) _root = tmp->str(); if ((tmp = object["return"])) @@ -24,29 +24,29 @@ Route::Route(Server *server, string location, JSONNode *datas) } } if ((tmp = object["cgi"])) { - JSONObject cgis = tmp->obj(); - for (JSONObject::iterator it = cgis.begin(); it != cgis.end(); it++) { - _cgi[(*it).first] = (*it).second->str(); - } - } + JSONObject cgis = tmp->obj(); + for (JSONObject::iterator it = cgis.begin(); it != cgis.end(); it++) { + _cgi[(*it).first] = (*it).second->str(); + } + } } Route::~Route(void) {} -string Route::getLocation(void) { return _location; } -string Route::getRoot(void) { return _root; } -string Route::getReturn(void) { return _ret; } -std::vector Route::getIndexsLst(void) { return _indexs; } -std::vector Route::getHeadersLst(void) { return _headers; } +string Route::getLocation(void) { return _location; } +string Route::getRoot(void) { return _root; } +string Route::getReturn(void) { return _ret; } +std::vector< string > Route::getIndexsLst(void) { return _indexs; } +std::vector< string > Route::getHeadersLst(void) { return _headers; } string Route::getIndex(string uri, string path) { - std::stringstream content; - std::stringstream ret; - DIR *dir; - struct dirent *entry; - struct stat info; - std::vector indexs = getIndexsLst(); - std::vector::iterator it; + std::stringstream content; + std::stringstream ret; + DIR *dir; + struct dirent *entry; + struct stat info; + std::vector< string > indexs = getIndexsLst(); + std::vector< string >::iterator it; if ((dir = opendir(path.c_str())) == NULL) return ""; @@ -78,17 +78,17 @@ string Route::getIndex(string uri, string path) { } string Route::correctUri(string uri) { - std::stringstream ret; - std::vector::iterator it; - std::vector::iterator it2; + std::stringstream ret; + std::vector< string >::iterator it; + std::vector< string >::iterator it2; cout << "Correcting request: " << uri << " with root: " << _root << "\n"; ret << "./" << _root; - std::vector loc_split = split(_location, '/'); - std::vector uri_split = split(uri, '/'); + std::vector< string > loc_split = split(_location, '/'); + std::vector< string > uri_split = split(uri, '/'); it2 = uri_split.begin(); for (it = loc_split.begin(); it < loc_split.end(); it++) { - while ( it2 < uri_split.end() && *it2 == "") + while (it2 < uri_split.end() && *it2 == "") it2++; while (it < loc_split.end() && *it == "") it++; @@ -99,7 +99,7 @@ string Route::correctUri(string uri) { while (it2 < uri_split.end()) { ret << "/" << *(it2++); } - + cout << "result: " << ret.str() << "\n"; return ret.str(); } diff --git a/srcs/load/Server.cpp b/srcs/load/Server.cpp index 8019148..e5e7987 100644 --- a/srcs/load/Server.cpp +++ b/srcs/load/Server.cpp @@ -1,12 +1,12 @@ #include "webserv.hpp" - /*|=======================| * Server constructor: - * + * * Input: A server block node given by JSONParser. - * Output: A Server class object and also a Route one as Server herite from Route. - * The Route constructor scrap the routing informations (index, root, autoindex ...) and the Server one the others ones (server_name, sub-routes) + * Output: A Server class object and also a Route one as Server herite from + * Route. The Route constructor scrap the routing informations (index, root, + * autoindex ...) and the Server one the others ones (server_name, sub-routes) */ Server::Server(JSONNode *server) : Route(NULL, "/", server) { JSONObject datas = server->obj(); @@ -22,21 +22,20 @@ Server::Server(JSONNode *server) : Route(NULL, "/", server) { } } - /* Get the server name (_server_name)*/ string Server::getName(void) { return _name; } - /*|=======================| * Create server's defined sockets: * * Input: A server block node from JSONParser. - * Output: A vector containing all the succesfull created sockets using listens from the server block. + * Output: A vector containing all the succesfull created sockets using listens + * from the server block. */ -std::vector Server::get_sockets(JSONNode *server) { - JSONObject datas = server->obj(); - std::vector ret; - listen_t listen; +std::vector< Master * > Server::get_sockets(JSONNode *server) { + JSONObject datas = server->obj(); + std::vector< Master * > ret; + listen_t listen; if (datas["listens"]) { JSONList listens = datas["listens"]->lst(); for (JSONList::iterator it = listens.begin(); it != listens.end(); @@ -48,7 +47,7 @@ std::vector Server::get_sockets(JSONNode *server) { continue; } _listens.push_back(listen); - Socket *sock = new Socket(listen); + Master *sock = new Master(listen); if (sock->launch() == EXIT_SUCCESS) ret.push_back(sock); else @@ -56,7 +55,7 @@ std::vector Server::get_sockets(JSONNode *server) { } } else { listen = get_listen_t("localhost:80"); - Socket *sock = new Socket(listen); + Master *sock = new Master(listen); _listens.push_back(listen); if (sock->launch() == EXIT_SUCCESS) { ret.push_back(sock); @@ -69,18 +68,19 @@ std::vector Server::get_sockets(JSONNode *server) { * Choose the route an uri asked to the server must lead to. * * Intput: The uri asked by the client to the server. - * Output: The route object choosen or the server itself if no location block is adapted. + * Output: The route object choosen or the server itself if no location block is + * adapted. */ Route *Server::choose_route(string uri) { // cout << uri << "\n"; - std::vector req = split(uri, '/'); - std::vector root; - for (std::map::iterator rit = _routes.begin(); + std::vector< string > req = split(uri, '/'); + std::vector< string > root; + for (std::map< string, Route * >::iterator rit = _routes.begin(); rit != _routes.end(); rit++) { root = split((*rit).first, '/'); - std::vector::iterator root_it = root.begin(); + std::vector< string >::iterator root_it = root.begin(); - for (std::vector::iterator it = req.begin(); it < req.end(); + for (std::vector< string >::iterator it = req.begin(); it < req.end(); it++) { if (*it == "") continue; @@ -94,15 +94,14 @@ Route *Server::choose_route(string uri) { return this; } - /*|=======================| -* Server destructor: -* -* delete all routes owned by the server; -*/ + * Server destructor: + * + * delete all routes owned by the server; + */ Server::~Server(void) { - for (std::map::iterator it = _routes.begin(); + for (std::map< string, Route * >::iterator it = _routes.begin(); it != _routes.end(); it++) delete (*it).second; cout << "Server destroyed!\n"; diff --git a/srcs/load/Socket.cpp b/srcs/load/Socket.cpp deleted file mode 100644 index 5fc94da..0000000 --- a/srcs/load/Socket.cpp +++ /dev/null @@ -1,282 +0,0 @@ -#include "webserv.hpp" - -Socket::Socket(listen_t listen) : _listen(listen) {} -Socket::Socket(int fd, Socket *parent) : _fd(fd), _parent(parent) {} -Socket::~Socket(void) { - close(_fd); - cout << "Socket destroyed!\n"; -} - -int Socket::launch(void) { - int opt = 1; - string ip = _listen.ip; - int port = _listen.port; - - _fd = socket(AF_INET, SOCK_STREAM, 0); - if (_fd == 0) { - cout << "Socket creation: " << strerror(errno) << "\n"; - return (EXIT_FAILURE); - } - int opt_ret = - setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)); - if (opt_ret < 0) { - cout << "Sockopt: " << strerror(errno) << "\n"; - return (EXIT_FAILURE); - } - - _address.sin_family = AF_INET; - _address.sin_addr.s_addr = inet_addr(ip.c_str()); - _address.sin_port = htons(port); - - if (bind(_fd, (struct sockaddr *)&_address, sizeof(_address)) < 0) { - cout << "Bind: " << strerror(errno) << "\n"; - return (EXIT_FAILURE); - } - cout << "Listener " << ip << " on port " << port << "\n"; - - if (listen(_fd, 3) < 0) { - cout << "Listen: " << strerror(errno) << "\n"; - return (EXIT_FAILURE); - } - cout << "Master: " << _fd << "\n"; - if (_fd < _min_fd) - _min_fd = _fd; - _amount++; - return (EXIT_SUCCESS); -} - -void Socket::set_fds(void) { - FD_SET(_fd, &_readfds); - - int child_fd; - for (std::vector::iterator it = _childs.begin(); - it < _childs.end(); it++) { - child_fd = (*it)->_fd; - FD_SET(child_fd, &_readfds); - if (child_fd > _max_fd) - _max_fd = child_fd; - } -} - -void Socket::refresh(Env *env) { - int valread; - int addrlen = sizeof(_address); - char buffer[10000]; - if (FD_ISSET(_fd, &_readfds)) { - int new_socket = - accept(_fd, (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); - fcntl(new_socket, F_SETFL, O_NONBLOCK); -#endif - cout << "New connection, socket fd is " << new_socket - << ", ip is : " << inet_ntoa(_address.sin_addr) - << ", port : " << ntohs(_address.sin_port) << "\n"; - _childs.push_back(new Socket(new_socket, this)); - } - int child_fd; - for (std::vector::iterator it = _childs.begin(); - it < _childs.end(); it++) { - child_fd = (*it)->_fd; - if (FD_ISSET(child_fd, &_readfds)) { - valread = read(child_fd, buffer, 10000); - if (valread == 0) { - getpeername(child_fd, (struct sockaddr *)&_address, - (socklen_t *)&addrlen); - cout << "Host disconnected, ip " << inet_ntoa(_address.sin_addr) - << ", port " << ntohs(_address.sin_port) << "\n"; - delete (*it); - _childs.erase(it); - } else { - buffer[valread] = '\0'; - if ((*it)->getRequest(buffer)) - (*it)->answer(env); - } - } - } -} - -Server *Socket::choose_server(Env *env, string host) { - std::vector exact; - std::vector inrange; - std::vector ip_listen; - std::vector ip_required; - // string ip = inet_ntoa(sock->_address.sin_addr); - // int port = ntohs(sock->_address.sin_port); - - // cout << "Which server for " << ip << ":" << port << "?\n"; - cout << "Socket: " << _listen.ip << ":" << _listen.port << "\n"; - ip_required = split(_listen.ip, '.'); - for (std::vector::iterator sit = env->_servers.begin(); - sit < env->_servers.end(); sit++) { - - std::vector serv_listens = (*sit)->_listens; - for (std::vector::iterator it = serv_listens.begin(); - it < serv_listens.end(); it++) { - - if (_listen.port != (*it).port) - continue; - if (_listen.ip == (*it).ip) { - exact.push_back(*sit); - continue; - } - bool is_inrange = true; - ip_listen = split((*it).ip, '.'); - std::vector::iterator r = ip_required.begin(); - for (std::vector::iterator l = ip_listen.begin(); - l < ip_listen.end(); l++) { - if (*l != *r && *l != "0") - is_inrange = false; - } - if (is_inrange == true) - inrange.push_back(*sit); - } - } - if (exact.size() == 0) { - for (std::vector::iterator sit = inrange.begin(); - sit < inrange.end(); sit++) { - if (host == (*sit)->getName()) - return *sit; - } - return inrange.front(); - } else - return exact.front(); -} -bool Socket::parseHeader() { - std::vector lines = split(_header, '\n'); - std::vector line; - if (lines.size() > 0) { - for (std::vector::iterator it = lines.begin() + 1; - it < lines.end(); it++) { - line = split(*it, ' '); - cout << line.at(0) << "scraped from header\n"; - _request[line.at(0)] = - std::vector(line.begin() + 1, line.end()); - } - } - std::vector method = split(lines.at(0), ' '); - if (method.at(0) == "POST" && - _request.find("Content-Length:") == _request.end() && - _request.find("Transfer-Encoding:") == _request.end()) - return false; - _request["Method:"] = method; - return true; -} - -bool Socket::getRequest(string paquet) { - cout << "|===|paquet|===>" << paquet << "|===||\n"; - if (paquet.length() < 1) // HTTPS? - return false; - std::vector lines = split(paquet, '\n'); - long chunk_len = - (_content.length() > 0 && _request["Transfer-Encoding:"].size() && - _request["Transfer-Encoding:"].at(0) == "chunked") - ? std::strtol(lines.at(0).substr(1).c_str(), 0, 16) - : -1; - cout << "Chunk length: " << chunk_len << "\n"; - for (std::vector::iterator it = lines.begin(); it < lines.end(); - it++) { - if (*it == "\r" && _content.length() == 0) - this->parseHeader(); - if (*it != "\r" && _content.length() == 0) - _header += *it + "\n"; - else if (chunk_len == -1 || it != lines.begin()) - _content += *it + "\n"; - } - cout << "Header: \n-|" << _header << "|-\n"; - cout << "Content: \n-|" << _content << "|-\n"; - if (_content.length() > 0) { - _content.resize(_content.length() - 1); - if (_request["Method:"].at(0) == "GET" || - (chunk_len == 0 || - std::strtoul(_request["Content-Length:"].at(0).c_str(), 0, 10) <= - _content.length())) { - cout << "Request received\n"; - return true; - } - } else - _header.resize(_header.length() - 1); - return false; -} - -int Socket::answer(Env *env) { - cout << "Method: " << _request["Method:"].at(0) << "\n"; - cout << "URI: " << _request["Method:"].at(1) << "\n"; - cout << "Host: " << _request["Host:"].at(0) << "\n"; - string ret; - std::stringstream answer; - answer << "HTTP/1.1"; - - Server *server = _parent->choose_server(env, _request["Host:"].at(0)); - Route *route = server->choose_route(_request["Method:"].at(1)); - string method = _request["Method:"].at(0); - std::vector allowed; - if (method != "GET" && method != "POST" && method != "DELETE") - send_answer("HTTP/1.1 405 Method Not Allowed\r\n\r\n"); - else if ((allowed = route->_headers).size() > 0) { - if (std::find(allowed.begin(), allowed.end(), method) == allowed.end()) - send_answer("HTTP/1.1 405 Method Not Allowed\r\n\r\n"); - } else if ((allowed = server->_headers).size() > 0) { - if (std::find(allowed.begin(), allowed.end(), method) == allowed.end()) - send_answer("HTTP/1.1 405 Method Not Allowed\r\n\r\n"); - } - - string path = route->correctUri(_request["Method:"].at(1)); - cout << "Path: " << path << "\n"; - string cgi; - if (route->_cgi.size()) - cgi = route->_cgi[get_extension(path)]; - cout << "Cgi:" << cgi << "\n"; - if (cgi != "") { - int status; - int fd[2]; - pipe(fd); - int pid = fork(); - if (pid == 0) { - const char **args = new const char *[cgi.length() + path.length() + 2]; - args[0] = cgi.c_str(); - args[1] = path.c_str(); - args[2] = NULL; - dup2(fd[1], STDOUT_FILENO); - close(fd[1]); - close(fd[0]); - execve(cgi.c_str(), (char **)args, NULL); - } - close(fd[1]); - waitpid(pid, &status, 0); - cout << "Cgi finished\n"; - char buffer[10000]; - size_t len = read(fd[0], buffer, 10000); - buffer[len] = 0; - ret = string(buffer); - len = ret.length() - ret.find("\r\n\r\n") - 4; - answer << " 200 OK\r\nContent-length: " << len << "\r\n"; - answer << ret; - } else { - ret = route->getIndex(_request["Method:"].at(1), path); - if (ret == "") { - cout << "No index: lf file\n"; - ret = read_file(path); - } - answer << (ret == "" ? " 404 Not Found\r\nContent-length: 0\r\n\r\n" - : " 200 OK\r\n") - << ret; - } - cout << "|===|Answer|===|\n" << answer.str() << "|===|End of answer|===|\n"; - send_answer(answer.str()); - _content = ""; - _header = ""; - return EXIT_SUCCESS; -} - -void Socket::send_answer(string msg) { -#ifdef __linux__ - send(_fd, msg.c_str(), msg.length(), MSG_NOSIGNAL); -#elif __APPLE__ - send(_fd, msg.c_str(), msg.length(), 0); -#endif -} diff --git a/srcs/tools.cpp b/srcs/tools.cpp index 687ec54..f170fec 100644 --- a/srcs/tools.cpp +++ b/srcs/tools.cpp @@ -1,7 +1,7 @@ #include "webserv.hpp" void *ft_memset(void *b, int c, size_t len) { - size_t i; + size_t i; unsigned char *b_cpy; b_cpy = (unsigned char *)b; @@ -18,10 +18,11 @@ bool isInt(string str) { return true; } -std::vector split(string str, char delim) { - std::vector tokens; - std::string token; - std::stringstream ss(str); +std::vector< string > split(string str, char delim) { + std::vector< std::string > tokens; + string token; + std::stringstream ss(str); + while (getline(ss, token, delim)) tokens.push_back(token); return tokens; @@ -29,8 +30,8 @@ std::vector split(string str, char delim) { listen_t get_listen_t(string listen) { listen_t ret; - size_t sep_pos = listen.rfind(':'); - string tmp = listen.substr(0, sep_pos); + 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(); @@ -39,9 +40,9 @@ listen_t get_listen_t(string listen) { } string getMime(string path) { - string extension; size_t pos = path.rfind('.'); - extension = (pos == string::npos) ? "txt" : path.substr(pos + 1); + string extension = (pos == string::npos) ? "txt" : path.substr(pos + 1); + if ((extension == "html") || (extension == "htm") || (extension == "shtml")) return ("text/html"); else if ((extension == "css")) @@ -210,17 +211,17 @@ string getMime(string path) { } string get_extension(string str) { - int dot_pos = str.rfind('.'); - string ret = str.substr(dot_pos); - cout << ret << "\n"; - return ret; + int dot_pos = str.rfind('.'); + string ret = str.substr(dot_pos); + cout << ret << "\n"; + return ret; } string read_file(string path) { - string str; - string content; + string str; + string content; std::stringstream ret; - struct stat info; + struct stat info; if (stat(path.c_str(), &info) != 0 || S_ISDIR(info.st_mode)) { std::cerr << "stat() error on " << path << ": " << strerror(errno) << "\n"; diff --git a/srcs/webserv.cpp b/srcs/webserv.cpp index 8c5c235..1b911f7 100644 --- a/srcs/webserv.cpp +++ b/srcs/webserv.cpp @@ -1,45 +1,28 @@ #include "webserv.hpp" -fd_set Socket::_readfds; -int Socket::_max_fd; -int Socket::_min_fd = INT_MAX; -int Socket::_amount = 0; +fd_set Master::_readfds; +int Master::_max_fd; +int Master::_min_fd = INT_MAX; +int Master::_amount = 0; int main(int ac, char **av) { - if (ac <= 2) { - std::string config = "default.json"; - if (ac == 2){ - std::ifstream file(av[1]); - if (file.good()) - config = av[1]; - else { - std::cout << "Error: " << av[1] << " is not a valid file" << std::endl; - return EXIT_FAILURE; - } - config = av[1]; - } - cout << "Parsing configuration file from JSON conf file.\n"; - cout << "You must be sure the syntax is correct\n"; - JSONParser parser(config); - JSONNode *conf = parser.parse(); - cout << "Initialization of server...\n"; - Env env(conf); + if (ac != 2) { + cout << "Usage:\n./webserv CONF.json\n"; + return EXIT_SUCCESS; + } - while (1) { - FD_ZERO(&Socket::_readfds); - Socket::_max_fd = Socket::_min_fd; - cout << "==> Check sockets still alive to listen\n"; - env.set_fds(); - cout << "|===||===| Waiting some HTTP request... |===||===|\n"; - int activity = select(Socket::_max_fd + Socket::_amount, - &(Socket::_readfds), NULL, NULL, NULL); - if ((activity < 0) && (errno != EINTR)) - cout << "Select: " << strerror(errno) << "\n"; - cout << "==> Handle requests and answers:\n"; - env.refresh(); - } + std::ifstream file(av[1]); + if (!file.good()) { + cout << "Error: " << av[1] << " is not a valid file\n"; + return EXIT_FAILURE; } - else - cout << "Usage:\n./webserv CONF.json\n"; - return (0); + cout << "Parsing configuration file from JSON conf file.\n"; + cout << "You must be sure the syntax is correct\n"; + JSONParser parser(av[1]); + JSONNode *conf = parser.parse(); + cout << "Initialization of server...\n"; + Env env(conf); + while (1) + env.cycle(); + return EXIT_SUCCESS; }