Browse Source

extracted sources from headers

test
nicolas-arnaud 2 years ago
parent
commit
9b52e248dc
  1. 17
      .gitignore
  2. 8
      Makefile
  3. 12
      includes/Env.hpp
  4. 30
      includes/Nodes.hpp
  5. 16
      includes/Parser.hpp
  6. 3
      includes/Route.hpp
  7. 13
      includes/Server.hpp
  8. 26
      includes/Socket.hpp
  9. 31
      includes/Token.hpp
  10. 21
      includes/webserv.hpp
  11. 106
      srcs/json/Nodes.cpp
  12. 131
      srcs/json/Nodes.hpp
  13. 200
      srcs/json/Parser.cpp
  14. 211
      srcs/json/Parser.hpp
  15. 111
      srcs/json/Token.cpp
  16. 158
      srcs/json/Token.hpp
  17. 23
      srcs/load/Env.cpp
  18. 28
      srcs/load/Env.hpp
  19. 1
      srcs/load/Route.cpp
  20. 25
      srcs/load/Server.cpp
  21. 33
      srcs/load/Server.hpp
  22. 117
      srcs/load/Socket.cpp
  23. 135
      srcs/load/Socket.hpp
  24. 31
      srcs/server.cpp
  25. 2
      srcs/webserv.cpp

17
.gitignore

@ -1,13 +1,16 @@
*
!srcs/
!srcs/load/
!srcs/json/
!srcs/*/*.cpp
!srcs/*/*.hpp
!srcs/*.hpp
!srcs/*.cpp
!Makefile
!LICENCE
!README.md
!default.json
!.gitignore
!includes/
!includes/*.hpp
!srcs/
!srcs/*.cpp
!srcs/load/
!srcs/json/
!srcs/*/*.cpp

8
Makefile

@ -1,14 +1,16 @@
NAME= server
SRCS= srcs/webserv.cpp srcs/tools.cpp
SRCS= srcs/webserv.cpp srcs/tools.cpp srcs/load/Env.cpp srcs/load/Server.cpp \
srcs/load/Socket.cpp srcs/load/Route.cpp \
srcs/json/Nodes.cpp srcs/json/Token.cpp srcs/json/Parser.cpp
OBJS= $(SRCS:.cpp=.o)
CXX=c++
CXXFLAGS= -g -Werror -Wextra -Wall -std=c++98
CXXFLAGS= -g -I includes -Werror -Wextra -Wall -std=c++98
all : $(NAME)
$(NAME): $(OBJS)
$(CXX) -g -fsanitize=address $(OBJS) -o $(NAME)
$(CXX) -g $(OBJS) -o $(NAME)
clean:
rm -rf $(OBJS)

12
includes/Env.hpp

@ -0,0 +1,12 @@
#pragma once
#include "webserv.hpp"
class JSONNode;
class Server;
class Env {
std::vector<Server> _servers;
public:
Env(JSONNode *conf);
};

30
includes/Nodes.hpp

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

16
includes/Parser.hpp

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

3
srcs/load/Route.hpp → includes/Route.hpp

