Browse Source

exported sockets to Env. fixed get_route and correct_uri. added listen_t struct. removed ipv6 parts.

master
nicolas-arnaud 2 years ago
parent
commit
a2d4e88c96
  1. 7
      default.json
  2. 2
      includes/Env.hpp
  3. 4
      includes/Route.hpp
  4. 6
      includes/Server.hpp
  5. 21
      includes/Socket.hpp
  6. 6
      includes/webserv.hpp
  7. 42
      srcs/load/Env.cpp
  8. 53
      srcs/load/Route.cpp
  9. 63
      srcs/load/Server.cpp
  10. 40
      srcs/load/Socket.cpp
  11. 10
      srcs/tools.cpp

7
default.json

@ -4,12 +4,12 @@
"servers": [ "servers": [
{ {
"server_name": "localhost", "server_name": "localhost",
"listens": ["80", "localhost:80", "localhost", "[::]:443"], "listens": ["localhost:8080", "localhost"],
"return": "301 https://$host$uri" "return": "301 https://$host$uri"
}, },
{ {
"server_name": "localhost", "server_name": "localhost",
"listens": ["8080"], "listens": ["192.168.62.61:8080"],
"root": "./public", "root": "./public",
"indexs": ["index.html"], "indexs": ["index.html"],
"locations": "locations":
@ -21,7 +21,8 @@
}, },
"img/": "img/":
{ {
"root": "images/" "root": "images/",
"autoindex": true
} }
} }

2
includes/Env.hpp

@ -3,9 +3,11 @@
class Env { class Env {
std::vector<Server *> _servers; std::vector<Server *> _servers;
std::vector<Socket *> _sockets;
public: public:
Env(JSONNode *conf); Env(JSONNode *conf);
void set_fds(); void set_fds();
void refresh(); void refresh();
Server *choose_server(Socket *sock, string host);
}; };

4
includes/Route.hpp

