Browse Source

save 22-11-6-2

test
nicolas-arnaud 2 years ago
parent
commit
48087a2563
  1. 5
      includes/Env.hpp
  2. 42
      includes/Nodes.hpp
  3. 21
      includes/Parser.hpp
  4. 2
      includes/Route.hpp
  5. 6
      includes/Server.hpp
  6. 18
      includes/Socket.hpp
  7. 38
      includes/Token.hpp
  8. 159
      srcs/json/Nodes.cpp
  9. 359
      srcs/json/Parser.cpp
  10. 176
      srcs/json/Token.cpp
  11. 46
      srcs/load/Env.cpp
  12. 6
      srcs/load/Route.cpp
  13. 55
      srcs/load/Server.cpp
  14. 162
      srcs/load/Socket.cpp
  15. 17
      srcs/tools.cpp
  16. 25
      srcs/webserv.cpp

5
includes/Env.hpp

@ -2,9 +2,10 @@
#include "webserv.hpp" #include "webserv.hpp"
class Env { class Env {
std::vector<Server *> _servers; std::vector<Server *> _servers;
public: public:
Env(JSONNode *conf); Env(JSONNode *conf);
void set_fds(); void set_fds();
void refresh(); void refresh();
}; };

42
includes/Nodes.hpp

@ -3,30 +3,30 @@
class JSONNode { class JSONNode {
public: public:
JSONObject obj(); JSONObject obj();
JSONList lst(); JSONList lst();
string str(); string str();
int nbr(); int nbr();
bool boo(); bool boo();
private: private:
enum Type { OBJECT, LIST, STRING, NUMBER, BOOLEAN, NULL_TYPE }; enum Type { OBJECT, LIST, STRING, NUMBER, BOOLEAN, NULL_TYPE };
union Values { union Values {
JSONObject *object; JSONObject *object;
JSONList *list; JSONList *list;
string *str; string *str;
int nbr; int nbr;
bool bValue; bool bValue;
} values; } values;
Type type; Type type;
void setObject(JSONObject *object); void setObject(JSONObject *object);
void setList(JSONList *list); void setList(JSONList *list);
void setString(string *str); void setString(string *str);
void setNumber(int nbr); void setNumber(int nbr);
void setBoolean(bool v); void setBoolean(bool v);
void setNull(); void setNull();
string stringify(int indentationLevel); string stringify(int indentationLevel);
friend class JSONParser; friend class JSONParser;
}; };

21
includes/Parser.hpp

@ -1,18 +1,17 @@
#pragma once #pragma once
#include "webserv.hpp" #include "webserv.hpp"
class JSONParser { class JSONParser {
std::fstream file; std::fstream file;
Tokenizer tokenizer; Tokenizer tokenizer;
public: public:
JSONParser(const string filename); JSONParser(const string filename);
JSONNode *parse(); JSONNode *parse();
JSONNode *parseObject(); JSONNode *parseObject();
JSONNode *parseList(); JSONNode *parseList();
JSONNode *parseString(); JSONNode *parseString();
JSONNode *parseNumber(); JSONNode *parseNumber();
JSONNode *parseBoolean(); JSONNode *parseBoolean();
JSONNode *parseNull(); JSONNode *parseNull();
}; };

2
includes/Route.hpp