@ -1,4 +1,5 @@
#include "../webserv.hpp"
#pragma once
#include "webserv.hpp"
class Route {
string _root;

13
includes/Server.hpp

@ -0,0 +1,13 @@
#pragma once
#include "webserv.hpp"
class Server {
string _name;
std::vector<Socket> _sockets;
std::map<string, Route *> _routes;
public:
Server(JSONNode *server);
void check();
};

26
includes/Socket.hpp

@ -0,0 +1,26 @@
#pragma once
#include "webserv.hpp"
class Socket {
string _ip;
int _port;
int _master_socket;
struct sockaddr_in _address;
int _max_clients;
int _client_socket[30];
public:
Socket(string def);
void check();
/*
Socket& operator=(Socket &src) {
_ip = src._ip;
_port = src._port;
_master_socket = src._master_socket;
_address = src._address;
return src;
}
*/
};

31
includes/Token.hpp

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

21
srcs/webserv.hpp → includes/webserv.hpp

@ -1,4 +1,5 @@
#pragma once
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
@ -14,16 +15,30 @@
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
using std::string;
#define DEBUG 0
using std::cout;
using std::strerror;
using std::string;
class JSONNode;
typedef std::map<string, JSONNode *> JSONObject;
typedef std::vector<JSONNode *> JSONList;
void *ft_memset(void *b, int c, size_t len);
bool isInt(string str);
#include "json/Parser.hpp"
#include "load/Env.hpp"
#include "Token.hpp"
#include "Parser.hpp"
#include "Nodes.hpp"
#include "Env.hpp"
#include "Route.hpp"
#include "Socket.hpp"
#include "Server.hpp"

106
srcs/json/Nodes.cpp

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

131
srcs/json/Nodes.hpp

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

200
srcs/json/Parser.cpp

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

211
srcs/json/Parser.hpp

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

111
srcs/json/Token.cpp

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

158
srcs/json/Token.hpp

@ -1,158 +0,0 @@
#include "Nodes.hpp"
#include <fstream>
enum TOKEN {
CURLY_OPEN,
CURLY_CLOSE,
COLON,
STRING,
NUMBER,
ARRAY_OPEN,
ARRAY_CLOSE,
COMMA,
BOOLEAN,
NULL_TYPE
};
typedef struct Token_s {
string value;
TOKEN type;
string toString() {
switch (type) {
case CURLY_OPEN: {
return "Curly open";
}
case CURLY_CLOSE: {
return "Curly close";
}
case COLON: {
return "COLON";
}
case NUMBER: {
return "Number: " + value;
}
case STRING: {
return "String: " + value;
}
case ARRAY_OPEN: {
return "Array open";
}
case ARRAY_CLOSE: {
return "Array close";
}
case COMMA: {
return "Comma";
}
case BOOLEAN: {
return "Boolean: " + value;
}
case NULL_TYPE: {
return "Null";
}
default:
return "Other...";
}
}
} Token;
class Tokenizer {
std::fstream file;
size_t prevPos;
public:
Tokenizer(string fileName) {
file.open(fileName.c_str(), std::ios::in);
if (!file.good())
cout << "File open error"
<< "\n";
};
bool hasMoreTokens() { return !file.eof(); }
char getWithoutWhiteSpace() {
char c = ' ';
while ((c == ' ' || c == '\n') || c == '\t') {
file.get(c); // check
if ((c == ' ' || c == '\n') && !file.good()) {
// cout << file.eof() << " " << file.fail() << "\n";
throw std::logic_error("Ran out of tokens");
} else if (!file.good()) {
return c;
}
}
return c;
};
void rollBackToken() {
if (file.eof())
file.clear();
file.seekg(prevPos);
};
Token getToken() {
char c;
if (file.eof()) {
cout << "Exhaused tokens" << "\n";
// throw std::exception("Exhausted tokens");
}
prevPos = file.tellg();
c = getWithoutWhiteSpace();
Token token;
token.type = NULL_TYPE;
if (c == '"') {
token.type = STRING;
token.value = "";
file.get(c);
while (c != '"') {
token.value += c;
file.get(c);
}
} else if (c == '{') {
token.type = CURLY_OPEN;
} else if (c == '}') {
token.type = CURLY_CLOSE;
} else if (c == '-' || (c >= '0' && c <= '9')) {
// Check if string is numeric
token.type = NUMBER;
token.value = "";
token.value += c;
std::streampos prevCharPos = file.tellg();
while ((c == '-') || (c >= '0' && c <= '9') || c == '.') {
prevCharPos = file.tellg();
file.get(c);
if (file.eof()) {
break;
} else {
if ((c == '-') || (c >= '0' && c <= '9') || (c == '.')) {
token.value += c;
} else {
file.seekg(prevCharPos);
}
}
}
} else if (c == 'f') {
token.type = BOOLEAN;
token.value = "False";
file.seekg(4, std::ios_base::cur);
} else if (c == 't') {
token.type = BOOLEAN;
token.value = "True";
file.seekg(3, std::ios_base::cur);
} else if (c == 'n') {
token.type = NULL_TYPE;
file.seekg(3, std::ios_base::cur);
} else if (c == '[') {
token.type = ARRAY_OPEN;
} else if (c == ']') {
token.type = ARRAY_CLOSE;
} else if (c == ':') {
token.type = COLON;
} else if (c == ',') {
token.type = COMMA;
}
// cout << token.type << " : " << token.value << "\n";
return token;
};
};

23
srcs/load/Env.cpp

@ -0,0 +1,23 @@
#include "webserv.hpp"
Env::Env(JSONNode *conf) {
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(*it);
_servers.push_back(server);
// delete *it;
cout << th[i] << " server launched.\n";
i++;
}
while (1) {
for (std::vector<Server>::iterator it = _servers.begin();
it < _servers.end(); it++) {
(*it).check();
}
}
// delete conf;
}

28
srcs/load/Env.hpp

@ -1,28 +0,0 @@
#include "../webserv.hpp"
#include "Server.hpp"
class Env {
//int _max_clients;
std::vector<Server> _servers;
public:
Env(JSONNode *conf) {
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(*it);
_servers.push_back(server);
//delete *it;
cout << th[i] << " server launched.\n";
i++;
}
while(1) {
for (std::vector<Server>::iterator it = _servers.begin();
it < _servers.end(); it++) {
(*it).check();
}
}
//delete conf;
}
};

1
srcs/load/Route.cpp

@ -0,0 +1 @@
#include "webserv.hpp"

25
srcs/load/Server.cpp