@ -3,14 +3,16 @@
class Route { class Route {
protected: protected:
string _location;
string _root; string _root;
string _ret; string _ret;
std::vector<string> _indexs; std::vector<string> _indexs;
bool _autoindex; bool _autoindex;
public: public:
Route(JSONNode *datas); Route(string location, JSONNode *datas);
~Route(void); ~Route(void);
string getLocation(void);
string getRoot(void); string getRoot(void);
string getReturn(void); string getReturn(void);
std::vector<string> getIndexs(void); std::vector<string> getIndexs(void);

6
includes/Server.hpp

@ -3,13 +3,11 @@
class Server : public Route { class Server : public Route {
string _name; string _name;
std::vector<Socket *> _sockets;
std::map<string, Route *> _routes; std::map<string, Route *> _routes;
public: public:
std::vector<listen_t> _listens;
Server(JSONNode *server); Server(JSONNode *server);
~Server(); ~Server();
void set_fds(); std::vector<Socket *> get_sockets(JSONNode *server);
void refresh();
Route *get_route(string uri); Route *get_route(string uri);
}; };

21
includes/Socket.hpp

@ -2,33 +2,22 @@
#include "webserv.hpp" #include "webserv.hpp"
class Socket { class Socket {
Server *_server;
string _ip;
int _port;
int _master_socket; int _master_socket;
struct sockaddr_in _address;
int _clients_amount; int _clients_amount;
std::vector<int> _clients; std::vector<int> _clients;
public: public:
struct sockaddr_in _address;
listen_t _listen;
static fd_set _readfds; static fd_set _readfds;
static int _max_fd; static int _max_fd;
static int _min_fd; static int _min_fd;
static int _amount; static int _amount;
Socket(Server *server, string def); Socket(listen_t listen);
~Socket(); ~Socket();
int launch(); int launch();
void set_fds(); void set_fds();
void refresh(); void refresh(Env *env);
void answer(int fd, string request); void answer(Env *env, int fd, string request);
void send_answer(int fd, string msg); 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;
}
*/
}; };

6
includes/webserv.hpp

@ -41,9 +41,15 @@ class JSONNode;
typedef std::map<string, JSONNode *> JSONObject; typedef std::map<string, JSONNode *> JSONObject;
typedef std::vector<JSONNode *> JSONList; typedef std::vector<JSONNode *> JSONList;
typedef struct listen_s {
string ip;
int port;
} listen_t;
void *ft_memset(void *b, int c, size_t len); void *ft_memset(void *b, int c, size_t len);
bool isInt(string str); bool isInt(string str);
std::vector<string> split(string str, char delim); std::vector<string> split(string str, char delim);
listen_t get_listen_t(string listen);
#include "Nodes.hpp" #include "Nodes.hpp"
#include "Token.hpp" #include "Token.hpp"

42
srcs/load/Env.cpp

@ -10,6 +10,8 @@ Env::Env(JSONNode *conf) {
it < servers.end(); it++) { it < servers.end(); it++) {
Server *server = new Server(*it); Server *server = new Server(*it);
_servers.push_back(server); _servers.push_back(server);
std::vector<Socket *> tmp_s = server->get_sockets(*it);
_sockets.insert(_sockets.end(), tmp_s.begin(), tmp_s.end());
// delete *it; // delete *it;
cout << th[i] << " server launched.\n"; cout << th[i] << " server launched.\n";
i++; i++;
@ -19,16 +21,46 @@ Env::Env(JSONNode *conf) {
} }
delete conf; delete conf;
} }
Server *Env::choose_server(Socket *sock, string host) {
std::vector<Server *> exact;
std::vector<Server *> 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<Server *>::iterator sit = _servers.begin();
sit < _servers.end(); sit++) {
std::vector<listen_t> serv_listens = (*sit)->_listens;
for (std::vector<listen_t>::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() { void Env::set_fds() {
for (std::vector<Server *>::iterator it = _servers.begin(); for (std::vector<Socket *>::iterator it = _sockets.begin();
it < _servers.end(); it++) { it < _sockets.end(); it++) {
(*it)->set_fds(); (*it)->set_fds();
} }
} }
void Env::refresh() { void Env::refresh() {
for (std::vector<Server *>::iterator it = _servers.begin(); for (std::vector<Socket *>::iterator it = _sockets.begin();
it < _servers.end(); it++) { it < _sockets.end(); it++) {
(*it)->refresh(); (*it)->refresh(this);
} }
} }

53
srcs/load/Route.cpp

@ -1,16 +1,18 @@
#include "webserv.hpp" #include "webserv.hpp"
Route::Route(JSONNode *datas) { Route::Route(string location, JSONNode *datas) : _location(location) {
JSONObject object = datas->obj(); JSONObject object = datas->obj();
if (object["root"]) JSONNode *tmp;
_root = object["root"]->str(); if ((tmp = object["root"]))
if (object["return"]) _root = tmp->str();
_ret = object["return"]->str(); if ((tmp = object["return"]))
if (object["autoindex"]) _ret = tmp->str();
_autoindex = object["autoindex"]->boo(); if ((tmp = object["autoindex"]))
if (object["indexs"]) { _autoindex = tmp->boo();
JSONList indexs = object["indexs"]->lst(); if ((tmp = object["indexs"])) {
for (JSONList::iterator it = indexs.begin(); it < indexs.end(); it++) { JSONList indexs = tmp->lst();
for (JSONList::iterator it = indexs.begin();
it < indexs.end(); it++) {
_indexs.push_back((*it)->str()); _indexs.push_back((*it)->str());
} }
} }
@ -18,6 +20,7 @@ Route::Route(JSONNode *datas) {
Route::~Route(void) {} Route::~Route(void) {}
string Route::getLocation(void) {return _location; }
string Route::getRoot(void) { return _root; } string Route::getRoot(void) { return _root; }
string Route::getReturn(void) { return _ret; } string Route::getReturn(void) { return _ret; }
std::vector<string> Route::getIndexs(void) { return _indexs; } std::vector<string> Route::getIndexs(void) { return _indexs; }
@ -52,11 +55,30 @@ string Route::getAutoindex(string uri) {
string Route::correctUri(string uri) { string Route::correctUri(string uri) {
std::stringstream ret; std::stringstream ret;
int slash_pos; //int slash_pos;
string root = _root; //string root = _root;
//int i = 0;
std::vector<string>::iterator it;
std::vector<string>::iterator it2;
cout << "Correcting request: " << uri cout << "Correcting request: " << uri
<< " with root: " << root << "\n"; << " with root: " << _root << "\n";
ret << _root;
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 == "")
it2++;
while (*it == "")
it++;
it2++;
}
while (it2 < uri_split.end()) {
ret << "/" << *(it2++);
}
/*
int i = 0; int i = 0;
while (uri.at(i) == '/') while (uri.at(i) == '/')
i++; i++;
@ -64,9 +86,12 @@ string Route::correctUri(string uri) {
while ((slash_pos = root.find('/')) > 0) { while ((slash_pos = root.find('/')) > 0) {
ret << root.substr(0, slash_pos); ret << root.substr(0, slash_pos);
root.erase(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; ret << uri;
*/
cout << "resutlt: " << ret.str() << "\n"; cout << "resutlt: " << ret.str() << "\n";
return ret.str(); return ret.str();
} }

63
srcs/load/Server.cpp

@ -1,45 +1,52 @@
#include "webserv.hpp" #include "webserv.hpp"
Server::Server(JSONNode *server) : Route(server) { Server::Server(JSONNode *server) : Route("/", server) {
JSONObject datas = server->obj(); JSONObject datas = server->obj();
if (datas["server_name"]) if (datas["server_name"])
_name = datas["server_name"]->str(); _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"]) { if (datas["locations"]) {
JSONObject locations = datas["locations"]->obj(); JSONObject locations = datas["locations"]->obj();
for (JSONObject::iterator it = locations.begin(); it != locations.end(); for (JSONObject::iterator it = locations.begin(); it != locations.end();
it++) { it++) {
Route *route = new Route((*it).second); Route *route = new Route((*it).first, (*it).second);
_routes[(*it).first] = route; _routes[(*it).first] = route;
} }
} }
} }
Server::~Server(void) { cout << "Server destroyed!\n"; } std::vector<Socket *> Server::get_sockets(JSONNode *server) {
JSONObject datas = server->obj();
void Server::set_fds(void) { std::vector<Socket *> ret;
for (std::vector<Socket *>::iterator it = _sockets.begin(); listen_t listen;
it < _sockets.end(); it++) { if (datas["listens"]) {
(*it)->set_fds(); 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) { Server::~Server(void) { cout << "Server destroyed!\n"; }
for (std::vector<Socket *>::iterator it = _sockets.begin();
it < _sockets.end(); it++) {
(*it)->refresh();
}
}
Route *Server::get_route(string uri) { Route *Server::get_route(string uri) {
cout << uri << "\n"; cout << uri << "\n";
@ -50,10 +57,10 @@ Route *Server::get_route(string uri) {
root = split((*rit).first, '/'); root = split((*rit).first, '/');
std::vector<string>::iterator root_it = root.begin(); std::vector<string>::iterator root_it = root.begin();
for (std::vector<string>::iterator it = req.begin(); for (std::vector<string>::iterator it = req.begin(); it < req.end();
it < req.end(); it++) { it++) {
if (*it == "") if (*it == "")
continue ; continue;
cout << *it << " - " << *root_it << "\n"; cout << *it << " - " << *root_it << "\n";
if (*it != *(root_it++)) if (*it != *(root_it++))
break; break;

40
srcs/load/Socket.cpp

@ -1,17 +1,7 @@
#include "webserv.hpp" #include "webserv.hpp"
Socket::Socket(Server *server, string def) : _server(server) { Socket::Socket(listen_t listen) : _listen(listen) {
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());
_clients_amount = 0; _clients_amount = 0;
} }
Socket::~Socket() { Socket::~Socket() {
@ -21,6 +11,9 @@ Socket::~Socket() {
int Socket::launch() { int Socket::launch() {
int opt = 1; int opt = 1;
string ip = _listen.ip;
int port = _listen.port;
_master_socket = socket(AF_INET, SOCK_STREAM, 0); _master_socket = socket(AF_INET, SOCK_STREAM, 0);
if (_master_socket == 0) { if (_master_socket == 0) {
cout << "Socket creation: " << strerror(errno) << "\n"; cout << "Socket creation: " << strerror(errno) << "\n";
@ -33,19 +26,16 @@ int Socket::launch() {
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
if (_ip.at(0) == '[') _address.sin_family = AF_INET;
_address.sin_family = AF_INET6; _address.sin_addr.s_addr = inet_addr(ip.c_str());
else _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)) < if (bind(_master_socket, (struct sockaddr *)&_address, sizeof(_address)) <
0) { 0) {
cout << "Bind: " << strerror(errno) << "\n"; cout << "Bind: " << strerror(errno) << "\n";
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
cout << "Listener " << _ip << " on port " << _port << "\n"; cout << "Listener " << ip << " on port " << port << "\n";
if (listen(_master_socket, 3) < 0) { if (listen(_master_socket, 3) < 0) {
cout << "Listen: " << strerror(errno) << "\n"; cout << "Listen: " << strerror(errno) << "\n";
@ -69,7 +59,7 @@ void Socket::set_fds() {
} }
} }
void Socket::refresh() { void Socket::refresh(Env *env) {
std::vector<int>::iterator it; std::vector<int>::iterator it;
int valread; int valread;
int addrlen = sizeof(_address); int addrlen = sizeof(_address);
@ -101,25 +91,29 @@ void Socket::refresh() {
_clients.erase(it); _clients.erase(it);
} else { } else {
buffer[valread] = '\0'; buffer[valread] = '\0';
answer(*it, buffer); answer(env, *it, buffer);
} }
} }
} }
} }
void Socket::answer(int fd, string request) { void Socket::answer(Env *env, int fd, string request) {
string uri = split(request, ' ').at(1); std::vector<string> lines = split(request, '\n');
string uri = split(lines.at(0), ' ').at(1);
cout << uri << "\n"; cout << uri << "\n";
cout << request << "\n|===|===|===|\n"; cout << request << "\n|===|===|===|\n";
std::stringstream answer; std::stringstream answer;
answer << "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: "; 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); answer << route->getAutoindex(uri);
cout << answer.str() << "\n|===|===|===|\n"; cout << answer.str() << "\n|===|===|===|\n";
send_answer(fd, answer.str()); send_answer(fd, answer.str());
} }
void Socket::send_answer(int fd, string msg) { void Socket::send_answer(int fd, string msg) {
#ifdef __linux__ #ifdef __linux__
send(fd, msg.c_str(), msg.length(), MSG_NOSIGNAL); send(fd, msg.c_str(), msg.length(), MSG_NOSIGNAL);

10
srcs/tools.cpp

@ -27,3 +27,13 @@ std::vector<string> split(string str, char delim) {
} }
return tokens; 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;
}

Loading…
Cancel
Save