Browse Source

WIP - rework try to handle same ip/port with differents servers

test
nicolas-arnaud 2 years ago
parent
commit
4c626e4b8a
  1. 2
      default.json
  2. 2
      includes/Env.hpp
  3. 6
      includes/Server.hpp
  4. 19
      includes/Socket.hpp
  5. 6
      includes/webserv.hpp
  6. 73
      srcs/load/Env.cpp
  7. 45
      srcs/load/Server.cpp
  8. 35
      srcs/load/Socket.cpp
  9. 14
      srcs/tools.cpp

2
default.json

@ -4,7 +4,7 @@
"servers": [
{
"server_name": "localhost",
"listens": ["80", "localhost:80", "localhost", "[::]:443"],
"listens": ["8080", "localhost:8080", "localhost", "[::]:443"],
"return": "301 https://$host$uri"
},
{

2
includes/Env.hpp

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

6
includes/Server.hpp

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

19
includes/Socket.hpp

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

73
srcs/load/Env.cpp

@ -1,34 +1,57 @@
#include "webserv.hpp"
Env::Env(JSONNode *conf) {
try {
JSONList servers = conf->obj()["servers"]->lst();
int i = 0;
string th[8] = {"first", "second", "third", "fourth",
"fifth", "sixth", "seventh", "eigth"};
for (std::vector<JSONNode *>::iterator it = servers.begin();
it < servers.end(); it++) {
Server *server = new Server(*it);
_servers.push_back(server);
// delete *it;
cout << th[i] << " server launched.\n";
i++;
}
} catch (std::exception &e) {
cout << e.what();
}
delete conf;
try {
JSONList servers = conf->obj()["servers"]->lst();
int i = 0;
string th[8] = {"first", "second", "third", "fourth",
"fifth", "sixth", "seventh", "eigth"};
for (std::vector<JSONNode *>::iterator it = servers.begin();
it < servers.end(); it++) {
Server *server = new Server(*it);
_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;
cout << th[i] << " server launched.\n";
i++;
}
} catch (std::exception &e) {
cout << e.what();
}
delete conf;
}
Server *Env::choose_server(Socket *sock, string host) {
std::vector<Server *> exact;
std::vector<Server *> inrange;
(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 (is_ip_into(sock->_listen.ip, (*it).ip))
}
}
return (exact.at(0));
}
void Env::set_fds() {
for (std::vector<Server *>::iterator it = _servers.begin();
it < _servers.end(); it++) {
(*it)->set_fds();
}
for (std::vector<Socket *>::iterator it = _sockets.begin();
it < _sockets.end(); it++) {
(*it)->set_fds();
}
}
void Env::refresh() {
for (std::vector<Server *>::iterator it = _servers.begin();
it < _servers.end(); it++) {
(*it)->refresh();
}
for (std::vector<Socket *>::iterator it = _sockets.begin();
it < _sockets.end(); it++) {
(*it)->refresh(this);
}
}

45
srcs/load/Server.cpp

@ -4,17 +4,6 @@ Server::Server(JSONNode *server) : Route(server) {
JSONObject datas = server->obj();
if (datas["server_name"])
_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"]) {
JSONObject locations = datas["locations"]->obj();
for (JSONObject::iterator it = locations.begin(); it != locations.end();
@ -25,21 +14,31 @@ Server::Server(JSONNode *server) : Route(server) {
}
}
Server::~Server(void) { cout << "Server destroyed!\n"; }
std::vector<Socket *> Server::get_sockets(JSONNode *server) {
JSONObject datas = server->obj();
std::vector<Socket *> ret;
if (datas["listens"]) {
JSONList listens = datas["listens"]->lst();
for (JSONList::iterator it = listens.begin(); it < listens.end();
it++) {
_listens.push_back(get_listen_t((*it)->str()));
Socket *sock = new Socket((*it)->str());
if (sock->launch() == EXIT_SUCCESS)
ret.push_back(sock);
else
delete sock;
}
} else {
Socket *sock = new Socket("localhost:80");
if (sock->launch() == EXIT_SUCCESS) {
ret.push_back(sock);
}
}
return ret;
void Server::set_fds(void) {
for (std::vector<Socket *>::iterator it = _sockets.begin();
it < _sockets.end(); it++) {
(*it)->set_fds();
}
}
void Server::refresh(void) {
for (std::vector<Socket *>::iterator it = _sockets.begin();
it < _sockets.end(); it++) {
(*it)->refresh();
}
}
Server::~Server(void) { cout << "Server destroyed!\n"; }
Route *Server::get_route(string uri) {
cout << uri << "\n";

35
srcs/load/Socket.cpp

@ -1,17 +1,8 @@
#include "webserv.hpp"
Socket::Socket(Server *server, string def) : _server(server) {
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());
Socket::Socket(string def) {
_listen = get_listen_t(def);
_clients_amount = 0;
}
Socket::~Socket() {
@ -21,6 +12,8 @@ Socket::~Socket() {
int Socket::launch() {
int opt = 1;
string ip = _listen.ip;
int port = _listen.port;
_master_socket = socket(AF_INET, SOCK_STREAM, 0);
if (_master_socket == 0) {
cout << "Socket creation: " << strerror(errno) << "\n";
@ -33,19 +26,19 @@ int Socket::launch() {
return (EXIT_FAILURE);
}
if (_ip.at(0) == '[')
if (ip.at(0) == '[')
_address.sin_family = AF_INET6;
else
_address.sin_family = AF_INET;
_address.sin_addr.s_addr = inet_addr(_ip.c_str());
_address.sin_port = htons(_port);
_address.sin_addr.s_addr = inet_addr(ip.c_str());
_address.sin_port = htons(port);
if (bind(_master_socket, (struct sockaddr *)&_address, sizeof(_address)) <
0) {
cout << "Bind: " << strerror(errno) << "\n";
return (EXIT_FAILURE);
}
cout << "Listener " << _ip << " on port " << _port << "\n";
cout << "Listener " << ip << " on port " << port << "\n";
if (listen(_master_socket, 3) < 0) {
cout << "Listen: " << strerror(errno) << "\n";
@ -69,7 +62,7 @@ void Socket::set_fds() {
}
}
void Socket::refresh() {
void Socket::refresh(Env *env) {
std::vector<int>::iterator it;
int valread;
int addrlen = sizeof(_address);
@ -101,21 +94,23 @@ void Socket::refresh() {
_clients.erase(it);
} else {
buffer[valread] = '\0';
answer(*it, buffer);
answer(env, *it, buffer);
}
}
}
}
void Socket::answer(int fd, string request) {
string uri = split(request, ' ').at(1);
void Socket::answer(Env *env, int fd, string request) {
std::vector<string> lines = split(request, '\n');
string uri = split(lines.at(0), ' ').at(1);
cout << uri << "\n";
cout << request << "\n|===|===|===|\n";
std::stringstream answer;
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);
answer << route->getAutoindex(uri);
cout << answer.str() << "\n|===|===|===|\n";
send_answer(fd, answer.str());

14
srcs/tools.cpp

@ -27,3 +27,17 @@ std::vector<string> split(string str, char delim) {
}
return tokens;
}
listen_t get_listen_t(string listen) {
listen_t ret;
size_t sep_pos = listen.rfind(':');
size_t ip6_endpos = listen.rfind(']');
string tmp = listen.substr(0, sep_pos);
if (ip6_endpos > sep_pos)
ret.ip = listen;
else
ret.ip = isInt(tmp) || tmp == "localhost" ? "0.0.0.0" : 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