@ -0,0 +1,25 @@
#include "webserv.hpp"
Server::Server(JSONNode *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 i = listens.begin(); i < listens.end(); i++) {
//_listens.push_back((*i)->str());
Socket sock((*i)->str());
_sockets.push_back(sock);
}
//_port = std::atoi(_listens.front().c_str());
}
//_routes["default"] = new Route(datas["root"], datas["return"],
//datas["index"], datas["autoindex"]);
}
void Server::check() {
for (std::vector<Socket>::iterator it = _sockets.begin();
it < _sockets.end(); it++) {
(*it).check();
}
}

33
srcs/load/Server.hpp

@ -1,33 +0,0 @@
#include "../webserv.hpp"
#include "Route.hpp"
#include "Socket.hpp"
class Server {
string _name;
std::vector<Socket> _sockets;
std::map<string, Route *> _routes;
public:
Server(JSONNode *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 i = listens.begin(); i < listens.end(); i++) {
//_listens.push_back((*i)->str());
Socket sock((*i)->str());
_sockets.push_back(sock);
}
//_port = std::atoi(_listens.front().c_str());
}
//_routes["default"] = new Route(datas["root"], datas["return"], datas["index"], datas["autoindex"]);
}
void check() {
for (std::vector<Socket>::iterator it = _sockets.begin(); it < _sockets.end(); it++){
(*it).check();
}
}
};

117
srcs/load/Socket.cpp

