Browse Source

fix conflicts

master
nicolas-arnaud 2 years ago
parent
commit
c1b4f792f0
  1. 8
      .gitignore
  2. 6
      default.json
  3. 8
      includes/Env.hpp
  4. 2
      includes/Server.hpp
  5. 1
      includes/Socket.hpp
  6. 0
      public/documents/test1
  7. 0
      public/documents/test2
  8. 2
      public/images/a_file
  9. 84
      srcs/load/Env.cpp
  10. 39
      srcs/load/Server.cpp
  11. 87
      srcs/load/Socket.cpp
  12. 20
      srcs/webserv.cpp

8
.gitignore

@ -6,6 +6,14 @@
!default.json
!.gitignore
!public/
!public/images/
!public/images/*
!public/testsite/
!public/testsite/*
!public/documents/
!public/documents/*
!includes/
!includes/*.hpp

6
default.json

@ -5,13 +5,15 @@
{
"server_name": "localhost",
"listens": ["localhost:8080"],
"root": "tester/",
"return": "301 https://$host$uri"
},
{
"server_name": "localhost",
"listens": ["192.168.62.61:8080", "localhost", "555"],
"root": "public/",
"indexs": ["index.html"],
"root": "public/testsite",
"indexs": ["basique.html"],
"cgi": "cgi.sh",
"locations":
{
"docs/":

8
includes/Env.hpp

@ -2,12 +2,12 @@
#include "webserv.hpp"
class Env {
std::vector<Server *> _servers;
std::vector<Socket *> _sockets;
public:
std::vector<Server *> _servers;
std::vector<Socket *> _sockets;
Env(JSONNode *conf);
void set_fds(void);
void refresh(void);
Server *choose_server(Socket *sock, string host);
Server *choose_server(Socket *sock, string host);
~Env();
};

2
includes/Server.hpp

@ -9,6 +9,6 @@ class Server : public Route {
Server(JSONNode *server);
~Server(void);
std::vector<Socket *> get_sockets(JSONNode *server);
Route *get_route(string uri);
Route *choose_route(string uri);
string getName(void);
};

1
includes/Socket.hpp

@ -16,6 +16,7 @@ class Socket {
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);

0
public/documents/test1

0
public/documents/test2

2
public/images/a_file

@ -0,0 +1,2 @@
jdkslaj\njkdsa;jfd\njdkaj;fjd
jdkslaj\njkdsa;jfd\njdkaj;fjd

84
srcs/load/Env.cpp

@ -1,20 +1,21 @@
#include "webserv.hpp"
/*|=======================|
* Environment constructor:
*
* Input: The JSONParser output
* Output: The env object containing servers and sockets vectors defined inside
* conf file by servers blocks and listens.
*/
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);
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();
@ -22,52 +23,10 @@ Env::Env(JSONNode *conf) {
delete conf;
}
Server *Env::choose_server(Socket *sock, string host) {
std::vector<Server *> exact;
std::vector<Server *> inrange;
std::vector<string> ip_listen;
std::vector<string> 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: " << sock->_listen.ip << ":" << sock->_listen.port << "\n";
ip_required = split(sock->_listen.ip, '.');
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);
continue;
}
bool is_inrange = true;
ip_listen = split((*it).ip, '.');
std::vector<string>::iterator r = ip_required.begin();
for (std::vector<string>::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<Server *>::iterator sit = inrange.begin();
sit < inrange.end(); sit++) {
if (host == (*sit)->getName())
return *sit;
}
return inrange.front();
} else
return exact.front();
}
/*|=======================|
* Append each master_sockets and their clients to list of fds SELECT must look
* at.
*/
void Env::set_fds(void) {
for (std::vector<Socket *>::iterator it = _sockets.begin();
@ -75,8 +34,29 @@ void Env::set_fds(void) {
(*it)->set_fds();
}
/*|=======================|
* Refresh all master_sockets and their clients datas (disconnect, new
* connection, etc..) and parse requests recieved.
*/
void Env::refresh(void) {
for (std::vector<Socket *>::iterator it = _sockets.begin();
it < _sockets.end(); it++)
(*it)->refresh(this);
}
/*|=======================|
* Environment destructor:
*
* The destructor call all servers and sockets destructors.
*/
Env::~Env() {
for (std::vector<Server *>::iterator it = _servers.begin();
it < _servers.end(); it++) {
delete *it;
}
for (std::vector<Socket *>::iterator it = _sockets.begin();
it < _sockets.end(); it++) {
delete *it;
}
}

39
srcs/load/Server.cpp

@ -1,5 +1,13 @@
#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)
*/
Server::Server(JSONNode *server) : Route(NULL, "/", server) {
JSONObject datas = server->obj();
if (datas["server_name"])
@ -14,10 +22,17 @@ Server::Server(JSONNode *server) : Route(NULL, "/", server) {
}
}
Server::~Server(void) { cout << "Server destroyed!\n"; }
/* 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.
*/
std::vector<Socket *> Server::get_sockets(JSONNode *server) {
JSONObject datas = server->obj();
std::vector<Socket *> ret;
@ -50,7 +65,13 @@ std::vector<Socket *> Server::get_sockets(JSONNode *server) {
return ret;
}
Route *Server::get_route(string uri) {
/*|=======================|
* 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.
*/
Route *Server::choose_route(string uri) {
// cout << uri << "\n";
std::vector<string> req = split(uri, '/');
std::vector<string> root;
@ -72,3 +93,17 @@ Route *Server::get_route(string uri) {
}
return this;
}
/*|=======================|
* Server destructor:
*
* delete all routes owned by the server;
*/
Server::~Server(void) {
for (std::map<string, Route *>::iterator it = _routes.begin();
it != _routes.end(); it++)
delete (*it).second;
cout << "Server destroyed!\n";
}

87
srcs/load/Socket.cpp

@ -2,7 +2,6 @@
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";
@ -47,8 +46,9 @@ int Socket::launch(void) {
}
void Socket::set_fds(void) {
int child_fd;
FD_SET(_fd, &_readfds);
int child_fd;
for (std::vector<Socket *>::iterator it = _childs.begin();
it < _childs.end(); it++) {
child_fd = (*it)->_fd;
@ -100,18 +100,68 @@ void Socket::refresh(Env *env) {
}
}
Server *Socket::choose_server(Env *env, string host) {
std::vector<Server *> exact;
std::vector<Server *> inrange;
std::vector<string> ip_listen;
std::vector<string> 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<Server *>::iterator sit = env->_servers.begin();
sit < env->_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 (_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<string>::iterator r = ip_required.begin();
for (std::vector<string>::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<Server *>::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<string> lines = split(_header, '\n');
std::vector<string> line;
if (lines.size() > 0) {
for (std::vector<string>::iterator it = lines.begin() + 1; it < lines.end(); it++) {
for (std::vector<string>::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<string>(line.begin() + 1, line.end());
_request[line.at(0)] =
std::vector<string>(line.begin() + 1, line.end());
}
}
std::vector<string> method = split(lines.at(0), ' ');
if (method.at(0) == "POST" && _request.find("Content-Length:") == _request.end() && _request.find("Transfer-Encoding:") ==_request.end())
if (method.at(0) == "POST" &&
_request.find("Content-Length:") == _request.end() &&
_request.find("Transfer-Encoding:") == _request.end())
return false;
_request["Method:"] = method;
return true;
@ -119,12 +169,17 @@ bool Socket::parseHeader() {
bool Socket::getRequest(string paquet) {
cout << "|===|paquet|===>" << paquet << "|===||\n";
if (paquet.length() < 1) //HTTPS?
if (paquet.length() < 1) // HTTPS?
return false;
std::vector<string> 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;
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<string>::iterator it = lines.begin(); it < lines.end(); it++) {
for (std::vector<string>::iterator it = lines.begin(); it < lines.end();
it++) {
if (*it == "\r" && _content.length() == 0)
this->parseHeader();
if (*it != "\r" && _content.length() == 0)
@ -136,7 +191,10 @@ bool Socket::getRequest(string paquet) {
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() ) ) {
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;
}
@ -153,8 +211,8 @@ int Socket::answer(Env *env) {
std::stringstream answer;
answer << "HTTP/1.1";
Server *server = env->choose_server(_parent, _request["Host:"].at(0));
Route *route = server->get_route(_request["Method:"].at(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<string> allowed;
if (method != "GET" && method != "POST" && method != "DELETE")
@ -162,11 +220,14 @@ int Socket::answer(Env *env) {
"HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n");
else if ((allowed = route->getHeadersLst()).size() > 0) {
if (std::find(allowed.begin(), allowed.end(), method) == allowed.end())
send_answer("HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n");
send_answer(
"HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n");
} else if ((allowed = server->getHeadersLst()).size() > 0) {
if (std::find(allowed.begin(), allowed.end(), method) == allowed.end())
send_answer("HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n");
send_answer(
"HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n");
}
string path = route->correctUri(_request["Method:"].at(1));
cout << "Path: " << path << "\n";
ret = route->getIndex(_request["Method:"].at(1), path);

20
srcs/webserv.cpp

@ -7,26 +7,30 @@ int Socket::_amount = 0;
int main(int ac, char **av) {
if (ac > 1) {
cout << "Parsing configuration file...\n";
if (ac < 2) {
cout << "Usage:\n";
cout << "./webserv CONF.json\n";
cout << "WARNING: You must use a correct json syntax and a correct "
"server configuration or don't expect it to work correctly.";
} else if (ac == 2) {
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 << "Configuration parsed.\n";
cout << "Setting environment...\n";
cout << "Initialization of server...\n";
Env env(conf);
cout << "Environement setup.\n";
while (1) {
FD_ZERO(&Socket::_readfds);
Socket::_max_fd = Socket::_min_fd;
cout << "==> Check sockets still alive to listen\n";
env.set_fds();
cout << "|===|===|===| SELECT |===|===|===|\n";
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();
}
}

Loading…
Cancel
Save