mirror of
https://github.com/3lswear/webserv.git
synced 2025-10-29 13:27:59 +03:00
add: config validity check
This commit is contained in:
@@ -90,18 +90,42 @@ void ServerConfig::setRoot(TOMLMap * data)
|
|||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------Parse-Config---------------------------------------
|
//--------------------------------------------------Parse-Config---------------------------------------
|
||||||
|
std::string ServerConfig::getTypestr(toml_node::e_type type)
|
||||||
|
{
|
||||||
|
if (type == toml_node::NUM)
|
||||||
|
return ("NUM");
|
||||||
|
else if (type == toml_node::ARRAY)
|
||||||
|
return ("ARRAY");
|
||||||
|
else if (type == toml_node::BOOL)
|
||||||
|
return ("BOOL");
|
||||||
|
else if (type == toml_node::STRING)
|
||||||
|
return ("STRING");
|
||||||
|
else if (type == toml_node::MAP)
|
||||||
|
return ("MAP");
|
||||||
|
else if (type == toml_node::MAPARRAY)
|
||||||
|
return ("MAPARRAY");
|
||||||
|
else
|
||||||
|
return ("UNKNOWN");
|
||||||
|
}
|
||||||
|
std::string ServerConfig::getWrongTypeErrorMSG(std::string field, toml_node::e_type expected, toml_node::e_type received)
|
||||||
|
{
|
||||||
|
std::string out = "Wrong type specified in " + field + " field, expected "
|
||||||
|
+ getTypestr(expected) + ", but received " + getTypestr(received) + "!";
|
||||||
|
return (out);
|
||||||
|
}
|
||||||
int ServerConfig::putBodySizeLimit(toml_node *node)
|
int ServerConfig::putBodySizeLimit(toml_node *node)
|
||||||
{
|
{
|
||||||
if (node->get_type() != toml_node::NUM)
|
if (node->get_type() != toml_node::NUM)
|
||||||
return (1);
|
throw ConfigException(getWrongTypeErrorMSG("body_size_limit", toml_node::NUM, node->get_type()));
|
||||||
_clientBodySize = node->getNum();
|
_clientBodySize = node->getNum();
|
||||||
|
if (_clientBodySize < 0)
|
||||||
|
throw ConfigException("Invalid body_size_limit specified!");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
int ServerConfig::putErrorPage(toml_node *node)
|
int ServerConfig::putErrorPage(toml_node *node)
|
||||||
{
|
{
|
||||||
if (node->get_type() != toml_node::MAP)
|
if (node->get_type() != toml_node::MAP)
|
||||||
return (1);
|
throw ConfigException(getWrongTypeErrorMSG("error_page", toml_node::MAP, node->get_type()));
|
||||||
TOMLMap *map = node->getMap();
|
TOMLMap *map = node->getMap();
|
||||||
TOMLMap::iterator it;
|
TOMLMap::iterator it;
|
||||||
std::string s;
|
std::string s;
|
||||||
@@ -110,7 +134,7 @@ int ServerConfig::putErrorPage(toml_node *node)
|
|||||||
while (it != map->end())
|
while (it != map->end())
|
||||||
{
|
{
|
||||||
if (it->second->get_type() != toml_node::STRING)
|
if (it->second->get_type() != toml_node::STRING)
|
||||||
return (1);
|
throw ConfigException(getWrongTypeErrorMSG("error_page path", toml_node::STRING, node->get_type()));
|
||||||
s = it->first;
|
s = it->first;
|
||||||
_errorPages[atoi(s.c_str())] = *it->second->getString();
|
_errorPages[atoi(s.c_str())] = *it->second->getString();
|
||||||
++it;
|
++it;
|
||||||
@@ -120,22 +144,27 @@ int ServerConfig::putErrorPage(toml_node *node)
|
|||||||
int ServerConfig::putHost(toml_node *node)
|
int ServerConfig::putHost(toml_node *node)
|
||||||
{
|
{
|
||||||
if (node->get_type() != toml_node::STRING)
|
if (node->get_type() != toml_node::STRING)
|
||||||
return (1);
|
throw ConfigException(getWrongTypeErrorMSG("host", toml_node::STRING, node->get_type()));
|
||||||
_host = *node->getString();
|
_host = *node->getString();
|
||||||
|
int ret = inet_addr(_host.c_str());
|
||||||
|
if (ret == -1)
|
||||||
|
throw ConfigException("Invalid host specified!");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
int ServerConfig::putName(toml_node *node)
|
int ServerConfig::putName(toml_node *node)
|
||||||
{
|
{
|
||||||
if (node->get_type() != toml_node::STRING)
|
if (node->get_type() != toml_node::STRING)
|
||||||
return (1);
|
throw ConfigException(getWrongTypeErrorMSG("server_name", toml_node::STRING, node->get_type()));
|
||||||
_serverName = *node->getString();
|
_serverName = *node->getString();
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
int ServerConfig::putPort(toml_node *node)
|
int ServerConfig::putPort(toml_node *node)
|
||||||
{
|
{
|
||||||
if (node->get_type() != toml_node::NUM)
|
if (node->get_type() != toml_node::NUM)
|
||||||
return (1);
|
throw ConfigException(getWrongTypeErrorMSG("server_name", toml_node::NUM, node->get_type()));
|
||||||
_port = node->getNum();
|
_port = node->getNum();
|
||||||
|
if (_port < 0 || _port > 65536)
|
||||||
|
throw ConfigException("Invalid port specified!");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,62 +199,61 @@ int ServerConfig::putLocation(toml_node *node)
|
|||||||
if (it1->first == "location")
|
if (it1->first == "location")
|
||||||
{
|
{
|
||||||
if (it1->second->get_type() != toml_node::STRING)
|
if (it1->second->get_type() != toml_node::STRING)
|
||||||
continue;
|
throw ConfigException(getWrongTypeErrorMSG("location", toml_node::STRING, it1->second->get_type()));
|
||||||
tmp->location = *it1->second->getString();
|
tmp->location = *it1->second->getString();
|
||||||
}
|
}
|
||||||
else if (it1->first == "root")
|
else if (it1->first == "root")
|
||||||
{
|
{
|
||||||
if (it1->second->get_type() != toml_node::STRING)
|
if (it1->second->get_type() != toml_node::STRING)
|
||||||
continue ;
|
throw ConfigException(getWrongTypeErrorMSG("root", toml_node::STRING, it1->second->get_type()));
|
||||||
tmp->root = *it1->second->getString();
|
tmp->root = *it1->second->getString();
|
||||||
}
|
}
|
||||||
else if (it1->first == "autoindex")
|
else if (it1->first == "autoindex")
|
||||||
{
|
{
|
||||||
if (it1->second->get_type() != toml_node::BOOL)
|
if (it1->second->get_type() != toml_node::BOOL)
|
||||||
continue ;
|
throw ConfigException(getWrongTypeErrorMSG("autoindex", toml_node::BOOL, it1->second->get_type()));
|
||||||
tmp->autoindex = it1->second->getBool();
|
tmp->autoindex = it1->second->getBool();
|
||||||
}
|
}
|
||||||
else if (it1->first == "upload_accept")
|
else if (it1->first == "upload_accept")
|
||||||
{
|
{
|
||||||
if (it1->second->get_type() != toml_node::BOOL)
|
if (it1->second->get_type() != toml_node::BOOL)
|
||||||
continue ;
|
throw ConfigException(getWrongTypeErrorMSG("upload_accept", toml_node::BOOL, it1->second->get_type()));
|
||||||
tmp->uploadAccept = it1->second->getBool();
|
tmp->uploadAccept = it1->second->getBool();
|
||||||
}
|
}
|
||||||
else if (it1->first == "upload_dir")
|
else if (it1->first == "upload_dir")
|
||||||
{
|
{
|
||||||
if (it1->second->get_type() != toml_node::STRING)
|
if (it1->second->get_type() != toml_node::STRING)
|
||||||
continue ;
|
throw ConfigException(getWrongTypeErrorMSG("upload_dir", toml_node::STRING, it1->second->get_type()));
|
||||||
tmp->uploadDir = *it1->second->getString();
|
tmp->uploadDir = *it1->second->getString();
|
||||||
}
|
}
|
||||||
else if (it1->first == "cgi_pass")
|
else if (it1->first == "cgi_pass")
|
||||||
{
|
{
|
||||||
if (it1->second->get_type() != toml_node::STRING)
|
if (it1->second->get_type() != toml_node::STRING)
|
||||||
continue ;
|
throw ConfigException(getWrongTypeErrorMSG("cgi_pass", toml_node::STRING, it1->second->get_type()));
|
||||||
tmp->cgi_pass = *it1->second->getString();
|
tmp->cgi_pass = *it1->second->getString();
|
||||||
}
|
}
|
||||||
else if (it1->first == "body_size_limit")
|
else if (it1->first == "body_size_limit")
|
||||||
{
|
{
|
||||||
DBOUT << "BodySize in locaton" << ENDL;
|
|
||||||
if (it1->second->get_type() != toml_node::NUM)
|
if (it1->second->get_type() != toml_node::NUM)
|
||||||
continue;
|
throw ConfigException(getWrongTypeErrorMSG("body_size_limit", toml_node::NUM, it1->second->get_type()));
|
||||||
tmp->clientBodySize = it1->second->getNum();
|
tmp->clientBodySize = it1->second->getNum();
|
||||||
}
|
}
|
||||||
else if (it1->first == "directory_file")
|
else if (it1->first == "directory_file")
|
||||||
{
|
{
|
||||||
if (it1->second->get_type() != toml_node::STRING)
|
if (it1->second->get_type() != toml_node::STRING)
|
||||||
continue ;
|
throw ConfigException(getWrongTypeErrorMSG("directory_file", toml_node::STRING, it1->second->get_type()));
|
||||||
tmp->directoryFile = *it1->second->getString();
|
tmp->directoryFile = *it1->second->getString();
|
||||||
}
|
}
|
||||||
else if (it1->first == "methods")
|
else if (it1->first == "methods")
|
||||||
{
|
{
|
||||||
if (it1->second->get_type() != toml_node::ARRAY)
|
if (it1->second->get_type() != toml_node::ARRAY)
|
||||||
continue ;
|
throw ConfigException(getWrongTypeErrorMSG("methods", toml_node::ARRAY, it1->second->get_type()));
|
||||||
Array = *it1->second->getArray();
|
Array = *it1->second->getArray();
|
||||||
it2 = Array.begin();
|
it2 = Array.begin();
|
||||||
while (it2 != Array.end())
|
while (it2 != Array.end())
|
||||||
{
|
{
|
||||||
if ((*it2)->get_type() != toml_node::STRING)
|
if ((*it2)->get_type() != toml_node::STRING)
|
||||||
continue ;
|
throw ConfigException(getWrongTypeErrorMSG("methods elem", toml_node::STRING, (*it2)->get_type()));
|
||||||
tmp->methods.push_back(*((*it2)->getString()));
|
tmp->methods.push_back(*((*it2)->getString()));
|
||||||
++it2;
|
++it2;
|
||||||
}
|
}
|
||||||
@@ -233,11 +261,17 @@ int ServerConfig::putLocation(toml_node *node)
|
|||||||
else if (it1->first == "redirect")
|
else if (it1->first == "redirect")
|
||||||
{
|
{
|
||||||
if (it1->second->get_type() != toml_node::ARRAY)
|
if (it1->second->get_type() != toml_node::ARRAY)
|
||||||
continue ;
|
throw ConfigException(getWrongTypeErrorMSG("redirect", toml_node::ARRAY, it1->second->get_type()));
|
||||||
Array = *it1->second->getArray();
|
Array = *it1->second->getArray();
|
||||||
|
if (Array.size() != 2)
|
||||||
|
throw ConfigException("The redirect field specified the wrong number of arguments!");
|
||||||
it2 = Array.begin();
|
it2 = Array.begin();
|
||||||
|
if ((*it2)->get_type() != toml_node::STRING)
|
||||||
|
throw ConfigException(getWrongTypeErrorMSG("redirect elem", toml_node::STRING, (*it2)->get_type()));
|
||||||
str = *(*it2)->getString();
|
str = *(*it2)->getString();
|
||||||
++it2;
|
++it2;
|
||||||
|
if ((*it2)->get_type() != toml_node::STRING)
|
||||||
|
throw ConfigException(getWrongTypeErrorMSG("redirect elem", toml_node::STRING, (*it2)->get_type()));
|
||||||
tmp->redirect.insert(std::make_pair(atoi(str.c_str()), *(*it2)->getString()));
|
tmp->redirect.insert(std::make_pair(atoi(str.c_str()), *(*it2)->getString()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -279,6 +313,58 @@ void ServerConfig::fillFields(void)
|
|||||||
ret = identify(block);
|
ret = identify(block);
|
||||||
++block;
|
++block;
|
||||||
}
|
}
|
||||||
|
checkConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServerConfig::checkFileAndDir(location *loc)
|
||||||
|
{
|
||||||
|
std::string root = loc->root;
|
||||||
|
std::string upload_dir = loc->uploadDir;
|
||||||
|
std::string directory_file = loc->directoryFile;
|
||||||
|
DIR *dir;
|
||||||
|
if (!root.empty())
|
||||||
|
{
|
||||||
|
dir = opendir(root.c_str());
|
||||||
|
if (dir == NULL)
|
||||||
|
throw ConfigException("Directory " + root + " " + strerror(errno) + "!");
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
if (!upload_dir.empty())
|
||||||
|
{
|
||||||
|
dir = opendir(upload_dir.c_str());
|
||||||
|
if (dir == NULL)
|
||||||
|
throw ConfigException("Directory " + upload_dir + " " + strerror(errno) + "!");
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
if (!directory_file.empty())
|
||||||
|
{
|
||||||
|
directory_file = root + "/" + directory_file;
|
||||||
|
std::ofstream file(directory_file.c_str(), std::ios::out | std::ios::binary);
|
||||||
|
if (!file.is_open())
|
||||||
|
throw ConfigException("File " + directory_file + " " + strerror(errno) + "!");
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerConfig::checkConfig(void)
|
||||||
|
{
|
||||||
|
if (_host.empty())
|
||||||
|
throw ConfigException("Host field not set!");
|
||||||
|
else if (_port == 0)
|
||||||
|
throw ConfigException("Port field not set!");
|
||||||
|
std::vector<location *>::iterator it;
|
||||||
|
|
||||||
|
it = _locations.begin();
|
||||||
|
location *tmp;
|
||||||
|
while (it != _locations.end())
|
||||||
|
{
|
||||||
|
tmp = *it;
|
||||||
|
if (tmp->location.empty())
|
||||||
|
throw ConfigException("Location field not set!");
|
||||||
|
checkFileAndDir(tmp);
|
||||||
|
it++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerConfig::printFields(void)
|
void ServerConfig::printFields(void)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define SERVERCONFIG_HPP
|
#define SERVERCONFIG_HPP
|
||||||
|
|
||||||
#include "webserv.hpp"
|
#include "webserv.hpp"
|
||||||
|
#include "ConfigException.hpp"
|
||||||
#include "parse.hpp"
|
#include "parse.hpp"
|
||||||
|
|
||||||
struct location
|
struct location
|
||||||
@@ -47,6 +48,7 @@ public:
|
|||||||
void setErrorPages(std::map<int, std::string>);
|
void setErrorPages(std::map<int, std::string>);
|
||||||
void setLocations(std::vector<location *>);
|
void setLocations(std::vector<location *>);
|
||||||
void setRoot(TOMLMap *);
|
void setRoot(TOMLMap *);
|
||||||
|
void checkConfig(void);
|
||||||
|
|
||||||
std::string &getServerName(void);
|
std::string &getServerName(void);
|
||||||
std::string &getHost(void);
|
std::string &getHost(void);
|
||||||
@@ -67,11 +69,15 @@ private:
|
|||||||
int putName(toml_node *);
|
int putName(toml_node *);
|
||||||
int putPort(toml_node *);
|
int putPort(toml_node *);
|
||||||
int putLocation(toml_node *);
|
int putLocation(toml_node *);
|
||||||
|
std::string getTypestr(toml_node::e_type);
|
||||||
|
std::string getWrongTypeErrorMSG(std::string field, toml_node::e_type expected, toml_node::e_type received);
|
||||||
|
bool checkFileAndDir(location *);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void fillFields(void);
|
void fillFields(void);
|
||||||
void printFields(void);
|
void printFields(void);
|
||||||
|
|
||||||
|
|
||||||
~ServerConfig();
|
~ServerConfig();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
0
src/config/ConfigException.cpp
Normal file
0
src/config/ConfigException.cpp
Normal file
17
src/config/ConfigException.hpp
Normal file
17
src/config/ConfigException.hpp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef CONFIGEXCEPTION_HPP
|
||||||
|
#define CONFIGEXCEPTION_HPP
|
||||||
|
|
||||||
|
#include "webserv.hpp"
|
||||||
|
|
||||||
|
class ConfigException
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string _msg;
|
||||||
|
public:
|
||||||
|
ConfigException(std::string const &str) : _msg(str){}
|
||||||
|
~ConfigException(){}
|
||||||
|
std::string getMessage() const {return (_msg);}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "webserv.hpp"
|
#include "webserv.hpp"
|
||||||
#include "parse.hpp"
|
#include "parse.hpp"
|
||||||
#include "Server.hpp"
|
#include "Server.hpp"
|
||||||
|
#include "ConfigException.hpp"
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@@ -19,10 +20,10 @@ int main(int argc, char **argv)
|
|||||||
server.readConfig(path);
|
server.readConfig(path);
|
||||||
server.start();
|
server.start();
|
||||||
}
|
}
|
||||||
catch(const std::exception& e)
|
catch(const ConfigException& e)
|
||||||
{
|
{
|
||||||
std::cerr << RED << e.what() << '\n' << ENDL;
|
|
||||||
}
|
|
||||||
server.end();
|
server.end();
|
||||||
|
std::cerr << RED << e.getMessage() << '\n' << ENDL;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user