@ -2,10 +2,12 @@
#include "webserv.hpp" #include "webserv.hpp"
class Route { class Route {
protected:
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(JSONNode *datas);
~Route(void); ~Route(void);

6
includes/Server.hpp

@ -1,9 +1,9 @@
#pragma once #pragma once
#include "webserv.hpp" #include "webserv.hpp"
class Server: public Route{ class Server : public Route {
string _name; string _name;
std::vector<Socket *> _sockets; std::vector<Socket *> _sockets;
std::map<string, Route *> _routes; std::map<string, Route *> _routes;
public: public:

18
includes/Socket.hpp

@ -2,13 +2,14 @@
#include "webserv.hpp" #include "webserv.hpp"
class Socket { class Socket {
Server *_server; Server *_server;
string _ip; string _ip;
int _port; int _port;
int _master_socket; int _master_socket;
struct sockaddr_in _address; struct sockaddr_in _address;
int _clients_amount; int _clients_amount;
std::vector<int> _clients; std::vector<int> _clients;
public: public:
static fd_set _readfds; static fd_set _readfds;
static int _max_fd; static int _max_fd;
@ -30,6 +31,3 @@ class Socket {
} }
*/ */
}; };

38
includes/Token.hpp

@ -2,31 +2,31 @@
#include "webserv.hpp" #include "webserv.hpp"
enum TOKEN { enum TOKEN {
CURLY_OPEN, CURLY_OPEN,
CURLY_CLOSE, CURLY_CLOSE,
COLON, COLON,
STRING, STRING,
NUMBER, NUMBER,
ARRAY_OPEN, ARRAY_OPEN,
ARRAY_CLOSE, ARRAY_CLOSE,
COMMA, COMMA,
BOOLEAN, BOOLEAN,
NULL_TYPE NULL_TYPE
}; };
typedef struct Token_s { typedef struct Token_s {
string value; string value;
TOKEN type; TOKEN type;
} Token; } Token;
class Tokenizer { class Tokenizer {
std::fstream file; std::fstream file;
size_t prevPos; size_t prevPos;
public: public:
Tokenizer(string fileName); Tokenizer(string fileName);
bool hasMoreTokens(); bool hasMoreTokens();
char getWithoutWhiteSpace(); char getWithoutWhiteSpace();
void rollBackToken(); void rollBackToken();
Token getToken(); Token getToken();
}; };

159
srcs/json/Nodes.cpp

@ -1,111 +1,110 @@
#include "webserv.hpp" #include "webserv.hpp"
#define DEBUG 0 #define DEBUG 0
JSONObject JSONNode::obj() { JSONObject JSONNode::obj() {
if (type == OBJECT) if (type == OBJECT)
return *values.object; return *values.object;
throw std::logic_error("Improper return"); throw std::logic_error("Improper return");
} }
JSONList JSONNode::lst() { JSONList JSONNode::lst() {
if (type == LIST) if (type == LIST)
return *values.list; return *values.list;
throw std::logic_error("Improper return"); throw std::logic_error("Improper return");
} }
string JSONNode::str() { string JSONNode::str() {
if (type == STRING) if (type == STRING)
return *values.str; return *values.str;
throw std::logic_error("Improper return"); throw std::logic_error("Improper return");
} }
int JSONNode::nbr() { int JSONNode::nbr() {
if (type == NUMBER) if (type == NUMBER)
return values.nbr; return values.nbr;
throw std::logic_error("Improper return"); throw std::logic_error("Improper return");
} }
bool JSONNode::boo() { bool JSONNode::boo() {
if (type == BOOLEAN) if (type == BOOLEAN)
return values.bValue; return values.bValue;
throw std::logic_error("Improper return"); throw std::logic_error("Improper return");
} }
void JSONNode::setObject(JSONObject *object) { void JSONNode::setObject(JSONObject *object) {
this->values.object = object; this->values.object = object;
type = OBJECT; type = OBJECT;
} }
void JSONNode::setList(JSONList *list) { void JSONNode::setList(JSONList *list) {
this->values.list = list; this->values.list = list;
type = LIST; type = LIST;
} }
void JSONNode::setString(string *str) { void JSONNode::setString(string *str) {
this->values.str = str; this->values.str = str;
type = STRING; type = STRING;
} }
void JSONNode::setNumber(int nbr) { void JSONNode::setNumber(int nbr) {
this->values.nbr = nbr; this->values.nbr = nbr;
type = NUMBER; type = NUMBER;
} }
void JSONNode::setBoolean(bool v) { void JSONNode::setBoolean(bool v) {
this->values.bValue = v; this->values.bValue = v;
type = BOOLEAN; type = BOOLEAN;
} }
void JSONNode::setNull() { type = NULL_TYPE; } void JSONNode::setNull() { type = NULL_TYPE; }
string JSONNode::stringify(int indentationLevel) { string JSONNode::stringify(int indentationLevel) {
string spaceString = string(indentationLevel, ' '); string spaceString = string(indentationLevel, ' ');
// sstreams // sstreams
std::stringstream output; std::stringstream output;
// cout < type << "\n"; // cout < type << "\n";
switch (type) { switch (type) {
case STRING: { case STRING: {
output << spaceString << *values.str; output << spaceString << *values.str;
break; break;
} }
case NUMBER: { case NUMBER: {
output << spaceString << values.nbr; output << spaceString << values.nbr;
break; break;
} }
case BOOLEAN: { case BOOLEAN: {
output << spaceString << (values.bValue ? "true" : "false"); output << spaceString << (values.bValue ? "true" : "false");
break; break;
} }
case NULL_TYPE: { case NULL_TYPE: {
output << spaceString << "null"; output << spaceString << "null";
break; break;
} }
case LIST: { case LIST: {
// cout << "["; // cout << "[";
output << spaceString << "[\n"; output << spaceString << "[\n";
unsigned int index = 0; unsigned int index = 0;
for (JSONList::iterator i = (*values.list).begin(); for (JSONList::iterator i = (*values.list).begin();
i != (*values.list).end(); i++) { i != (*values.list).end(); i++) {
output << (*i)->stringify(indentationLevel + 1); output << (*i)->stringify(indentationLevel + 1);
if (index < (*values.list).size() - 1) { if (index < (*values.list).size() - 1) {
output << ",\n"; output << ",\n";
} }
index++; index++;
}; };
output << "\n" << spaceString << "]\n"; output << "\n" << spaceString << "]\n";
break; break;
} }
case OBJECT: { case OBJECT: {
output << spaceString << "{\n"; output << spaceString << "{\n";
for (JSONObject::iterator i = (*values.object).begin(); for (JSONObject::iterator i = (*values.object).begin();
i != (*values.object).end(); i++) { i != (*values.object).end(); i++) {
output << spaceString << " " output << spaceString << " "
<< "\"" << i->first << "\"" << "\"" << i->first << "\""
<< ": "; << ": ";
output << i->second->stringify(indentationLevel + 1); output << i->second->stringify(indentationLevel + 1);
JSONObject::iterator next = i; JSONObject::iterator next = i;
next++; next++;
if ((next) != (*values.object).end()) { if ((next) != (*values.object).end()) {
output << ",\n"; output << ",\n";
} }
output << spaceString << "\n"; output << spaceString << "\n";
} }
output << spaceString << "}"; output << spaceString << "}";
return output.str(); return output.str();
} }
} }
return output.str(); return output.str();
} }

359
srcs/json/Parser.cpp

@ -1,200 +1,199 @@
#include "webserv.hpp" #include "webserv.hpp"
JSONParser::JSONParser(const string filename) : tokenizer(filename) {} JSONParser::JSONParser(const string filename) : tokenizer(filename) {}
JSONNode *JSONParser::parse() { JSONNode *JSONParser::parse() {
string key = ""; string key = "";
JSONNode *parsed; JSONNode *parsed;
while (tokenizer.hasMoreTokens()) { while (tokenizer.hasMoreTokens()) {
Token token; Token token;
try { try {
token = tokenizer.getToken(); token = tokenizer.getToken();
switch (token.type) { switch (token.type) {
case CURLY_OPEN: { case CURLY_OPEN: {
parsed = parseObject(); parsed = parseObject();
break; break;
} }
case ARRAY_OPEN: { case ARRAY_OPEN: {
parsed = parseList(); parsed = parseList();
break; break;
} }
case STRING: { case STRING: {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
parsed = parseString(); parsed = parseString();
break; break;
} }
case NUMBER: { case NUMBER: {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
parsed = parseNumber(); parsed = parseNumber();
break; break;
} }
case BOOLEAN: { case BOOLEAN: {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
parsed = parseBoolean(); parsed = parseBoolean();
break; break;
} }
default: default:
break; break;
} }
} catch (std::logic_error &e) { } catch (std::logic_error &e) {
break; break;
} }
} }
return parsed; return parsed;
} }
JSONNode *JSONParser::parseObject() { JSONNode *JSONParser::parseObject() {
JSONNode *node = new JSONNode; JSONNode *node = new JSONNode;
JSONObject *keyObjectMap = new JSONObject; JSONObject *keyObjectMap = new JSONObject;
while (1) { while (1) {
if (tokenizer.hasMoreTokens()) { if (tokenizer.hasMoreTokens()) {
Token token = tokenizer.getToken(); Token token = tokenizer.getToken();
string key = token.value; string key = token.value;
tokenizer.getToken(); tokenizer.getToken();
token = tokenizer.getToken(); token = tokenizer.getToken();
switch (token.type) { switch (token.type) {
case CURLY_OPEN: { case CURLY_OPEN: {
if (DEBUG) if (DEBUG)
cout << "=object=|" << key << "|===>>\n"; cout << "=object=|" << key << "|===>>\n";
(*keyObjectMap)[key] = parseObject(); (*keyObjectMap)[key] = parseObject();
if (DEBUG) if (DEBUG)
cout << "<<===end object\n"; cout << "<<===end object\n";
break; break;
} }
case ARRAY_OPEN: { case ARRAY_OPEN: {
if (DEBUG) if (DEBUG)
cout << "-list-|" << key << "|--->>\n"; cout << "-list-|" << key << "|--->>\n";
(*keyObjectMap)[key] = parseList(); (*keyObjectMap)[key] = parseList();
if (DEBUG) if (DEBUG)
cout << "<<---end list\n"; cout << "<<---end list\n";
break; break;
} }
case STRING: { case STRING: {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
(*keyObjectMap)[key] = parseString(); (*keyObjectMap)[key] = parseString();
if (DEBUG) if (DEBUG)
cout << key << "='" << (*keyObjectMap)[key]->str() << "'\n"; cout << key << "='" << (*keyObjectMap)[key]->str() << "'\n";
break; break;
} }
case NUMBER: { case NUMBER: {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
(*keyObjectMap)[key] = parseNumber(); (*keyObjectMap)[key] = parseNumber();
if (DEBUG) if (DEBUG)
cout << key << "=" << (*keyObjectMap)[key]->nbr() << "\n"; cout << key << "=" << (*keyObjectMap)[key]->nbr() << "\n";
break; break;
} }
case BOOLEAN: { case BOOLEAN: {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
(*keyObjectMap)[key] = parseBoolean(); (*keyObjectMap)[key] = parseBoolean();
if (DEBUG) if (DEBUG)
cout << key << "(BOOL)\n"; cout << key << "(BOOL)\n";
break; break;
} }
case NULL_TYPE: { case NULL_TYPE: {
(*keyObjectMap)[key] = parseNull(); (*keyObjectMap)[key] = parseNull();
break; break;
} }
default: default:
break; break;
} }
token = tokenizer.getToken(); token = tokenizer.getToken();
if (token.type == CURLY_CLOSE) if (token.type == CURLY_CLOSE)
break; break;
} else { } else {
throw std::logic_error("No more tokens"); throw std::logic_error("No more tokens");
} }
} }
node->setObject(keyObjectMap); node->setObject(keyObjectMap);
return node; return node;
} }
JSONNode *JSONParser::parseList() { JSONNode *JSONParser::parseList() {
JSONNode *node = new JSONNode(); JSONNode *node = new JSONNode();
JSONList *list = new JSONList(); JSONList *list = new JSONList();
bool hasCompleted = false; bool hasCompleted = false;
while (!hasCompleted) { while (!hasCompleted) {
if (!tokenizer.hasMoreTokens()) { if (!tokenizer.hasMoreTokens()) {
throw std::logic_error("No more tokens"); throw std::logic_error("No more tokens");
} else { } else {
Token token = tokenizer.getToken(); Token token = tokenizer.getToken();
JSONNode *subNode; JSONNode *subNode;
switch (token.type) { switch (token.type) {
case CURLY_OPEN: { case CURLY_OPEN: {
if (DEBUG) if (DEBUG)
cout << "=object===>>\n"; cout << "=object===>>\n";
subNode = parseObject(); subNode = parseObject();
if (DEBUG) if (DEBUG)
cout << "<<===end object\n"; cout << "<<===end object\n";
break; break;
} }
case ARRAY_OPEN: { case ARRAY_OPEN: {
if (DEBUG) if (DEBUG)
cout << "-list--->>\n"; cout << "-list--->>\n";
subNode = parseList(); subNode = parseList();
if (DEBUG) if (DEBUG)
cout << "<<---end list\n"; cout << "<<---end list\n";
break; break;
} }
case STRING: { case STRING: {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
subNode = parseString(); subNode = parseString();
if (DEBUG) if (DEBUG)
cout << "|'" << subNode->str() << "'"; cout << "|'" << subNode->str() << "'";
break; break;
} }
case NUMBER: { case NUMBER: {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
subNode = parseNumber(); subNode = parseNumber();
if (DEBUG) if (DEBUG)
cout << "|" << subNode->nbr(); cout << "|" << subNode->nbr();
break; break;
} }
case BOOLEAN: { case BOOLEAN: {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
subNode = parseBoolean(); subNode = parseBoolean();
break; break;
} }
case NULL_TYPE: { case NULL_TYPE: {
subNode = parseNull(); subNode = parseNull();
break; break;
} }
default: default:
break; break;
} }
list->push_back(subNode); list->push_back(subNode);
token = tokenizer.getToken(); token = tokenizer.getToken();
if (token.type == ARRAY_CLOSE) { if (token.type == ARRAY_CLOSE) {
hasCompleted = true; hasCompleted = true;
} }
} }
} }
node->setList(list); node->setList(list);
return node; return node;
} }
JSONNode *JSONParser::parseString() { JSONNode *JSONParser::parseString() {
JSONNode *node = new JSONNode(); JSONNode *node = new JSONNode();
Token token = tokenizer.getToken(); Token token = tokenizer.getToken();
string *sValue = new string(token.value); string *sValue = new string(token.value);
node->setString(sValue); node->setString(sValue);
return node; return node;
} }
JSONNode *JSONParser::parseNumber() { JSONNode *JSONParser::parseNumber() {
JSONNode *node = new JSONNode(); JSONNode *node = new JSONNode();
Token token = tokenizer.getToken(); Token token = tokenizer.getToken();
string value = token.value; string value = token.value;
int nbr = std::atoi(value.c_str()); int nbr = std::atoi(value.c_str());
node->setNumber(nbr); node->setNumber(nbr);
return node; return node;
} }
JSONNode *JSONParser::parseBoolean() { JSONNode *JSONParser::parseBoolean() {
JSONNode *node = new JSONNode(); JSONNode *node = new JSONNode();
Token token = tokenizer.getToken(); Token token = tokenizer.getToken();
node->setBoolean(token.value == "True" ? true : false); node->setBoolean(token.value == "True" ? true : false);
return node; return node;
} }
JSONNode *JSONParser::parseNull() { JSONNode *JSONParser::parseNull() {
JSONNode *node = new JSONNode(); JSONNode *node = new JSONNode();
node->setNull(); node->setNull();
return node; return node;
} }

176
srcs/json/Token.cpp

@ -1,111 +1,97 @@
#include "webserv.hpp" #include "webserv.hpp"
/*
enum TOKEN {
CURLY_OPEN,
CURLY_CLOSE,
COLON,
STRING,
NUMBER,
ARRAY_OPEN,
ARRAY_CLOSE,
COMMA,
BOOLEAN,
NULL_TYPE
};
*/
Tokenizer::Tokenizer(string fileName) { Tokenizer::Tokenizer(string fileName) {
file.open(fileName.c_str(), std::ios::in); file.open(fileName.c_str(), std::ios::in);
if (!file.good()) if (!file.good())
cout << "File open error" cout << "File open error"
<< "\n"; << "\n";
} }
bool Tokenizer::hasMoreTokens() { return !file.eof(); } bool Tokenizer::hasMoreTokens() { return !file.eof(); }
char Tokenizer::getWithoutWhiteSpace() { char Tokenizer::getWithoutWhiteSpace() {
char c = ' '; char c = ' ';
while ((c == ' ' || c == '\n') || c == '\t') { while ((c == ' ' || c == '\n') || c == '\t') {
file.get(c); // check file.get(c); // check
if ((c == ' ' || c == '\n') && !file.good()) { if ((c == ' ' || c == '\n') && !file.good()) {
// cout << file.eof() << " " << file.fail() << "\n"; // cout << file.eof() << " " << file.fail() << "\n";
throw std::logic_error("Ran out of tokens"); throw std::logic_error("Ran out of tokens");
} else if (!file.good()) { } else if (!file.good()) {
return c; return c;
} }
} }
return c; return c;
} }
void Tokenizer::rollBackToken() { void Tokenizer::rollBackToken() {
if (file.eof()) if (file.eof())
file.clear(); file.clear();
file.seekg(prevPos); file.seekg(prevPos);
} }
Token Tokenizer::getToken() { Token Tokenizer::getToken() {
char c; char c;
if (file.eof()) { if (file.eof()) {
cout << "Exhaused tokens" cout << "Exhaused tokens"
<< "\n"; << "\n";
// throw std::exception("Exhausted tokens"); // throw std::exception("Exhausted tokens");
} }
prevPos = file.tellg(); prevPos = file.tellg();
c = getWithoutWhiteSpace(); c = getWithoutWhiteSpace();
Token token; Token token;
token.type = NULL_TYPE; token.type = NULL_TYPE;
if (c == '"') { if (c == '"') {
token.type = STRING; token.type = STRING;
token.value = ""; token.value = "";
file.get(c); file.get(c);
while (c != '"') { while (c != '"') {
token.value += c; token.value += c;
file.get(c); file.get(c);
} }
} else if (c == '{') { } else if (c == '{') {
token.type = CURLY_OPEN; token.type = CURLY_OPEN;
} else if (c == '}') { } else if (c == '}') {
token.type = CURLY_CLOSE; token.type = CURLY_CLOSE;
} else if (c == '-' || (c >= '0' && c <= '9')) { } else if (c == '-' || (c >= '0' && c <= '9')) {
// Check if string is numeric // Check if string is numeric
token.type = NUMBER; token.type = NUMBER;
token.value = ""; token.value = "";
token.value += c; token.value += c;
std::streampos prevCharPos = file.tellg(); std::streampos prevCharPos = file.tellg();
while ((c == '-') || (c >= '0' && c <= '9') || c == '.') { while ((c == '-') || (c >= '0' && c <= '9') || c == '.') {
prevCharPos = file.tellg(); prevCharPos = file.tellg();
file.get(c); file.get(c);
if (file.eof()) { if (file.eof()) {
break; break;
} else { } else {
if ((c == '-') || (c >= '0' && c <= '9') || (c == '.')) { if ((c == '-') || (c >= '0' && c <= '9') || (c == '.')) {
token.value += c; token.value += c;
} else { } else {
file.seekg(prevCharPos); file.seekg(prevCharPos);
} }
} }
} }
} else if (c == 'f') { } else if (c == 'f') {
token.type = BOOLEAN; token.type = BOOLEAN;
token.value = "False"; token.value = "False";
file.seekg(4, std::ios_base::cur); file.seekg(4, std::ios_base::cur);
} else if (c == 't') { } else if (c == 't') {
token.type = BOOLEAN; token.type = BOOLEAN;
token.value = "True"; token.value = "True";
file.seekg(3, std::ios_base::cur); file.seekg(3, std::ios_base::cur);
} else if (c == 'n') { } else if (c == 'n') {
token.type = NULL_TYPE; token.type = NULL_TYPE;
file.seekg(3, std::ios_base::cur); file.seekg(3, std::ios_base::cur);
} else if (c == '[') { } else if (c == '[') {
token.type = ARRAY_OPEN; token.type = ARRAY_OPEN;
} else if (c == ']') { } else if (c == ']') {
token.type = ARRAY_CLOSE; token.type = ARRAY_CLOSE;
} else if (c == ':') { } else if (c == ':') {
token.type = COLON; token.type = COLON;
} else if (c == ',') { } else if (c == ',') {
token.type = COMMA; token.type = COMMA;
} }
// cout << token.type << " : " << token.value << "\n"; // cout << token.type << " : " << token.value << "\n";
return token; return token;
} }

46
srcs/load/Env.cpp

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

6
srcs/load/Route.cpp

@ -1,7 +1,7 @@
#include "webserv.hpp" #include "webserv.hpp"
Route::Route(JSONNode *datas) { Route::Route(JSONNode *datas) {
JSONObject object = datas->obj(); JSONObject object = datas->obj();
if (object["root"]) if (object["root"])
_root = object["root"]->str(); _root = object["root"]->str();
if (object["return"]) if (object["return"])
@ -20,7 +20,5 @@ Route::~Route(void) {}
string getRoot(void); string getRoot(void);
string getReturn(void); string getReturn(void);
std::vector<string> Route::getIndexs(void) { std::vector<string> Route::getIndexs(void) { return _indexs; }
return _indexs;
}
bool getAutoindex(void); bool getAutoindex(void);

55
srcs/load/Server.cpp

@ -1,50 +1,51 @@
#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"]) { if (datas["listens"]) {
JSONList listens = datas["listens"]->lst(); JSONList listens = datas["listens"]->lst();
for (JSONList::iterator it = listens.begin(); it < listens.end(); it++) { for (JSONList::iterator it = listens.begin(); it < listens.end();
Socket *sock = new Socket(this, (*it)->str()); it++) {
if (sock->launch() == EXIT_SUCCESS) Socket *sock = new Socket(this, (*it)->str());
_sockets.push_back(sock); if (sock->launch() == EXIT_SUCCESS)
_sockets.push_back(sock);
else else
delete sock; 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(); it++) { for (JSONObject::iterator it = locations.begin(); it != locations.end();
it++) {
Route *route = new Route((*it).second); Route *route = new Route((*it).second);
_routes[(*it).first] = route; _routes[(*it).first] = route;
} }
} }
} }
Server::~Server(void) { Server::~Server(void) { cout << "Server destroyed!\n"; }
cout << "Server destroyed!\n";
}
void Server::set_fds(void) { void Server::set_fds(void) {
for (std::vector<Socket *>::iterator it = _sockets.begin(); for (std::vector<Socket *>::iterator it = _sockets.begin();
it < _sockets.end(); it++) { it < _sockets.end(); it++) {
(*it)->set_fds(); (*it)->set_fds();
} }
} }
void Server::refresh(void) { void Server::refresh(void) {
for (std::vector<Socket *>::iterator it = _sockets.begin(); for (std::vector<Socket *>::iterator it = _sockets.begin();
it < _sockets.end(); it++) { it < _sockets.end(); it++) {
(*it)->refresh(); (*it)->refresh();
} }
} }
Route *Server::get_route(string uri) { Route *Server::get_route(string uri) {
for (std::map<string, Route *>::iterator it = _routes.begin(); it != _routes.end(); it++) { for (std::map<string, Route *>::iterator it = _routes.begin();
it != _routes.end(); it++) {
if (uri == (*it).first) if (uri == (*it).first)
return (*it).second; return (*it).second;
} }
return this; return this;
} }

162
srcs/load/Socket.cpp

@ -1,114 +1,116 @@
#include "webserv.hpp" #include "webserv.hpp"
Socket::Socket(Server *server, string def): _server(server) { Socket::Socket(Server *server, string def) : _server(server) {
size_t sep_pos = def.rfind(':'); size_t sep_pos = def.rfind(':');
size_t ip6_endpos = def.rfind(']'); size_t ip6_endpos = def.rfind(']');
string tmp = def.substr(0, sep_pos); string tmp = def.substr(0, sep_pos);
if (ip6_endpos > sep_pos) if (ip6_endpos > sep_pos)
_ip = def; _ip = def;
else else
_ip = isInt(tmp) || tmp == "localhost" ? "127.0.0.1" : tmp; _ip = isInt(tmp) || tmp == "localhost" ? "127.0.0.1" : tmp;
tmp = def.substr(sep_pos + 1, def.length() - sep_pos - 1).c_str(); tmp = def.substr(sep_pos + 1, def.length() - sep_pos - 1).c_str();
_port = !isInt(tmp) ? 80 : std::atoi(tmp.c_str()); _port = !isInt(tmp) ? 80 : std::atoi(tmp.c_str());
_clients_amount = 0; _clients_amount = 0;
} }
Socket::~Socket() { Socket::~Socket() {
close(_master_socket); close(_master_socket);
cout << "Socket destroyed!\n"; cout << "Socket destroyed!\n";
} }
int Socket::launch() { int Socket::launch() {
int opt = 1; int opt = 1;
_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";
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
int opt_ret = setsockopt(_master_socket, SOL_SOCKET, SO_REUSEADDR, int opt_ret = setsockopt(_master_socket, SOL_SOCKET, SO_REUSEADDR,
(char *)&opt, sizeof(opt)); (char *)&opt, sizeof(opt));
if (opt_ret < 0) { if (opt_ret < 0) {
cout << "Sockopt: " << strerror(errno) << "\n"; cout << "Sockopt: " << strerror(errno) << "\n";
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
_address.sin_family = AF_INET; _address.sin_family = AF_INET;
_address.sin_addr.s_addr = inet_addr(_ip.c_str()); _address.sin_addr.s_addr = inet_addr(_ip.c_str());
_address.sin_port = htons(_port); _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";
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
cout << "Socket::_master_socket: " << _master_socket << "\n"; cout << "Socket::_master_socket: " << _master_socket << "\n";
if (_master_socket < _min_fd) if (_master_socket < _min_fd)
_min_fd = _master_socket; _min_fd = _master_socket;
_amount++; _amount++;
return (EXIT_SUCCESS); return (EXIT_SUCCESS);
} }
void Socket::set_fds() { void Socket::set_fds() {
FD_SET(_master_socket, &_readfds); FD_SET(_master_socket, &_readfds);
for (std::vector<int>::iterator it = _clients.begin(); it < _clients.end(); for (std::vector<int>::iterator it = _clients.begin(); it < _clients.end();
it++) { it++) {
FD_SET(*it, &_readfds); FD_SET(*it, &_readfds);
if (*it > _max_fd) if (*it > _max_fd)
_max_fd = *it; _max_fd = *it;
} }
} }
void Socket::refresh() { void Socket::refresh() {
std::vector<int>::iterator it; std::vector<int>::iterator it;
int valread; int valread;
int addrlen = sizeof(_address); int addrlen = sizeof(_address);
char buffer[1024]; char buffer[10000];
if (FD_ISSET(_master_socket, &_readfds)) { if (FD_ISSET(_master_socket, &_readfds)) {
int new_socket = accept(_master_socket, (struct sockaddr *)&_address, int new_socket = accept(_master_socket, (struct sockaddr *)&_address,
(socklen_t *)&addrlen); (socklen_t *)&addrlen);
if (new_socket < 0) { if (new_socket < 0) {
cout << "Accept: " << strerror(errno) << "\n"; cout << "Accept: " << strerror(errno) << "\n";
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#ifdef __APPLE__ #ifdef __APPLE__
fcntl(new_socket, F_GETNOSIGPIPE); fcntl(new_socket, F_GETNOSIGPIPE);
#endif #endif
cout << "New connection, socket fd is " << new_socket cout << "New connection, socket fd is " << new_socket
<< ", ip is : " << inet_ntoa(_address.sin_addr) << ", ip is : " << inet_ntoa(_address.sin_addr)
<< ", port : " << ntohs(_address.sin_port) << "\n"; << ", port : " << ntohs(_address.sin_port) << "\n";
_clients.push_back(new_socket); _clients.push_back(new_socket);
} }
for (it = _clients.begin(); it < _clients.end(); it++) { for (it = _clients.begin(); it < _clients.end(); it++) {
if (FD_ISSET(*it, &_readfds)) { if (FD_ISSET(*it, &_readfds)) {
valread = read(*it, buffer, 1024); valread = read(*it, buffer, 10000);
if (valread == 0) { if (valread == 0) {
getpeername(*it, (struct sockaddr *)&_address, getpeername(*it, (struct sockaddr *)&_address,
(socklen_t *)&addrlen); (socklen_t *)&addrlen);
cout << "Host disconnected, ip " << inet_ntoa(_address.sin_addr) cout << "Host disconnected, ip " << inet_ntoa(_address.sin_addr)
<< ", port " << ntohs(_address.sin_port) << "\n"; << ", port " << ntohs(_address.sin_port) << "\n";
close(*it); close(*it);
_clients.erase(it); _clients.erase(it);
} else } else {
buffer[valread]='\0';
this->answer(*it, buffer); this->answer(*it, buffer);
} }
} }
}
} }
void Socket::answer(int fd, string request) { void Socket::answer(int fd, string request) {
string uri = "path/to/page/"; string uri = "path/to/page/";
Route *route = _server->get_route(uri); Route *route = _server->get_route(uri);
(void)route; (void)route;
char r404[72] = char r404[72] =
"HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!"; "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!";
cout << request << "\n"; cout << request << "\n|===|===|===|\n";
#ifdef __linux__ #ifdef __linux__
send(fd, r404, strlen(r404), MSG_NOSIGNAL); send(fd, r404, strlen(r404), MSG_NOSIGNAL);
#elif __APPLE__ #elif __APPLE__

17
srcs/tools.cpp

@ -1,18 +1,19 @@
#include "webserv.hpp" #include "webserv.hpp"
void *ft_memset(void *b, int c, size_t len) { void *ft_memset(void *b, int c, size_t len) {
size_t i; size_t i;
unsigned char *b_cpy; unsigned char *b_cpy;
b_cpy = (unsigned char *)b; b_cpy = (unsigned char *)b;
i = 0; i = 0;
while (i < len) while (i < len)
*(unsigned char *)(b_cpy + i++) = (unsigned char)c; *(unsigned char *)(b_cpy + i++) = (unsigned char)c;
return ((void *)b); return ((void *)b);
} }
bool isInt(string str) { bool isInt(string str) {
for (string::iterator it = str.begin(); it < str.end(); it++) for (string::iterator it = str.begin(); it < str.end(); it++)
if (*it < '0' || *it > '9') return false; if (*it < '0' || *it > '9')
return false;
return true; return true;
} }

25
srcs/webserv.cpp

@ -1,5 +1,4 @@
#include "webserv.hpp" #include "webserv.hpp"
#include <time.h>
fd_set Socket::_readfds; fd_set Socket::_readfds;
int Socket::_max_fd; int Socket::_max_fd;
@ -8,24 +7,26 @@ int Socket::_amount = 0;
int main(int ac, char **av) { int main(int ac, char **av) {
if (ac > 1) { if (ac > 1) {
cout << "Parsing configuration file...\n"; cout << "Parsing configuration file...\n";
JSONParser parser(av[1]); JSONParser parser(av[1]);
JSONNode *conf = parser.parse(); JSONNode *conf = parser.parse();
cout << "Configuration parsed.\n"; cout << "Configuration parsed.\n";
cout << "Setting environment...\n"; cout << "Setting environment...\n";
Env env(conf); Env env(conf);
while (1) { while (1) {
cout << "|===|===|===| CYCLE |===|===|===|\n";
FD_ZERO(&Socket::_readfds); FD_ZERO(&Socket::_readfds);
Socket::_max_fd = Socket::_min_fd; Socket::_max_fd = Socket::_min_fd;
env.set_fds(); env.set_fds();
int activity = select(Socket::_max_fd + Socket::_amount, &(Socket::_readfds), NULL, NULL, NULL); int activity = select(Socket::_max_fd + Socket::_amount,
&(Socket::_readfds), NULL, NULL, NULL);
if ((activity < 0) && (errno != EINTR)) if ((activity < 0) && (errno != EINTR))
cout << "Select: " << strerror(errno) << "\n"; cout << "Select: " << strerror(errno) << "\n";
env.refresh(); env.refresh();
} }
} }
return (0); return (0);
} }

Loading…
Cancel
Save