diff --git a/includes/Route.hpp b/includes/Route.hpp
index e009456..a406958 100644
--- a/includes/Route.hpp
+++ b/includes/Route.hpp
@@ -4,14 +4,11 @@
class Route {
protected:
Server *_server;
- string _location;
- string _root;
- string _ret;
+ string _location, _root, _ret;
bool _autoindex;
public:
- vec_string _indexs;
- vec_string _allowed_methods;
+ vec_string _indexs, _allowed_methods;
std::map< string, string > _cgi;
int _client_max_body_size;
diff --git a/srcs/load/Env.cpp b/srcs/load/Env.cpp
index 705303e..8a17d8e 100644
--- a/srcs/load/Env.cpp
+++ b/srcs/load/Env.cpp
@@ -25,7 +25,6 @@ Env::~Env() {
*/
Env::Env(JSONNode *conf) {
try {
-
JSONList servers = conf->obj()["servers"]->lst();
for (std::vector< JSONNode * >::iterator it = servers.begin();
it < servers.end(); it++) {
diff --git a/srcs/load/Route.cpp b/srcs/load/Route.cpp
index 73b09b7..4efdb21 100644
--- a/srcs/load/Route.cpp
+++ b/srcs/load/Route.cpp
@@ -51,15 +51,17 @@ string Route::getLocation(void) { return _location; }
string Route::getRoot(void) { return _root; }
string Route::getReturn(void) { return _ret; }
/* |==========|
- * Find either an autoindex or an index into the directory required by request
+ * Generate the autoindex of folder.
+ * If while generating it an index file is found, it return the opened file.
+ * Else it finish generating autoindex and return it finally if autoindex is
+ * enable on this route.
*
- * Input: The uri client asked, the real local path to the directory
- * Output: The file or the autoindex page to display
+ * Input: The uri client asked and the real local path to the directory
+ * Output: The index or the autoindex page to display
*/
string Route::getIndex(string uri, string path) {
- std::stringstream content;
- std::stringstream ret;
+ std::stringstream body, ret;
DIR *dir;
struct dirent *entry;
struct stat info;
@@ -68,9 +70,9 @@ string Route::getIndex(string uri, string path) {
if ((dir = opendir(path.c_str())) == NULL) {
return "";
} else {
- cout << "get index(): path=" << path << "\n";
- content << "
" << path
- << " files :
\n\n";
+ // cout << "get index(): path=" << path << "\n";
+ body << "" << path
+ << " files :
\n\n";
while ((entry = readdir(dir)) != NULL) {
if (entry->d_name[0] == '.')
continue;
@@ -78,21 +80,21 @@ string Route::getIndex(string uri, string path) {
if (entry->d_name == *it)
return (read_file(path + "/" + *it));
}
- content << "- d_name << "\">"
- << entry->d_name << "
\n";
+ body << "- d_name << "\">"
+ << entry->d_name << "
\n";
if (stat(path.c_str(), &info) != 0)
std::cerr << "stat() error on " << path << ": "
<< strerror(errno) << "\n";
}
- content << "
";
+ body << "
";
closedir(dir);
}
if (!_autoindex)
return "";
- cout << "Getting autoindex\n";
+ // cout << "Getting autoindex\n";
ret << "Content-type: text/html \r\n";
- ret << "Content-length: " << content.str().length() << "\r\n";
- ret << "\r\n" << content.str();
+ ret << "Content-length: " << body.str().length() << "\r\n";
+ ret << "\r\n" << body.str();
return ret.str();
}
/* |==========|
@@ -104,24 +106,21 @@ string Route::getIndex(string uri, string path) {
string Route::correctUri(string uri) {
std::stringstream ret;
- vec_string::iterator it;
- vec_string::iterator it2;
-
- ret << "./" << _root;
- vec_string loc_split = split(_location, "/");
- vec_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 == "")
- it2++;
- while (it < loc_split.end() && *it == "")
- it++;
- if (it != loc_split.end())
- it2++;
- }
+ vec_string::iterator loc_word, uri_word;
- while (it2 < uri_split.end()) {
- ret << "/" << *(it2++);
+ vec_string loc_words = split(_location, "/");
+ vec_string uri_words = split(uri, "/");
+ uri_word = uri_words.begin();
+ for (loc_word = loc_words.begin(); loc_word < loc_words.end(); loc_word++) {
+ while (uri_word < uri_words.end() && *uri_word == "")
+ uri_word++;
+ while (loc_word < loc_words.end() && *loc_word == "")
+ loc_word++;
+ if (loc_word != loc_words.end())
+ uri_word++;
}
+ ret << "./" << _root;
+ while (uri_word < uri_words.end())
+ ret << "/" << *(uri_word++);
return ret.str();
}
diff --git a/srcs/load/Server.cpp b/srcs/load/Server.cpp
index 5f25289..27f4398 100644
--- a/srcs/load/Server.cpp
+++ b/srcs/load/Server.cpp
@@ -33,7 +33,6 @@ Server::Server(JSONNode *server) : Route(NULL, "/", server) {
}
}
}
-
/* Get the server name (_server_name)*/
string Server::getName(void) { return _name; }
@@ -46,31 +45,31 @@ string Server::getName(void) { return _name; }
Master *Server::create_master(string str) {
ip_port_t listen = get_ip_port_t(str);
- if (listen.ip.at(0) == '[') {
+ if (listen.ip.at(0) != '[') {
+ try {
+ _listens.push_back(listen);
+ Master *sock = new Master(listen);
+ return (sock);
+ } catch (std::exception &e) {
+ std::cerr << e.what() << '\n';
+ }
+ } else
cout << "Listen: IPv6 isn't supported\n";
- }
- try {
- _listens.push_back(listen);
- Master *sock = new Master(listen);
- return (sock);
- } catch (std::exception &e) {
- std::cerr << e.what() << '\n';
- return NULL;
- }
+ return NULL;
}
/*|===========|
* 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< Master * > Server::get_sockets(JSONNode *server) {
JSONObject datas = server->obj();
std::vector< Master * > ret;
- ip_port_t listen;
Master *tmp;
+ ip_port_t listen;
if (datas["listens"]) {
JSONList listens = datas["listens"]->lst();
for (JSONList::iterator it = listens.begin(); it != listens.end();
@@ -86,27 +85,27 @@ std::vector< Master * > 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) {
- vec_string req = split(uri, "/");
- vec_string root;
- for (std::map< string, Route * >::iterator rit = _routes.begin();
- rit != _routes.end(); rit++) {
- root = split((*rit).first, "/");
- cout << "Route: " << (*rit).first << "\n";
- vec_string::iterator root_it = root.begin();
- for (vec_string::iterator it = req.begin(); it < req.end(); it++) {
- while (it != req.end() && *it == "")
- it++;
- if (*it != *(root_it++))
+ vec_string uri_words, loc_words;
+ uri_words = split(uri, "/");
+ for (std::map< string, Route * >::iterator loc_it = _routes.begin();
+ loc_it != _routes.end(); loc_it++) {
+ loc_words = split((*loc_it).first, "/");
+ vec_string::iterator loc_word = loc_words.begin();
+ for (vec_string::iterator uri_word = uri_words.begin();
+ uri_word < uri_words.end(); uri_word++) {
+ while (uri_word != uri_words.end() && *uri_word == "")
+ uri_word++;
+ if (*uri_word != *(loc_word++))
break;
- while (root_it != root.end() && *root_it == "")
- root_it++;
- if (root_it == root.end())
- return ((*rit).second);
+ while (loc_word != loc_words.end() && *loc_word == "")
+ loc_word++;
+ if (loc_word == loc_words.end())
+ return ((*loc_it).second);
}
}
return this;
diff --git a/srcs/sock/Client.cpp b/srcs/sock/Client.cpp
index d1bf8fc..3d9e7b4 100644
--- a/srcs/sock/Client.cpp
+++ b/srcs/sock/Client.cpp
@@ -37,14 +37,10 @@ bool Client::getHeader(Env *env, string paquet) {
else
paquet.clear();
_header += *it + (it + 1 != lines.end() ? "\r\n" : "");
- if (_header.find("\r\n\r\n") != string::npos) {
- print_block("HEADER: ", _header);
- if (!this->parseHeader(env))
- return false;
- if (paquet.length() > 0)
- return getBody(paquet);
- return true;
- }
+ if (_header.find("\r\n\r\n") != string::npos)
+ return !this->parseHeader(env)
+ ? false
+ : (paquet.length() > 0 ? getBody(paquet) : true);
}
return false;
}
@@ -54,25 +50,19 @@ bool Client::getBody(string paquet) {
vec_string::iterator it;
for (it = lines.begin(); it < lines.end(); it++) {
- // cout << "line: " << *it << "\n";
if ((*it).length() && _len <= 0 &&
header_pick("Transfer-Encoding:", 0) == "chunked") {
_len = std::strtol((*it).c_str(), 0, 16) + 2;
_last_chunk = _len == 2 ? true : false;
- // +2 for the final \r\n closing chunk
} else if (_len > 0 || it != lines.begin()) {
_body += *it + "\r\n";
_len -= ((*it).length() + 2);
}
}
- if (_body.size())
- _body.resize(_body.length() - 2);
+ // if (_body.size())
+ _body.resize(_body.length() - 2);
_len += 2;
- if (_last_chunk && _len == 0) {
- print_block("BODY: ", _body);
- return true;
- }
- return false;
+ return (_last_chunk && _len == 0) ? true : false;
}
bool Client::parseHeader(Env *env) {
@@ -104,66 +94,55 @@ bool Client::parseHeader(Env *env) {
if (len != "") {
_len = std::atoi(len.c_str());
_last_chunk = true;
- if (_len > _route->_client_max_body_size) {
- send_error(413);
- return false;
- }
+ if (_len > _route->_client_max_body_size)
+ return (send_error(413), false);
}
return true;
}
bool Client::check_method(void) {
vec_string allowed;
- if (_method != "GET" && _method != "POST" && _method != "DELETE" &&
- _method != "PUT")
- send_error(405);
- else if ((allowed = _route->_allowed_methods).size() > 0) {
- if (std::find(allowed.begin(), allowed.end(), _method) == allowed.end())
- send_error(405);
- else
- return true;
- } else if ((allowed = _server->_allowed_methods).size() > 0) {
- if (std::find(allowed.begin(), allowed.end(), _method) == allowed.end())
- send_error(405);
- else
- return true;
- } else
+ if ((allowed = _route->_allowed_methods).size() > 0 ||
+ (allowed = _server->_allowed_methods).size() > 0)
+ return std::find(allowed.begin(), allowed.end(), _method) <
+ allowed.end()
+ ? true
+ : false;
+ else if (_method == "GET" || _method == "POST" || _method != "DELETE" ||
+ _method != "PUT")
return (true);
return (false);
}
string Client::header_pick(string key, size_t id) {
- if (_request[key].size() <= id)
- return "";
- return _request[key].at(id);
+ return _request[key].size() <= id ? "" : _request[key].at(id);
}
void Client::answer(void) {
- cout << "Method: " << _method << "\n";
- cout << "URI: " << _uri << "\n";
- cout << "Host: " << _host << "\n";
+ print_block("Header: ", _header);
+ print_block("Body: ", _body);
string ret;
string path = _route->correctUri(_uri);
- string cgi =
- _route->_cgi.size()
- ? _route->_cgi[get_extension(path)]
- : (_server->_cgi.size() ? _server->_cgi[get_extension(path)] : "");
+ string cgi = _route->_cgi.size() ? _route->_cgi[get_extension(path)]
+ : _server->_cgi.size() ? _server->_cgi[get_extension(path)]
+ : "";
cout << "Path: " << path << "\n";
if (_method == "PUT")
create_file(path);
- if (cgi == "") {
- if (check_method()) {
- if ((ret = _route->getIndex(_uri, path)) == "")
- ret = read_file(path);
- if (ret == "404")
- send_error(404);
- else if (ret == "403")
- send_error(403);
- else
- send_answer("HTTP/1.1 200 OK\r\n" + ret);
- }
- } else
+ if (cgi != "")
send_cgi(cgi, path);
+ else if (!check_method())
+ send_error(405);
+ else {
+ if ((ret = _route->getIndex(_uri, path)) == "")
+ ret = read_file(path);
+ if (ret == "404")
+ send_error(404);
+ else if (ret == "403")
+ send_error(403);
+ else
+ send_answer("HTTP/1.1 200 OK\r\n" + ret);
+ }
}
void Client::create_file(string path) {
@@ -186,8 +165,7 @@ void Client::send_cgi(string cgi, string path) {
if (!std::ifstream(cgi.c_str()).good())
return send_error(404);
pipe(fd);
- int pid = fork();
- if (pid == 0) {
+ if (fork() == 0) {
const char **args = new const char *[cgi.length() + path.length() + 2];
args[0] = cgi.c_str();
args[1] = path.c_str();
@@ -202,7 +180,7 @@ void Client::send_cgi(string cgi, string path) {
execve(cgi.c_str(), (char **)args, (char **)env);
}
close(fd[1]);
- waitpid(pid, &status, 0);
+ waitpid(-1, &status, 0);
char buffer[10000];
buffer[read(fd[0], buffer, 10000)] = 0;
ret = string(buffer);
diff --git a/srcs/sock/Master.cpp b/srcs/sock/Master.cpp
index dcc03f7..8e5ac28 100644
--- a/srcs/sock/Master.cpp
+++ b/srcs/sock/Master.cpp
@@ -16,34 +16,27 @@ Master::~Master(void) {
*/
Master::Master(ip_port_t list) : _listen(list) {
- int opt = 1;
+ int x = 1, port = _listen.port;
string ip = _listen.ip;
- int port = _listen.port;
_fd = socket(AF_INET, SOCK_STREAM, 0);
if (_fd == 0)
throw std::runtime_error("socket() error" + string(strerror(errno)));
- int opt_ret =
- setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
- if (opt_ret < 0) {
- close(_fd);
+ if (setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&x, sizeof(x)) < 0 &&
+ close(_fd) <= 0)
throw std::runtime_error("setsockopt() error: " +
string(strerror(errno)));
- }
_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) {
- close(_fd);
+ if (bind(_fd, (struct sockaddr *)&_address, sizeof(_address)) &&
+ close(_fd) <= 0)
throw std::runtime_error("bind() error: " + string(strerror(errno)));
- }
- if (listen(_fd, 3) < 0) {
- close(_fd);
+ if (listen(_fd, 3) < 0 && close(_fd) <= 0)
throw std::runtime_error("listen() error: " + string(strerror(errno)));
- }
cout << "New master socket with fd " << _fd << " which listen " << ip << ":"
<< port << "\n";
if (_fd < _min_fd)
@@ -54,14 +47,12 @@ Master::Master(ip_port_t list) : _listen(list) {
void Master::set_fds(void) {
FD_SET(_fd, &_readfds);
- int child_fd;
- for (std::vector< Client * >::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;
+ for (std::vector< Client * >::iterator child = _childs.begin();
+ child < _childs.end(); child++) {
+ FD_SET((*child)->_fd, &_readfds);
+ if ((*child)->_fd > _max_fd)
+ _max_fd = (*child)->_fd;
}
}
/* |==========|
@@ -101,11 +92,8 @@ void Master::refresh(Env *env) {
(socklen_t *)&addrlen);
delete (*it);
_childs.erase(it);
- } else {
- // print_block("Paquet: ", buffer);
- if ((*it)->getHeader(env, buffer))
- (*it)->answer();
- }
+ } else if ((*it)->getHeader(env, buffer))
+ (*it)->answer();
}
}
}
@@ -126,21 +114,19 @@ void Master::refresh(Env *env) {
*/
Server *Master::choose_server(Env *env, string host) {
- std::vector< Server * > exact;
- std::vector< Server * > inrange;
- vec_string ip_listen;
- vec_string ip_required;
+ std::vector< Server * > exact, inrange;
+ vec_string ip_listen, ip_required;
ip_required = split(_listen.ip, ".");
- for (std::vector< Server * >::iterator sit = env->_servers.begin();
- sit < env->_servers.end(); sit++) {
- std::vector< ip_port_t > serv_listens = (*sit)->_listens;
+ for (std::vector< Server * >::iterator server = env->_servers.begin();
+ server < env->_servers.end(); server++) {
+ std::vector< ip_port_t > serv_listens = (*server)->_listens;
for (std::vector< ip_port_t >::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);
+ exact.push_back(*server);
continue;
}
bool is_inrange = true;
@@ -151,22 +137,22 @@ Server *Master::choose_server(Env *env, string host) {
if (*l != *r && *l != "0")
is_inrange = false;
}
- if (is_inrange == true)
- inrange.push_back(*sit);
+ if (is_inrange)
+ inrange.push_back(*server);
}
}
if (exact.size() == 0) {
- for (std::vector< Server * >::iterator sit = inrange.begin();
- sit < inrange.end(); sit++) {
- if (host == (*sit)->getName())
- return *sit;
+ for (std::vector< Server * >::iterator server = inrange.begin();
+ server < inrange.end(); server++) {
+ if (host == (*server)->getName())
+ return *server;
}
return inrange.front();
} else {
- for (std::vector< Server * >::iterator sit = exact.begin();
- sit < exact.end(); sit++) {
- if (host == (*sit)->getName())
- return *sit;
+ for (std::vector< Server * >::iterator server = exact.begin();
+ server < exact.end(); server++) {
+ if (host == (*server)->getName())
+ return *server;
}
return exact.front();
}
diff --git a/srcs/tools.cpp b/srcs/tools.cpp
index 5d8e1db..e7e644f 100644
--- a/srcs/tools.cpp
+++ b/srcs/tools.cpp
@@ -1,14 +1,12 @@
#include "webserv.hpp"
void *ft_memset(void *b, int c, size_t len) {
- size_t i;
unsigned char *b_cpy;
b_cpy = (unsigned char *)b;
- i = 0;
- while (i < len)
- *(unsigned char *)(b_cpy + i++) = (unsigned char)c;
- return ((void *)b);
+ for (size_t i = 0; i < len; i++)
+ *(unsigned char *)(b_cpy + i) = (unsigned char)c;
+ return (b);
}
bool isInt(string str) {
@@ -19,10 +17,10 @@ bool isInt(string str) {
}
vec_string split(string str, string delim) {
- string temp(str);
- string token;
- size_t pos;
- std::vector< std::string > tokens;
+ string temp(str);
+ string token;
+ size_t pos;
+ vec_string tokens;
while ((pos = temp.find(delim)) != string::npos) {
token = temp.substr(0, pos);
@@ -51,6 +49,33 @@ ip_port_t get_ip_port_t(string ip, int port) {
return ret;
}
+string read_file(string path) {
+ struct stat info;
+ if (stat(path.c_str(), &info) != 0) {
+ std::cerr << "stat() error on " << path << ": " << strerror(errno)
+ << "\n";
+ return "404";
+ } else if (S_ISDIR(info.st_mode))
+ return "404";
+
+ std::ifstream file(path.c_str());
+ if (!file.good())
+ return "404";
+
+ string str, body;
+ while (file) {
+ std::getline(file, str);
+ body += str + "\n";
+ }
+
+ std::stringstream ret;
+ ret << "Content-type: " << getMime(path) << "\r\n"
+ << "Content-length: " << body.length() << "\r\n"
+ << "\r\n"
+ << body;
+ return (ret.str());
+}
+
string getMime(string path) {
size_t pos = path.rfind('.');
string extension = (pos == string::npos) ? "txt" : path.substr(pos + 1);
@@ -221,27 +246,3 @@ string getMime(string path) {
else
return ("text/plain");
}
-
-string read_file(string path) {
- string str;
- string content;
- std::stringstream ret;
- struct stat info;
- if (stat(path.c_str(), &info) != 0) {
- std::cerr << "stat() error on " << path << ": " << strerror(errno)
- << "\n";
- return "404";
- } else if (S_ISDIR(info.st_mode))
- return "404";
- std::ifstream file(path.c_str());
- if (!file.good())
- return "404";
- while (file) {
- std::getline(file, str);
- content += str + "\n";
- }
- ret << "Content-type: " << getMime(path) << "\r\n";
- ret << "Content-length: " << content.length() << "\r\n";
- ret << "\r\n" << content;
- return (ret.str());
-}
diff --git a/srcs/webserv.cpp b/srcs/webserv.cpp
index a6514d7..ca3ffad 100644
--- a/srcs/webserv.cpp
+++ b/srcs/webserv.cpp
@@ -1,30 +1,35 @@
#include "webserv.hpp"
fd_set Master::_readfds;
-int Master::_max_fd;
int Master::_min_fd = INT_MAX;
+int Master::_max_fd = 0;
int Master::_amount = 0;
int main(int ac, char **av) {
try {
if (ac > 2)
throw std::runtime_error("Too many arguments");
+
std::string config_file = "default.json";
if (ac == 2)
config_file = av[1];
+
std::ifstream file(config_file.c_str());
if (!file.good())
throw std::runtime_error("File not found");
+
cout << "Parsing configuration file from JSON conf file.\n";
cout << "You must be sure the syntax is correct\n";
JSONParser parser(config_file);
JSONNode *conf = parser.parse();
+
cout << "Initialization of server...\n";
Env env(conf);
while (1)
env.cycle();
} catch (const std::exception &e) {
std::cerr << e.what() << '\n';
+ return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}