@ -0,0 +1,117 @@
#include "webserv.hpp"
Socket::Socket(string def) {
size_t split = def.rfind(':');
string tmp = def.substr(0, split - 1);
_ip = isInt(tmp) ? "localhost" : tmp;
tmp = def.substr(split + 1, def.length() - split - 1).c_str();
_port = !isInt(tmp) ? 80 : std::atoi(tmp.c_str());
_max_clients = 30;
int opt = 1;
_master_socket = socket(AF_INET, SOCK_STREAM, 0);
if (_master_socket == 0) {
cout << "Socket creation: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
int opt_ret = setsockopt(_master_socket, SOL_SOCKET, SO_REUSEADDR,
(char *)&opt, sizeof(opt));
if (opt_ret < 0) {
cout << "Sockopt: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
_address.sin_family = AF_INET;
_address.sin_addr.s_addr = INADDR_ANY;
_address.sin_port = htons(_port);
if (bind(_master_socket, (struct sockaddr *)&_address, sizeof(_address)) <
0) {
cout << "Bind: " << strerror(errno) << "\n";
cout << "Socket destroyed!\n";
return;
exit(EXIT_FAILURE);
}
cout << "Listener on port " << _port << "\n";
if (listen(_master_socket, 3) < 0) {
cout << "Listen: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
for (int i = 0; i < _max_clients; i++)
_client_socket[i] = 0;
}
void Socket::check() {
int new_socket, activity, i, valread, sd;
char buffer[1024];
char r404[72] =
"HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!";
fd_set readfds;
int max_sd = _master_socket;
int addrlen = sizeof(_address);
FD_ZERO(&readfds);
FD_SET(_master_socket, &readfds);
for (i = 0; i < _max_clients; i++) {
sd = _client_socket[i];
if (sd > 0)
FD_SET(sd, &readfds);
if (sd > max_sd)
max_sd = sd;
}
activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);
if ((activity < 0) && (errno != EINTR))
cout << "Select: " << strerror(errno) << "\n";
if (FD_ISSET(_master_socket, &readfds)) {
new_socket = accept(_master_socket, (struct sockaddr *)&_address,
(socklen_t *)&addrlen);
if (new_socket < 0) {
cout << "Accept: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
#ifdef __APPLE__
fcntl(new_socket, F_GETNOSIGPIPE);
#endif
cout << "New connection, socket fd is " << new_socket
<< ", ip is : " << inet_ntoa(_address.sin_addr)
<< ", port : " << ntohs(_address.sin_port) << "\n";
for (i = 0; i < _max_clients; i++) {
if (_client_socket[i] == 0) {
_client_socket[i] = new_socket;
cout << "Adding to list of sockets as " << i << "\n";
break;
}
}
}
cout << "Socket: " << _ip << ":" << _port << "\n";
for (i = 0; i < _max_clients; i++) {
sd = _client_socket[i];
if (FD_ISSET(sd, &readfds)) {
cout << "Client " << i << ": set\n";
valread = read(sd, buffer, 1024);
if (valread == 0) {
getpeername(sd, (struct sockaddr *)&_address,
(socklen_t *)&addrlen);
cout << "Host disconnected, ip " << inet_ntoa(_address.sin_addr)
<< ", port " << ntohs(_address.sin_port) << "\n";
close(sd);
_client_socket[i] = 0;
} else {
cout << buffer << "\n";
#ifdef __linux__
send(sd, r404, strlen(r404), MSG_NOSIGNAL);
#elif __APPLE__
send(sd, r404, strlen(r404), 0);
#endif
}
}
}
}

135
srcs/load/Socket.hpp

@ -1,135 +0,0 @@
#include "../webserv.hpp"
class Socket {
string _ip;
int _port;
int _master_socket;
struct sockaddr_in _address;
int _max_clients;
int _client_socket[30];
public:
Socket(string def) {
size_t split = def.rfind(':');
string tmp = def.substr(0, split - 1);
_ip = isInt(tmp) ? "localhost" : tmp;
tmp = def.substr(split + 1, def.length() - split - 1).c_str();
_port = !isInt(tmp) ? 80 : std::atoi(tmp.c_str());
_max_clients = 30;
int opt = 1;
_master_socket = socket(AF_INET, SOCK_STREAM, 0);
if (_master_socket == 0) {
cout << "Socket creation: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
int opt_ret = setsockopt(_master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
if (opt_ret < 0) {
cout << "Sockopt: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
_address.sin_family = AF_INET;
_address.sin_addr.s_addr = INADDR_ANY;
_address.sin_port = htons(_port);
if (bind(_master_socket, (struct sockaddr *)&_address, sizeof(_address)) < 0) {
cout << "Bind: " << strerror(errno) << "\n";
cout << "Socket destroyed!\n";
return ;
exit(EXIT_FAILURE);
}
cout << "Listener on port " << _port << "\n";
if (listen(_master_socket, 3) < 0) {
cout << "Listen: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
for (int i = 0; i < _max_clients; i++)
_client_socket[i] = 0;
}
void check() {
int new_socket, activity, i, valread, sd;
char buffer[1024];
char r404[72] = "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!";
fd_set readfds;
int max_sd = _master_socket;
int addrlen = sizeof(_address);
FD_ZERO(&readfds);
FD_SET(_master_socket, &readfds);
for (i = 0; i < _max_clients; i++) {
sd = _client_socket[i];
if (sd > 0)
FD_SET(sd, &readfds);
if (sd > max_sd)
max_sd = sd;
}
activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);
if ((activity < 0) && (errno != EINTR))
cout << "Select: " << strerror(errno) << "\n";
if (FD_ISSET(_master_socket, &readfds)) {
new_socket = accept(_master_socket, (struct sockaddr *)&_address,(socklen_t *)&addrlen);
if (new_socket < 0) {
cout << "Accept: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
#ifdef __APPLE__
fcntl(new_socket, F_GETNOSIGPIPE);
#endif
cout << "New connection, socket fd is " << new_socket
<< ", ip is : " << inet_ntoa(_address.sin_addr)
<< ", port : " << ntohs(_address.sin_port) << "\n";
for (i = 0; i < _max_clients; i++) {
if (_client_socket[i] == 0) {
_client_socket[i] = new_socket;
cout << "Adding to list of sockets as " << i << "\n";
break;
}
}
}
cout << "Socket: " << _ip << ":" << _port << "\n";
for (i = 0; i < _max_clients; i++) {
sd = _client_socket[i];
if (FD_ISSET(sd, &readfds)) {
cout << "Client " << i << ": set\n";
valread = read(sd, buffer, 1024);
if (valread == 0) {
getpeername(sd, (struct sockaddr *)&_address,
(socklen_t *)&addrlen);
cout << "Host disconnected, ip "
<< inet_ntoa(_address.sin_addr) << ", port "
<< ntohs(_address.sin_port) << "\n";
close(sd);
_client_socket[i] = 0;
} else {
cout << buffer << "\n";
#ifdef __linux__
send(sd, r404, strlen(r404), MSG_NOSIGNAL);
#elif __APPLE__
send(sd, r404, strlen(r404), 0);
#endif
}
}
}
}
/*
Socket& operator=(Socket &src) {
_ip = src._ip;
_port = src._port;
_master_socket = src._master_socket;
_address = src._address;
return src;
}
*/
};

31
srcs/server.cpp

@ -1,31 +0,0 @@
#include "webserv.hpp"
#include "json/Parser.hpp"
#include "load/Env.hpp"
int main(int ac, char **av) {
Env env;
if (ac > 1) {
cout << "Parsing configuration file...\n";
JSONParser parser(av[1]);
JSONNode *conf = parser.parse();
cout << "Configuration parsed.\n";
cout << "Setting environment...\n";
env.max_clients = conf->obj()["max_clients"]->nbr();
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);
delete *it;
server->launch();
cout << th[i] << " server launched.";
i++;
}
delete conf;
}
return (0);
}

2
srcs/webserv.cpp

@ -10,7 +10,7 @@ int main(int ac, char **av) {
cout << "Configuration parsed.\n";
cout << "Setting environment...\n";
Env env(conf);
Env env(conf);
}
return (0);
}

Loading…
Cancel
Save